Skip to content

Commit

Permalink
Add CLI2 invocation back to pull command
Browse files Browse the repository at this point in the history
Re-arrange + export ThemeCommand helpers
  • Loading branch information
jamesmengo committed Sep 23, 2024
1 parent 4502916 commit c2bceec
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 4 deletions.
8 changes: 8 additions & 0 deletions packages/cli/oclif.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5692,6 +5692,14 @@
"name": "ignore",
"type": "option"
},
"legacy": {
"allowNo": false,
"description": "Use the legacy Ruby implementation for the `shopify theme pull` command.",
"env": "SHOPIFY_FLAG_LEGACY",
"hidden": true,
"name": "legacy",
"type": "boolean"
},
"live": {
"allowNo": false,
"char": "l",
Expand Down
105 changes: 105 additions & 0 deletions packages/theme/src/cli/commands/theme/pull.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import Pull from './pull.js'
import {DevelopmentThemeManager} from '../../utilities/development-theme-manager.js'
import {ensureThemeStore} from '../../utilities/theme-store.js'
import {describe, vi, expect, test} from 'vitest'
import {Config} from '@oclif/core'
import {execCLI2} from '@shopify/cli-kit/node/ruby'
import {AdminSession, ensureAuthenticatedThemes} from '@shopify/cli-kit/node/session'
import {useEmbeddedThemeCLI} from '@shopify/cli-kit/node/context/local'
import {renderWarning} from '@shopify/cli-kit/node/ui'
import {Theme} from '@shopify/cli-kit/node/themes/types'
import {buildTheme} from '@shopify/cli-kit/node/themes/factories'

vi.mock('../../services/pull.js')
vi.mock('../../utilities/development-theme-manager.js')
vi.mock('../../utilities/theme-selector.js')
vi.mock('../../utilities/theme-store.js')
vi.mock('@shopify/cli-kit/node/context/local')
vi.mock('@shopify/cli-kit/node/ruby')
vi.mock('@shopify/cli-kit/node/session')
vi.mock('@shopify/cli-kit/node/ui')

const CommandConfig = new Config({root: __dirname})

describe('Pull', () => {
const adminSession = {token: '', storeFqdn: ''}
const path = '/my-theme'

describe('run with CLI 2 implementation', () => {
async function run(argv: string[], theme?: Theme) {
await runPullCommand(['--legacy', ...argv], path, adminSession, theme)
}

function expectCLI2ToHaveBeenCalledWith(command: string) {
expect(execCLI2).toHaveBeenCalledWith(command.split(' '), {
adminToken: adminSession.token,
store: 'example.myshopify.com',
})
}

test('should pass development theme from local storage to CLI 2', async () => {
vi.mocked(useEmbeddedThemeCLI).mockReturnValue(true)

const theme = buildTheme({id: 1, name: 'Theme', role: 'development'})!
await run([], theme)

expect(DevelopmentThemeManager.prototype.find).not.toHaveBeenCalled()
expect(DevelopmentThemeManager.prototype.fetch).toHaveBeenCalledOnce()
expectCLI2ToHaveBeenCalledWith(`theme pull ${path} --development-theme-id ${theme.id}`)
})

test('should pass theme and development theme from local storage to CLI 2', async () => {
vi.mocked(useEmbeddedThemeCLI).mockReturnValue(true)

const themeId = 2
const theme = buildTheme({id: 3, name: 'Theme', role: 'development'})!
await run([`--theme=${themeId}`], theme)

expectCLI2ToHaveBeenCalledWith(`theme pull ${path} --theme ${themeId} --development-theme-id ${theme.id}`)
})

test("should not pass development theme to CLI 2 when user isn't using the embedded CLI", async () => {
vi.mocked(useEmbeddedThemeCLI).mockReturnValue(false)

const themeId = 2
const theme = buildTheme({id: 3, name: 'Theme', role: 'development'})!
await run([`--theme=${themeId}`], theme)

expectCLI2ToHaveBeenCalledWith(`theme pull ${path} --theme ${themeId}`)
})

test('should not pass development theme to CLI 2 if local storage is empty', async () => {
vi.mocked(useEmbeddedThemeCLI).mockReturnValue(true)
await run([])

expect(DevelopmentThemeManager.prototype.find).not.toHaveBeenCalled()
expect(DevelopmentThemeManager.prototype.fetch).toHaveBeenCalledOnce()
expectCLI2ToHaveBeenCalledWith(`theme pull ${path}`)
})

test('should pass theme and development theme to CLI 2', async () => {
vi.mocked(useEmbeddedThemeCLI).mockReturnValue(true)
const theme = buildTheme({id: 4, name: 'Theme', role: 'development'})!
await run(['--development'], theme)

expect(DevelopmentThemeManager.prototype.find).toHaveBeenCalledOnce()
expect(DevelopmentThemeManager.prototype.fetch).not.toHaveBeenCalled()
expectCLI2ToHaveBeenCalledWith(`theme pull ${path} --theme ${theme.id} --development-theme-id ${theme.id}`)
})
})

async function runPullCommand(argv: string[], path: string, adminSession: AdminSession, theme?: Theme) {
vi.mocked(renderWarning).mockReturnValue('shhh!')
vi.mocked(ensureThemeStore).mockReturnValue('example.myshopify.com')
vi.mocked(ensureAuthenticatedThemes).mockResolvedValue(adminSession)
if (theme) {
vi.spyOn(DevelopmentThemeManager.prototype, 'find').mockResolvedValue(theme)
}
vi.spyOn(DevelopmentThemeManager.prototype, 'fetch').mockResolvedValue(theme)

await CommandConfig.load()
const pull = new Pull([`--path=${path}`, ...argv], CommandConfig)

await pull.run()
}
})
53 changes: 49 additions & 4 deletions packages/theme/src/cli/commands/theme/pull.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import {themeFlags} from '../../flags.js'
import ThemeCommand from '../../utilities/theme-command.js'
import ThemeCommand, {FlagValues} from '../../utilities/theme-command.js'
import {pull, PullFlags} from '../../services/pull.js'
import {Flags} from '@oclif/core'
import {ensureThemeStore} from '../../utilities/theme-store.js'
import {DevelopmentThemeManager} from '../../utilities/development-theme-manager.js'
import {showEmbeddedCLIWarning} from '../../utilities/embedded-cli-warning.js'
import {globalFlags} from '@shopify/cli-kit/node/cli'
import {Flags} from '@oclif/core'
import {ensureAuthenticatedThemes} from '@shopify/cli-kit/node/session'
import {useEmbeddedThemeCLI} from '@shopify/cli-kit/node/context/local'
import {execCLI2} from '@shopify/cli-kit/node/ruby'

export default class Pull extends ThemeCommand {
static summary = 'Download your remote theme files locally.'
Expand Down Expand Up @@ -54,13 +60,18 @@ If no theme is specified, then you're prompted to select the theme to pull from
description: 'Proceed without confirmation, if current directory does not seem to be theme directory.',
env: 'SHOPIFY_FLAG_FORCE',
}),
legacy: Flags.boolean({
hidden: true,
description: 'Use the legacy Ruby implementation for the `shopify theme pull` command.',
env: 'SHOPIFY_FLAG_LEGACY',
}),
}

static cli2Flags = ['theme', 'development', 'live', 'nodelete', 'only', 'ignore', 'force', 'development-theme-id']

async run(): Promise<void> {
showEmbeddedCLIWarning()
const {flags} = await this.parse(Pull)

const pullFlags: PullFlags = {
path: flags.path,
password: flags.password,
Expand All @@ -75,6 +86,40 @@ If no theme is specified, then you're prompted to select the theme to pull from
force: flags.force,
}

await pull(pullFlags)
if (flags.legacy) {
await this.execLegacy()
} else {
await pull(pullFlags)
}
}

async execLegacy() {
const {flags} = await this.parse(Pull)
const store = ensureThemeStore({store: flags.store})
const adminSession = await ensureAuthenticatedThemes(store, flags.password)

const developmentThemeManager = new DevelopmentThemeManager(adminSession)
const developmentTheme = await (flags.development
? developmentThemeManager.find()
: developmentThemeManager.fetch())

const flagsForCli2 = flags as typeof flags & FlagValues

if (developmentTheme) {
if (flagsForCli2.development) {
flagsForCli2.theme = `${developmentTheme.id}`
flagsForCli2.development = false
}
if (useEmbeddedThemeCLI()) {
flagsForCli2['development-theme-id'] = developmentTheme.id
}
}

const flagsToPass = this.passThroughFlags(flagsForCli2, {allowedFlags: Pull.cli2Flags})
const command = ['theme', 'pull', flagsForCli2.path, ...flagsToPass].filter((arg) => {
return arg !== undefined
})

await execCLI2(command, {store, adminToken: adminSession.token})
}
}

0 comments on commit c2bceec

Please sign in to comment.