11
2- import { SpawnStatus } from 'codify-schemas' ;
2+ import { OS , SpawnStatus } from 'codify-schemas' ;
3+ import os from 'node:os' ;
34
45import { PluginInitOrchestrator } from '../common/initialize-plugins.js' ;
5- import { ProcessName , ctx } from '../events/context.js' ;
6+ import { ProcessName , ctx , SubProcessName } from '../events/context.js' ;
67import { Reporter } from '../ui/reporters/reporter.js' ;
8+ import { StubReporter } from '../ui/reporters/stub-reporter.js' ;
79import { sleep } from '../utils/index.js' ;
810import { spawn , spawnSafe } from '../utils/spawn.js' ;
9- import { PlanOrchestrator } from './plan.js' ;
11+ import { PlanOrchestrator , PlanOrchestratorResponse } from './plan.js' ;
1012import { ValidateOrchestrator } from './validate.js' ;
1113
1214export interface TestArgs {
1315 path ?: string ;
1416 secure ?: boolean ;
1517 verbosityLevel ?: number ;
18+ vmOs : OS ;
1619}
1720
1821export const TestOrchestrator = {
1922 async run ( args : TestArgs , reporter : Reporter ) : Promise < void > {
20-
21- // Perform validation initially to ensure the project is valid
22- const initializationResult = await PluginInitOrchestrator . run ( args , reporter ) ;
23- await ValidateOrchestrator . run ( { existing : initializationResult } , reporter ) ;
24-
25- const planResult = await PlanOrchestrator . run ( {
26- codifyConfigs : [ {
27- type : 'project' ,
28- plugins : { default : '/Users/kevinwang/Projects/codify-homebrew-plugin/src/index.ts' }
29- } , {
30- type : 'homebrew' ,
31- formulae : [ 'sshpass' ]
32- } , {
33- type : 'tart' ,
34- clone : [ { sourceName : 'ghcr.io/cirruslabs/macos-tahoe-base:latest' , name : 'codify-test-vm' } ] ,
35- } ] ,
36- } , reporter ) ;
23+ ctx . processStarted ( ProcessName . TEST ) ;
24+ reporter . silent = true ;
3725
38- // Short circuit and exit if every change is NOOP
39- if ( ! planResult . plan . isEmpty ( ) ) {
40- const confirm = await reporter . promptConfirmation ( 'The following resources will need to be installed (Tart VM - 25gb). Do you want to continue?' )
41- if ( ! confirm ) {
42- return process . exit ( 0 ) ;
43- }
44-
45- const { plan, pluginManager, project } = planResult ;
46- const filteredPlan = plan . filterNoopResources ( )
26+ ctx . subprocessStarted ( SubProcessName . TEST_INITIALIZE_AND_VALIDATE ) ;
27+ // Perform validation initially to ensure the project is valid
28+ const initializationResult = await PluginInitOrchestrator . run ( { ...args , noProgress : true } , new StubReporter ( ) ) ;
29+ await ValidateOrchestrator . run ( { existing : initializationResult , noProgress : true } , new StubReporter ( ) ) ;
30+ ctx . subprocessFinished ( SubProcessName . TEST_INITIALIZE_AND_VALIDATE ) ;
4731
48- ctx . processStarted ( ProcessName . APPLY ) ;
49- await pluginManager . apply ( project , filteredPlan ) ;
50- ctx . processFinished ( ProcessName . APPLY ) ;
51- }
32+ await this . ensureVmIsInstalled ( reporter , args . vmOs ) ;
5233
34+ ctx . subprocessStarted ( SubProcessName . TEST_STARTING_VM ) ;
35+ const baseVmName = args . vmOs === OS . Darwin ? 'codify-test-vm-macos' : 'codify-test-vm-linux' ;
5336 const vmName = this . generateVmName ( ) ;
54- await spawnSafe ( `tart clone codify-test-vm ${ vmName } ` , { interactive : true } ) ;
37+ await spawnSafe ( `tart clone ${ baseVmName } ${ vmName } ` , { interactive : true } ) ;
5538
5639 // Run this in the background. The user will have to manually exit the GUI to stop the test.
5740 spawnSafe ( `tart run ${ vmName } ` , { interactive : true } )
5841 . finally ( ( ) => {
42+ ctx . subprocessFinished ( SubProcessName . TEST_USER_CONTINUE_ON_VM ) ;
43+ ctx . subprocessStarted ( SubProcessName . TEST_DELETING_VM ) ;
44+
45+ spawnSafe ( `tart delete ${ vmName } ` , { interactive : true } )
46+ ctx . subprocessFinished ( SubProcessName . TEST_DELETING_VM ) ;
47+
48+ ctx . processFinished ( ProcessName . TEST ) ;
5949 console . log ( 'VM has been killed... exiting.' )
6050 process . exit ( 1 ) ;
6151 } )
6252 await sleep ( 10_000 ) ;
6353 await this . waitUntilVmIsReady ( vmName ) ;
6454
55+ ctx . subprocessFinished ( SubProcessName . TEST_STARTING_VM ) ;
56+
57+ ctx . subprocessStarted ( SubProcessName . TEST_COPYING_OVER_CONFIGS_AND_OPENING_TERMINAL ) ;
6558 // Install codify on the VM
6659 // await spawn(`tart exec ${vmName} /bin/bash -c "$(curl -fsSL https://releases.codifycli.com/install.sh)"`, { interactive: true });
6760 const { data : ip } = await spawnSafe ( `tart ip ${ vmName } ` , { interactive : true } ) ;
6861 await spawn ( `sshpass -p "admin" scp -o PubkeyAuthentication=no -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${ initializationResult . project . codifyFiles [ 0 ] } admin@${ ip } :~/codify.jsonc` , { interactive : true } ) ;
69- // await spawn(`tart exec ${vmName} codify apply`, undefined, { interactive: true });
7062
71- await spawn ( `tart exec ${ vmName } osascript -e "tell application \\"Terminal\\" to do script \\"cd ~/ && codify apply\\""` )
63+ if ( args . vmOs === OS . Darwin ) {
64+ await spawn ( `tart exec ${ vmName } osascript -e "tell application \\"Terminal\\" to do script \\"cd ~/ && codify apply\\""` , { interactive : true } ) ;
65+ } else {
66+ await spawn ( `tart exec ${ vmName } gnome-terminal -- bash -c "cd ~/ && codify apply"` , { interactive : true } ) ;
67+ }
68+
69+ ctx . subprocessFinished ( SubProcessName . TEST_COPYING_OVER_CONFIGS_AND_OPENING_TERMINAL ) ;
70+ ctx . subprocessStarted ( SubProcessName . TEST_USER_CONTINUE_ON_VM ) ;
7271
7372 await sleep ( 1_000_000_000 ) ;
7473 } ,
@@ -77,6 +76,57 @@ export const TestOrchestrator = {
7776 return `codify-test-vm-${ Date . now ( ) } ` ;
7877 } ,
7978
79+ async ensureVmIsInstalled ( reporter : Reporter , vmOs : OS ) : Promise < void > {
80+ if ( vmOs === OS . Windows ) {
81+ throw new Error ( 'VM installation not supported on Windows' ) ;
82+ }
83+
84+ const hostSystem = os . platform ( ) === 'darwin' ? OS . Darwin : OS . Linux ;
85+
86+ let planResult : PlanOrchestratorResponse ;
87+ if ( hostSystem === OS . Darwin ) {
88+ const vmImage = vmOs === OS . Darwin ? 'ghcr.io/cirruslabs/macos-tahoe-base:latest' : 'ghcr.io/cirruslabs/ubuntu-runner-arm64:latest' ;
89+ const vmName = vmOs === OS . Darwin ? 'codify-test-vm-macos' : 'codify-test-vm-linux' ;
90+
91+ ctx . subprocessStarted ( SubProcessName . TEST_CHECKING_VM_INSTALLED ) ;
92+ planResult = await PlanOrchestrator . run ( {
93+ codifyConfigs : [ {
94+ type : 'project' ,
95+ plugins : { default : '/Users/kevinwang/Projects/codify-homebrew-plugin/src/index.ts' }
96+ } , {
97+ type : 'homebrew' ,
98+ formulae : [ 'sshpass' ]
99+ } , {
100+ type : 'tart' ,
101+ clone : [ { sourceName : vmImage , name : vmName } ] ,
102+ } ] ,
103+ noProgress : true ,
104+ verbosityLevel : - 1 ,
105+ } , new StubReporter ( ) ) ;
106+
107+ reporter . silent = false ;
108+ ctx . subprocessFinished ( SubProcessName . TEST_CHECKING_VM_INSTALLED ) ;
109+ } else {
110+ throw new Error ( 'VM installation not supported on Linux just yet' ) ;
111+ }
112+
113+ // Short circuit and exit if every change is NOOP
114+ if ( ! planResult . plan . isEmpty ( ) ) {
115+ reporter . displayPlan ( planResult . plan ) ;
116+ const confirm = await reporter . promptConfirmation ( 'The following resources will need to be installed (Tart VM - 25gb). Do you want to continue?' )
117+ if ( ! confirm ) {
118+ return process . exit ( 0 ) ;
119+ }
120+
121+ const { plan, pluginManager, project } = planResult ;
122+ await pluginManager . setVerbosityLevel ( 3 ) ;
123+ const filteredPlan = plan . filterNoopResources ( )
124+
125+ await reporter . displayProgress ( ) ;
126+ await pluginManager . apply ( project , filteredPlan ) ;
127+ }
128+ } ,
129+
80130 async waitUntilVmIsReady ( vmName : string ) : Promise < void > {
81131 while ( true ) {
82132 const result = await spawnSafe ( `tart exec ${ vmName } pwd` , { interactive : true , timeout : 5000 } )
0 commit comments