From 49784030c0dad889bab427753d9dae8bb64b4303 Mon Sep 17 00:00:00 2001 From: Ariel Caplan Date: Tue, 8 Nov 2022 19:21:48 +0200 Subject: [PATCH 1/4] Allowlist relevant flags for CLI2 passthrough --- packages/theme/src/cli/commands/theme/check.ts | 15 ++++++++++++++- packages/theme/src/cli/commands/theme/delete.ts | 4 +++- packages/theme/src/cli/commands/theme/dev.ts | 4 +++- packages/theme/src/cli/commands/theme/open.ts | 4 +++- packages/theme/src/cli/commands/theme/publish.ts | 4 +++- packages/theme/src/cli/commands/theme/pull.ts | 4 +++- packages/theme/src/cli/commands/theme/push.ts | 16 +++++++++++++++- .../theme/src/cli/utilities/theme-command.ts | 8 ++++---- 8 files changed, 48 insertions(+), 11 deletions(-) diff --git a/packages/theme/src/cli/commands/theme/check.ts b/packages/theme/src/cli/commands/theme/check.ts index 256ac3d2c0b..ba6784feb94 100644 --- a/packages/theme/src/cli/commands/theme/check.ts +++ b/packages/theme/src/cli/commands/theme/check.ts @@ -74,9 +74,22 @@ Excludes checks matching any category when specified more than once`, }), } + static cli2Flags = [ + 'auto-correct', + 'category', + 'config', + 'exclude-category', + 'fail-level', + 'init', + 'list', + 'output', + 'print', + 'version', + ] + async run(): Promise { const {flags} = await this.parse(Check) - await execCLI2(['theme', 'check', flags.path, ...this.passThroughFlags(flags, {exclude: ['path', 'verbose']})], { + await execCLI2(['theme', 'check', flags.path, ...this.passThroughFlags(flags, {relevantFlags: Check.cli2Flags})], { directory: flags.path, }) } diff --git a/packages/theme/src/cli/commands/theme/delete.ts b/packages/theme/src/cli/commands/theme/delete.ts index 78c11467ea1..2ece985632a 100644 --- a/packages/theme/src/cli/commands/theme/delete.ts +++ b/packages/theme/src/cli/commands/theme/delete.ts @@ -32,6 +32,8 @@ export default class Delete extends ThemeCommand { store: themeFlags.store, } + static cli2Flags = ['development', 'show-all', 'force'] + async run(): Promise { const {flags, argv} = await this.parse(Delete) @@ -43,7 +45,7 @@ export default class Delete extends ThemeCommand { command.push(...argv) } - const flagsToPass = this.passThroughFlags(flags, {exclude: ['store', 'verbose', 'password']}) + const flagsToPass = this.passThroughFlags(flags, {relevantFlags: Delete.cli2Flags}) command.push(...flagsToPass) const adminSession = await session.ensureAuthenticatedThemes(store, flags.password) diff --git a/packages/theme/src/cli/commands/theme/dev.ts b/packages/theme/src/cli/commands/theme/dev.ts index 8713d2704f5..81008a6a37a 100644 --- a/packages/theme/src/cli/commands/theme/dev.ts +++ b/packages/theme/src/cli/commands/theme/dev.ts @@ -70,13 +70,15 @@ export default class Dev extends ThemeCommand { }), } + static cli2Flags = ['host', 'live-reload', 'poll', 'theme-editor-sync', 'port', 'theme', 'only', 'ignore', 'stable'] + // Tokens are valid for 120m, better to be safe and refresh every 90min ThemeRefreshTimeoutInMinutes = 90 async run(): Promise { const {flags} = await this.parse(Dev) - const flagsToPass = this.passThroughFlags(flags, {exclude: ['path', 'store', 'verbose']}) + const flagsToPass = this.passThroughFlags(flags, {relevantFlags: Dev.cli2Flags}) const command = ['theme', 'serve', flags.path, ...flagsToPass] const store = await getThemeStore(flags) diff --git a/packages/theme/src/cli/commands/theme/open.ts b/packages/theme/src/cli/commands/theme/open.ts index 8b8269dc09c..133396a6a9e 100644 --- a/packages/theme/src/cli/commands/theme/open.ts +++ b/packages/theme/src/cli/commands/theme/open.ts @@ -34,9 +34,11 @@ export default class Open extends ThemeCommand { store: themeFlags.store, } + static cli2Flags = ['development', 'editor', 'live', 'theme'] + async run(): Promise { const {flags} = await this.parse(Open) - const flagsToPass = this.passThroughFlags(flags, {exclude: ['store', 'verbose', 'password']}) + const flagsToPass = this.passThroughFlags(flags, {relevantFlags: Open.cli2Flags}) const command = ['theme', 'open', ...flagsToPass] const store = await getThemeStore(flags) diff --git a/packages/theme/src/cli/commands/theme/publish.ts b/packages/theme/src/cli/commands/theme/publish.ts index d6dbfccaa06..61cc578d257 100644 --- a/packages/theme/src/cli/commands/theme/publish.ts +++ b/packages/theme/src/cli/commands/theme/publish.ts @@ -21,11 +21,13 @@ export default class Publish extends ThemeCommand { store: themeFlags.store, } + static cli2Flags = ['force'] + async run(): Promise { const {flags, args} = await this.parse(Publish) const store = await getThemeStore(flags) - const flagsToPass = this.passThroughFlags(flags, {exclude: ['path', 'store', 'verbose', 'password']}) + const flagsToPass = this.passThroughFlags(flags, {relevantFlags: Publish.cli2Flags}) const command = ['theme', 'publish'] if (args.themeId) { command.push(args.themeId) diff --git a/packages/theme/src/cli/commands/theme/pull.ts b/packages/theme/src/cli/commands/theme/pull.ts index ab8b452c786..50b5232ab49 100644 --- a/packages/theme/src/cli/commands/theme/pull.ts +++ b/packages/theme/src/cli/commands/theme/pull.ts @@ -51,6 +51,8 @@ export default class Pull extends ThemeCommand { }), } + static cli2Flags = ['theme', 'development', 'live', 'nodelete', 'only', 'ignore'] + async run(): Promise { const {flags} = await this.parse(Pull) @@ -59,7 +61,7 @@ export default class Pull extends ThemeCommand { validPath = path.resolve(flags.path) } - const flagsToPass = this.passThroughFlags(flags, {exclude: ['path', 'verbose', 'store', 'password']}) + const flagsToPass = this.passThroughFlags(flags, {relevantFlags: Pull.cli2Flags}) const command = ['theme', 'pull', validPath, ...flagsToPass] diff --git a/packages/theme/src/cli/commands/theme/push.ts b/packages/theme/src/cli/commands/theme/push.ts index 21f328a6902..079114840b0 100644 --- a/packages/theme/src/cli/commands/theme/push.ts +++ b/packages/theme/src/cli/commands/theme/push.ts @@ -78,10 +78,24 @@ export default class Push extends ThemeCommand { }), } + static cli2Flags = [ + 'theme', + 'development', + 'live', + 'unpublished', + 'nodelete', + 'only', + 'ignore', + 'json', + 'allow-live', + 'publish', + 'stable', + ] + async run(): Promise { const {flags} = await this.parse(Push) - const flagsToPass = this.passThroughFlags(flags, {exclude: ['path', 'store', 'verbose', 'password']}) + const flagsToPass = this.passThroughFlags(flags, {relevantFlags: Push.cli2Flags}) const command = ['theme', 'push', flags.path, ...flagsToPass] const store = await getThemeStore(flags) diff --git a/packages/theme/src/cli/utilities/theme-command.ts b/packages/theme/src/cli/utilities/theme-command.ts index 28da3204f65..e10b0e08630 100644 --- a/packages/theme/src/cli/utilities/theme-command.ts +++ b/packages/theme/src/cli/utilities/theme-command.ts @@ -4,15 +4,15 @@ interface FlagValues { [key: string]: boolean | string | string[] | number | undefined } interface PassThroughFlagsOptions { - // Exclude flags that are only for CLI3 but will cause errors if passed to CLI2 - exclude?: string[] + // Only pass on flags that are relevant to CLI2 + relevantFlags?: string[] } export default abstract class ThemeCommand extends Command { - passThroughFlags(flags: FlagValues, {exclude}: PassThroughFlagsOptions): string[] { + passThroughFlags(flags: FlagValues, {relevantFlags}: PassThroughFlagsOptions): string[] { const passThroughFlags: string[] = [] for (const [label, value] of Object.entries(flags)) { - if ((exclude ?? []).includes(label)) { + if (!(relevantFlags ?? []).includes(label)) { continue } else if (typeof value === 'boolean') { if (value) passThroughFlags.push(`--${label}`) From 496083f4597adefbd75aec702fefc6a1683d1dfc Mon Sep 17 00:00:00 2001 From: Ariel Caplan Date: Sun, 27 Nov 2022 15:11:39 +0200 Subject: [PATCH 2/4] Rename to allowedFlags --- packages/theme/src/cli/commands/theme/check.ts | 2 +- packages/theme/src/cli/commands/theme/delete.ts | 2 +- packages/theme/src/cli/commands/theme/dev.ts | 2 +- packages/theme/src/cli/commands/theme/open.ts | 2 +- packages/theme/src/cli/commands/theme/publish.ts | 2 +- packages/theme/src/cli/commands/theme/pull.ts | 2 +- packages/theme/src/cli/commands/theme/push.ts | 2 +- packages/theme/src/cli/utilities/theme-command.ts | 6 +++--- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/theme/src/cli/commands/theme/check.ts b/packages/theme/src/cli/commands/theme/check.ts index ba6784feb94..0e01036c5d1 100644 --- a/packages/theme/src/cli/commands/theme/check.ts +++ b/packages/theme/src/cli/commands/theme/check.ts @@ -89,7 +89,7 @@ Excludes checks matching any category when specified more than once`, async run(): Promise { const {flags} = await this.parse(Check) - await execCLI2(['theme', 'check', flags.path, ...this.passThroughFlags(flags, {relevantFlags: Check.cli2Flags})], { + await execCLI2(['theme', 'check', flags.path, ...this.passThroughFlags(flags, {allowedFlags: Check.cli2Flags})], { directory: flags.path, }) } diff --git a/packages/theme/src/cli/commands/theme/delete.ts b/packages/theme/src/cli/commands/theme/delete.ts index 2ece985632a..3c26e8006d0 100644 --- a/packages/theme/src/cli/commands/theme/delete.ts +++ b/packages/theme/src/cli/commands/theme/delete.ts @@ -45,7 +45,7 @@ export default class Delete extends ThemeCommand { command.push(...argv) } - const flagsToPass = this.passThroughFlags(flags, {relevantFlags: Delete.cli2Flags}) + const flagsToPass = this.passThroughFlags(flags, {allowedFlags: Delete.cli2Flags}) command.push(...flagsToPass) const adminSession = await session.ensureAuthenticatedThemes(store, flags.password) diff --git a/packages/theme/src/cli/commands/theme/dev.ts b/packages/theme/src/cli/commands/theme/dev.ts index 81008a6a37a..84fa32ad925 100644 --- a/packages/theme/src/cli/commands/theme/dev.ts +++ b/packages/theme/src/cli/commands/theme/dev.ts @@ -78,7 +78,7 @@ export default class Dev extends ThemeCommand { async run(): Promise { const {flags} = await this.parse(Dev) - const flagsToPass = this.passThroughFlags(flags, {relevantFlags: Dev.cli2Flags}) + const flagsToPass = this.passThroughFlags(flags, {allowedFlags: Dev.cli2Flags}) const command = ['theme', 'serve', flags.path, ...flagsToPass] const store = await getThemeStore(flags) diff --git a/packages/theme/src/cli/commands/theme/open.ts b/packages/theme/src/cli/commands/theme/open.ts index 133396a6a9e..e6627f26cb7 100644 --- a/packages/theme/src/cli/commands/theme/open.ts +++ b/packages/theme/src/cli/commands/theme/open.ts @@ -38,7 +38,7 @@ export default class Open extends ThemeCommand { async run(): Promise { const {flags} = await this.parse(Open) - const flagsToPass = this.passThroughFlags(flags, {relevantFlags: Open.cli2Flags}) + const flagsToPass = this.passThroughFlags(flags, {allowedFlags: Open.cli2Flags}) const command = ['theme', 'open', ...flagsToPass] const store = await getThemeStore(flags) diff --git a/packages/theme/src/cli/commands/theme/publish.ts b/packages/theme/src/cli/commands/theme/publish.ts index 61cc578d257..24888df5a45 100644 --- a/packages/theme/src/cli/commands/theme/publish.ts +++ b/packages/theme/src/cli/commands/theme/publish.ts @@ -27,7 +27,7 @@ export default class Publish extends ThemeCommand { const {flags, args} = await this.parse(Publish) const store = await getThemeStore(flags) - const flagsToPass = this.passThroughFlags(flags, {relevantFlags: Publish.cli2Flags}) + const flagsToPass = this.passThroughFlags(flags, {allowedFlags: Publish.cli2Flags}) const command = ['theme', 'publish'] if (args.themeId) { command.push(args.themeId) diff --git a/packages/theme/src/cli/commands/theme/pull.ts b/packages/theme/src/cli/commands/theme/pull.ts index 50b5232ab49..7c9a3733e15 100644 --- a/packages/theme/src/cli/commands/theme/pull.ts +++ b/packages/theme/src/cli/commands/theme/pull.ts @@ -61,7 +61,7 @@ export default class Pull extends ThemeCommand { validPath = path.resolve(flags.path) } - const flagsToPass = this.passThroughFlags(flags, {relevantFlags: Pull.cli2Flags}) + const flagsToPass = this.passThroughFlags(flags, {allowedFlags: Pull.cli2Flags}) const command = ['theme', 'pull', validPath, ...flagsToPass] diff --git a/packages/theme/src/cli/commands/theme/push.ts b/packages/theme/src/cli/commands/theme/push.ts index 079114840b0..22356436a0e 100644 --- a/packages/theme/src/cli/commands/theme/push.ts +++ b/packages/theme/src/cli/commands/theme/push.ts @@ -95,7 +95,7 @@ export default class Push extends ThemeCommand { async run(): Promise { const {flags} = await this.parse(Push) - const flagsToPass = this.passThroughFlags(flags, {relevantFlags: Push.cli2Flags}) + const flagsToPass = this.passThroughFlags(flags, {allowedFlags: Push.cli2Flags}) const command = ['theme', 'push', flags.path, ...flagsToPass] const store = await getThemeStore(flags) diff --git a/packages/theme/src/cli/utilities/theme-command.ts b/packages/theme/src/cli/utilities/theme-command.ts index e10b0e08630..7dc2c79ca57 100644 --- a/packages/theme/src/cli/utilities/theme-command.ts +++ b/packages/theme/src/cli/utilities/theme-command.ts @@ -5,14 +5,14 @@ interface FlagValues { } interface PassThroughFlagsOptions { // Only pass on flags that are relevant to CLI2 - relevantFlags?: string[] + allowedFlags?: string[] } export default abstract class ThemeCommand extends Command { - passThroughFlags(flags: FlagValues, {relevantFlags}: PassThroughFlagsOptions): string[] { + passThroughFlags(flags: FlagValues, {allowedFlags}: PassThroughFlagsOptions): string[] { const passThroughFlags: string[] = [] for (const [label, value] of Object.entries(flags)) { - if (!(relevantFlags ?? []).includes(label)) { + if (!(allowedFlags ?? []).includes(label)) { continue } else if (typeof value === 'boolean') { if (value) passThroughFlags.push(`--${label}`) From d2c8b9f70a2a086bd4f0b6aeaea59e57f7b78e8e Mon Sep 17 00:00:00 2001 From: Ariel Caplan Date: Sun, 27 Nov 2022 15:11:47 +0200 Subject: [PATCH 3/4] Add new force flag --- packages/theme/src/cli/commands/theme/dev.ts | 13 ++++++++++++- packages/theme/src/cli/commands/theme/pull.ts | 2 +- packages/theme/src/cli/commands/theme/push.ts | 1 + packages/theme/src/cli/commands/theme/share.ts | 10 ++++++++-- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/packages/theme/src/cli/commands/theme/dev.ts b/packages/theme/src/cli/commands/theme/dev.ts index 84fa32ad925..5f4f37e2a76 100644 --- a/packages/theme/src/cli/commands/theme/dev.ts +++ b/packages/theme/src/cli/commands/theme/dev.ts @@ -70,7 +70,18 @@ export default class Dev extends ThemeCommand { }), } - static cli2Flags = ['host', 'live-reload', 'poll', 'theme-editor-sync', 'port', 'theme', 'only', 'ignore', 'stable'] + static cli2Flags = [ + 'host', + 'live-reload', + 'poll', + 'theme-editor-sync', + 'port', + 'theme', + 'only', + 'ignore', + 'stable', + 'force', + ] // Tokens are valid for 120m, better to be safe and refresh every 90min ThemeRefreshTimeoutInMinutes = 90 diff --git a/packages/theme/src/cli/commands/theme/pull.ts b/packages/theme/src/cli/commands/theme/pull.ts index 7c9a3733e15..83b3f377318 100644 --- a/packages/theme/src/cli/commands/theme/pull.ts +++ b/packages/theme/src/cli/commands/theme/pull.ts @@ -51,7 +51,7 @@ export default class Pull extends ThemeCommand { }), } - static cli2Flags = ['theme', 'development', 'live', 'nodelete', 'only', 'ignore'] + static cli2Flags = ['theme', 'development', 'live', 'nodelete', 'only', 'ignore', 'force'] async run(): Promise { const {flags} = await this.parse(Pull) diff --git a/packages/theme/src/cli/commands/theme/push.ts b/packages/theme/src/cli/commands/theme/push.ts index 22356436a0e..f231bac2d09 100644 --- a/packages/theme/src/cli/commands/theme/push.ts +++ b/packages/theme/src/cli/commands/theme/push.ts @@ -90,6 +90,7 @@ export default class Push extends ThemeCommand { 'allow-live', 'publish', 'stable', + 'force', ] async run(): Promise { diff --git a/packages/theme/src/cli/commands/theme/share.ts b/packages/theme/src/cli/commands/theme/share.ts index a3b50ebbaa4..595e054ac9b 100644 --- a/packages/theme/src/cli/commands/theme/share.ts +++ b/packages/theme/src/cli/commands/theme/share.ts @@ -1,7 +1,7 @@ import {themeFlags} from '../../flags.js' import {getThemeStore} from '../../utilities/theme-store.js' import ThemeCommand from '../../utilities/theme-command.js' -import {cli, session} from '@shopify/cli-kit' +import {cli, path, session} from '@shopify/cli-kit' import {execCLI2} from '@shopify/cli-kit/node/ruby' import {Flags} from '@oclif/core' @@ -20,10 +20,16 @@ export default class Share extends ThemeCommand { }), } + static cli2Flags = ['force'] + async run(): Promise { const {flags} = await this.parse(Share) + const directory = flags.path ? path.resolve(flags.path) : process.cwd() + const flagsToPass = this.passThroughFlags(flags, {allowedFlags: Share.cli2Flags}) + const store = await getThemeStore(flags) const adminSession = await session.ensureAuthenticatedThemes(store, flags.password) - await execCLI2(['theme', 'share', flags.path], {adminSession}) + + await execCLI2(['theme', 'share', directory, ...flagsToPass], {adminSession}) } } From ad85ea39f93257d15a5352e8570bbea9126f852c Mon Sep 17 00:00:00 2001 From: Ariel Caplan Date: Sun, 27 Nov 2022 15:27:21 +0200 Subject: [PATCH 4/4] Pass through clone-url in init --- packages/theme/src/cli/commands/theme/init.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/theme/src/cli/commands/theme/init.ts b/packages/theme/src/cli/commands/theme/init.ts index 028b2ebcaa3..d7478e5074c 100644 --- a/packages/theme/src/cli/commands/theme/init.ts +++ b/packages/theme/src/cli/commands/theme/init.ts @@ -27,11 +27,14 @@ export default class Init extends ThemeCommand { }), } + static cli2Flags = ['clone-url'] + async run(): Promise { const {args, flags} = await this.parse(Init) const directory = flags.path ? path.resolve(flags.path) : process.cwd() const name = args.name || (await this.promptName(directory)) - const command = ['theme', 'init', name] + const flagsToPass = this.passThroughFlags(flags, {allowedFlags: Init.cli2Flags}) + const command = ['theme', 'init', name, ...flagsToPass] await execCLI2(command, { directory, })