diff --git a/packages/wb/src/commands/buildIfNeeded.ts b/packages/wb/src/commands/buildIfNeeded.ts index a94a5a11..5d9a4142 100644 --- a/packages/wb/src/commands/buildIfNeeded.ts +++ b/packages/wb/src/commands/buildIfNeeded.ts @@ -9,11 +9,9 @@ import chalk from 'chalk'; import type { ArgumentsCamelCase, CommandModule, InferredOptionTypes } from 'yargs'; import type { Project } from '../project.js'; -import { findAllProjects } from '../project.js'; +import { findSelfProject } from '../project.js'; import type { sharedOptionsBuilder } from '../sharedOptionsBuilder.js'; -import { prepareForRunningCommand } from './commandUtils.js'; - const builder = { command: { description: 'A build command', @@ -53,33 +51,26 @@ export async function buildIfNeeded( argv: Partial>>, projectPathForTesting?: string ): Promise { - const projects = await findAllProjects(argv, projectPathForTesting); - if (!projects) return true; - - const isGitRepo = fs.existsSync(path.join(projects.root.dirPath, '.git')); + const project = await findSelfProject(argv, projectPathForTesting); + if (!project) return true; - let built = false; - for (const project of prepareForRunningCommand('buildIfNeeded', projects.all)) { - if (!isGitRepo) { - if (!build(project, argv)) return; - built = true; - continue; - } + if (!fs.existsSync(path.join(project.rootDirPath, '.git'))) { + build(project, argv); + return true; + } - const [canSkip, cacheFilePath, contentHash] = await canSkipBuild(project, argv); - if (canSkip) { - console.info(chalk.green(`Skip to run '${argv.command}' 💫`)); - continue; - } + const [canSkip, cacheFilePath, contentHash] = await canSkipBuild(project, argv); + if (canSkip) { + console.info(chalk.green(`Skip to run '${argv.command}' 💫`)); + return false; + } - if (!build(project, argv)) return; - built = true; + if (!build(project, argv)) return; - if (!argv.dryRun) { - await fs.promises.writeFile(cacheFilePath, contentHash, 'utf8'); - } + if (!argv.dryRun) { + await fs.promises.writeFile(cacheFilePath, contentHash, 'utf8'); } - return built; + return true; } const ignoringEnvVarNames = new Set(['CI', 'PWDEBUG', 'TMPDIR']); diff --git a/packages/wb/src/commands/setup.ts b/packages/wb/src/commands/setup.ts index e4986625..34d0b745 100644 --- a/packages/wb/src/commands/setup.ts +++ b/packages/wb/src/commands/setup.ts @@ -8,6 +8,8 @@ import { findAllProjects } from '../project.js'; import { promisePool } from '../promisePool.js'; import { runWithSpawn, runWithSpawnInParallel } from '../scripts/run.js'; +import { prepareForRunningCommand } from './commandUtils.js'; + const builder = {} as const; export const setupCommand: CommandModule> = { @@ -27,7 +29,7 @@ export async function setup( const projects = await findAllProjects(argv, projectPathForTesting); if (!projects) return; - for (const project of projects.all) { + for (const project of prepareForRunningCommand('setup', projects.all)) { const dirents = await fs.readdir(project.dirPath, { withFileTypes: true }); if (project === projects.root) { if (os.platform() === 'darwin') { diff --git a/packages/wb/src/commands/start.ts b/packages/wb/src/commands/start.ts index 6cee7030..97b070dd 100644 --- a/packages/wb/src/commands/start.ts +++ b/packages/wb/src/commands/start.ts @@ -46,9 +46,12 @@ export const startCommand: CommandModule 1) { - // Disable interactive mode - project.env['CI'] = '1'; - } - project.env['FORCE_COLOR'] ||= '3'; - project.env.WB_ENV ||= 'test'; - const deps = project.packageJson.dependencies || {}; const devDeps = project.packageJson.devDependencies || {}; let scripts: BaseExecutionScripts; @@ -80,6 +71,15 @@ export async function test( scripts = plainAppScripts; } + console.info(`Running "test" for ${project.name} ...`); + + if (projects.all.length > 1) { + // Disable interactive mode + project.env['CI'] = '1'; + } + project.env['FORCE_COLOR'] ||= '3'; + project.env.WB_ENV ||= 'test'; + const promises: Promise[] = []; if (argv.ci) { const unitTestsExistPromise = existsAsync(path.join(project.dirPath, 'tests', 'unit')); diff --git a/packages/wb/src/commands/typecheck.ts b/packages/wb/src/commands/typecheck.ts index a215eee2..bf3a9a1f 100644 --- a/packages/wb/src/commands/typecheck.ts +++ b/packages/wb/src/commands/typecheck.ts @@ -22,18 +22,8 @@ export const typeCheckCommand: CommandModule< if (!projects) return; for (const project of projects.all) { - console.info(`Running typecheck for ${project.name} ...`); - - if (projects.all.length > 1) { - // Disable interactive mode - project.env['CI'] = '1'; - } - project.env['FORCE_COLOR'] ||= '3'; - const commands: string[] = []; - if (project.packageJson.workspaces) { - commands.push(`yarn workspaces foreach --all --parallel --exclude ${project.name} --verbose run typecheck`); - } else { + if (!project.packageJson.workspaces) { if (project.packageJson.dependencies?.typescript || project.packageJson.devDependencies?.typescript) { commands.push('tsc --noEmit --Pretty'); } @@ -41,6 +31,16 @@ export const typeCheckCommand: CommandModule< commands.push('pyright'); } } + if (commands.length === 0) continue; + + console.info(`Running "typecheck" for ${project.name} ...`); + + if (projects.all.length > 1) { + // Disable interactive mode + project.env['CI'] = '1'; + } + project.env['FORCE_COLOR'] ||= '3'; + const exitCode = await runWithSpawn(commands.join(' && '), project, argv); if (exitCode !== 0) { const packageJson = JSON.parse(await fs.readFile('package.json', 'utf8')) as PackageJson; diff --git a/packages/wb/src/project.ts b/packages/wb/src/project.ts index 294e3109..3330387e 100644 --- a/packages/wb/src/project.ts +++ b/packages/wb/src/project.ts @@ -109,18 +109,15 @@ export interface FoundProjects { all: Project[]; } -export function findSelfProject(argv: EnvReaderOptions): Project | undefined { - const dirPath = process.cwd(); +export function findSelfProject(argv: EnvReaderOptions, dirPath?: string): Project | undefined { + dirPath ??= process.cwd(); if (!fs.existsSync(path.join(dirPath, 'package.json'))) return; return new Project(dirPath, argv); } -export async function findAllProjects( - argv: EnvReaderOptions, - projectPathForTesting?: string -): Promise { - const rootAndSelfProjects = findRootAndSelfProjects(argv, projectPathForTesting); +export async function findAllProjects(argv: EnvReaderOptions, dirPath?: string): Promise { + const rootAndSelfProjects = findRootAndSelfProjects(argv, dirPath); if (!rootAndSelfProjects) return; return { @@ -134,15 +131,15 @@ export async function findAllProjects( export function findRootAndSelfProjects( argv: EnvReaderOptions, - projectPathForTesting?: string + dirPath?: string ): Omit | undefined { - projectPathForTesting ??= process.cwd(); - if (!fs.existsSync(path.join(projectPathForTesting, 'package.json'))) return; + dirPath ??= process.cwd(); + if (!fs.existsSync(path.join(dirPath, 'package.json'))) return; - const thisProject = new Project(projectPathForTesting, argv); + const thisProject = new Project(dirPath, argv); let rootProject = thisProject; - if (!thisProject.packageJson.workspaces && path.dirname(projectPathForTesting).endsWith('/packages')) { - const rootDirPath = path.resolve(projectPathForTesting, '..', '..'); + if (!thisProject.packageJson.workspaces && path.dirname(dirPath).endsWith('/packages')) { + const rootDirPath = path.resolve(dirPath, '..', '..'); if (fs.existsSync(path.join(rootDirPath, 'package.json'))) { rootProject = new Project(rootDirPath, argv); } diff --git a/packages/wb/src/scripts/dockerScripts.ts b/packages/wb/src/scripts/dockerScripts.ts index 97689bdb..4f18b60e 100644 --- a/packages/wb/src/scripts/dockerScripts.ts +++ b/packages/wb/src/scripts/dockerScripts.ts @@ -17,7 +17,7 @@ class DockerScripts { && ${prefix}YARN wb optimizeForDockerBuild --outside && YARN wb retry -- docker build -t ${project.nameWithoutNamespace} --build-arg ARCH=$([ $(uname -m) = 'arm64' ] && echo arm64 || echo amd64) - --build-arg WB_ENV=${process.env.WB_ENV} + --build-arg WB_ENV=${project.env.WB_ENV} --build-arg WB_VERSION=dev .`; } stopAndStart(project: Project, unbuffer = false, additionalOptions = '', additionalArgs = ''): string { diff --git a/packages/wb/src/scripts/execution/baseExecutionScripts.ts b/packages/wb/src/scripts/execution/baseExecutionScripts.ts index cc382812..584d7b36 100644 --- a/packages/wb/src/scripts/execution/baseExecutionScripts.ts +++ b/packages/wb/src/scripts/execution/baseExecutionScripts.ts @@ -47,7 +47,7 @@ export abstract class BaseExecutionScripts { // Basically, `playwright` (not `yarn playwright`) should work, // but it doesn't work on a project depending on `artillery-engine-playwright`. // So we use `yarn playwright` instead of `playwright` here. - const env = process.env.WB_ENV; + const env = project.env.WB_ENV; return `WB_ENV=${env} NEXT_PUBLIC_WB_ENV=${env} APP_ENV=${env} PORT=8080 YARN concurrently --kill-others --raw --success first "rm -Rf ${prismaDirectory}/mount && ${startCommand} && exit 1" "concurrently --kill-others-on-fail --raw 'wait-on -t 600000 -i 2000 http://127.0.0.1:8080' 'yarn playwright install --with-deps' @@ -55,7 +55,7 @@ export abstract class BaseExecutionScripts { } testE2EDev(project: Project, argv: ScriptArgv, { playwrightArgs, startCommand }: TestE2EDevOptions): string { - const env = process.env.WB_ENV; + const env = project.env.WB_ENV; return `WB_ENV=${env} NEXT_PUBLIC_WB_ENV=${env} APP_ENV=${env} PORT=8080 YARN concurrently --kill-others --raw --success first "${startCommand} && exit 1" "concurrently --kill-others-on-fail --raw 'wait-on -t 600000 -i 2000 http://127.0.0.1:8080' 'yarn playwright install --with-deps' @@ -64,9 +64,9 @@ export abstract class BaseExecutionScripts { abstract testStart(project: Project, argv: ScriptArgv): string; - testUnit(_: Project, _2: ScriptArgv): string { + testUnit(project: Project, _2: ScriptArgv): string { // Since this command is referred to from other commands, we have to use "vitest run". - return `WB_ENV=${process.env.WB_ENV} YARN vitest run tests/unit --color --passWithNoTests`; + return `WB_ENV=${project.env.WB_ENV} YARN vitest run tests/unit --color --passWithNoTests`; } protected waitApp(project: Project, argv: ScriptArgv, port = this.defaultPort): string { diff --git a/packages/wb/src/scripts/execution/blitzScripts.ts b/packages/wb/src/scripts/execution/blitzScripts.ts index f4bd8c16..0e00673a 100644 --- a/packages/wb/src/scripts/execution/blitzScripts.ts +++ b/packages/wb/src/scripts/execution/blitzScripts.ts @@ -15,14 +15,14 @@ class BlitzScripts extends BaseExecutionScripts { } override start(project: Project, argv: ScriptArgv): string { - const appEnv = process.env.WB_ENV ? `APP_ENV=${process.env.WB_ENV} ` : ''; + const appEnv = project.env.WB_ENV ? `APP_ENV=${project.env.WB_ENV} ` : ''; return `${appEnv}YARN concurrently --raw --kill-others-on-fail "blitz dev ${argv.normalizedArgsText ?? ''}" "${this.waitAndOpenApp(project, argv)}"`; } override startProduction(project: Project, argv: ScriptArgv, port: number): string { - const appEnv = process.env.WB_ENV ? `APP_ENV=${process.env.WB_ENV} ` : ''; + const appEnv = project.env.WB_ENV ? `APP_ENV=${project.env.WB_ENV} ` : ''; return `${appEnv}NODE_ENV=production YARN concurrently --raw --kill-others-on-fail "${prismaScripts.reset(project)} && ${project.getBuildCommand( argv diff --git a/packages/wb/src/scripts/execution/httpServerScripts.ts b/packages/wb/src/scripts/execution/httpServerScripts.ts index 21a2e9d9..6aed0584 100644 --- a/packages/wb/src/scripts/execution/httpServerScripts.ts +++ b/packages/wb/src/scripts/execution/httpServerScripts.ts @@ -43,14 +43,14 @@ class HttpServerScripts extends BaseExecutionScripts { )})`, }: TestE2EOptions ): string { - return `NODE_ENV=production WB_ENV=${process.env.WB_ENV} PORT=8080 YARN concurrently --kill-others --raw --success first + return `NODE_ENV=production WB_ENV=${project.env.WB_ENV} PORT=8080 YARN concurrently --kill-others --raw --success first "${startCommand} && exit 1" "wait-on -t 600000 -i 2000 http://127.0.0.1:8080 && vitest run tests/e2e --color --passWithNoTests"`; } override testE2EDev(project: Project, argv: ScriptArgv, { startCommand }: TestE2EDevOptions): string { return `NODE_ENV=production WB_ENV=${ - process.env.WB_ENV + project.env.WB_ENV } PORT=8080 YARN concurrently --kill-others --raw --success first "${startCommand || this.start(project, argv)} && exit 1" "wait-on -t 600000 -i 2000 http://127.0.0.1:8080 && vitest run tests/e2e --color --passWithNoTests"`;