Conversation
|
@ArquintL this is marked as a draft PR but you asked for the review. Should I provide feedback on the implementation already? regarding the cli options, I would opt for one of the following:
|
|
@jcp19 This PR is in draft mode as the design choices are more like suggestions. Code-wise, I do not have any additional changes planned so I'd appreciate a code review. We currently do not have a JSON field for every existing CLI option but if necessary, we can always add more (in separate PRs) |
|
High-level questions about the design:
|
|
I think that the following design could also work:
Under this design, the (*) While thinking of how all options relate to each other, and especially, how the configs of each package relate to each other, I was confronted again with the fact that right now, we read all configs of all files, regardless of their packages. I think this is a bad idea, which leads to unexpected results (e.g., if we import a package that was verified for overflow checks, it enables overflow checks for the current package). Maybe we should consider deprecating in-file configs when we introduce the json config, except for tests. |
Sorry for the imprecision, it's only mandatory if
One can argue whether we should allow
If both files are optional? How would we identify which folder forms a module's root? By detecting
Not sure whether this is less confusing but I think that this should work. The only weird case affects |
Either that or by traversing the directory tree, starting in the current package, and moving from parent to parent until a
IIRC, you do not pass a package in the recursive mode, but rather, the project root. So, I guess we would iterate through all packages in that directory. I think we need to think about what should be the roles of the project root and module root (should they be unified somehow?). |
After additional consideration, I am happy with @ArquintL general proposal, but I would rather choose one of the behaviours I proposed above for the case when we provide more CLI flags in addition to |
jcp19
left a comment
There was a problem hiding this comment.
So far, I reviewed up to src/main/scala/viper/gobra/frontend/Config.scala. I will continue the review later
| case None => config | ||
| case Some(p) => config.copy(includeDirs = config.includeDirs.map( | ||
| // it's important to convert includeDir to a string first as `path` might be a ZipPath and `includeDir` might not | ||
| includeDir => p.toAbsolutePath.resolve(includeDir.toString))) |
There was a problem hiding this comment.
do I see it correctly that we are only resolving the include directories here? What about the other parameters that may contain paths? (e.g., --includePackages or -i)
There was a problem hiding this comment.
I'm now disallowing "-i" and "-d" in "other" as one can already express these using the appropriate field and I didn't wanted to bother about correctly resolving these path as these inputs are turned into a packageInfoInputMap
| object CliEnumConverter { | ||
| trait EnumCase { | ||
| def value: String | ||
| } | ||
|
|
||
| /** trait for an enum value to configure parsing and serialization of this enum */ | ||
| trait CliEnum[E <: EnumCase] { | ||
| def values: List[E] | ||
| def convert(s: String): E = values.find(_.value == s).getOrElse(Violation.violation(s"Unexpected value: $s")) | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
this looks fine to me. An alternative would be to use the builtin Enumeration type in Scala (https://www.scala-lang.org/api/2.13.15/scala/Enumeration.html) which may lead to a shorter implementation.
There was a problem hiding this comment.
Good point. However, ViperBackend and MoreJoins carry additional fields which are useful but do not seem to be supported by Enumeration (at least according to Claude)
| val logLevel: Level = ConfigDefaults.DefaultLogLevel | ||
| val debug: Boolean = Level.DEBUG.isGreaterOrEqual(logLevel) | ||
| BaseConfig( | ||
| gobraDirectory = ConfigDefaults.DefaultGobraDirectory, |
There was a problem hiding this comment.
there are a few options that always get the default value (instead of being configurable). Is there a reason for that?
There was a problem hiding this comment.
This is correct. However, these options can still be changed via the other field in a JSON configuration. Parsing and merging in of options in an other field happens afterwards
| printVpr = c.job_cfg.print_vpr.getOrElse(debug), | ||
| streamErrs = !ConfigDefaults.DefaultNoStreamErrors), | ||
| backend = c.job_cfg.backend.map(_.underlying), | ||
| isolate = ConfigDefaults.DefaultIsolate, |
There was a problem hiding this comment.
does this mean that chopping never works if we provide a json config?
There was a problem hiding this comment.
I've now made chop a job JSON config option too
| // at this point, we do not know anymore from which config file these arguments come from. | ||
| // Thus, we do not resolve potential paths. | ||
| Config.parseCliArgs(otherArgs, None).map(Some(_)) |
There was a problem hiding this comment.
Things get a bit tricky here, but wouldn't it be easier to resolve all paths before merging?
There was a problem hiding this comment.
Maybe we want to disallow passing options that take paths in "other"
There was a problem hiding this comment.
I've changed the implementation accordingly
bd4cb25 to
0fa163c
Compare
…ic to merge different options
… by introducing 'InputConfig' as an intermediate representation for configuration options
|
@jcp19 Sorry this got quite ugly in the end ^^ |
This PR pushes @jcp19's idea further to use a JSON file to configure Gobra by integrating the parsing of the JSON file into Gobra. The accepted JSON structure follows gobrago with the following differences:
gobra-mod.jsonandgobra.json, respectivelyinstallation_cfganddefault_job_cfgotherfield. In particular, these options are parsed and merged with the other non-other fields, constituting a configuration after merging. I.e., this merging is happening before applying the precedence rule that overwrites module-level options.In addition, the following design choices have been made:
--config <path>is used to configure Gobra<path>must exist and can either be one of the following:--printConfigis additionally permitted to display the actually used configuration. All other options result in an error. If--printConfigis not provided, Gobra prints a short note stating with configuration files have been considered.<path>towards the filesystem's root directory