Skip to content

CLI args/config file refactoring #897

@adamralph

Description

@adamralph

IMO this whole space is currently quite confusing and clunky. After spending time on #896 I started to think about an alternative approach. Here's what I've come up with so far:

  1. Splitting of the CLI args into command args and script args is lifted up to Program.Main. I think this can be re-written trivially so it won't be necessary to encapsulate it in a type. It's really a Program.Main level operation.
  2. Parsing of the command args into ScriptCsArgs is lifted up to Program.Main. Normally this is a simple call to PowerArgs but since this also has to do some gymnastics regarding -install which has two optional parameters, package name and version (something which I think is not natively supported by PowerArgs), this is probably best encapsulated in a ScriptCsArgsFactory. If ScriptCsArgsFactory throws an exception, Program.Main writes the exception message to the console, shows usage and then exits with code 1 (as currently implemented in implemented CommandLine.UnexpectedOption #896)
  3. If ScriptCsArgs.Version or ScriptCsArgs.Help are true, Program.Main either shows the version or displays usage respectively and exits with code 0. This removes the need for VersionCommand and ShowUsageCommand which, IMO, are not commands, they are just options to show metadata without actually performing a command. This fits the behaviour of other platforms, e.g. node. For more on that, see Consider refactoring our arg design to use sub commands #175 (comment)
  4. We read and store the Config property from ScriptCsArgs
  5. We introduce a new type ScriptCsConfig and construct an instance using ScriptCsArgs. This can be encapsulated in a ScriptCsConfigFactory if required

Once these steps have been completed, the concept of 'arguments' no longer exists (disregarding the script args which need to be passed all the way through). We only have to think about rehydrating ScriptCsConfig instances from the local and global config files and then performing a masking operation: commandLineScriptCsConfig + localScriptCsConfig + globalScriptCsConfig. All properties on ScriptCsConfig should be nullable so for each property we take the first non-null value, falling back to a default.

We then pass the final ScriptCsConfig instance, along with the script args, to CommandFactory and the rest of the code remains as is.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions