Skip to content
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

Merged
merged 14 commits into from
Dec 15, 2021
Merged

Add ConfigManager #1160

merged 14 commits into from
Dec 15, 2021

Conversation

shonfeder
Copy link
Contributor

@shonfeder shonfeder commented Dec 8, 2021

Closes #1069

This adds the configuration management component, based around PureConfig,
decided for in #1156:

Changes:

  • Add dependency on PureConfig
  • Specify ApalacheConfigs trait (extending OutputManagerConfig) to serve
    as the collection of loadable application configurations.
  • Add new ConfigManager(cli: CliArgs) class as a sibling of OutputManager
  • Look for a local config file .apalache.cfg, starting from the cwd, and climbing up through parent dirs.
  • Factor out all configuration from OutputManager, removing the
    syncFromCli method.

Routine:

  • Tests added for any new code
  • Ran make fmt-fix (or had formatting run automatically on all files edited)
  • Documentation added for any new functionality
  • Entry added to UNRELEASED.md for any new functionality

Shon Feder added 10 commits December 14, 2021 20:57
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
@shonfeder shonfeder force-pushed the shon/1069/add-config-mgr branch from 470e217 to 3cf3d30 Compare December 15, 2021 01:57
@shonfeder shonfeder requested review from Kukovec and konnov December 15, 2021 02:05
@shonfeder shonfeder marked this pull request as ready for review December 15, 2021 02:06
@shonfeder shonfeder changed the title WIP: Add ConfigManager Add ConfigManager Dec 15, 2021
Copy link
Collaborator

@konnov konnov left a 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.

Comment on lines +73 to +75
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.
Copy link
Collaborator

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.

Copy link
Contributor Author

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.

Comment on lines +31 to +32
Local configuration files support JSON and the JSON superset
[HOCON](/~https://github.com/lightbend/config/blob/master/HOCON.md).
Copy link
Collaborator

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?

Copy link
Contributor Author

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.

Comment on lines +37 to +43
```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
Copy link
Collaborator

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.

Copy link
Contributor Author

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.

docs/src/apalache/running.md Show resolved Hide resolved
docs/src/adr/009adr-outputs.md Outdated Show resolved Hide resolved
docs/src/apalache/running.md Outdated Show resolved Hide resolved
Copy link
Collaborator

@Kukovec Kukovec left a 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.
Copy link
Collaborator

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)

Copy link
Contributor Author

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.

docs/src/adr/009adr-outputs.md Outdated Show resolved Hide resolved
docs/src/apalache/config.md Outdated Show resolved Hide resolved
docs/src/apalache/config.md Outdated Show resolved Hide resolved
docs/src/apalache/config.md Show resolved Hide resolved
docs/src/apalache/config.md Show resolved Hide resolved
docs/src/apalache/running.md Outdated Show resolved Hide resolved
Comment on lines 62 to 64
val TLA_PLUS_DIR = ".tlaplus"
val APALACHE_CFG = "apalache.cfg"
val DOT_APALACHE_CFG = "." + APALACHE_CFG
Copy link
Collaborator

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?

Copy link
Contributor Author

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.

Copy link
Collaborator

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/

Copy link
Collaborator

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

docs/src/adr/009adr-outputs.md Outdated Show resolved Hide resolved
docs/src/adr/009adr-outputs.md Outdated Show resolved Hide resolved
docs/src/apalache/running.md Show resolved Hide resolved
docs/src/apalache/running.md Show resolved Hide resolved
docs/src/adr/009adr-outputs.md Outdated Show resolved Hide resolved
Comment on lines +31 to +32
Local configuration files support JSON and the JSON superset
[HOCON](/~https://github.com/lightbend/config/blob/master/HOCON.md).
Copy link
Contributor Author

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.

Comment on lines +37 to +43
```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
Copy link
Contributor Author

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.

docs/src/apalache/config.md Show resolved Hide resolved
docs/src/apalache/running.md Outdated Show resolved Hide resolved
Comment on lines 62 to 64
val TLA_PLUS_DIR = ".tlaplus"
val APALACHE_CFG = "apalache.cfg"
val DOT_APALACHE_CFG = "." + APALACHE_CFG
Copy link
Contributor Author

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.

Co-authored-by: Kukovec <jure.kukovec@gmail.com>
Co-authored-by: Igor Konnov <igor@informal.systems>
@shonfeder shonfeder requested a review from Kukovec December 15, 2021 15:23
@shonfeder shonfeder enabled auto-merge December 15, 2021 18:28
@shonfeder shonfeder merged commit 49138e1 into unstable Dec 15, 2021
@apalache-bot apalache-bot mentioned this pull request Dec 20, 2021
@apalache-bot apalache-bot mentioned this pull request Dec 20, 2021
@shonfeder shonfeder deleted the shon/1069/add-config-mgr branch February 4, 2022 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[FEATURE] Route all configuration management through a single component
3 participants