diff --git a/src/cli.ts b/src/cli.ts index 926eb79d..2daa9f04 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,12 +1,10 @@ #!/usr/bin/env node import yargs from 'yargs'; -// eslint-disable-next-line import/no-unresolved import { hideBin } from 'yargs/helpers'; import buildCommand from './cli/commands/build'; import activateCommand from './cli/commands/activate'; import orchestrateCommand from './cli/commands/orchestrate'; -import cacheCommand from './cli/commands/cache'; import statusCommand from './cli/commands/status'; import versionCommand from './cli/commands/version'; import updateCommand from './cli/commands/update'; @@ -18,7 +16,6 @@ const cli = yargs(hideBin(process.argv)) .command(buildCommand) .command(activateCommand) .command(orchestrateCommand) - .command(cacheCommand) .command(statusCommand) .command(versionCommand) .command(updateCommand) diff --git a/src/cli/__tests__/cli-integration.test.ts b/src/cli/__tests__/cli-integration.test.ts index 95754806..b6607176 100644 --- a/src/cli/__tests__/cli-integration.test.ts +++ b/src/cli/__tests__/cli-integration.test.ts @@ -38,7 +38,6 @@ describe('CLI integration', () => { expect(result.stdout).toContain('build'); expect(result.stdout).toContain('activate'); expect(result.stdout).toContain('orchestrate'); - expect(result.stdout).toContain('cache'); expect(result.stdout).toContain('status'); expect(result.stdout).toContain('version'); expect(result.stdout).toContain('update'); @@ -83,6 +82,7 @@ describe('CLI integration', () => { expect(result.code).toStrictEqual(0); expect(result.stdout).toContain('--target-platform'); expect(result.stdout).toContain('--provider-strategy'); + expect(result.stdout).toContain('cache'); }); it('exits 0 for activate --help', async () => { @@ -92,8 +92,8 @@ describe('CLI integration', () => { expect(result.stdout).toContain('activate'); }); - it('exits 0 for cache --help', async () => { - const result = await runCli(['cache', '--help']); + it('exits 0 for orchestrate cache --help', async () => { + const result = await runCli(['orchestrate', 'cache', '--help']); expect(result.code).toStrictEqual(0); expect(result.stdout).toContain('cache'); diff --git a/src/cli/__tests__/commands.test.ts b/src/cli/__tests__/commands.test.ts index 08e9de5e..16909ea2 100644 --- a/src/cli/__tests__/commands.test.ts +++ b/src/cli/__tests__/commands.test.ts @@ -1,7 +1,6 @@ import buildCommand from '../commands/build'; import activateCommand from '../commands/activate'; import orchestrateCommand from '../commands/orchestrate'; -import cacheCommand from '../commands/cache'; import statusCommand from '../commands/status'; import versionCommand from '../commands/version'; import updateCommand from '../commands/update'; @@ -13,6 +12,7 @@ function createFakeYargs(): { yargs: any; options: Record } { positional: jest.fn(), example: jest.fn(), env: jest.fn(), + command: jest.fn(), }; yargs.option.mockImplementation((name: string, config: any) => { @@ -27,6 +27,7 @@ function createFakeYargs(): { yargs: any; options: Record } { }); yargs.example.mockReturnValue(yargs); yargs.env.mockReturnValue(yargs); + yargs.command.mockReturnValue(yargs); return { yargs, options }; } @@ -165,7 +166,6 @@ describe('CLI commands', () => { (orchestrateCommand.builder as Function)(yargs); expect(options['target-platform']).toBeDefined(); - expect(options['target-platform'].demandOption).toStrictEqual(true); expect(options['provider-strategy']).toBeDefined(); expect(options['provider-strategy'].default).toStrictEqual('aws'); expect(options['aws-stack-name']).toBeDefined(); @@ -175,23 +175,13 @@ describe('CLI commands', () => { expect(options['watch-to-end']).toBeDefined(); expect(options['clone-depth']).toBeDefined(); }); - }); - describe('cache command', () => { - it('exports the correct command name', () => { - expect(cacheCommand.command).toStrictEqual('cache '); - }); + it('registers cache as a subcommand', () => { + const { yargs } = createFakeYargs(); - it('has a description', () => { - expect(cacheCommand.describe).toBeTruthy(); - }); + (orchestrateCommand.builder as Function)(yargs); - it('has a builder function', () => { - expect(typeof cacheCommand.builder).toStrictEqual('function'); - }); - - it('has a handler function', () => { - expect(typeof cacheCommand.handler).toStrictEqual('function'); + expect(yargs.command).toHaveBeenCalled(); }); }); diff --git a/src/cli/commands/cache.ts b/src/cli/commands/cache.ts index 498c20a9..b70d2383 100644 --- a/src/cli/commands/cache.ts +++ b/src/cli/commands/cache.ts @@ -24,9 +24,9 @@ const cacheCommand: CommandModule = { description: 'Path to the Unity project', default: '.', }) - .example('game-ci cache list', 'List all cached workspaces') - .example('game-ci cache restore --cache-dir ./my-cache', 'Restore a cached workspace') - .example('game-ci cache clear', 'Clear all cached workspaces'); + .example('game-ci orchestrate cache list', 'List all cached workspaces') + .example('game-ci orchestrate cache restore --cache-dir ./my-cache', 'Restore a cached workspace') + .example('game-ci orchestrate cache clear', 'Clear all cached workspaces'); }, handler: async (cliArguments) => { const action = cliArguments.action as string; diff --git a/src/cli/commands/orchestrate.ts b/src/cli/commands/orchestrate.ts index 8f681881..3d805607 100644 --- a/src/cli/commands/orchestrate.ts +++ b/src/cli/commands/orchestrate.ts @@ -2,6 +2,7 @@ import type { CommandModule } from 'yargs'; import * as core from '@actions/core'; import { BuildParameters, ImageTag, Orchestrator } from '../../model'; import { mapCliArgumentsToInput, CliArguments } from '../input-mapper'; +import cacheCommand from './cache'; interface OrchestrateArguments extends CliArguments { targetPlatform: string; @@ -10,14 +11,14 @@ interface OrchestrateArguments extends CliArguments { const orchestrateCommand: CommandModule = { command: 'orchestrate', - describe: 'Run a build via orchestrator providers (AWS, Kubernetes, etc.)', + describe: 'Orchestrator — remote builds, cache management, and provider tools', builder: (yargs) => { return yargs + .command(cacheCommand) .option('target-platform', { alias: 'targetPlatform', type: 'string', description: 'Platform that the build should target', - demandOption: true, }) .option('provider-strategy', { alias: 'providerStrategy', @@ -188,6 +189,10 @@ const orchestrateCommand: CommandModule = { }, handler: async (cliArguments) => { try { + if (!cliArguments.targetPlatform) { + throw new Error('--target-platform is required for orchestrate builds. Run game-ci orchestrate --help.'); + } + mapCliArgumentsToInput(cliArguments); const buildParameters = await BuildParameters.create();