Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions cli/__mocks__/ora.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
module.exports = {
start: jest.fn().mockReturnThis(),
stop: jest.fn().mockReturnThis(),
succeed: jest.fn().mockReturnThis(),
fail: jest.fn().mockReturnThis(),
};
function mockOra() {
return {
start: jest.fn().mockReturnThis(),
stop: jest.fn().mockReturnThis(),
succeed: jest.fn().mockReturnThis(),
fail: jest.fn().mockReturnThis(),
};
}

module.exports = mockOra;
module.exports.default = mockOra;
103 changes: 54 additions & 49 deletions cli/commands/site/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { Blueprint } from '@wp-playground/blueprints';
import { RecommendedPHPVersion } from '@wp-playground/common';
import {
filterUnsupportedBlueprintFeatures,
scanBlueprintForUnsupportedFeatures,
validateBlueprintData,
} from 'common/lib/blueprint-validation';
import { getDomainNameValidationError } from 'common/lib/domains';
Expand Down Expand Up @@ -35,6 +34,8 @@ const DEFAULT_VERSIONS = {
const MINIMUM_WORDPRESS_VERSION = '6.2.1' as const; // https://wordpress.github.io/wordpress-playground/blueprints/examples/#load-an-older-wordpress-version
const ALLOWED_PHP_VERSIONS = [ ...SupportedPHPVersions ];

const logger = new Logger< LoggerAction >();

export async function runCommand(
sitePath: string,
options: {
Expand All @@ -43,12 +44,10 @@ export async function runCommand(
phpVersion: ( typeof ALLOWED_PHP_VERSIONS )[ number ];
customDomain?: string;
enableHttps: boolean;
blueprint?: string;
blueprintJson?: unknown;
noStart: boolean;
}
): Promise< void > {
const logger = new Logger< LoggerAction >();

try {
logger.reportStart( LoggerAction.VALIDATE, __( 'Validating site configuration...' ) );

Expand Down Expand Up @@ -76,40 +75,24 @@ export async function runCommand(
}

let blueprint: Blueprint | undefined;
if ( options.blueprint ) {
if ( ! fs.existsSync( options.blueprint ) ) {
throw new LoggerError( sprintf( __( 'Blueprint file not found: %s' ), options.blueprint ) );
}
let blueprintJson: Blueprint;
try {
const blueprintContent = fs.readFileSync( options.blueprint, 'utf-8' );
blueprintJson = JSON.parse( blueprintContent );
} catch ( error ) {
throw new LoggerError(
sprintf( __( 'Invalid blueprint JSON file: %s' ), options.blueprint ),
error
);
}
const validation = await validateBlueprintData( blueprintJson );
if ( options.blueprintJson ) {
const validation = await validateBlueprintData( options.blueprintJson );
if ( ! validation.valid ) {
throw new LoggerError( validation.error );
}

const unsupportedFeatures = scanBlueprintForUnsupportedFeatures( blueprintJson );
if ( unsupportedFeatures.length > 0 ) {
for ( const feature of unsupportedFeatures ) {
logger.reportWarning(
sprintf(
/* translators: %1$s: feature name, %2$s: reason */
__( `Blueprint feature "%1$s" is not supported: %2$s` ),
feature.name,
feature.reason
)
);
}
for ( const warning of validation.warnings ) {
logger.reportWarning(
sprintf(
/* translators: %1$s: feature name, %2$s: reason */
__( `Blueprint feature "%1$s" is not supported: %2$s` ),
warning.feature,
warning.reason
)
);
}

blueprint = filterUnsupportedBlueprintFeatures( blueprintJson ) as Blueprint;
blueprint = filterUnsupportedBlueprintFeatures( options.blueprintJson ) as Blueprint;
}

const appdata = await readAppdata();
Expand Down Expand Up @@ -213,7 +196,7 @@ export async function runCommand(

await setupCustomDomain( siteDetails, logger );

const startMessage = options.blueprint
const startMessage = blueprint
? __( 'Starting WordPress site and applying blueprint...' )
: __( 'Starting WordPress site...' );
logger.reportStart( LoggerAction.START_SITE, startMessage );
Expand Down Expand Up @@ -251,13 +234,6 @@ export async function runCommand(
logSiteDetails( siteDetails );
console.log( __( 'Run "studio site start" to start the site.' ) );
}
} catch ( error ) {
if ( error instanceof LoggerError ) {
logger.reportError( error );
} else {
const loggerError = new LoggerError( __( 'Failed to create site' ), error );
logger.reportError( loggerError );
}
} finally {
disconnect();
}
Expand Down Expand Up @@ -304,15 +280,44 @@ export const registerCommand = ( yargs: StudioArgv ) => {
} );
},
handler: async ( argv ) => {
await runCommand( argv.path, {
name: argv.name,
wpVersion: argv.wp,
phpVersion: argv.php,
customDomain: argv.domain,
enableHttps: argv.https,
blueprint: argv.blueprint,
noStart: ! argv.start,
} );
try {
let blueprintJson: unknown;

if ( argv.blueprint ) {
if ( ! fs.existsSync( argv.blueprint ) ) {
throw new LoggerError(
sprintf( __( 'Blueprint file not found: %s' ), argv.blueprint )
);
}

try {
const blueprintContent = fs.readFileSync( argv.blueprint, 'utf-8' );
blueprintJson = JSON.parse( blueprintContent );
} catch ( error ) {
throw new LoggerError(
sprintf( __( 'Invalid blueprint JSON file: %s' ), argv.blueprint ),
error
);
}
}

await runCommand( argv.path, {
name: argv.name,
wpVersion: argv.wp,
phpVersion: argv.php,
customDomain: argv.domain,
enableHttps: argv.https,
blueprintJson: blueprintJson,
noStart: ! argv.start,
} );
} catch ( error ) {
if ( error instanceof LoggerError ) {
logger.reportError( error );
} else {
const loggerError = new LoggerError( __( 'Failed to load site' ), error );
logger.reportError( loggerError );
}
}
},
} );
};
22 changes: 12 additions & 10 deletions cli/commands/site/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ async function getSiteListData( sites: SiteData[] ) {
return result;
}

export async function runCommand( format: 'table' | 'json' ): Promise< void > {
const logger = new Logger< LoggerAction >();
const logger = new Logger< LoggerAction >();

export async function runCommand( format: 'table' | 'json' ): Promise< void > {
try {
logger.reportStart( LoggerAction.LOAD_SITES, __( 'Loading sites…' ) );
const appdata = await readAppdata();
Expand Down Expand Up @@ -86,13 +86,6 @@ export async function runCommand( format: 'table' | 'json' ): Promise< void > {
} else {
console.log( JSON.stringify( sitesData, null, 2 ) );
}
} catch ( error ) {
if ( error instanceof LoggerError ) {
logger.reportError( error );
} else {
const loggerError = new LoggerError( __( 'Failed to load sites' ), error );
logger.reportError( loggerError );
}
} finally {
disconnect();
}
Expand All @@ -111,7 +104,16 @@ export const registerCommand = ( yargs: StudioArgv ) => {
} );
},
handler: async ( argv ) => {
await runCommand( argv.format as 'table' | 'json' );
try {
await runCommand( argv.format as 'table' | 'json' );
} catch ( error ) {
if ( error instanceof LoggerError ) {
logger.reportError( error );
} else {
const loggerError = new LoggerError( __( 'Failed to load site' ), error );
logger.reportError( loggerError );
}
}
},
} );
};
22 changes: 12 additions & 10 deletions cli/commands/site/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import { isServerRunning, startWordPressServer } from 'cli/lib/wordpress-server-
import { Logger, LoggerError } from 'cli/logger';
import { StudioArgv } from 'cli/types';

export async function runCommand( sitePath: string, skipBrowser = false ): Promise< void > {
const logger = new Logger< LoggerAction >();
const logger = new Logger< LoggerAction >();

export async function runCommand( sitePath: string, skipBrowser = false ): Promise< void > {
try {
logger.reportStart( LoggerAction.LOAD_SITES, __( 'Loading site…' ) );
const site = await getSiteByFolder( sitePath );
Expand Down Expand Up @@ -58,13 +58,6 @@ export async function runCommand( sitePath: string, skipBrowser = false ): Promi
} catch ( error ) {
throw new LoggerError( __( 'Failed to start WordPress server' ), error );
}
} catch ( error ) {
if ( error instanceof LoggerError ) {
logger.reportError( error );
} else {
const loggerError = new LoggerError( __( 'Failed to start site infrastructure' ), error );
logger.reportError( loggerError );
}
} finally {
disconnect();
}
Expand All @@ -82,7 +75,16 @@ export const registerCommand = ( yargs: StudioArgv ) => {
} );
},
handler: async ( argv ) => {
await runCommand( argv.path, argv.skipBrowser );
try {
await runCommand( argv.path, argv.skipBrowser );
} catch ( error ) {
if ( error instanceof LoggerError ) {
logger.reportError( error );
} else {
const loggerError = new LoggerError( __( 'Failed to load site' ), error );
logger.reportError( loggerError );
}
}
},
} );
};
26 changes: 14 additions & 12 deletions cli/commands/site/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { isServerRunning } from 'cli/lib/wordpress-server-manager';
import { Logger, LoggerError } from 'cli/logger';
import { StudioArgv } from 'cli/types';

export async function runCommand( siteFolder: string, format: 'table' | 'json' ): Promise< void > {
const logger = new Logger< LoggerAction >();
const logger = new Logger< LoggerAction >();

export async function runCommand( siteFolder: string, format: 'table' | 'json' ): Promise< void > {
try {
logger.reportStart( LoggerAction.LOAD_SITES, __( 'Loading site…' ) );
const site = await getSiteByFolder( siteFolder );
Expand Down Expand Up @@ -69,13 +69,6 @@ export async function runCommand( siteFolder: string, format: 'table' | 'json' )

console.log( JSON.stringify( logData, null, 2 ) );
}
} catch ( error ) {
if ( error instanceof LoggerError ) {
logger.reportError( error );
} else {
const loggerError = new LoggerError( __( 'Failed to load site' ), error );
logger.reportError( loggerError );
}
} finally {
disconnect();
}
Expand All @@ -88,13 +81,22 @@ export const registerCommand = ( yargs: StudioArgv ) => {
builder: ( yargs ) => {
return yargs.option( 'format', {
type: 'string',
choices: [ 'table', 'json' ],
default: 'table',
choices: [ 'table', 'json' ] as const,
default: 'table' as const,
description: __( 'Output format' ),
} );
},
handler: async ( argv ) => {
await runCommand( argv.path, argv.format as 'table' | 'json' );
try {
await runCommand( argv.path, argv.format );
} catch ( error ) {
if ( error instanceof LoggerError ) {
logger.reportError( error );
} else {
const loggerError = new LoggerError( __( 'Failed to load site' ), error );
logger.reportError( loggerError );
}
}
},
} );
};
22 changes: 12 additions & 10 deletions cli/commands/site/stop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import { isServerRunning, stopWordPressServer } from 'cli/lib/wordpress-server-m
import { Logger, LoggerError } from 'cli/logger';
import { StudioArgv } from 'cli/types';

export async function runCommand( siteFolder: string ): Promise< void > {
const logger = new Logger< LoggerAction >();
const logger = new Logger< LoggerAction >();

export async function runCommand( siteFolder: string ): Promise< void > {
try {
const site = await getSiteByFolder( siteFolder );

Expand All @@ -30,13 +30,6 @@ export async function runCommand( siteFolder: string ): Promise< void > {
} catch ( error ) {
throw new LoggerError( __( 'Failed to stop WordPress server' ), error );
}
} catch ( error ) {
if ( error instanceof LoggerError ) {
logger.reportError( error );
} else {
const loggerError = new LoggerError( __( 'Failed to stop site infrastructure' ), error );
logger.reportError( loggerError );
}
} finally {
disconnect();
}
Expand All @@ -50,7 +43,16 @@ export const registerCommand = ( yargs: StudioArgv ) => {
return yargs;
},
handler: async ( argv ) => {
await runCommand( argv.path );
try {
await runCommand( argv.path );
} catch ( error ) {
if ( error instanceof LoggerError ) {
logger.reportError( error );
} else {
const loggerError = new LoggerError( __( 'Failed to load site' ), error );
logger.reportError( loggerError );
}
}
},
} );
};
Loading