-
-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ConfigManager #1160
Add ConfigManager #1160
Conversation
To the point where current integration tests are passing.
We just check overrides for one config value, since we aren't checking that the PureConfig library can load configs, only that our desired precedence levels and overrides work as expected via the PureConfig library. I've tested the default global config locally, as I'm not sure of a good way to put that in the integration tests.
- To use the authorship schema proposed in the new ADR template. - To reflect introduction of the ConfigManager
470e217
to
3cf3d30
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! See several comments.
Apalache should also look for a local configuration file `.apalache.cfg`, within | ||
current working directory or its parents. If it finds such file, any configured | ||
parameters therein will override the parameters from the global config file. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder, whether we want to merge the TLC config in our configuration settings too. Certainly, we have way more options than the TLC config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd not be opposed, but I'm also not very clear on the use or nature of TLC configuration. Could you maybe elaborate on #1177 or a new issue?
In either case, I think that'd be work for a followup.
Local configuration files support JSON and the JSON superset | ||
[HOCON](/~https://github.com/lightbend/config/blob/master/HOCON.md). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JSON has a weird limit on the length of integer literals. Does it apply to HOCON too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a limit on integer sizes in the JSON spec: https://www.json.org/json-en.html
Is this an implementation detail of certain deserialization libs, or is there a different spec where you've seen this?
I'm not sure whether the implementation of HOCON has such a limit. The docs seem to indicate a limit of 64 bit integers: /~https://github.com/lightbend/config/blob/main/HOCON.md
I don't see how this could be a problem for any of the current configurations we support tho.
```yaml | ||
# Directory in which to write all log files and records of each run | ||
out-dir: "${PWD}/_apalache-out" | ||
|
||
# Whether or not to write additional files, that report on intermediate | ||
# processing steps | ||
write-intermediate: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This example looks like yaml, not json, which contradicts the preceding sentence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which sentence does it contradict? This is valid HOCON.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. I'm just happy General
finally defines a file
field.
@@ -67,9 +68,18 @@ following: | |||
|
|||
## 4. Global Configuration File | |||
|
|||
Apalache should define a global configuration file `apalache-global-config`, e.g. in the `<HOME>/.tlaplus` directory, in which users can define the default values of all parameters, including all flags listed in section 1, as well as `out-dir`. The format of the configuration file is an implementation detail and will not be specified here. | |||
Apalache should define a global configuration file `apalache.cfg`, e.g. in the `<HOME>/.tlaplus` directory, in which users can define the default values of all parameters, including all flags listed in section 1, as well as `out-dir`. The format of the configuration file is an implementation detail and will not be specified here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I recall Igor complaining about the name apalache.cfg
last time I suggested it
#1025 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That link doesn't actually take me to a particular comment (I think just because of how github hides resolved comments). @konnov are you still opposed to this config file name? It seems in keeping with the conventions I'm familiar with from other tools and the patterns suggested by the PureConfig
docs.
val TLA_PLUS_DIR = ".tlaplus" | ||
val APALACHE_CFG = "apalache.cfg" | ||
val DOT_APALACHE_CFG = "." + APALACHE_CFG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't these be better suited for a companion object?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know :)
What's the advantage of putting it it in the companion object?
I do think these should private tho. I'll at least change that.
I can't find anything in the Scala style guide that says where fields like this should be declared. Could you point me towards something that explains why putting such things in companion object might be preferable?
My own feeling is that -- in this case -- moving these into the companion object it would negatively impact readability: these values are only accessed in the class methods, and don't show up anywhere in the one method in the companion object. Moving them would then require readers to jump back and forth between the class and the companion object to see what means what.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we generally have the convention across the codebase that any public static X
-type value goes in a companion object, so it can be accessed without creating a fresh instance.
This page quotes the "Scala Cookbook": https://alvinalexander.com/scala/how-to-static-members-in-scala-companion-objects-fields-methods/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not gospel, but it is convention elsewhere in the project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the fact that these are (now) private and not meant to be accessed outside of the class at all impact your feelings on this? (I.e., they are never supposed to be accessed at all, whether by creating instance or not).
I still don't see there anything that explains a benefit in this case, and the downside on readability (and abstraction) seem pretty evident to me. I don't want to buck our conventions, but I'd rather there be a good reason if I'm going to negatively impact readability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A bit more concretely, that recipe is for the case where
You want to create a Scala class that has both instance methods and static methods, but unlike Java, Scala does not have a static keyword.
afaict, that's not what we're actually after here.
Local configuration files support JSON and the JSON superset | ||
[HOCON](/~https://github.com/lightbend/config/blob/master/HOCON.md). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see a limit on integer sizes in the JSON spec: https://www.json.org/json-en.html
Is this an implementation detail of certain deserialization libs, or is there a different spec where you've seen this?
I'm not sure whether the implementation of HOCON has such a limit. The docs seem to indicate a limit of 64 bit integers: /~https://github.com/lightbend/config/blob/main/HOCON.md
I don't see how this could be a problem for any of the current configurations we support tho.
```yaml | ||
# Directory in which to write all log files and records of each run | ||
out-dir: "${PWD}/_apalache-out" | ||
|
||
# Whether or not to write additional files, that report on intermediate | ||
# processing steps | ||
write-intermediate: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which sentence does it contradict? This is valid HOCON.
val TLA_PLUS_DIR = ".tlaplus" | ||
val APALACHE_CFG = "apalache.cfg" | ||
val DOT_APALACHE_CFG = "." + APALACHE_CFG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know :)
What's the advantage of putting it it in the companion object?
I do think these should private tho. I'll at least change that.
I can't find anything in the Scala style guide that says where fields like this should be declared. Could you point me towards something that explains why putting such things in companion object might be preferable?
My own feeling is that -- in this case -- moving these into the companion object it would negatively impact readability: these values are only accessed in the class methods, and don't show up anywhere in the one method in the companion object. Moving them would then require readers to jump back and forth between the class and the companion object to see what means what.
tla-io/src/main/scala/at/forsyte/apalache/io/ConfigManager.scala
Outdated
Show resolved
Hide resolved
Co-authored-by: Kukovec <jure.kukovec@gmail.com> Co-authored-by: Igor Konnov <igor@informal.systems>
Closes #1069
This adds the configuration management component, based around
PureConfig
,decided for in #1156:
Changes:
PureConfig
ApalacheConfigs
trait (extendingOutputManagerConfig
) to serveas the collection of loadable application configurations.
ConfigManager(cli: CliArgs)
class as a sibling ofOutputManager
.apalache.cfg
, starting from the cwd, and climbing up through parent dirs.OutputManager
, removing thesyncFromCli
method.Routine:
make fmt-fix
(or had formatting run automatically on all files edited)