@flowscripter/dynamic-cli-framework 9.1.3 → 10.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"MultiCommandCliHelpCommand.d.ts","sourceRoot":"","sources":["../../../src/command/MultiCommandCliHelpCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAE7E,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,MAAM,EACX,aAAa,EACd,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAYvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAM/E;;GAEG;AACH,uBAAe,kCAAkC;;IAC/C,QAAQ,CAAC,IAAI,UAAU;IACvB,QAAQ,CAAC,WAAW,8BAA8B;IAIlD,YAAY,cAAc,EAAE,OAAO,EAAE,eAAe,EAAE,eAAe,EAGpE;IA8HD,UAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA6ChE;IAED,UAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmFnF;CACF;AAED;;GAEG;AACH,qBAAa,gCACX,SAAQ,kCACR,YAAW,aAAa;IAExB,QAAQ,CAAC,UAAU,OAAO;IAE1B,QAAQ,CAAC,QAAQ;;;;MAIf;IAEW,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAOrF;CACF;AAED;;GAEG;AACH,qBAAa,6BACX,SAAQ,kCACR,YAAW,UAAU;IAErB,SAAgB,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAM;IAEpD,SAAgB,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,CAOpD;IAEW,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO5E;CACF"}
1
+ {"version":3,"file":"MultiCommandCliHelpCommand.d.ts","sourceRoot":"","sources":["../../../src/command/MultiCommandCliHelpCommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yCAAyC,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAE7E,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,MAAM,EACX,aAAa,EACd,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAYvE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAM/E;;GAEG;AACH,uBAAe,kCAAkC;;IAC/C,QAAQ,CAAC,IAAI,UAAU;IACvB,QAAQ,CAAC,WAAW,8BAA8B;IAIlD,YAAY,cAAc,EAAE,OAAO,EAAE,eAAe,EAAE,eAAe,EAGpE;IA8HD,UAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA6ChE;IAED,UAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyFnF;CACF;AAED;;GAEG;AACH,qBAAa,gCACX,SAAQ,kCACR,YAAW,aAAa;IAExB,QAAQ,CAAC,UAAU,OAAO;IAE1B,QAAQ,CAAC,QAAQ;;;;MAIf;IAEW,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAOrF;CACF;AAED;;GAEG;AACH,qBAAa,6BACX,SAAQ,kCACR,YAAW,UAAU;IAErB,SAAgB,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAM;IAEpD,SAAgB,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,CAOpD;IAEW,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAO5E;CACF"}
@@ -188,7 +188,7 @@ class MultiCommandCliAbstractHelpCommand {
188
188
  },
189
189
  ],
190
190
  });
191
- helpSections.push(...getCommandArgsHelpSections(context.cliConfig, this.#includeEnvVars, subCommand, false));
191
+ helpSections.push(...getCommandArgsHelpSections(context.cliConfig, this.#includeEnvVars, subCommand, false, groupCommand));
192
192
  helpSections.push(...getCommandExamplesHelpSections(printerService, context, subCommand));
193
193
  await printHelpSections(printerService, tableGeneratorService, helpSections);
194
194
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CommandValidator.d.ts","sourceRoot":"","sources":["../../../../src/runtime/command/CommandValidator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAiBvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAmJzE,MAAM,CAAC,OAAO,OAAO,gBAAgB;;IAInC,YAAmB,SAAS,EAAE,SAAS,EAEtC;IAED;;;;;;OAMG;IACI,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAUtC;CAgWF"}
1
+ {"version":3,"file":"CommandValidator.d.ts","sourceRoot":"","sources":["../../../../src/runtime/command/CommandValidator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAiBvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAmJzE,MAAM,CAAC,OAAO,OAAO,gBAAgB;;IAKnC,YAAmB,SAAS,EAAE,SAAS,EAEtC;IAED;;;;;;OAMG;IACI,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAUtC;CAsWF"}
@@ -97,6 +97,7 @@ function validateSubCommandArgument(subCommandArgument) {
97
97
  export default class CommandValidator {
98
98
  #cliConfig;
99
99
  #configurationKeys = [];
100
+ #currentGroupCommand;
100
101
  constructor(cliConfig) {
101
102
  this.#cliConfig = cliConfig;
102
103
  }
@@ -184,7 +185,13 @@ export default class CommandValidator {
184
185
  throw new Error(`Group command: '${groupCommand.name}' contains member sub-command with the same name`);
185
186
  }
186
187
  subCommandNames.push(subCommand.name);
187
- this.#validateSubCommand(subCommand);
188
+ this.#currentGroupCommand = groupCommand;
189
+ try {
190
+ this.#validateSubCommand(subCommand);
191
+ }
192
+ finally {
193
+ this.#currentGroupCommand = undefined;
194
+ }
188
195
  });
189
196
  }
190
197
  /**
@@ -254,7 +261,7 @@ export default class CommandValidator {
254
261
  !isConfigurationKeyLegal(argument.configurationKey)) {
255
262
  throw new Error(`Illegal configuration key: '${argument.configurationKey}'`);
256
263
  }
257
- const configurationKey = getSubCommandArgumentConfigurationKey(this.#cliConfig, command, argumentAncestry);
264
+ const configurationKey = getSubCommandArgumentConfigurationKey(this.#cliConfig, command, argumentAncestry, this.#currentGroupCommand);
258
265
  if (configurationKey !== undefined) {
259
266
  if (this.#configurationKeys.includes(configurationKey)) {
260
267
  throw new Error(`Command: '${command.name}' contains arguments with the same configuration key: '${configurationKey}'`);
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/runtime/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAiB/E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAEvF,OAAO,KAAK,4BAA4B,MAAM,0DAA0D,CAAC;AACzG,OAAO,KAAK,uBAAuB,MAAM,qDAAqD,CAAC;AAK/F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAKvE,OAAO,qBAAqB,MAAM,6CAA6C,CAAC;AAMhF;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG;IAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAkfzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2EG;AACH,wBAAsB,GAAG,CACvB,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,eAAe,EAAE,eAAe,EAChC,uBAAuB,EAAE,uBAAuB,EAChD,4BAA4B,EAAE,4BAA4B,GAAG,SAAS,EACtE,uBAAuB,EAAE,uBAAuB,GAAG,SAAS,EAC5D,OAAO,EAAE,OAAO,EAChB,cAAc,CAAC,EAAE,OAAO,EACxB,cAAc,CAAC,EAAE,qBAAqB,GACrC,OAAO,CAAC,YAAY,CAAC,CAkKvB"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/runtime/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAiB/E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yCAAyC,CAAC;AAEvF,OAAO,KAAK,4BAA4B,MAAM,0DAA0D,CAAC;AACzG,OAAO,KAAK,uBAAuB,MAAM,qDAAqD,CAAC;AAK/F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAKvE,OAAO,qBAAqB,MAAM,6CAA6C,CAAC;AAMhF;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG;IAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAmfzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2EG;AACH,wBAAsB,GAAG,CACvB,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,eAAe,EAAE,eAAe,EAChC,uBAAuB,EAAE,uBAAuB,EAChD,4BAA4B,EAAE,4BAA4B,GAAG,SAAS,EACtE,uBAAuB,EAAE,uBAAuB,GAAG,SAAS,EAC5D,OAAO,EAAE,OAAO,EAChB,cAAc,CAAC,EAAE,OAAO,EACxB,cAAc,CAAC,EAAE,qBAAqB,GACrC,OAAO,CAAC,YAAY,CAAC,CAkKvB"}
@@ -186,7 +186,7 @@ async function findAndExecuteNonModifierCommand(availableArgs, unusedArgs, nonMo
186
186
  unusedArgs.push(...scanResult.unusedArgSequences);
187
187
  if (scanResult.nonModifierCommandClause) {
188
188
  const defaultArgumentValues = configurationServiceProvider
189
- ? await configurationServiceProvider.getDefaultArgumentValues(context.cliConfig, scanResult.nonModifierCommandClause.command)
189
+ ? await configurationServiceProvider.getDefaultArgumentValues(context.cliConfig, scanResult.nonModifierCommandClause.command, scanResult.nonModifierCommandClause.groupCommand)
190
190
  : undefined;
191
191
  if (isGlobalCommand(scanResult.nonModifierCommandClause.command)) {
192
192
  parseResult = parseGlobalCommandClause(scanResult.nonModifierCommandClause, defaultArgumentValues);
@@ -1,6 +1,7 @@
1
1
  import type { ServiceInfo, ServiceProvider } from "@flowscripter/dynamic-cli-framework-api";
2
2
  import type { SingleValueType, Values, ValueNode, PopulatedValues, PopulatedValueType } from "@flowscripter/dynamic-cli-framework-api";
3
3
  import type { Context } from "@flowscripter/dynamic-cli-framework-api";
4
+ import type { GroupCommand } from "@flowscripter/dynamic-cli-framework-api";
4
5
  import type { Command } from "@flowscripter/dynamic-cli-framework-api";
5
6
  import type { CLIConfig } from "@flowscripter/dynamic-cli-framework-api";
6
7
  export type KeyValueServiceScopeType = "command" | "service";
@@ -27,7 +28,8 @@ export type KeyValueServiceScopeType = "command" | "service";
27
28
  *
28
29
  * A JSON file where the structure matches {@link Values} and the defaults are stored
29
30
  * under a top level `defaults` property. The second level of properties is used to refer to {@link Command.name}
30
- * and the contained values are treated as command {@link Values}. As an example:
31
+ * (or `<group name>:<member name>` for a member of a {@link GroupCommand}) and the contained values are treated as
32
+ * command {@link Values}. As an example:
31
33
  *
32
34
  * ```
33
35
  * {
@@ -44,6 +46,9 @@ export type KeyValueServiceScopeType = "command" | "service";
44
46
  * "command2": {
45
47
  * "arg4": true
46
48
  * },
49
+ * "group1:member1": {
50
+ * "arg5": "bar"
51
+ * },
47
52
  * "globalCommand": "globalArgumentValue"
48
53
  * },
49
54
  * "key-values": {
@@ -74,13 +79,15 @@ export type KeyValueServiceScopeType = "command" | "service";
74
79
  * Argument configuration keys are concatenated with a `_` separator.
75
80
  * Any arguments which support array values must by suffixed with `_` and an explicit array index.
76
81
  * If the root argument in the path does not use a custom {@link Argument.configurationKey} then the key path
77
- * is additionally suffixed with the {@link CLIConfig.name} and the {@link Command.name} with `_` separators.
82
+ * is additionally prefixed with the {@link CLIConfig.name}, the {@link GroupCommand.name} (if the command is a group
83
+ * member) and the {@link Command.name} with `_` separators.
78
84
  * This is best explained with examples...
79
85
  *
80
86
  * No custom configuration key examples:
81
87
  *
82
88
  * * executable: `MyCLI`, command: `globalCommand1`, global command argument => environment variable: `MYCLI_GLOBALCOMMAND1`
83
89
  * * executable: `MyCLI`, command: `command1`, simple root argument: `arg1` => environment variable: `MYCLI_COMMAND1_ARG1`
90
+ * * executable: `MyCLI`, group: `group1`, member command: `member1`, simple root argument: `arg1` => environment variable: `MYCLI_GROUP1_MEMBER1_ARG1`
84
91
  * * executable: `MyCLI`, command: `command1`, array root argument, 1st element: `arg2[0]` => environment variable: `MYCLI_COMMAND1_ARG2_0`
85
92
  * * executable: `MyCLI`, command: `command1`, argument is a digit so it is by default suffixed with `_`: `3` => environment variable: `MYCLI_COMMAND1__3`
86
93
  * * executable: `MyCLI`, command: `command1`, nested sub-argument: `arg1.arg2` => environment variable: `MYCLI_COMMAND1_ARG1_ARG2`
@@ -127,8 +134,10 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
127
134
  *
128
135
  * @param cliConfig the {@link CLIConfig} to use for retrieving configuration keys.
129
136
  * @param command the {@link Command} instance to retrieve default argument values for.
137
+ * @param groupCommand the {@link GroupCommand} if the command is a group member. The configuration file key
138
+ * is then `<group name>:<command name>` and the env var names include the group name.
130
139
  */
131
- getDefaultArgumentValues(cliConfig: CLIConfig, command: Command): Promise<PopulatedValues | PopulatedValueType | undefined>;
140
+ getDefaultArgumentValues(cliConfig: CLIConfig, command: Command, groupCommand?: GroupCommand): Promise<PopulatedValues | PopulatedValueType | undefined>;
132
141
  /**
133
142
  * Get-or-create the underlying, raw {@link ValueNode} `Map` for the given scope - for
134
143
  * {@link KeyValueServiceProvider}'s exclusive use, via its direct reference to this provider.
@@ -1 +1 @@
1
- {"version":3,"file":"ConfigurationServiceProvider.d.ts","sourceRoot":"","sources":["../../../../src/service/configuration/ConfigurationServiceProvider.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAE5F,OAAO,KAAK,EACV,eAAe,EACf,MAAM,EACN,SAAS,EACT,eAAe,EACf,kBAAkB,EACnB,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AASvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAOvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQzE,MAAM,MAAM,wBAAwB,GAAG,SAAS,GAAG,SAAS,CAAC;AAkB7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8FG;AACH,MAAM,CAAC,OAAO,OAAO,4BAA6B,YAAW,eAAe;;IAC1E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAA4B;IACtD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAEjC,SAAgB,cAAc,EAAE,OAAO,CAAC;IACxC,SAAgB,aAAa,EAAE,OAAO,CAAC;IACvC,SAAgB,oBAAoB,EAAE,OAAO,CAAC;IAGvC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IAKnC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAAC,CAAa;IAqBvE;;;;;;;;OAQG;IACH,YACE,eAAe,EAAE,MAAM,EACvB,cAAc,UAAQ,EACtB,aAAa,UAAQ,EACrB,oBAAoB,UAAQ,EAW7B;IAEM,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAehE;IAEM,iBAAiB,CAAC,cAAc,EAAE,MAAM,QAE9C;IAED;;;;;;;OAOG;IACU,wBAAwB,CACnC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,eAAe,GAAG,kBAAkB,GAAG,SAAS,CAAC,CAoD3D;IAED;;;;;;OAMG;IACI,eAAe,CACpB,SAAS,EAAE,wBAAwB,EACnC,QAAQ,EAAE,MAAM,GACf,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAOxB;IAED;;;;;;OAMG;IACU,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAQzD;IAEY,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA0CxD;IA4DM,eAAe,IAAI,MAAM,CAgC/B;CACF"}
1
+ {"version":3,"file":"ConfigurationServiceProvider.d.ts","sourceRoot":"","sources":["../../../../src/service/configuration/ConfigurationServiceProvider.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAE5F,OAAO,KAAK,EACV,eAAe,EACf,MAAM,EACN,SAAS,EACT,eAAe,EACf,kBAAkB,EACnB,MAAM,yCAAyC,CAAC;AAEjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAS5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAOvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQzE,MAAM,MAAM,wBAAwB,GAAG,SAAS,GAAG,SAAS,CAAC;AAkB7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoGG;AACH,MAAM,CAAC,OAAO,OAAO,4BAA6B,YAAW,eAAe;;IAC1E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAA4B;IACtD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAEjC,SAAgB,cAAc,EAAE,OAAO,CAAC;IACxC,SAAgB,aAAa,EAAE,OAAO,CAAC;IACvC,SAAgB,oBAAoB,EAAE,OAAO,CAAC;IAGvC,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IAKnC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAAC,CAAa;IAqBvE;;;;;;;;OAQG;IACH,YACE,eAAe,EAAE,MAAM,EACvB,cAAc,UAAQ,EACtB,aAAa,UAAQ,EACrB,oBAAoB,UAAQ,EAW7B;IAEM,cAAc,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAehE;IAEM,iBAAiB,CAAC,cAAc,EAAE,MAAM,QAE9C;IAED;;;;;;;;;OASG;IACU,wBAAwB,CACnC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,eAAe,GAAG,kBAAkB,GAAG,SAAS,CAAC,CAsD3D;IAED;;;;;;OAMG;IACI,eAAe,CACpB,SAAS,EAAE,wBAAwB,EACnC,QAAQ,EAAE,MAAM,GACf,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAOxB;IAED;;;;;;OAMG;IACU,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAQzD;IAEY,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA0CxD;IA4DM,eAAe,IAAI,MAAM,CAgC/B;CACF"}
@@ -47,7 +47,8 @@ class ConfigurationServiceImpl {
47
47
  *
48
48
  * A JSON file where the structure matches {@link Values} and the defaults are stored
49
49
  * under a top level `defaults` property. The second level of properties is used to refer to {@link Command.name}
50
- * and the contained values are treated as command {@link Values}. As an example:
50
+ * (or `<group name>:<member name>` for a member of a {@link GroupCommand}) and the contained values are treated as
51
+ * command {@link Values}. As an example:
51
52
  *
52
53
  * ```
53
54
  * {
@@ -64,6 +65,9 @@ class ConfigurationServiceImpl {
64
65
  * "command2": {
65
66
  * "arg4": true
66
67
  * },
68
+ * "group1:member1": {
69
+ * "arg5": "bar"
70
+ * },
67
71
  * "globalCommand": "globalArgumentValue"
68
72
  * },
69
73
  * "key-values": {
@@ -94,13 +98,15 @@ class ConfigurationServiceImpl {
94
98
  * Argument configuration keys are concatenated with a `_` separator.
95
99
  * Any arguments which support array values must by suffixed with `_` and an explicit array index.
96
100
  * If the root argument in the path does not use a custom {@link Argument.configurationKey} then the key path
97
- * is additionally suffixed with the {@link CLIConfig.name} and the {@link Command.name} with `_` separators.
101
+ * is additionally prefixed with the {@link CLIConfig.name}, the {@link GroupCommand.name} (if the command is a group
102
+ * member) and the {@link Command.name} with `_` separators.
98
103
  * This is best explained with examples...
99
104
  *
100
105
  * No custom configuration key examples:
101
106
  *
102
107
  * * executable: `MyCLI`, command: `globalCommand1`, global command argument => environment variable: `MYCLI_GLOBALCOMMAND1`
103
108
  * * executable: `MyCLI`, command: `command1`, simple root argument: `arg1` => environment variable: `MYCLI_COMMAND1_ARG1`
109
+ * * executable: `MyCLI`, group: `group1`, member command: `member1`, simple root argument: `arg1` => environment variable: `MYCLI_GROUP1_MEMBER1_ARG1`
104
110
  * * executable: `MyCLI`, command: `command1`, array root argument, 1st element: `arg2[0]` => environment variable: `MYCLI_COMMAND1_ARG2_0`
105
111
  * * executable: `MyCLI`, command: `command1`, argument is a digit so it is by default suffixed with `_`: `3` => environment variable: `MYCLI_COMMAND1__3`
106
112
  * * executable: `MyCLI`, command: `command1`, nested sub-argument: `arg1.arg2` => environment variable: `MYCLI_COMMAND1_ARG1_ARG2`
@@ -191,20 +197,23 @@ export default class ConfigurationServiceProvider {
191
197
  *
192
198
  * @param cliConfig the {@link CLIConfig} to use for retrieving configuration keys.
193
199
  * @param command the {@link Command} instance to retrieve default argument values for.
200
+ * @param groupCommand the {@link GroupCommand} if the command is a group member. The configuration file key
201
+ * is then `<group name>:<command name>` and the env var names include the group name.
194
202
  */
195
- async getDefaultArgumentValues(cliConfig, command) {
203
+ async getDefaultArgumentValues(cliConfig, command, groupCommand) {
196
204
  if (!this.configEnabled) {
197
205
  logger.debug("configuration of default values is not enabled");
198
206
  return undefined;
199
207
  }
200
- logger.debug("getting default argument values for command: %s", command.name);
208
+ const commandKey = groupCommand ? `${groupCommand.name}:${command.name}` : command.name;
209
+ logger.debug("getting default argument values for command: %s", commandKey);
201
210
  if (command.enableConfiguration === undefined || command.enableConfiguration !== true) {
202
211
  logger.debug("enableConfiguration for command: %s is not true", command.name);
203
212
  return undefined;
204
213
  }
205
214
  let result;
206
215
  if (isGlobalModifierCommand(command) || isGlobalCommand(command)) {
207
- const configuredValue = this.defaultsData.get(command.name);
216
+ const configuredValue = this.defaultsData.get(commandKey);
208
217
  const envVarValue = this.envVarsEnabled
209
218
  ? getGlobalCommandValueFromEnvVars(cliConfig, command)
210
219
  : undefined;
@@ -212,9 +221,9 @@ export default class ConfigurationServiceProvider {
212
221
  result = envVarValue !== undefined ? envVarValue : configuredValue;
213
222
  }
214
223
  else if (isSubCommand(command)) {
215
- const configuredValues = this.defaultsData.get(command.name);
224
+ const configuredValues = this.defaultsData.get(commandKey);
216
225
  const envVarValues = this.envVarsEnabled
217
- ? getSubCommandValuesFromEnvVars(cliConfig, command)
226
+ ? getSubCommandValuesFromEnvVars(cliConfig, command, groupCommand)
218
227
  : undefined;
219
228
  if (envVarValues === undefined) {
220
229
  result = configuredValues;
@@ -1,3 +1,4 @@
1
+ import type { GroupCommand } from "@flowscripter/dynamic-cli-framework-api";
1
2
  import type { Command } from "@flowscripter/dynamic-cli-framework-api";
2
3
  import type { CLIConfig } from "@flowscripter/dynamic-cli-framework-api";
3
4
  import type { SubCommandArgument } from "@flowscripter/dynamic-cli-framework-api";
@@ -9,8 +10,10 @@ import type { GlobalCommandArgument } from "@flowscripter/dynamic-cli-framework-
9
10
  * @param command the {@link Command} to use for determining the default configuration key.
10
11
  * @param argumentAncestry a list of {@link SubCommandArgument} instances from the root command arguments to a leaf argument.
11
12
  * Apart from {@link ComplexOption} instances this will always only have a single entry.
13
+ * @param groupCommand the {@link GroupCommand} if the command is a member of a group, in which case the group name
14
+ * is an additional key segment.
12
15
  */
13
- export declare function getSubCommandArgumentConfigurationKey(cliConfig: CLIConfig, command: Command, argumentAncestry: Array<SubCommandArgument>): string | undefined;
16
+ export declare function getSubCommandArgumentConfigurationKey(cliConfig: CLIConfig, command: Command, argumentAncestry: Array<SubCommandArgument>, groupCommand?: GroupCommand): string | undefined;
14
17
  /**
15
18
  * Determine the configuration key for the specified {@link GlobalCommandArgument}.
16
19
  *
@@ -1 +1 @@
1
- {"version":3,"file":"configHelper.d.ts","sourceRoot":"","sources":["../../../src/util/configHelper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAgBrF;;;;;;;GAOG;AACH,wBAAgB,qCAAqC,CACnD,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,gBAAgB,EAAE,KAAK,CAAC,kBAAkB,CAAC,GAC1C,MAAM,GAAG,SAAS,CA2BpB;AAED;;;;;;GAMG;AACH,wBAAgB,wCAAwC,CACtD,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,qBAAqB,EAAE,qBAAqB,GAC3C,MAAM,GAAG,SAAS,CAcpB"}
1
+ {"version":3,"file":"configHelper.d.ts","sourceRoot":"","sources":["../../../src/util/configHelper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yCAAyC,CAAC;AAClF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAgBrF;;;;;;;;;GASG;AACH,wBAAgB,qCAAqC,CACnD,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,gBAAgB,EAAE,KAAK,CAAC,kBAAkB,CAAC,EAC3C,YAAY,CAAC,EAAE,YAAY,GAC1B,MAAM,GAAG,SAAS,CA8BpB;AAED;;;;;;GAMG;AACH,wBAAgB,wCAAwC,CACtD,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,OAAO,EAChB,qBAAqB,EAAE,qBAAqB,GAC3C,MAAM,GAAG,SAAS,CAcpB"}
@@ -18,8 +18,10 @@ function getKeySegment(segment, isCustom = false, isArray = false) {
18
18
  * @param command the {@link Command} to use for determining the default configuration key.
19
19
  * @param argumentAncestry a list of {@link SubCommandArgument} instances from the root command arguments to a leaf argument.
20
20
  * Apart from {@link ComplexOption} instances this will always only have a single entry.
21
+ * @param groupCommand the {@link GroupCommand} if the command is a member of a group, in which case the group name
22
+ * is an additional key segment.
21
23
  */
22
- export function getSubCommandArgumentConfigurationKey(cliConfig, command, argumentAncestry) {
24
+ export function getSubCommandArgumentConfigurationKey(cliConfig, command, argumentAncestry, groupCommand) {
23
25
  if (command.enableConfiguration === undefined || command.enableConfiguration !== true) {
24
26
  return undefined;
25
27
  }
@@ -30,6 +32,9 @@ export function getSubCommandArgumentConfigurationKey(cliConfig, command, argume
30
32
  const firstArgument = argumentAncestry[0];
31
33
  if (firstArgument.configurationKey === undefined) {
32
34
  keySegments.push(getKeySegment(cliConfig.name));
35
+ if (groupCommand) {
36
+ keySegments.push(getKeySegment(groupCommand.name));
37
+ }
33
38
  keySegments.push(getKeySegment(command.name));
34
39
  }
35
40
  argumentAncestry.forEach((argument) => {
@@ -1,6 +1,7 @@
1
1
  import type { CLIConfig } from "@flowscripter/dynamic-cli-framework-api";
2
2
  import { type PopulatedSingleValueType, type PopulatedValues } from "@flowscripter/dynamic-cli-framework-api";
3
3
  import type { GlobalCommand } from "@flowscripter/dynamic-cli-framework-api";
4
+ import type { GroupCommand } from "@flowscripter/dynamic-cli-framework-api";
4
5
  import type { SubCommand } from "@flowscripter/dynamic-cli-framework-api";
5
6
  /**
6
7
  * Get configured argument value for the specified {@link GlobalCommandArgument} from environment variables.
@@ -16,6 +17,8 @@ export declare function getGlobalCommandValueFromEnvVars(cliConfig: CLIConfig, c
16
17
  * @param cliConfig the {@link CLIConfig} to use for determining the default configuration key.
17
18
  * @param command the {@link SubCommand} to use for determining the default configuration key and containing
18
19
  * {@link Positional} and {@link Option} instances to populate values for.
20
+ * @param groupCommand the {@link GroupCommand} if the command is a group member, in which case the group name
21
+ * is an additional env var name segment.
19
22
  */
20
- export declare function getSubCommandValuesFromEnvVars(cliConfig: CLIConfig, command: SubCommand): PopulatedValues | undefined;
23
+ export declare function getSubCommandValuesFromEnvVars(cliConfig: CLIConfig, command: SubCommand, groupCommand?: GroupCommand): PopulatedValues | undefined;
21
24
  //# sourceMappingURL=envVarHelper.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"envVarHelper.d.ts","sourceRoot":"","sources":["../../../src/util/envVarHelper.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAGL,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACrB,MAAM,yCAAyC,CAAC;AAOjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAmC1E;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAC9C,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,aAAa,GACrB,wBAAwB,CAa1B;AAwID;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,UAAU,GAClB,eAAe,GAAG,SAAS,CA4E7B"}
1
+ {"version":3,"file":"envVarHelper.d.ts","sourceRoot":"","sources":["../../../src/util/envVarHelper.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAGL,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACrB,MAAM,yCAAyC,CAAC;AAOjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAqC1E;;;;;;GAMG;AACH,wBAAgB,gCAAgC,CAC9C,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,aAAa,GACrB,wBAAwB,CAa1B;AAwID;;;;;;;;GAQG;AACH,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,UAAU,EACnB,YAAY,CAAC,EAAE,YAAY,GAC1B,eAAe,GAAG,SAAS,CAsF7B"}
@@ -8,11 +8,12 @@ function getKeySegment(segment) {
8
8
  }
9
9
  return keySegment;
10
10
  }
11
- function getSubCommandArgumentKeyPrefix(cliConfig, command, subCommandArgument) {
11
+ function getSubCommandArgumentKeyPrefix(cliConfig, command, subCommandArgument, groupCommand) {
12
12
  if (subCommandArgument.configurationKey) {
13
13
  return subCommandArgument.configurationKey;
14
14
  }
15
- return `${getKeySegment(cliConfig.name)}_${getKeySegment(command.name)}_${getKeySegment(subCommandArgument.name)}`;
15
+ const groupSegment = groupCommand ? `${getKeySegment(groupCommand.name)}_` : "";
16
+ return `${getKeySegment(cliConfig.name)}_${groupSegment}${getKeySegment(command.name)}_${getKeySegment(subCommandArgument.name)}`;
16
17
  }
17
18
  function getGlobalArgumentKeyPrefix(cliConfig, command, globalCommandArgument) {
18
19
  if (globalCommandArgument.configurationKey) {
@@ -146,13 +147,15 @@ function getOptionValuesFromEnvVars(envVarValues, potentialEnvVarNames, env, opt
146
147
  * @param cliConfig the {@link CLIConfig} to use for determining the default configuration key.
147
148
  * @param command the {@link SubCommand} to use for determining the default configuration key and containing
148
149
  * {@link Positional} and {@link Option} instances to populate values for.
150
+ * @param groupCommand the {@link GroupCommand} if the command is a group member, in which case the group name
151
+ * is an additional env var name segment.
149
152
  */
150
- export function getSubCommandValuesFromEnvVars(cliConfig, command) {
153
+ export function getSubCommandValuesFromEnvVars(cliConfig, command, groupCommand) {
151
154
  const envVarValues = Object.create(null);
152
155
  if (command.options) {
153
156
  for (const option of command.options) {
154
157
  const potentialEnvVarNames = Object.keys(process.env);
155
- const optionPrefix = getSubCommandArgumentKeyPrefix(cliConfig, command, option);
158
+ const optionPrefix = getSubCommandArgumentKeyPrefix(cliConfig, command, option, groupCommand);
156
159
  getOptionValuesFromEnvVars(envVarValues, potentialEnvVarNames, process.env ?? {}, option, optionPrefix);
157
160
  }
158
161
  }
@@ -163,7 +166,7 @@ export function getSubCommandValuesFromEnvVars(cliConfig, command) {
163
166
  positional.name === "prototype") {
164
167
  throw new Error(`Unsafe key name in use: ${positional.name}, CodeQL Rule ID: js/prototype-polluting-assignment`);
165
168
  }
166
- let envVarNamePrefix = getSubCommandArgumentKeyPrefix(cliConfig, command, positional);
169
+ let envVarNamePrefix = getSubCommandArgumentKeyPrefix(cliConfig, command, positional, groupCommand);
167
170
  if (positional.isVarargMultiple) {
168
171
  envVarNamePrefix = `${envVarNamePrefix}_`;
169
172
  const matches = Object.keys(process.env).filter((envVarName) => envVarName.startsWith(envVarNamePrefix));
@@ -19,7 +19,7 @@ export interface HelpSection {
19
19
  export declare function printHelpSections(printerService: PrinterService, tableGeneratorService: TableGeneratorService, sections: Array<HelpSection>): Promise<void>;
20
20
  export declare function getGlobalArgumentHelpEntry(cliConfig: CLIConfig, includeEnvVars: boolean, globalCommand: GlobalCommand): HelpEntry;
21
21
  export declare function getSubCommandArgumentsSyntax(subCommand: SubCommand): string;
22
- export declare function getCommandArgsHelpSections(cliConfig: CLIConfig, includeEnvVars: boolean, subCommand: SubCommand, isSingleCommandApp: boolean): Array<HelpSection>;
22
+ export declare function getCommandArgsHelpSections(cliConfig: CLIConfig, includeEnvVars: boolean, subCommand: SubCommand, isSingleCommandApp: boolean, groupCommand?: GroupCommand): Array<HelpSection>;
23
23
  export declare function getCommandExamplesHelpSections(printerService: PrinterService, context: Context, subCommand: SubCommand): Array<HelpSection>;
24
24
  export declare function getMultiCommandAppSyntax(context: Context, globalModifierCommands: ReadonlyArray<GlobalModifierCommand>, globalCommands: ReadonlyArray<GlobalCommand>, groupCommands: ReadonlyArray<GroupCommand>, subCommands: ReadonlyArray<SubCommand>): string;
25
25
  export declare function findPossibleCommandNames(commandName: string, groupCommands: ReadonlyArray<GroupCommand>, subCommands: ReadonlyArray<SubCommand>): string[];
@@ -1 +1 @@
1
- {"version":3,"file":"helpHelper.d.ts","sourceRoot":"","sources":["../../../src/util/helpHelper.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAG7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAIvE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AACrF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAM5E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAG9E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAiCrF,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;CACxC;AAsDD,wBAAsB,iBAAiB,CACrC,cAAc,EAAE,cAAc,EAC9B,qBAAqB,EAAE,qBAAqB,EAC5C,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,GAC3B,OAAO,CAAC,IAAI,CAAC,CA2Cf;AA2BD,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,OAAO,EACvB,aAAa,EAAE,aAAa,GAC3B,SAAS,CA6DX;AAED,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CA+C3E;AAkLD,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,OAAO,EACvB,UAAU,EAAE,UAAU,EACtB,kBAAkB,EAAE,OAAO,GAC1B,KAAK,CAAC,WAAW,CAAC,CAoBpB;AACD,wBAAgB,8BAA8B,CAC5C,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,UAAU,GACrB,KAAK,CAAC,WAAW,CAAC,CAgCpB;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,OAAO,EAChB,sBAAsB,EAAE,aAAa,CAAC,qBAAqB,CAAC,EAC5D,cAAc,EAAE,aAAa,CAAC,aAAa,CAAC,EAC5C,aAAa,EAAE,aAAa,CAAC,YAAY,CAAC,EAC1C,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,GACrC,MAAM,CA8IR;AAED,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,aAAa,CAAC,YAAY,CAAC,EAC1C,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,GACrC,MAAM,EAAE,CAkBV"}
1
+ {"version":3,"file":"helpHelper.d.ts","sourceRoot":"","sources":["../../../src/util/helpHelper.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAC;AAG7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yCAAyC,CAAC;AAC1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,yCAAyC,CAAC;AAIvE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AACrF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAC;AAM5E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAG9E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAiCrF,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;CACxC;AAsDD,wBAAsB,iBAAiB,CACrC,cAAc,EAAE,cAAc,EAC9B,qBAAqB,EAAE,qBAAqB,EAC5C,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,GAC3B,OAAO,CAAC,IAAI,CAAC,CA2Cf;AA2BD,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,OAAO,EACvB,aAAa,EAAE,aAAa,GAC3B,SAAS,CA6DX;AAED,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CA+C3E;AA8LD,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,OAAO,EACvB,UAAU,EAAE,UAAU,EACtB,kBAAkB,EAAE,OAAO,EAC3B,YAAY,CAAC,EAAE,YAAY,GAC1B,KAAK,CAAC,WAAW,CAAC,CA4BpB;AACD,wBAAgB,8BAA8B,CAC5C,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,UAAU,GACrB,KAAK,CAAC,WAAW,CAAC,CAgCpB;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,OAAO,EAChB,sBAAsB,EAAE,aAAa,CAAC,qBAAqB,CAAC,EAC5D,cAAc,EAAE,aAAa,CAAC,aAAa,CAAC,EAC5C,aAAa,EAAE,aAAa,CAAC,YAAY,CAAC,EAC1C,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,GACrC,MAAM,CA8IR;AAED,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,aAAa,CAAC,YAAY,CAAC,EAC1C,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,GACrC,MAAM,EAAE,CAkBV"}
@@ -216,7 +216,7 @@ export function getSubCommandArgumentsSyntax(subCommand) {
216
216
  });
217
217
  return syntax;
218
218
  }
219
- function getOptionHelpEntry(cliConfig, includeEnvVars, command, option, subEntryIndent = 0, optionAncestry = []) {
219
+ function getOptionHelpEntry(cliConfig, includeEnvVars, command, option, subEntryIndent = 0, optionAncestry = [], groupCommand) {
220
220
  let subEntries;
221
221
  let optionCharacters = "--";
222
222
  let aliasCharacter = "-";
@@ -230,10 +230,7 @@ function getOptionHelpEntry(cliConfig, includeEnvVars, command, option, subEntry
230
230
  if (option.type === ComplexValueTypeName.COMPLEX) {
231
231
  subEntries = [];
232
232
  option.properties.forEach((property) => {
233
- subEntries.push(getOptionHelpEntry(cliConfig, includeEnvVars, command, property, newSubEntryIndent, [
234
- ...optionAncestry,
235
- option,
236
- ]));
233
+ subEntries.push(getOptionHelpEntry(cliConfig, includeEnvVars, command, property, newSubEntryIndent, [...optionAncestry, option], groupCommand));
237
234
  });
238
235
  }
239
236
  else {
@@ -279,10 +276,7 @@ function getOptionHelpEntry(cliConfig, includeEnvVars, command, option, subEntry
279
276
  notesItems.push("array");
280
277
  }
281
278
  if (includeEnvVars && option.type !== ComplexValueTypeName.COMPLEX) {
282
- const configurationKey = getSubCommandArgumentConfigurationKey(cliConfig, command, [
283
- ...optionAncestry,
284
- option,
285
- ]);
279
+ const configurationKey = getSubCommandArgumentConfigurationKey(cliConfig, command, [...optionAncestry, option], groupCommand);
286
280
  if (configurationKey !== undefined) {
287
281
  notesItems.push(`env var: ${configurationKey}`);
288
282
  }
@@ -303,7 +297,7 @@ function getOptionHelpEntry(cliConfig, includeEnvVars, command, option, subEntry
303
297
  helpSubEntries: subEntries,
304
298
  };
305
299
  }
306
- function getPositionalHelpEntry(cliConfig, includeEnvVars, command, positional) {
300
+ function getPositionalHelpEntry(cliConfig, includeEnvVars, command, positional, groupCommand) {
307
301
  const notesItems = [];
308
302
  if (positional.allowableValues !== undefined && positional.allowableValues.length > 0) {
309
303
  notesItems.push(`valid values: ${userInputList(positional.allowableValues, "|")}`);
@@ -341,9 +335,7 @@ function getPositionalHelpEntry(cliConfig, includeEnvVars, command, positional)
341
335
  notesItems.push("array");
342
336
  }
343
337
  if (includeEnvVars) {
344
- const configurationKey = getSubCommandArgumentConfigurationKey(cliConfig, command, [
345
- positional,
346
- ]);
338
+ const configurationKey = getSubCommandArgumentConfigurationKey(cliConfig, command, [positional], groupCommand);
347
339
  if (configurationKey !== undefined) {
348
340
  notesItems.push(`env var: ${configurationKey}`);
349
341
  }
@@ -362,7 +354,7 @@ function getPositionalHelpEntry(cliConfig, includeEnvVars, command, positional)
362
354
  description,
363
355
  };
364
356
  }
365
- export function getCommandArgsHelpSections(cliConfig, includeEnvVars, subCommand, isSingleCommandApp) {
357
+ export function getCommandArgsHelpSections(cliConfig, includeEnvVars, subCommand, isSingleCommandApp, groupCommand) {
366
358
  const helpSections = [];
367
359
  if (subCommand.options.length > 0 || subCommand.positionals.length > 0) {
368
360
  const argumentsSection = {
@@ -370,10 +362,10 @@ export function getCommandArgsHelpSections(cliConfig, includeEnvVars, subCommand
370
362
  helpEntries: [],
371
363
  };
372
364
  subCommand.options.forEach((option) => {
373
- argumentsSection.helpEntries.push(getOptionHelpEntry(cliConfig, includeEnvVars, subCommand, option));
365
+ argumentsSection.helpEntries.push(getOptionHelpEntry(cliConfig, includeEnvVars, subCommand, option, 0, [], groupCommand));
374
366
  });
375
367
  subCommand.positionals.forEach((positional) => {
376
- argumentsSection.helpEntries.push(getPositionalHelpEntry(cliConfig, includeEnvVars, subCommand, positional));
368
+ argumentsSection.helpEntries.push(getPositionalHelpEntry(cliConfig, includeEnvVars, subCommand, positional, groupCommand));
377
369
  });
378
370
  helpSections.push(argumentsSection);
379
371
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowscripter/dynamic-cli-framework",
3
- "version": "9.1.3",
3
+ "version": "10.0.0",
4
4
  "description": "A framework for developing CLI applications which supports dynamic discovery and installation of new commands",
5
5
  "keywords": [
6
6
  "bun",
@@ -288,7 +288,13 @@ abstract class MultiCommandCliAbstractHelpCommand {
288
288
  });
289
289
 
290
290
  helpSections.push(
291
- ...getCommandArgsHelpSections(context.cliConfig, this.#includeEnvVars, subCommand, false),
291
+ ...getCommandArgsHelpSections(
292
+ context.cliConfig,
293
+ this.#includeEnvVars,
294
+ subCommand,
295
+ false,
296
+ groupCommand,
297
+ ),
292
298
  );
293
299
 
294
300
  helpSections.push(...getCommandExamplesHelpSections(printerService, context, subCommand));
@@ -165,6 +165,7 @@ function validateSubCommandArgument(subCommandArgument: SubCommandArgument): voi
165
165
  export default class CommandValidator {
166
166
  readonly #cliConfig: CLIConfig;
167
167
  readonly #configurationKeys: Array<string> = [];
168
+ #currentGroupCommand: GroupCommand | undefined;
168
169
 
169
170
  public constructor(cliConfig: CLIConfig) {
170
171
  this.#cliConfig = cliConfig;
@@ -265,7 +266,12 @@ export default class CommandValidator {
265
266
  );
266
267
  }
267
268
  subCommandNames.push(subCommand.name);
268
- this.#validateSubCommand(subCommand);
269
+ this.#currentGroupCommand = groupCommand;
270
+ try {
271
+ this.#validateSubCommand(subCommand);
272
+ } finally {
273
+ this.#currentGroupCommand = undefined;
274
+ }
269
275
  });
270
276
  }
271
277
 
@@ -365,6 +371,7 @@ export default class CommandValidator {
365
371
  this.#cliConfig,
366
372
  command,
367
373
  argumentAncestry,
374
+ this.#currentGroupCommand,
368
375
  );
369
376
 
370
377
  if (configurationKey !== undefined) {
@@ -314,6 +314,7 @@ async function findAndExecuteNonModifierCommand(
314
314
  ? await configurationServiceProvider.getDefaultArgumentValues(
315
315
  context.cliConfig,
316
316
  scanResult.nonModifierCommandClause.command,
317
+ scanResult.nonModifierCommandClause.groupCommand,
317
318
  )
318
319
  : undefined;
319
320
 
@@ -13,6 +13,7 @@ import type {
13
13
  } from "@flowscripter/dynamic-cli-framework-api";
14
14
  import getLogger from "../../util/logger.ts";
15
15
  import type { Context } from "@flowscripter/dynamic-cli-framework-api";
16
+ import type { GroupCommand } from "@flowscripter/dynamic-cli-framework-api";
16
17
  import DumpConfigCommand from "./command/DumpConfigCommand.ts";
17
18
  import {
18
19
  CONFIGURATION_SERVICE_ID,
@@ -77,7 +78,8 @@ class ConfigurationServiceImpl implements ConfigurationService {
77
78
  *
78
79
  * A JSON file where the structure matches {@link Values} and the defaults are stored
79
80
  * under a top level `defaults` property. The second level of properties is used to refer to {@link Command.name}
80
- * and the contained values are treated as command {@link Values}. As an example:
81
+ * (or `<group name>:<member name>` for a member of a {@link GroupCommand}) and the contained values are treated as
82
+ * command {@link Values}. As an example:
81
83
  *
82
84
  * ```
83
85
  * {
@@ -94,6 +96,9 @@ class ConfigurationServiceImpl implements ConfigurationService {
94
96
  * "command2": {
95
97
  * "arg4": true
96
98
  * },
99
+ * "group1:member1": {
100
+ * "arg5": "bar"
101
+ * },
97
102
  * "globalCommand": "globalArgumentValue"
98
103
  * },
99
104
  * "key-values": {
@@ -124,13 +129,15 @@ class ConfigurationServiceImpl implements ConfigurationService {
124
129
  * Argument configuration keys are concatenated with a `_` separator.
125
130
  * Any arguments which support array values must by suffixed with `_` and an explicit array index.
126
131
  * If the root argument in the path does not use a custom {@link Argument.configurationKey} then the key path
127
- * is additionally suffixed with the {@link CLIConfig.name} and the {@link Command.name} with `_` separators.
132
+ * is additionally prefixed with the {@link CLIConfig.name}, the {@link GroupCommand.name} (if the command is a group
133
+ * member) and the {@link Command.name} with `_` separators.
128
134
  * This is best explained with examples...
129
135
  *
130
136
  * No custom configuration key examples:
131
137
  *
132
138
  * * executable: `MyCLI`, command: `globalCommand1`, global command argument => environment variable: `MYCLI_GLOBALCOMMAND1`
133
139
  * * executable: `MyCLI`, command: `command1`, simple root argument: `arg1` => environment variable: `MYCLI_COMMAND1_ARG1`
140
+ * * executable: `MyCLI`, group: `group1`, member command: `member1`, simple root argument: `arg1` => environment variable: `MYCLI_GROUP1_MEMBER1_ARG1`
134
141
  * * executable: `MyCLI`, command: `command1`, array root argument, 1st element: `arg2[0]` => environment variable: `MYCLI_COMMAND1_ARG2_0`
135
142
  * * executable: `MyCLI`, command: `command1`, argument is a digit so it is by default suffixed with `_`: `3` => environment variable: `MYCLI_COMMAND1__3`
136
143
  * * executable: `MyCLI`, command: `command1`, nested sub-argument: `arg1.arg2` => environment variable: `MYCLI_COMMAND1_ARG1_ARG2`
@@ -238,17 +245,22 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
238
245
  *
239
246
  * @param cliConfig the {@link CLIConfig} to use for retrieving configuration keys.
240
247
  * @param command the {@link Command} instance to retrieve default argument values for.
248
+ * @param groupCommand the {@link GroupCommand} if the command is a group member. The configuration file key
249
+ * is then `<group name>:<command name>` and the env var names include the group name.
241
250
  */
242
251
  public async getDefaultArgumentValues(
243
252
  cliConfig: CLIConfig,
244
253
  command: Command,
254
+ groupCommand?: GroupCommand,
245
255
  ): Promise<PopulatedValues | PopulatedValueType | undefined> {
246
256
  if (!this.configEnabled) {
247
257
  logger.debug("configuration of default values is not enabled");
248
258
  return undefined;
249
259
  }
250
260
 
251
- logger.debug("getting default argument values for command: %s", command.name);
261
+ const commandKey = groupCommand ? `${groupCommand.name}:${command.name}` : command.name;
262
+
263
+ logger.debug("getting default argument values for command: %s", commandKey);
252
264
 
253
265
  if (command.enableConfiguration === undefined || command.enableConfiguration !== true) {
254
266
  logger.debug("enableConfiguration for command: %s is not true", command.name);
@@ -258,16 +270,16 @@ export default class ConfigurationServiceProvider implements ServiceProvider {
258
270
  let result: PopulatedValues | PopulatedValueType | undefined;
259
271
 
260
272
  if (isGlobalModifierCommand(command) || isGlobalCommand(command)) {
261
- const configuredValue = this.defaultsData.get(command.name) as SingleValueType;
273
+ const configuredValue = this.defaultsData.get(commandKey) as SingleValueType;
262
274
  const envVarValue = this.envVarsEnabled
263
275
  ? getGlobalCommandValueFromEnvVars(cliConfig, command)
264
276
  : undefined;
265
277
  // default to environment variable value
266
278
  result = envVarValue !== undefined ? envVarValue : configuredValue;
267
279
  } else if (isSubCommand(command)) {
268
- const configuredValues = this.defaultsData.get(command.name) as Values;
280
+ const configuredValues = this.defaultsData.get(commandKey) as Values;
269
281
  const envVarValues = this.envVarsEnabled
270
- ? getSubCommandValuesFromEnvVars(cliConfig, command)
282
+ ? getSubCommandValuesFromEnvVars(cliConfig, command, groupCommand)
271
283
  : undefined;
272
284
  if (envVarValues === undefined) {
273
285
  result = configuredValues;
@@ -1,3 +1,4 @@
1
+ import type { GroupCommand } from "@flowscripter/dynamic-cli-framework-api";
1
2
  import type { Command } from "@flowscripter/dynamic-cli-framework-api";
2
3
  import type { CLIConfig } from "@flowscripter/dynamic-cli-framework-api";
3
4
  import type { Option } from "@flowscripter/dynamic-cli-framework-api";
@@ -26,11 +27,14 @@ function getKeySegment(segment: string, isCustom = false, isArray = false) {
26
27
  * @param command the {@link Command} to use for determining the default configuration key.
27
28
  * @param argumentAncestry a list of {@link SubCommandArgument} instances from the root command arguments to a leaf argument.
28
29
  * Apart from {@link ComplexOption} instances this will always only have a single entry.
30
+ * @param groupCommand the {@link GroupCommand} if the command is a member of a group, in which case the group name
31
+ * is an additional key segment.
29
32
  */
30
33
  export function getSubCommandArgumentConfigurationKey(
31
34
  cliConfig: CLIConfig,
32
35
  command: Command,
33
36
  argumentAncestry: Array<SubCommandArgument>,
37
+ groupCommand?: GroupCommand,
34
38
  ): string | undefined {
35
39
  if (command.enableConfiguration === undefined || command.enableConfiguration !== true) {
36
40
  return undefined;
@@ -43,6 +47,9 @@ export function getSubCommandArgumentConfigurationKey(
43
47
  const firstArgument = argumentAncestry[0]!;
44
48
  if (firstArgument.configurationKey === undefined) {
45
49
  keySegments.push(getKeySegment(cliConfig.name));
50
+ if (groupCommand) {
51
+ keySegments.push(getKeySegment(groupCommand.name));
52
+ }
46
53
  keySegments.push(getKeySegment(command.name));
47
54
  }
48
55
 
@@ -14,6 +14,7 @@ import { MAXIMUM_ARGUMENT_ARRAY_SIZE } from "@flowscripter/dynamic-cli-framework
14
14
  import type { Option } from "@flowscripter/dynamic-cli-framework-api";
15
15
  import type { GlobalCommandArgument } from "@flowscripter/dynamic-cli-framework-api";
16
16
  import type { GlobalCommand } from "@flowscripter/dynamic-cli-framework-api";
17
+ import type { GroupCommand } from "@flowscripter/dynamic-cli-framework-api";
17
18
  import type { SubCommand } from "@flowscripter/dynamic-cli-framework-api";
18
19
  import type { ComplexOption } from "@flowscripter/dynamic-cli-framework-api";
19
20
 
@@ -29,11 +30,13 @@ function getSubCommandArgumentKeyPrefix(
29
30
  cliConfig: CLIConfig,
30
31
  command: Command,
31
32
  subCommandArgument: SubCommandArgument,
33
+ groupCommand?: GroupCommand,
32
34
  ) {
33
35
  if (subCommandArgument.configurationKey) {
34
36
  return subCommandArgument.configurationKey;
35
37
  }
36
- return `${getKeySegment(cliConfig.name)}_${getKeySegment(command.name)}_${getKeySegment(
38
+ const groupSegment = groupCommand ? `${getKeySegment(groupCommand.name)}_` : "";
39
+ return `${getKeySegment(cliConfig.name)}_${groupSegment}${getKeySegment(command.name)}_${getKeySegment(
37
40
  subCommandArgument.name,
38
41
  )}`;
39
42
  }
@@ -214,16 +217,24 @@ function getOptionValuesFromEnvVars(
214
217
  * @param cliConfig the {@link CLIConfig} to use for determining the default configuration key.
215
218
  * @param command the {@link SubCommand} to use for determining the default configuration key and containing
216
219
  * {@link Positional} and {@link Option} instances to populate values for.
220
+ * @param groupCommand the {@link GroupCommand} if the command is a group member, in which case the group name
221
+ * is an additional env var name segment.
217
222
  */
218
223
  export function getSubCommandValuesFromEnvVars(
219
224
  cliConfig: CLIConfig,
220
225
  command: SubCommand,
226
+ groupCommand?: GroupCommand,
221
227
  ): PopulatedValues | undefined {
222
228
  const envVarValues = Object.create(null) as PopulatedValues;
223
229
  if (command.options) {
224
230
  for (const option of command.options) {
225
231
  const potentialEnvVarNames = Object.keys(process.env);
226
- const optionPrefix = getSubCommandArgumentKeyPrefix(cliConfig, command, option as Option);
232
+ const optionPrefix = getSubCommandArgumentKeyPrefix(
233
+ cliConfig,
234
+ command,
235
+ option as Option,
236
+ groupCommand,
237
+ );
227
238
  getOptionValuesFromEnvVars(
228
239
  envVarValues,
229
240
  potentialEnvVarNames,
@@ -244,7 +255,12 @@ export function getSubCommandValuesFromEnvVars(
244
255
  `Unsafe key name in use: ${positional.name}, CodeQL Rule ID: js/prototype-polluting-assignment`,
245
256
  );
246
257
  }
247
- let envVarNamePrefix = getSubCommandArgumentKeyPrefix(cliConfig, command, positional);
258
+ let envVarNamePrefix = getSubCommandArgumentKeyPrefix(
259
+ cliConfig,
260
+ command,
261
+ positional,
262
+ groupCommand,
263
+ );
248
264
 
249
265
  if (positional.isVarargMultiple) {
250
266
  envVarNamePrefix = `${envVarNamePrefix}_`;
@@ -312,6 +312,7 @@ function getOptionHelpEntry(
312
312
  option: Option | ComplexOption,
313
313
  subEntryIndent = 0,
314
314
  optionAncestry: Array<Option | ComplexOption> = [],
315
+ groupCommand?: GroupCommand,
315
316
  ): HelpEntry {
316
317
  let subEntries: Array<HelpEntry> | undefined;
317
318
  let optionCharacters = "--";
@@ -328,10 +329,15 @@ function getOptionHelpEntry(
328
329
  subEntries = [];
329
330
  option.properties.forEach((property) => {
330
331
  subEntries!.push(
331
- getOptionHelpEntry(cliConfig, includeEnvVars, command, property, newSubEntryIndent, [
332
- ...optionAncestry,
333
- option,
334
- ]),
332
+ getOptionHelpEntry(
333
+ cliConfig,
334
+ includeEnvVars,
335
+ command,
336
+ property,
337
+ newSubEntryIndent,
338
+ [...optionAncestry, option],
339
+ groupCommand,
340
+ ),
335
341
  );
336
342
  });
337
343
  } else {
@@ -384,10 +390,12 @@ function getOptionHelpEntry(
384
390
  }
385
391
 
386
392
  if (includeEnvVars && option.type !== ComplexValueTypeName.COMPLEX) {
387
- const configurationKey = getSubCommandArgumentConfigurationKey(cliConfig, command, [
388
- ...(optionAncestry as Array<SubCommandArgument>),
389
- option as unknown as SubCommandArgument,
390
- ]);
393
+ const configurationKey = getSubCommandArgumentConfigurationKey(
394
+ cliConfig,
395
+ command,
396
+ [...(optionAncestry as Array<SubCommandArgument>), option as unknown as SubCommandArgument],
397
+ groupCommand,
398
+ );
391
399
  if (configurationKey !== undefined) {
392
400
  notesItems.push(`env var: ${configurationKey}`);
393
401
  }
@@ -418,6 +426,7 @@ function getPositionalHelpEntry(
418
426
  includeEnvVars: boolean,
419
427
  command: Command,
420
428
  positional: Positional,
429
+ groupCommand?: GroupCommand,
421
430
  ): HelpEntry {
422
431
  const notesItems: Array<string> = [];
423
432
  if (positional.allowableValues !== undefined && positional.allowableValues.length > 0) {
@@ -458,9 +467,12 @@ function getPositionalHelpEntry(
458
467
  }
459
468
 
460
469
  if (includeEnvVars) {
461
- const configurationKey = getSubCommandArgumentConfigurationKey(cliConfig, command, [
462
- positional,
463
- ]);
470
+ const configurationKey = getSubCommandArgumentConfigurationKey(
471
+ cliConfig,
472
+ command,
473
+ [positional],
474
+ groupCommand,
475
+ );
464
476
  if (configurationKey !== undefined) {
465
477
  notesItems.push(`env var: ${configurationKey}`);
466
478
  }
@@ -486,6 +498,7 @@ export function getCommandArgsHelpSections(
486
498
  includeEnvVars: boolean,
487
499
  subCommand: SubCommand,
488
500
  isSingleCommandApp: boolean,
501
+ groupCommand?: GroupCommand,
489
502
  ): Array<HelpSection> {
490
503
  const helpSections: Array<HelpSection> = [];
491
504
  if (subCommand.options.length > 0 || subCommand.positionals.length > 0) {
@@ -495,12 +508,20 @@ export function getCommandArgsHelpSections(
495
508
  };
496
509
  subCommand.options.forEach((option) => {
497
510
  argumentsSection.helpEntries.push(
498
- getOptionHelpEntry(cliConfig, includeEnvVars, subCommand, option as Option),
511
+ getOptionHelpEntry(
512
+ cliConfig,
513
+ includeEnvVars,
514
+ subCommand,
515
+ option as Option,
516
+ 0,
517
+ [],
518
+ groupCommand,
519
+ ),
499
520
  );
500
521
  });
501
522
  subCommand.positionals.forEach((positional) => {
502
523
  argumentsSection.helpEntries.push(
503
- getPositionalHelpEntry(cliConfig, includeEnvVars, subCommand, positional),
524
+ getPositionalHelpEntry(cliConfig, includeEnvVars, subCommand, positional, groupCommand),
504
525
  );
505
526
  });
506
527
  helpSections.push(argumentsSection);