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

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions apps/cli/commands/config/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { getWordPressVersion } from '@studio/common/lib/get-wordpress-version';
import { decodePassword } from '@studio/common/lib/passwords';
import { getSiteFileAccess } from '@studio/common/lib/site-file-access';
import { getSiteRuntime, siteModeFromRuntime } from '@studio/common/lib/site-runtime';
import { getWpEnvironmentType } from '@studio/common/lib/wp-environment-type';
import { SiteCommandLoggerAction as LoggerAction } from '@studio/common/logger-actions';
import { __, sprintf } from '@wordpress/i18n';
import CliTable3 from 'cli-table3';
Expand Down Expand Up @@ -43,6 +44,8 @@ function getConfigEntries( site: SiteData ): ConfigEntry[] {
{ key: 'admin-email', value: site.adminEmail },
{ key: 'debug-log', value: site.enableDebugLog ?? false },
{ key: 'debug-display', value: site.enableDebugDisplay ?? false },
{ key: 'script-debug', value: site.enableScriptDebug ?? false },
{ key: 'environment-type', value: getWpEnvironmentType( site ) },
];
}

Expand Down
42 changes: 39 additions & 3 deletions apps/cli/commands/config/set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ import {
isValidWordPressVersion,
isWordPressVersionAtLeast,
} from '@studio/common/lib/wordpress-version-utils';
import {
getWpEnvironmentType,
wpEnvironmentTypeSchema,
WP_ENVIRONMENT_TYPES,
type WpEnvironmentType,
} from '@studio/common/lib/wp-environment-type';
import { SiteCommandLoggerAction as LoggerAction } from '@studio/common/logger-actions';
import { SupportedPHPVersions } from '@studio/common/types/php-versions';
import { __, sprintf } from '@wordpress/i18n';
Expand Down Expand Up @@ -70,6 +76,8 @@ export interface SetCommandOptions {
adminEmail?: string;
debugLog?: boolean;
debugDisplay?: boolean;
scriptDebug?: boolean;
environmentType?: WpEnvironmentType;
}

export async function runCommand( sitePath: string, options: SetCommandOptions ): Promise< void > {
Expand All @@ -86,6 +94,8 @@ export async function runCommand( sitePath: string, options: SetCommandOptions )
adminPassword,
debugLog,
debugDisplay,
scriptDebug,
environmentType,
} = options;
let { adminEmail } = options;

Expand All @@ -102,11 +112,13 @@ export async function runCommand( sitePath: string, options: SetCommandOptions )
adminPassword === undefined &&
adminEmail === undefined &&
debugLog === undefined &&
debugDisplay === undefined
debugDisplay === undefined &&
scriptDebug === undefined &&
environmentType === undefined
) {
throw new LoggerError(
__(
'At least one option (--name, --domain, --https, --php, --wp, --runtime, --file-access, --xdebug, --admin-username, --admin-password, --admin-email, --debug-log, --debug-display) is required.'
'At least one option (--name, --domain, --https, --php, --wp, --runtime, --file-access, --xdebug, --admin-username, --admin-password, --admin-email, --debug-log, --debug-display, --script-debug, --environment-type) is required.'
)
);
}
Expand Down Expand Up @@ -204,6 +216,9 @@ export async function runCommand( sitePath: string, options: SetCommandOptions )
const debugLogChanged = debugLog !== undefined && debugLog !== site.enableDebugLog;
const debugDisplayChanged =
debugDisplay !== undefined && debugDisplay !== site.enableDebugDisplay;
const scriptDebugChanged = scriptDebug !== undefined && scriptDebug !== site.enableScriptDebug;
const environmentTypeChanged =
environmentType !== undefined && environmentType !== getWpEnvironmentType( site );

const hasChanges =
nameChanged ||
Expand All @@ -216,7 +231,9 @@ export async function runCommand( sitePath: string, options: SetCommandOptions )
xdebugChanged ||
credentialsChanged ||
debugLogChanged ||
debugDisplayChanged;
debugDisplayChanged ||
scriptDebugChanged ||
environmentTypeChanged;
if ( ! hasChanges ) {
throw new LoggerError(
__( 'No changes to apply. The site already has the specified settings.' )
Expand All @@ -234,6 +251,8 @@ export async function runCommand( sitePath: string, options: SetCommandOptions )
credentialsChanged,
debugLogChanged,
debugDisplayChanged,
scriptDebugChanged,
environmentTypeChanged,
} );
const oldDomain = site.customDomain;

Expand Down Expand Up @@ -281,6 +300,12 @@ export async function runCommand( sitePath: string, options: SetCommandOptions )
if ( debugDisplayChanged ) {
foundSite.enableDebugDisplay = debugDisplay;
}
if ( scriptDebugChanged ) {
foundSite.enableScriptDebug = scriptDebug;
}
if ( environmentTypeChanged ) {
foundSite.environmentType = environmentType;
}

await saveCliConfig( cliConfig );
site = foundSite;
Expand Down Expand Up @@ -446,6 +471,15 @@ export const registerCommand = ( yargs: StudioArgv ) => {
.option( 'debug-display', {
type: 'boolean',
description: __( 'Enable WP_DEBUG_DISPLAY' ),
} )
.option( 'script-debug', {
type: 'boolean',
description: __( 'Enable SCRIPT_DEBUG' ),
} )
.option( 'environment-type', {
type: 'string',
description: __( 'Set WP_ENVIRONMENT_TYPE' ),
choices: WP_ENVIRONMENT_TYPES,
} );
},
handler: async ( argv ) => {
Expand All @@ -464,6 +498,8 @@ export const registerCommand = ( yargs: StudioArgv ) => {
adminEmail: argv.adminEmail,
debugLog: argv.debugLog,
debugDisplay: argv.debugDisplay,
scriptDebug: argv.scriptDebug,
environmentType: wpEnvironmentTypeSchema.optional().parse( argv.environmentType ),
} );
} catch ( error ) {
if ( error instanceof LoggerError ) {
Expand Down
6 changes: 6 additions & 0 deletions apps/cli/commands/config/tests/get.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ describe( 'CLI: studio config get', () => {
adminEmail: 'admin@example.com',
enableDebugLog: true,
enableDebugDisplay: false,
enableScriptDebug: true,
environmentType: 'development' as const,
};

beforeEach( () => {
Expand Down Expand Up @@ -148,6 +150,8 @@ describe( 'CLI: studio config get', () => {
'admin-email': 'admin@example.com',
'debug-log': true,
'debug-display': false,
'script-debug': true,
'environment-type': 'development',
},
null,
2
Expand Down Expand Up @@ -183,6 +187,8 @@ describe( 'CLI: studio config get', () => {
'admin-email': null,
'debug-log': false,
'debug-display': false,
'script-debug': false,
'environment-type': 'local',
},
null,
2
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/commands/config/tests/set.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ describe( 'CLI: studio config set', () => {
describe( 'Validation', () => {
it( 'should throw when no options provided', async () => {
await expect( runCommand( testSitePath, {} ) ).rejects.toThrow(
'At least one option (--name, --domain, --https, --php, --wp, --runtime, --file-access, --xdebug, --admin-username, --admin-password, --admin-email, --debug-log, --debug-display) is required.'
'At least one option (--name, --domain, --https, --php, --wp, --runtime, --file-access, --xdebug, --admin-username, --admin-password, --admin-email, --debug-log, --debug-display, --script-debug, --environment-type) is required.'
);
} );

Expand Down
5 changes: 5 additions & 0 deletions apps/cli/lib/native-php/blueprints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
createBlueprintTempDir,
removeBlueprintTempDir,
} from '@studio/common/lib/blueprint-bundle';
import { getWpEnvironmentType } from '@studio/common/lib/wp-environment-type';
import { getBlueprintsPharPath, getPhpBinaryPath } from 'cli/lib/dependency-management/paths';
import { runPhpCommand } from './php-process';
import type { NativePhpSupportedVersion } from '@studio/common/lib/php-binary-metadata';
Expand Down Expand Up @@ -35,6 +36,10 @@ export async function runBlueprint(
WP_DEBUG: enableDebugLog || enableDebugDisplay,
WP_DEBUG_LOG: enableDebugLog,
WP_DEBUG_DISPLAY: enableDebugDisplay,
// SCRIPT_DEBUG is independent of WP_DEBUG in WordPress, so it must not
// feed the WP_DEBUG expression above.
SCRIPT_DEBUG: config.enableScriptDebug ?? false,
WP_ENVIRONMENT_TYPE: getWpEnvironmentType( config ),
};

blueprint.contents.constants = {
Expand Down
10 changes: 9 additions & 1 deletion apps/cli/lib/native-php/site-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import path from 'node:path';
import { DEFAULT_LOCALE } from '@studio/common/lib/locale';
import { escapePhpSingleQuotedString } from '@studio/common/lib/mu-plugins';
import { decodePassword } from '@studio/common/lib/passwords';
import { getWpEnvironmentType } from '@studio/common/lib/wp-environment-type';
import { getWpCliPharPath } from 'cli/lib/dependency-management/paths';
import { runPhpCommand } from './php-process';
import { getFullyResolvedTmpDirPath } from './tmp-dir';
Expand All @@ -18,7 +19,10 @@ export async function ensureWpConfig(
phpVersion: NativePhpSupportedVersion,
signal: AbortSignal,
wpConfigTransformerPath: string,
config?: Pick< ServerConfig, 'enableDebugLog' | 'enableDebugDisplay' >
config?: Pick<
ServerConfig,
'enableDebugLog' | 'enableDebugDisplay' | 'enableScriptDebug' | 'environmentType'
>
): Promise< void > {
const wpConfigPath = path.join( siteFolder, 'wp-config.php' );
const wpConfigSamplePath = path.join( siteFolder, 'wp-config-sample.php' );
Expand All @@ -45,6 +49,10 @@ $transformer->to_file( $wp_config_path );
WP_DEBUG: enableDebugLog || enableDebugDisplay,
WP_DEBUG_LOG: enableDebugLog,
WP_DEBUG_DISPLAY: enableDebugDisplay,
// SCRIPT_DEBUG is independent of WP_DEBUG in WordPress, so it must not
// feed the WP_DEBUG expression above.
SCRIPT_DEBUG: config?.enableScriptDebug ?? false,
WP_ENVIRONMENT_TYPE: getWpEnvironmentType( config ?? {} ),
};

try {
Expand Down
67 changes: 67 additions & 0 deletions apps/cli/lib/native-php/tests/site-setup.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { ensureWpConfig } from 'cli/lib/native-php/site-setup';

const runPhpCommand = vi.hoisted( () => vi.fn() );

vi.mock( 'cli/lib/native-php/php-process', () => ( { runPhpCommand } ) );
vi.mock( 'cli/lib/dependency-management/paths', () => ( {
getWpCliPharPath: () => '/wp-cli.phar',
} ) );

// The constants are passed to PHP as the third positional arg, JSON-encoded.
async function getWrittenConstants(
config?: Parameters< typeof ensureWpConfig >[ 4 ]
): Promise< Record< string, unknown > > {
runPhpCommand.mockClear();
await ensureWpConfig(
'/nonexistent-site',
'8.4',
new AbortController().signal,
'/wp-config-transformer.php',
config
);
const args = runPhpCommand.mock.calls[ 0 ][ 0 ] as string[];
return JSON.parse( args[ args.length - 1 ] );
}

describe( 'ensureWpConfig', () => {
beforeEach( () => {
runPhpCommand.mockResolvedValue( undefined );
} );

it( 'defaults both new constants when no config is supplied', async () => {
const constants = await getWrittenConstants();

expect( constants.SCRIPT_DEBUG ).toBe( false );
expect( constants.WP_ENVIRONMENT_TYPE ).toBe( 'local' );
} );

it( 'writes SCRIPT_DEBUG when script debug is enabled', async () => {
const constants = await getWrittenConstants( { enableScriptDebug: true } );

expect( constants.SCRIPT_DEBUG ).toBe( true );
} );

// SCRIPT_DEBUG is independent of WP_DEBUG in WordPress. Enabling it must not
// turn on WP_DEBUG as a side effect.
it( 'does not enable WP_DEBUG when only SCRIPT_DEBUG is enabled', async () => {
const constants = await getWrittenConstants( { enableScriptDebug: true } );

expect( constants.WP_DEBUG ).toBe( false );
expect( constants.WP_DEBUG_LOG ).toBe( false );
expect( constants.WP_DEBUG_DISPLAY ).toBe( false );
} );

it( 'writes the configured environment type', async () => {
const constants = await getWrittenConstants( { environmentType: 'staging' } );

expect( constants.WP_ENVIRONMENT_TYPE ).toBe( 'staging' );
} );

it( 'still derives WP_DEBUG from the debug log and display flags', async () => {
const constants = await getWrittenConstants( { enableDebugLog: true } );

expect( constants.WP_DEBUG ).toBe( true );
expect( constants.WP_DEBUG_LOG ).toBe( true );
} );
} );
3 changes: 3 additions & 0 deletions apps/cli/lib/types/wordpress-server-ipc.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { siteFileAccessSchema } from '@studio/common/lib/site-file-access';
import { wpEnvironmentTypeSchema } from '@studio/common/lib/wp-environment-type';
import { z } from 'zod';
import type { WordPressInstallMode } from '@wp-playground/wordpress';

Expand Down Expand Up @@ -32,6 +33,8 @@ export const serverConfigSchema = z.object( {
enableXdebug: z.boolean().optional(),
enableDebugLog: z.boolean().optional(),
enableDebugDisplay: z.boolean().optional(),
enableScriptDebug: z.boolean().optional(),
environmentType: wpEnvironmentTypeSchema.optional(),
blueprint: z
.object( {
contents: z.any(), // Blueprint type is complex, allow any for now
Expand Down
7 changes: 7 additions & 0 deletions apps/cli/lib/wordpress-server-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
SITE_RUNTIME_PLAYGROUND,
type SiteRuntime,
} from '@studio/common/lib/site-runtime';
import { getWpEnvironmentType } from '@studio/common/lib/wp-environment-type';
import { SiteCommandLoggerAction } from '@studio/common/logger-actions';
import { __ } from '@wordpress/i18n';
import { z } from 'zod';
Expand Down Expand Up @@ -198,6 +199,12 @@ function buildServerConfig(
serverConfig.enableDebugDisplay = true;
}

if ( site.enableScriptDebug ) {
serverConfig.enableScriptDebug = true;
}

serverConfig.environmentType = getWpEnvironmentType( site );

return serverConfig;
}

Expand Down
5 changes: 5 additions & 0 deletions apps/cli/playground-server-child.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
import { formatPlaygroundCliMessage } from '@studio/common/lib/playground-cli-messages';
import { sequential } from '@studio/common/lib/sequential';
import { isWordPressDevVersion } from '@studio/common/lib/wordpress-version-utils';
import { getWpEnvironmentType } from '@studio/common/lib/wp-environment-type';
import { BlueprintBundle } from '@wp-playground/blueprints';
import { runCLI, RunCLIArgs, RunCLIServer } from '@wp-playground/cli';
import {
Expand Down Expand Up @@ -291,6 +292,10 @@ async function getBaseRunCLIArgs(
WP_DEBUG: enableDebugLog || enableDebugDisplay,
WP_DEBUG_LOG: enableDebugLog,
WP_DEBUG_DISPLAY: enableDebugDisplay,
// SCRIPT_DEBUG is independent of WP_DEBUG in WordPress, so it must not
// feed the WP_DEBUG expression above.
SCRIPT_DEBUG: config.enableScriptDebug ?? false,
WP_ENVIRONMENT_TYPE: getWpEnvironmentType( config ),
};

let blueprintBundle: BlueprintBundle | undefined;
Expand Down
9 changes: 9 additions & 0 deletions apps/local/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import { fetchStudioAssistantQuota } from '@studio/common/lib/studio-assistant-q
import { fetchSyncableSites } from '@studio/common/lib/sync/sync-api';
import { detectInstalledApps } from '@studio/common/lib/user-settings/installed-apps';
import { isWordPressDevVersion } from '@studio/common/lib/wordpress-version-utils';
import { getWpEnvironmentType } from '@studio/common/lib/wp-environment-type';
import {
cleanupBlueprintTempDir,
extractBlueprintUpload,
Expand Down Expand Up @@ -158,6 +159,8 @@ function toSiteDetails( site: SiteListItem ) {
enableXdebug: site.enableXdebug,
enableDebugLog: site.enableDebugLog,
enableDebugDisplay: site.enableDebugDisplay,
enableScriptDebug: site.enableScriptDebug,
environmentType: site.environmentType,
siteIcon: null,
};
}
Expand Down Expand Up @@ -699,6 +702,12 @@ export async function startLocalServer( options: LocalServerOptions ): Promise<
if ( ( updated.enableDebugDisplay ?? false ) !== ( current.enableDebugDisplay ?? false ) ) {
options.debugDisplay = updated.enableDebugDisplay ?? false;
}
if ( ( updated.enableScriptDebug ?? false ) !== ( current.enableScriptDebug ?? false ) ) {
options.scriptDebug = updated.enableScriptDebug ?? false;
}
if ( getWpEnvironmentType( updated ) !== getWpEnvironmentType( current ) ) {
options.environmentType = getWpEnvironmentType( updated );
}

// More than path + siteId means a real change to apply.
if ( Object.keys( options ).length > 2 ) {
Expand Down
Loading