Skip to content

Add infrastructure for required non-interactive flags - #8207

Open
gonzaloriestra wants to merge 2 commits into
mainfrom
gonzalo/noninteractive-required-flags
Open

Add infrastructure for required non-interactive flags#8207
gonzaloriestra wants to merge 2 commits into
mainfrom
gonzalo/noninteractive-required-flags

Conversation

@gonzaloriestra

@gonzaloriestra gonzaloriestra commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Related: https://github.com/shop/issues-develop/issues/22928

Summary

  • Add requiredIfNonInteractive flag metadata and append Required if non interactive to help descriptions.
  • Validate direct, alternative, and conditional requirements centrally in BaseCommand.
  • Report all missing non-interactive requirements together and support wrapped flags in the ESLint rule.

Context

This builds on the approach explored in #7716 by @nickwesselman: annotate flags at definition time and validate them centrally in BaseCommand. It completes the infrastructure with grouped and conditional requirements plus aggregated errors.

This PR only prepares the infrastructure. Command adoption follows in the dependent PRs for apps, themes, stores, and other commands.

Testing

See #8223

@github-actions github-actions Bot added the Area: @shopify/cli @shopify/cli package issues label Jul 30, 2026
@gonzaloriestra

Copy link
Copy Markdown
Contributor Author

/snapit

@github-actions

Copy link
Copy Markdown
Contributor

🫰✨ Thanks @gonzaloriestra! Your snapshot has been published to npm.

Test the snapshot by installing your package globally:

pnpm i -g --@shopify:registry=https://registry.npmjs.org @shopify/cli@0.0.0-snapshot-20260731093434

Caution

After installing, validate the version by running shopify version in your terminal.
If the versions don't match, you might have multiple global instances installed.
Use which shopify to find out which one you are running and uninstall it.

@gonzaloriestra
gonzaloriestra force-pushed the gonzalo/noninteractive-required-flags branch from 62cc62e to 40d5db8 Compare July 31, 2026 10:32
@gonzaloriestra gonzaloriestra changed the title Show required non-interactive flags in CLI help Add infrastructure for required non-interactive flags Jul 31, 2026
@gonzaloriestra
gonzaloriestra force-pushed the gonzalo/noninteractive-required-flags branch from 40d5db8 to 9daf6ea Compare July 31, 2026 12:29
@gonzaloriestra
gonzaloriestra marked this pull request as ready for review July 31, 2026 14:09
@gonzaloriestra
gonzaloriestra requested a review from a team as a code owner July 31, 2026 14:09
@gonzaloriestra
gonzaloriestra force-pushed the gonzalo/noninteractive-required-flags branch from 9daf6ea to 415b7bb Compare July 31, 2026 14:15
@github-actions

Copy link
Copy Markdown
Contributor

Differences in type declarations

We detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:

  • Some seemingly private modules might be re-exported through public modules.
  • If the branch is behind main you might see odd diffs, rebase main into this branch.

New type declarations

We found no new type declarations in this PR

Existing type declarations

packages/cli-kit/dist/public/node/base-command.d.ts
@@ -2,8 +2,15 @@ import { Command } from '@oclif/core';
 import { OutputFlags, Input, ParserOutput, FlagInput, OutputArgs } from '@oclif/core/parser';
 export type ArgOutput = OutputArgs<any>;
 export type FlagOutput = OutputFlags<any>;
+export interface NonTTYFlagRequirement {
+    /** At least one of these flags must be present when the requirement applies. */
+    flags: string[];
+    /** Determines whether the requirement applies to the parsed flags. */
+    when?: (flags: FlagOutput) => boolean;
+}
 declare abstract class BaseCommand extends Command {
     static baseFlags: FlagInput<{}>;
+    static nonTTYFlagRequirements(_flags: FlagOutput): NonTTYFlagRequirement[];
     static descriptionWithoutMarkdown(): string | undefined;
     static analyticsNameOverride(): string | undefined;
     static analyticsStopCommand(): string | undefined;
@@ -22,6 +29,8 @@ declare abstract class BaseCommand extends Command {
     }>;
     protected environmentsFilename(): string | undefined;
     protected failMissingNonTTYFlags(flags: FlagOutput, requiredFlags: string[]): void;
+    private failMissingNonTTYFlagRequirements;
+    private applicableNonTTYFlagRequirements;
     private resultWithEnvironment;
     /**
      * Tries to load an environment to forward to the command. If no environment
packages/cli-kit/dist/public/node/cli.d.ts
@@ -55,6 +55,19 @@ export declare const portFlag: (options?: {
     env?: string;
     hidden?: boolean;
 }) => import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
+/**
+ * Marks a flag as required when the CLI cannot prompt for a value.
+ *
+ * The flag remains optional in interactive terminals. In non-interactive environments,
+ * `BaseCommand` validates the flag automatically and the requirement is shown in `--help`.
+ * Use `BaseCommand.nonTTYFlagRequirements` for conditional or alternative requirements.
+ *
+ * @param flag - An oclif flag definition.
+ * @returns A new flag definition annotated for non-interactive validation and help output.
+ */
+export declare function requiredIfNonInteractive<TFlag extends {
+    description?: string;
+}>(flag: TFlag): TFlag;
 /**
  * Clear the CLI cache, used to store some API responses and handle notifications status
  */

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: @shopify/cli @shopify/cli package issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant