From 0d6f0445101dfaf7ca87f4e7c6f16ec9176b3e17 Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Tue, 24 Oct 2023 22:32:39 +0900 Subject: [PATCH 01/21] . --- package.json | 4 +- packages/shared-lib-blitz-next/package.json | 6 +- packages/shared-lib-node/package.json | 8 +- packages/shared-lib-react/package.json | 6 +- packages/shared-lib/package.json | 6 +- packages/wb/package.json | 9 +- packages/wb/src/commands/buildIfNeeded.ts | 2 - .../wb/src/commands/optimizeForDockerBuild.ts | 2 - packages/wb/src/project.ts | 71 +++---- packages/wb/src/scripts/dockerScripts.ts | 14 +- .../scripts/execution/baseExecutionScripts.ts | 44 +++-- .../wb/src/scripts/execution/blitzScripts.ts | 16 +- .../scripts/execution/httpServerScripts.ts | 24 ++- .../wb/src/scripts/execution/nextScripts.ts | 20 +- .../src/scripts/execution/plainAppScripts.ts | 17 +- .../wb/src/scripts/execution/remixScripts.ts | 20 +- packages/wb/src/scripts/prismaScripts.ts | 24 +-- packages/wb/src/utils.ts | 4 +- yarn.lock | 185 ++++++++++-------- 19 files changed, 257 insertions(+), 225 deletions(-) diff --git a/package.json b/package.json index f2ee3f2c..159f109d 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,9 @@ }, "prettier": "@willbooster/prettier-config", "devDependencies": { - "@qiwi/multi-semantic-release": "7.1.0", + "@qiwi/multi-semantic-release": "7.1.1", "@types/eslint": "8.44.6", - "@typescript-eslint/parser": "6.8.0", + "@typescript-eslint/parser": "6.9.0", "@willbooster/prettier-config": "9.1.1", "conventional-changelog-conventionalcommits": "6.1.0", "eslint": "8.52.0", diff --git a/packages/shared-lib-blitz-next/package.json b/packages/shared-lib-blitz-next/package.json index 56d7960e..e06ca9f7 100644 --- a/packages/shared-lib-blitz-next/package.json +++ b/packages/shared-lib-blitz-next/package.json @@ -38,12 +38,12 @@ "devDependencies": { "@types/eslint": "8.44.6", "@types/micromatch": "4.0.4", - "@typescript-eslint/eslint-plugin": "6.8.0", - "@typescript-eslint/parser": "6.8.0", + "@typescript-eslint/eslint-plugin": "6.9.0", + "@typescript-eslint/parser": "6.9.0", "@willbooster/eslint-config-ts": "10.5.0", "@willbooster/prettier-config": "9.1.1", "blitz": "2.0.0-beta.34", - "build-ts": "11.0.4", + "build-ts": "11.0.5", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/shared-lib-node/package.json b/packages/shared-lib-node/package.json index 0b6b48b7..73bb63d1 100644 --- a/packages/shared-lib-node/package.json +++ b/packages/shared-lib-node/package.json @@ -42,12 +42,12 @@ "devDependencies": { "@types/eslint": "8.44.6", "@types/micromatch": "4.0.4", - "@types/node": "20.8.7", - "@typescript-eslint/eslint-plugin": "6.8.0", - "@typescript-eslint/parser": "6.8.0", + "@types/node": "20.8.8", + "@typescript-eslint/eslint-plugin": "6.9.0", + "@typescript-eslint/parser": "6.9.0", "@willbooster/eslint-config-ts": "10.5.0", "@willbooster/prettier-config": "9.1.1", - "build-ts": "11.0.4", + "build-ts": "11.0.5", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/shared-lib-react/package.json b/packages/shared-lib-react/package.json index 5b1bfb91..187dc1d7 100644 --- a/packages/shared-lib-react/package.json +++ b/packages/shared-lib-react/package.json @@ -48,12 +48,12 @@ "@types/micromatch": "4.0.4", "@types/react": "18.2.31", "@types/react-dom": "18.2.14", - "@typescript-eslint/eslint-plugin": "6.8.0", - "@typescript-eslint/parser": "6.8.0", + "@typescript-eslint/eslint-plugin": "6.9.0", + "@typescript-eslint/parser": "6.9.0", "@willbooster/eslint-config-ts-react": "10.1.7", "@willbooster/prettier-config": "9.1.1", "babel-loader": "9.1.3", - "build-ts": "11.0.4", + "build-ts": "11.0.5", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/shared-lib/package.json b/packages/shared-lib/package.json index dd9afd86..4dbe8799 100644 --- a/packages/shared-lib/package.json +++ b/packages/shared-lib/package.json @@ -38,11 +38,11 @@ "devDependencies": { "@types/eslint": "8.44.6", "@types/micromatch": "4.0.4", - "@typescript-eslint/eslint-plugin": "6.8.0", - "@typescript-eslint/parser": "6.8.0", + "@typescript-eslint/eslint-plugin": "6.9.0", + "@typescript-eslint/parser": "6.9.0", "@willbooster/eslint-config-ts": "10.5.0", "@willbooster/prettier-config": "9.1.1", - "build-ts": "11.0.4", + "build-ts": "11.0.5", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/wb/package.json b/packages/wb/package.json index ed83a966..e859f481 100644 --- a/packages/wb/package.json +++ b/packages/wb/package.json @@ -23,6 +23,7 @@ }, "prettier": "@willbooster/prettier-config", "dependencies": { + "at-decorators": "1.2.0", "chalk": "5.3.0", "dotenv": "16.3.1", "kill-port": "2.0.1", @@ -33,13 +34,13 @@ "@types/eslint": "8.44.6", "@types/kill-port": "2.0.2", "@types/micromatch": "4.0.4", - "@types/node": "20.8.7", + "@types/node": "20.8.8", "@types/yargs": "17.0.29", - "@typescript-eslint/eslint-plugin": "6.8.0", - "@typescript-eslint/parser": "6.8.0", + "@typescript-eslint/eslint-plugin": "6.9.0", + "@typescript-eslint/parser": "6.9.0", "@willbooster/eslint-config-ts": "10.5.0", "@willbooster/prettier-config": "9.1.1", - "build-ts": "11.0.4", + "build-ts": "11.0.5", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/wb/src/commands/buildIfNeeded.ts b/packages/wb/src/commands/buildIfNeeded.ts index 6a5996e5..4d4dc31b 100644 --- a/packages/wb/src/commands/buildIfNeeded.ts +++ b/packages/wb/src/commands/buildIfNeeded.ts @@ -8,8 +8,6 @@ import { ignoreEnoentAsync } from '@willbooster/shared-lib/src'; import chalk from 'chalk'; import type { ArgumentsCamelCase, CommandModule, InferredOptionTypes } from 'yargs'; -import { project } from '../project.js'; - const builder = { command: { description: 'A build command', diff --git a/packages/wb/src/commands/optimizeForDockerBuild.ts b/packages/wb/src/commands/optimizeForDockerBuild.ts index 6b3b4e9b..eb035aa7 100644 --- a/packages/wb/src/commands/optimizeForDockerBuild.ts +++ b/packages/wb/src/commands/optimizeForDockerBuild.ts @@ -5,8 +5,6 @@ import path from 'node:path'; import type { PackageJson } from 'type-fest'; import type { CommandModule, InferredOptionTypes } from 'yargs'; -import { project } from '../project.js'; - const builder = { outside: { description: 'Whether the optimization is executed outside a docker container or not', diff --git a/packages/wb/src/project.ts b/packages/wb/src/project.ts index 520394a5..830e28ed 100644 --- a/packages/wb/src/project.ts +++ b/packages/wb/src/project.ts @@ -1,31 +1,24 @@ import fs from 'node:fs'; import path from 'node:path'; +import { memoizeOne } from 'at-decorators'; import type { PackageJson } from 'type-fest'; import type { ScriptArgv } from './scripts/builder.js'; -class Project { - private _buildCommand: string | undefined; +export class Project { private _dirPath: string; - private _rootDirPath: string | undefined; - private _dockerfile: string | undefined; - private _hasDockerfile: boolean | undefined; - private _name: string | undefined; - private _nameWithoutNamespace: string | undefined; - private _rootPackageJson: PackageJson | undefined; - private _dockerPackageJson: PackageJson | undefined; - private _packageJson: PackageJson | undefined; private _pathByName = new Map(); - constructor() { - this._dirPath = process.cwd(); + constructor(dirPath: string) { + this._dirPath = dirPath; } + @memoizeOne getBuildCommand(argv?: ScriptArgv): string { - return (this._buildCommand ??= this.packageJson.scripts?.build?.includes('buildIfNeeded') + return this.packageJson.scripts?.build?.includes('buildIfNeeded') ? 'yarn build' - : `YARN wb buildIfNeeded ${argv?.verbose ? '--verbose' : ''}`); + : `YARN wb buildIfNeeded ${argv?.verbose ? '--verbose' : ''}`; } get dirPath(): string { @@ -36,56 +29,56 @@ class Project { this._dirPath = path.resolve(newDirPath); } + @memoizeOne get rootDirPath(): string { - return (this._rootDirPath ??= fs.existsSync(path.join(this.dirPath, '..', '..', 'package.json')) + return fs.existsSync(path.join(this.dirPath, '..', '..', 'package.json')) ? path.resolve(this.dirPath, '..', '..') - : this.dirPath); + : this.dirPath; } + @memoizeOne get dockerfile(): string { - return (this._dockerfile ??= fs.readFileSync(this.findFile('Dockerfile'), 'utf8')); + return fs.readFileSync(this.findFile('Dockerfile'), 'utf8'); } + @memoizeOne get hasDockerfile(): boolean { - if (this._hasDockerfile !== undefined) return this._hasDockerfile; - try { - this._hasDockerfile = !!this.findFile('Dockerfile'); + return !!this.findFile('Dockerfile'); } catch { - this._hasDockerfile = false; + return false; } - return this._hasDockerfile; } + @memoizeOne get name(): string { - return (this._name ??= project.rootPackageJson.name || 'unknown'); + return this.rootPackageJson.name || 'unknown'; } + @memoizeOne get nameWithoutNamespace(): string { - if (this._nameWithoutNamespace === undefined) { - const name = project.rootPackageJson.name || 'unknown'; - const index = name.lastIndexOf('/'); - this._nameWithoutNamespace = index === -1 ? name : name.slice(index + 1); - } - return this._nameWithoutNamespace; + const name = this.rootPackageJson.name || 'unknown'; + const index = name.lastIndexOf('/'); + return index === -1 ? name : name.slice(index + 1); } + @memoizeOne get packageJson(): PackageJson { - return (this._packageJson ??= JSON.parse(fs.readFileSync(path.join(this.dirPath, 'package.json'), 'utf8'))); + return JSON.parse(fs.readFileSync(path.join(this.dirPath, 'package.json'), 'utf8')); } + @memoizeOne get rootPackageJson(): PackageJson { - return (this._rootPackageJson ??= - this.rootDirPath === this.dirPath - ? this.packageJson - : JSON.parse(fs.readFileSync(path.join(this.rootDirPath, 'package.json'), 'utf8'))); + return this.rootDirPath === this.dirPath + ? this.packageJson + : JSON.parse(fs.readFileSync(path.join(this.rootDirPath, 'package.json'), 'utf8')); } + @memoizeOne get dockerPackageJson(): PackageJson { - return (this._dockerPackageJson ??= - path.dirname(this.findFile('Dockerfile')) === this.dirPath - ? this.packageJson - : JSON.parse(fs.readFileSync(path.join(path.dirname(this.findFile('Dockerfile')), 'package.json'), 'utf8'))); + return path.dirname(this.findFile('Dockerfile')) === this.dirPath + ? this.packageJson + : JSON.parse(fs.readFileSync(path.join(path.dirname(this.findFile('Dockerfile')), 'package.json'), 'utf8')); } findFile(fileName: string): string { @@ -100,5 +93,3 @@ class Project { return filePath; } } - -export const project = new Project(); diff --git a/packages/wb/src/scripts/dockerScripts.ts b/packages/wb/src/scripts/dockerScripts.ts index a8c164fd..e475f47e 100644 --- a/packages/wb/src/scripts/dockerScripts.ts +++ b/packages/wb/src/scripts/dockerScripts.ts @@ -1,6 +1,6 @@ import path from 'node:path'; -import { project } from '../project.js'; +import { Project } from '../project.js'; import { spawnSyncOnExit } from '../utils.js'; /** @@ -8,7 +8,7 @@ import { spawnSyncOnExit } from '../utils.js'; * Note that `YARN zzz` is replaced with `yarn zzz` or `node_modules/.bin/zzz`. */ class DockerScripts { - buildDevImage(): string { + buildDevImage(project: Project): string { // e.g. coding-booster uses `"docker/build/prepare": "touch drill-users.csv",` const prefix = project.dockerPackageJson.scripts?.['docker/build/prepare'] ? 'yarn run docker/build/prepare && ' @@ -20,15 +20,15 @@ class DockerScripts { --build-arg WB_ENV=${process.env.WB_ENV} --build-arg WB_VERSION=dev .`; } - stopAndStart(unbuffer = false, additionalOptions = '', additionalArgs = ''): string { - return `${this.stop()} && ${unbuffer ? 'unbuffer ' : ''}${this.start(additionalOptions, additionalArgs)}`; + stopAndStart(project: Project, unbuffer = false, additionalOptions = '', additionalArgs = ''): string { + return `${this.stop(project)} && ${unbuffer ? 'unbuffer ' : ''}${this.start(project, additionalOptions, additionalArgs)}`; } - start(additionalOptions = '', additionalArgs = ''): string { - spawnSyncOnExit(this.stop()); + start(project: Project, additionalOptions = '', additionalArgs = ''): string { + spawnSyncOnExit(this.stop(project)); return `docker run --rm -it -p 8080:8080 --name ${project.nameWithoutNamespace} ${additionalOptions} ${project.nameWithoutNamespace} ${additionalArgs}`; } - stop(): string { + stop(project: Project): string { return `true $(docker rm -f $(docker container ls -q -f name=${project.nameWithoutNamespace}) 2> /dev/null)`; } diff --git a/packages/wb/src/scripts/execution/baseExecutionScripts.ts b/packages/wb/src/scripts/execution/baseExecutionScripts.ts index ce99cb25..43cf27ad 100644 --- a/packages/wb/src/scripts/execution/baseExecutionScripts.ts +++ b/packages/wb/src/scripts/execution/baseExecutionScripts.ts @@ -1,5 +1,6 @@ import type { ScriptArgv } from '../builder.js'; import { dockerScripts } from '../dockerScripts.js'; +import { Project } from '../../project.js'; export interface TestE2EDevOptions { // '--e2e generate' calls 'codegen http://localhost:8080' @@ -18,22 +19,31 @@ export interface TestE2EOptions extends TestE2EDevOptions { export abstract class BaseExecutionScripts { protected constructor(private readonly defaultPort = 3000) {} - buildDocker(): string { - return dockerScripts.buildDevImage(); + buildDocker(project: Project): string { + return dockerScripts.buildDevImage(project); } - abstract start(argv: ScriptArgv): string; + abstract start(project: Project, argv: ScriptArgv): string; - abstract startProduction(argv: ScriptArgv, port: number): string; + abstract startProduction(project: Project, argv: ScriptArgv, port: number): string; - startDocker(argv: ScriptArgv): string { - return `${this.buildDocker()} + startDocker(project: Project, argv: ScriptArgv): string { + return `${this.buildDocker(project)} && YARN concurrently --raw --kill-others-on-fail - "${dockerScripts.stopAndStart(false, argv.normalizedDockerArgsText ?? '', argv.normalizedArgsText ?? '')}" - "${this.waitAndOpenApp(argv, 8080)}"`; + "${dockerScripts.stopAndStart( + project, + false, + argv.normalizedDockerArgsText ?? '', + argv.normalizedArgsText ?? '' + )}" + "${this.waitAndOpenApp(project, argv, 8080)}"`; } - testE2E(argv: ScriptArgv, { playwrightArgs, prismaDirectory, startCommand }: TestE2EOptions): string { + testE2E( + project: Project, + argv: ScriptArgv, + { playwrightArgs, prismaDirectory, startCommand }: TestE2EOptions + ): string { // 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. @@ -44,7 +54,7 @@ export abstract class BaseExecutionScripts { && yarn playwright ${playwrightArgs}"`; } - testE2EDev(argv: ScriptArgv, { playwrightArgs, startCommand }: TestE2EDevOptions): string { + testE2EDev(project: Project, argv: ScriptArgv, { playwrightArgs, startCommand }: TestE2EDevOptions): string { const env = process.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" @@ -52,14 +62,14 @@ export abstract class BaseExecutionScripts { && yarn playwright ${playwrightArgs}"`; } - abstract testStart(argv: ScriptArgv): string; + abstract testStart(project: Project, argv: ScriptArgv): string; - testUnit(_: ScriptArgv): string { + testUnit(_: 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`; } - protected waitApp(argv: ScriptArgv, port = this.defaultPort): string { + protected waitApp(project: Project, argv: ScriptArgv, port = this.defaultPort): string { return `wait-on -t 10000 http://127.0.0.1:${port} 2> /dev/null || wait-on -t 10000 -i 500 http://127.0.0.1:${port} 2> /dev/null || wait-on -t 10000 -i 1000 http://127.0.0.1:${port} 2> /dev/null @@ -68,7 +78,11 @@ export abstract class BaseExecutionScripts { || wait-on -t 60000 -i 5000 http://127.0.0.1:${port}`; } - protected waitAndOpenApp(argv: ScriptArgv, port = this.defaultPort): string { - return `${this.waitApp(argv, port)} || wait-on http://127.0.0.1:${port} && open-cli http://localhost:${port}`; + protected waitAndOpenApp(project: Project, argv: ScriptArgv, port = this.defaultPort): string { + return `${this.waitApp( + project, + argv, + port + )} || wait-on http://127.0.0.1:${port} && open-cli http://localhost:${port}`; } } diff --git a/packages/wb/src/scripts/execution/blitzScripts.ts b/packages/wb/src/scripts/execution/blitzScripts.ts index 8b03ee15..691b3efa 100644 --- a/packages/wb/src/scripts/execution/blitzScripts.ts +++ b/packages/wb/src/scripts/execution/blitzScripts.ts @@ -1,4 +1,4 @@ -import { project } from '../../project.js'; +import { project, Project } from '../../project.js'; import type { ScriptArgv } from '../builder.js'; import { prismaScripts } from '../prismaScripts.js'; @@ -14,14 +14,14 @@ class BlitzScripts extends BaseExecutionScripts { super(); } - override start(argv: ScriptArgv): string { + override start(project: Project, argv: ScriptArgv): string { const appEnv = process.env.WB_ENV ? `APP_ENV=${process.env.WB_ENV} ` : ''; return `${appEnv}YARN concurrently --raw --kill-others-on-fail "blitz dev ${argv.normalizedArgsText ?? ''}" - "${this.waitAndOpenApp(argv)}"`; + "${this.waitAndOpenApp(project, argv)}"`; } - override startProduction(argv: ScriptArgv, port: number): string { + override startProduction(project: Project, argv: ScriptArgv, port: number): string { const appEnv = process.env.WB_ENV ? `APP_ENV=${process.env.WB_ENV} ` : ''; return `${appEnv}NODE_ENV=production YARN concurrently --raw --kill-others-on-fail "${prismaScripts.reset()} && ${project.getBuildCommand( @@ -31,6 +31,7 @@ class BlitzScripts extends BaseExecutionScripts { } override testE2E( + project: Project, argv: ScriptArgv, { playwrightArgs = 'test tests/e2e', @@ -39,7 +40,7 @@ class BlitzScripts extends BaseExecutionScripts { )} && pm2-runtime start ${project.findFile('ecosystem.config.cjs')}`, }: TestE2EOptions ): string { - return super.testE2E(argv, { + return super.testE2E(project, argv, { playwrightArgs, prismaDirectory: 'db', startCommand, @@ -47,13 +48,14 @@ class BlitzScripts extends BaseExecutionScripts { } override testE2EDev( + project: Project, argv: ScriptArgv, { playwrightArgs = 'test tests/e2e', startCommand = 'blitz dev -p 8080' }: TestE2EDevOptions ): string { - return super.testE2EDev(argv, { playwrightArgs, startCommand }); + return super.testE2EDev(project, argv, { playwrightArgs, startCommand }); } - override testStart(argv: ScriptArgv): string { + override testStart(project: Project, argv: ScriptArgv): string { return `YARN concurrently --kill-others --raw --success first "blitz dev" "${this.waitApp(argv)}"`; } } diff --git a/packages/wb/src/scripts/execution/httpServerScripts.ts b/packages/wb/src/scripts/execution/httpServerScripts.ts index 7c9453b7..3e4bfddb 100644 --- a/packages/wb/src/scripts/execution/httpServerScripts.ts +++ b/packages/wb/src/scripts/execution/httpServerScripts.ts @@ -1,4 +1,4 @@ -import { project } from '../../project.js'; +import { Project } from '../../project.js'; import type { ScriptArgv } from '../builder.js'; import { dockerScripts } from '../dockerScripts.js'; @@ -14,28 +14,31 @@ class HttpServerScripts extends BaseExecutionScripts { super(); } - override start(argv: ScriptArgv): string { + override start(project: Project, argv: ScriptArgv): string { return `YARN build-ts run src/index.ts ${argv.watch ? '--watch' : ''} -- ${argv.normalizedArgsText ?? ''}`; } - override startDocker(argv: ScriptArgv): string { - return `${this.buildDocker()} && ${dockerScripts.stopAndStart( + override startDocker(project: Project, argv: ScriptArgv): string { + return `${this.buildDocker(project)} && ${dockerScripts.stopAndStart( + project, false, argv.normalizedDockerArgsText ?? '', argv.normalizedArgsText ?? '' )}`; } - override startProduction(argv: ScriptArgv, port = 8080): string { + override startProduction(project: Project, argv: ScriptArgv, port = 8080): string { return `NODE_ENV=production ${project.getBuildCommand( argv )} && NODE_ENV=production PORT=\${PORT:-${port}} node dist/index.js ${argv.normalizedArgsText ?? ''}`; } override testE2E( + project: Project, argv: ScriptArgv, { startCommand = `if [ -e "prisma" ]; then prisma migrate reset --force --skip-generate; fi && (${this.startProduction( + project, argv )})`, }: TestE2EOptions @@ -45,16 +48,19 @@ class HttpServerScripts extends BaseExecutionScripts { "wait-on -t 600000 -i 2000 http://127.0.0.1:8080 && vitest run tests/e2e --color --passWithNoTests"`; } - override testE2EDev(argv: ScriptArgv, { startCommand }: TestE2EDevOptions): string { + override testE2EDev(project: Project, argv: ScriptArgv, { startCommand }: TestE2EDevOptions): string { return `NODE_ENV=production WB_ENV=${ process.env.WB_ENV } PORT=8080 YARN concurrently --kill-others --raw --success first - "${startCommand || this.start(argv)} && exit 1" + "${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"`; } - override testStart(argv: ScriptArgv): string { - return `YARN concurrently --kill-others --raw --success first "${this.start(argv)}" "${this.waitApp(argv)}"`; + override testStart(project: Project, argv: ScriptArgv): string { + return `YARN concurrently --kill-others --raw --success first "${this.start(project, argv)}" "${this.waitApp( + project, + argv + )}"`; } } diff --git a/packages/wb/src/scripts/execution/nextScripts.ts b/packages/wb/src/scripts/execution/nextScripts.ts index cd8dc4b9..3ed2358b 100644 --- a/packages/wb/src/scripts/execution/nextScripts.ts +++ b/packages/wb/src/scripts/execution/nextScripts.ts @@ -1,4 +1,4 @@ -import { project } from '../../project.js'; +import { Project } from '../../project.js'; import type { ScriptArgv } from '../builder.js'; import { prismaScripts } from '../prismaScripts.js'; @@ -14,21 +14,22 @@ class NextScripts extends BaseExecutionScripts { super(); } - override start(argv: ScriptArgv): string { + override start(project: Project, argv: ScriptArgv): string { return `YARN concurrently --raw --kill-others-on-fail "next dev ${argv.normalizedArgsText ?? ''}" - "${this.waitAndOpenApp(argv)}"`; + "${this.waitAndOpenApp(project, argv)}"`; } - override startProduction(argv: ScriptArgv, port: number): string { + override startProduction(project: Project, argv: ScriptArgv, port: number): string { return `NODE_ENV=production YARN concurrently --raw --kill-others-on-fail "${prismaScripts.reset()} && ${project.getBuildCommand( argv )} && PORT=${port} pm2-runtime start ${project.findFile('ecosystem.config.cjs')} ${argv.normalizedArgsText ?? ''}" - "${this.waitAndOpenApp(argv, port)}"`; + "${this.waitAndOpenApp(project, argv, port)}"`; } override testE2E( + project: Project, argv: ScriptArgv, { playwrightArgs = 'test tests/e2e', @@ -37,7 +38,7 @@ class NextScripts extends BaseExecutionScripts { )} && pm2-runtime start ${project.findFile('ecosystem.config.cjs')}`, }: TestE2EOptions ): string { - return super.testE2E(argv, { + return super.testE2E(project, argv, { playwrightArgs, prismaDirectory: 'db', startCommand, @@ -45,14 +46,15 @@ class NextScripts extends BaseExecutionScripts { } override testE2EDev( + project: Project, argv: ScriptArgv, { playwrightArgs = 'test tests/e2e', startCommand = 'next dev -p 8080' }: TestE2EDevOptions ): string { - return super.testE2EDev(argv, { playwrightArgs, startCommand }); + return super.testE2EDev(project, argv, { playwrightArgs, startCommand }); } - override testStart(argv: ScriptArgv): string { - return `YARN concurrently --kill-others --raw --success first "next dev" "${this.waitApp(argv)}"`; + override testStart(project: Project, argv: ScriptArgv): string { + return `YARN concurrently --kill-others --raw --success first "next dev" "${this.waitApp(project, argv)}"`; } } diff --git a/packages/wb/src/scripts/execution/plainAppScripts.ts b/packages/wb/src/scripts/execution/plainAppScripts.ts index f83b0d5b..ab7fda3d 100644 --- a/packages/wb/src/scripts/execution/plainAppScripts.ts +++ b/packages/wb/src/scripts/execution/plainAppScripts.ts @@ -1,4 +1,4 @@ -import { project } from '../../project.js'; +import { Project } from '../../project.js'; import type { ScriptArgv } from '../builder.js'; import { dockerScripts } from '../dockerScripts.js'; @@ -13,33 +13,34 @@ class PlainAppScripts extends BaseExecutionScripts { super(); } - override start(argv: ScriptArgv): string { + override start(project: Project, argv: ScriptArgv): string { return `YARN build-ts run src/index.ts ${argv.watch ? '--watch' : ''} -- ${argv.normalizedArgsText ?? ''}`; } - override startDocker(argv: ScriptArgv): string { - return `${this.buildDocker()} && ${dockerScripts.stopAndStart( + override startDocker(project: Project, argv: ScriptArgv): string { + return `${this.buildDocker(project)} && ${dockerScripts.stopAndStart( + project, false, argv.normalizedDockerArgsText ?? '', argv.normalizedArgsText ?? '' )}`; } - override startProduction(argv: ScriptArgv): string { + override startProduction(project: Project, argv: ScriptArgv): string { return `NODE_ENV=production ${project.getBuildCommand(argv)} && NODE_ENV=production node dist/index.js ${ argv.normalizedArgsText ?? '' }`; } - override testE2E(): string { + override testE2E(_: Project): string { return `echo 'do nothing.'`; } - override testE2EDev(): string { + override testE2EDev(_: Project): string { return `echo 'do nothing.'`; } - override testStart(): string { + override testStart(_: Project): string { return `echo 'do nothing.'`; } } diff --git a/packages/wb/src/scripts/execution/remixScripts.ts b/packages/wb/src/scripts/execution/remixScripts.ts index 7c46892c..41bb32ac 100644 --- a/packages/wb/src/scripts/execution/remixScripts.ts +++ b/packages/wb/src/scripts/execution/remixScripts.ts @@ -1,4 +1,4 @@ -import { project } from '../../project.js'; +import { Project } from '../../project.js'; import type { ScriptArgv } from '../builder.js'; import { prismaScripts } from '../prismaScripts.js'; @@ -14,21 +14,22 @@ class RemixScripts extends BaseExecutionScripts { super(); } - override start(argv: ScriptArgv): string { + override start(project: Project, argv: ScriptArgv): string { return `YARN concurrently --raw --kill-others-on-fail "remix dev ${argv.normalizedArgsText ?? ''}" - "${this.waitAndOpenApp(argv)}"`; + "${this.waitAndOpenApp(project, argv)}"`; } - override startProduction(argv: ScriptArgv, port: number): string { + override startProduction(project: Project, argv: ScriptArgv, port: number): string { return `NODE_ENV=production YARN concurrently --raw --kill-others-on-fail "${prismaScripts.reset()} && ${project.getBuildCommand( argv )} && PORT=${port} pm2-runtime start ${project.findFile('ecosystem.config.cjs')} ${argv.normalizedArgsText ?? ''}" - "${this.waitAndOpenApp(argv, port)}"`; + "${this.waitAndOpenApp(project, argv, port)}"`; } override testE2E( + project: Project, argv: ScriptArgv, { playwrightArgs = 'test tests/e2e', @@ -37,18 +38,19 @@ class RemixScripts extends BaseExecutionScripts { )} && pm2-runtime start ${project.findFile('ecosystem.config.cjs')}`, }: TestE2EOptions ): string { - return super.testE2E(argv, { playwrightArgs, prismaDirectory: 'prisma', startCommand }); + return super.testE2E(project, argv, { playwrightArgs, prismaDirectory: 'prisma', startCommand }); } override testE2EDev( + project: Project, argv: ScriptArgv, { playwrightArgs = 'test tests/e2e', startCommand = 'remix dev' }: TestE2EDevOptions ): string { - return super.testE2EDev(argv, { playwrightArgs, startCommand }); + return super.testE2EDev(project, argv, { playwrightArgs, startCommand }); } - override testStart(argv: ScriptArgv): string { - return `YARN concurrently --kill-others --raw --success first "remix dev" "${this.waitApp(argv)}"`; + override testStart(project: Project, argv: ScriptArgv): string { + return `YARN concurrently --kill-others --raw --success first "remix dev" "${this.waitApp(project, argv)}"`; } } diff --git a/packages/wb/src/scripts/prismaScripts.ts b/packages/wb/src/scripts/prismaScripts.ts index 622973c3..89fd4d64 100644 --- a/packages/wb/src/scripts/prismaScripts.ts +++ b/packages/wb/src/scripts/prismaScripts.ts @@ -1,6 +1,6 @@ import path from 'node:path'; -import { project } from '../project.js'; +import { Project } from '../project.js'; /** * A collection of scripts for executing Prisma commands. @@ -8,18 +8,18 @@ import { project } from '../project.js'; * and `YARN zzz` is replaced with `yarn zzz` or `node_modules/.bin/zzz`. */ class PrismaScripts { - deploy(): string { + deploy(_: Project): string { return 'PRISMA migrate deploy'; } - deployForce(backupPath: string): string { + deployForce(project: Project, backupPath: string): string { const dirName = project.packageJson.dependencies?.['blitz'] ? 'db' : 'prisma'; // Don't skip "migrate deploy" because restored database may be older than the current schema. return `rm -Rf ${dirName}/mount/prod.sqlite3*; PRISMA migrate reset --force && rm -Rf ${dirName}/mount/prod.sqlite3* && litestream restore -o ${dirName}/mount/prod.sqlite3 ${backupPath} && ALLOW_TO_SKIP_SEED=0 PRISMA migrate deploy`; } - litestream(): string { + litestream(_: Project): string { return `node -e ' const { PrismaClient } = require("@prisma/client"); new PrismaClient().$queryRaw\`PRAGMA journal_mode = WAL;\` @@ -27,28 +27,28 @@ new PrismaClient().$queryRaw\`PRAGMA journal_mode = WAL;\` '`; } - migrate(): string { - return `PRISMA migrate deploy && PRISMA generate && ${this.seed()}`; + migrate(project: Project): string { + return `PRISMA migrate deploy && PRISMA generate && ${this.seed(project)}`; } - migrateDev(): string { + migrateDev(_: Project): string { return `PRISMA migrate dev`; } - reset(): string { + reset(project: Project): string { // cf. https://www.prisma.io/docs/guides/database/seed-database#integrated-seeding-with-prisma-migrate // Blitz does not trigger seed automatically, so we need to run it manually. - return `PRISMA migrate reset --force --skip-seed && ${this.seed()}`; + return `PRISMA migrate reset --force --skip-seed && ${this.seed(project)}`; // I'm not sure why we need to remove all sqlite files, so I commented out the following line. // return `true $(rm -Rf db/**/*.sqlite* 2> /dev/null) && true $(rm -Rf prisma/**/*.sqlite* 2> /dev/null) && PRISMA migrate reset --force --skip-seed && ${this.seed()}`; } - restore(backupPath: string, outputPath: string): string { + restore(project: Project, backupPath: string, outputPath: string): string { const dirName = project.packageJson.dependencies?.['blitz'] ? 'db' : 'prisma'; return `rm -Rf ${dirName}/restored.sqlite3; GOOGLE_APPLICATION_CREDENTIALS=gcp-sa-key.json litestream restore -o ${outputPath} ${backupPath}`; } - seed(scriptPath?: string): string { + seed(project: Project, scriptPath?: string): string { if (project.packageJson.dependencies?.['blitz']) return `YARN blitz db seed${scriptPath ? ` -f ${scriptPath}` : ''}`; if (scriptPath) return 'YARN build-ts run prisma/seeds.ts'; @@ -56,7 +56,7 @@ new PrismaClient().$queryRaw\`PRAGMA journal_mode = WAL;\` return `if [ -e "prisma/seeds.ts" ]; then YARN build-ts run prisma/seeds.ts; fi`; } - studio(dbUrlOrPath?: string): string { + studio(_: Project, dbUrlOrPath?: string): string { let prefix = ''; if (dbUrlOrPath) { try { diff --git a/packages/wb/src/utils.ts b/packages/wb/src/utils.ts index c5c0f6da..40fb8007 100644 --- a/packages/wb/src/utils.ts +++ b/packages/wb/src/utils.ts @@ -2,8 +2,8 @@ import { spawnSync } from 'node:child_process'; import killPortProcess from 'kill-port'; -import { project } from './project.js'; import { printFinishedAndExitIfNeeded, printStart } from './scripts/run.js'; +import { Project } from './project.js'; const killed = new Set(); @@ -28,7 +28,7 @@ async function killPortProcessHandlingErrors(port: number): Promise { } } -export function spawnSyncOnExit(command: string): void { +export function spawnSyncOnExit(project: Project, command: string): void { const killFunc = async (): Promise => { if (killed.has(command)) return; diff --git a/yarn.lock b/yarn.lock index d5e0815b..98eae093 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2998,16 +2998,16 @@ __metadata: languageName: node linkType: hard -"@qiwi/multi-semantic-release@npm:7.1.0": - version: 7.1.0 - resolution: "@qiwi/multi-semantic-release@npm:7.1.0" +"@qiwi/multi-semantic-release@npm:7.1.1": + version: 7.1.1 + resolution: "@qiwi/multi-semantic-release@npm:7.1.1" dependencies: - "@semrel-extra/topo": "npm:^1.13.0" + "@semrel-extra/topo": "npm:^1.14.0" blork: "npm:^9.3.0" - cosmiconfig: "npm:^8.2.0" + cosmiconfig: "npm:^8.3.6" debug: "npm:^4.3.4" detect-indent: "npm:^7.0.1" - detect-newline: "npm:^4.0.0" + detect-newline: "npm:^4.0.1" execa: "npm:^7.1.1" get-stream: "npm:^6.0.1" git-log-parser: "npm:^1.2.0" @@ -3021,7 +3021,7 @@ __metadata: stream-buffers: "npm:^3.0.2" bin: multi-semantic-release: bin/cli.js - checksum: c34566951395e857cdac8ac75f7c4b67b462bb497f6dc677ed50511abf55a542e8574d2ce4b81b31951ab5a4830de0cd043af278b4697017d080c15b42385dfd + checksum: 4d75b768493f619d80d5f6adfc20ecab3e662ce7556923e622007c95ee09bbdb28e08603873216ac15418b7a27b0571332d0a712290b1dab0fb2cd4e7b81dbdf languageName: node linkType: hard @@ -3888,7 +3888,7 @@ __metadata: languageName: node linkType: hard -"@semrel-extra/topo@npm:^1.13.0": +"@semrel-extra/topo@npm:^1.14.0": version: 1.14.0 resolution: "@semrel-extra/topo@npm:1.14.0" dependencies: @@ -5572,7 +5572,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:*, @types/node@npm:20.8.7": +"@types/node@npm:*": version: 20.8.7 resolution: "@types/node@npm:20.8.7" dependencies: @@ -5581,6 +5581,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:20.8.8": + version: 20.8.8 + resolution: "@types/node@npm:20.8.8" + dependencies: + undici-types: "npm:~5.25.1" + checksum: 739b3d6f4aa760d72373d504d91adec86ac2eab502f68a80214711983e7d1886fd276ade78a276a2affe4942a55ad65cf655c3aa9464d1150f6405445c5ba635 + languageName: node + linkType: hard + "@types/node@npm:^14.0.10 || ^16.0.0": version: 16.18.59 resolution: "@types/node@npm:16.18.59" @@ -5832,15 +5841,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:6.8.0": - version: 6.8.0 - resolution: "@typescript-eslint/eslint-plugin@npm:6.8.0" +"@typescript-eslint/eslint-plugin@npm:6.9.0": + version: 6.9.0 + resolution: "@typescript-eslint/eslint-plugin@npm:6.9.0" dependencies: "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:6.8.0" - "@typescript-eslint/type-utils": "npm:6.8.0" - "@typescript-eslint/utils": "npm:6.8.0" - "@typescript-eslint/visitor-keys": "npm:6.8.0" + "@typescript-eslint/scope-manager": "npm:6.9.0" + "@typescript-eslint/type-utils": "npm:6.9.0" + "@typescript-eslint/utils": "npm:6.9.0" + "@typescript-eslint/visitor-keys": "npm:6.9.0" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.2.4" @@ -5853,25 +5862,25 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: bb86942c67a3aa050e9fe568d1156ef4b7769cde826f1ea41f7c3419dde6d75e785f5846a5887f3816d2fe58e6136ef593153147ab7983f0d9f339dbd4fb3f5c + checksum: 0907c596b1309f4f9e49fb82906ac05a03ec10b5127a0c4628bd9027b0e4a5344a8278af44d5eb69a6819af1b30487e54b5209eacc17334269dbbd4c8fc10aa9 languageName: node linkType: hard -"@typescript-eslint/parser@npm:6.8.0": - version: 6.8.0 - resolution: "@typescript-eslint/parser@npm:6.8.0" +"@typescript-eslint/parser@npm:6.9.0": + version: 6.9.0 + resolution: "@typescript-eslint/parser@npm:6.9.0" dependencies: - "@typescript-eslint/scope-manager": "npm:6.8.0" - "@typescript-eslint/types": "npm:6.8.0" - "@typescript-eslint/typescript-estree": "npm:6.8.0" - "@typescript-eslint/visitor-keys": "npm:6.8.0" + "@typescript-eslint/scope-manager": "npm:6.9.0" + "@typescript-eslint/types": "npm:6.9.0" + "@typescript-eslint/typescript-estree": "npm:6.9.0" + "@typescript-eslint/visitor-keys": "npm:6.9.0" debug: "npm:^4.3.4" peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 958f7cb1cafd1388a2ba000c84a1caf3d62047d51d1c481f548cf450c8e9fc4cbcb4e9d2a0d18bbc5915bba5389bb7d20d8b36aa22f2354ef9c3bf80bb14622a + checksum: b1943297f4c5fa2bf9293c61b717037a21d73f36b67ad7a1180b6961fcfa6540dfc327365827b4316fd032f5c587e46be206b235c5f982f7a49f7191f4c653ad languageName: node linkType: hard @@ -5885,22 +5894,22 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.8.0": - version: 6.8.0 - resolution: "@typescript-eslint/scope-manager@npm:6.8.0" +"@typescript-eslint/scope-manager@npm:6.9.0": + version: 6.9.0 + resolution: "@typescript-eslint/scope-manager@npm:6.9.0" dependencies: - "@typescript-eslint/types": "npm:6.8.0" - "@typescript-eslint/visitor-keys": "npm:6.8.0" - checksum: c528d858a3c647ca695d2245b6009f8d779a165c9de419f4f17ad861312964c767e0963781c38627ddb3a7ff4f68d8a9f095a8a1f30f194356ec53aefb7a5363 + "@typescript-eslint/types": "npm:6.9.0" + "@typescript-eslint/visitor-keys": "npm:6.9.0" + checksum: 26b52a02419edf073859b7a3d15b4b4a9b3acd7e33232bff2cb2589cdf81c784cd818f677b6eefc08f3354ed4aa010b370a085ec89e8150fffeba8da0d3951ad languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.8.0": - version: 6.8.0 - resolution: "@typescript-eslint/type-utils@npm:6.8.0" +"@typescript-eslint/type-utils@npm:6.9.0": + version: 6.9.0 + resolution: "@typescript-eslint/type-utils@npm:6.9.0" dependencies: - "@typescript-eslint/typescript-estree": "npm:6.8.0" - "@typescript-eslint/utils": "npm:6.8.0" + "@typescript-eslint/typescript-estree": "npm:6.9.0" + "@typescript-eslint/utils": "npm:6.9.0" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.0.1" peerDependencies: @@ -5908,7 +5917,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: dea804a02e6e3280c9d9665adf6e399d33e51d90516497a55e1534733da07aff7230b16e942e2c61e0616cca1f26f6c42fed0e4ad3672ffd3843bdcc95ba858a + checksum: ac56a0e5a90a9ea3c1e54a908f8da95b7ae37cde3395554a310517aeee8a0da0747162ca8db389f7fe0e7cd414f4c34ed4684553c396eb1ff0b4d5ce2071a798 languageName: node linkType: hard @@ -5919,10 +5928,10 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:6.8.0": - version: 6.8.0 - resolution: "@typescript-eslint/types@npm:6.8.0" - checksum: 714a716f796a805335768ca5b762e2202173586d802cc0ce4e49dac8c211056f66af6a57c8eb29dbc58c310204062f8ed48007e962f345e2ecfa290abacafaec +"@typescript-eslint/types@npm:6.9.0": + version: 6.9.0 + resolution: "@typescript-eslint/types@npm:6.9.0" + checksum: 18ca92e19ed45407f55e75353047e9cd08183639939ba912a995c89bac89cfc28ddd10f02d8d8f71e44494337f80ee87096aff9498026f0d23f1899a72adf70a languageName: node linkType: hard @@ -5944,12 +5953,12 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.8.0": - version: 6.8.0 - resolution: "@typescript-eslint/typescript-estree@npm:6.8.0" +"@typescript-eslint/typescript-estree@npm:6.9.0": + version: 6.9.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.9.0" dependencies: - "@typescript-eslint/types": "npm:6.8.0" - "@typescript-eslint/visitor-keys": "npm:6.8.0" + "@typescript-eslint/types": "npm:6.9.0" + "@typescript-eslint/visitor-keys": "npm:6.9.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -5958,24 +5967,24 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 9707f1b3e7189686dd0f68407b2f147597b4604384e54e47abd95cdaff4e2a2b76ef89a25bd584f0285011f4303d576b0705623e24288eed8121e56d6b90da44 + checksum: cf747f1540ac4760b01a56acf6a5d84457d46a3542309d9c853323cb6ca307559114e3226e6c2f17d757b42f52ee9c8dc57368cc34a8f292ff105b1fca9a3601 languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.8.0": - version: 6.8.0 - resolution: "@typescript-eslint/utils@npm:6.8.0" +"@typescript-eslint/utils@npm:6.9.0": + version: 6.9.0 + resolution: "@typescript-eslint/utils@npm:6.9.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.12" "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:6.8.0" - "@typescript-eslint/types": "npm:6.8.0" - "@typescript-eslint/typescript-estree": "npm:6.8.0" + "@typescript-eslint/scope-manager": "npm:6.9.0" + "@typescript-eslint/types": "npm:6.9.0" + "@typescript-eslint/typescript-estree": "npm:6.9.0" semver: "npm:^7.5.4" peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: e882a84fd8906f8c3227ae25568d2ff565ff4bad665102808e087b13fdb79fb4f122a76132f01157baf535f91afb96734d1d07296fdecd44c465a59af9894e8e + checksum: bf9ef9ad66212a46ddf8335d16f80a583803c2ba2d3b1f2a8f37449b0409105377d03fa52381c57676aae48dd5cf83adba2465155b6b96b8c91a40a5987a6ded languageName: node linkType: hard @@ -6007,13 +6016,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.8.0": - version: 6.8.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.8.0" +"@typescript-eslint/visitor-keys@npm:6.9.0": + version: 6.9.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.9.0" dependencies: - "@typescript-eslint/types": "npm:6.8.0" + "@typescript-eslint/types": "npm:6.9.0" eslint-visitor-keys: "npm:^3.4.1" - checksum: 71c3080eea8928eb6337889f767f2d5ee666aa87edd376fdeafabeb9b99171760c074d3bf413d7227920c9ad0ba7e93207cace8394793442fb3bc7ead438a24d + checksum: fa255a8fd74c4f3cf990281a70d76dafc0f7fc4122507051210b74627ae4b514903c7eaab69090f47ff8421ee48f218633849939653cb6c48001fcc9f4bc65d8 languageName: node linkType: hard @@ -6320,12 +6329,12 @@ __metadata: dependencies: "@types/eslint": "npm:8.44.6" "@types/micromatch": "npm:4.0.4" - "@typescript-eslint/eslint-plugin": "npm:6.8.0" - "@typescript-eslint/parser": "npm:6.8.0" + "@typescript-eslint/eslint-plugin": "npm:6.9.0" + "@typescript-eslint/parser": "npm:6.9.0" "@willbooster/eslint-config-ts": "npm:10.5.0" "@willbooster/prettier-config": "npm:9.1.1" blitz: "npm:2.0.0-beta.34" - build-ts: "npm:11.0.4" + build-ts: "npm:11.0.5" eslint: "npm:8.52.0" eslint-config-prettier: "npm:9.0.0" eslint-import-resolver-typescript: "npm:3.6.1" @@ -6358,12 +6367,12 @@ __metadata: dependencies: "@types/eslint": "npm:8.44.6" "@types/micromatch": "npm:4.0.4" - "@types/node": "npm:20.8.7" - "@typescript-eslint/eslint-plugin": "npm:6.8.0" - "@typescript-eslint/parser": "npm:6.8.0" + "@types/node": "npm:20.8.8" + "@typescript-eslint/eslint-plugin": "npm:6.9.0" + "@typescript-eslint/parser": "npm:6.9.0" "@willbooster/eslint-config-ts": "npm:10.5.0" "@willbooster/prettier-config": "npm:9.1.1" - build-ts: "npm:11.0.4" + build-ts: "npm:11.0.5" dotenv: "npm:16.3.1" eslint: "npm:8.52.0" eslint-config-prettier: "npm:9.0.0" @@ -6401,12 +6410,12 @@ __metadata: "@types/micromatch": "npm:4.0.4" "@types/react": "npm:18.2.31" "@types/react-dom": "npm:18.2.14" - "@typescript-eslint/eslint-plugin": "npm:6.8.0" - "@typescript-eslint/parser": "npm:6.8.0" + "@typescript-eslint/eslint-plugin": "npm:6.9.0" + "@typescript-eslint/parser": "npm:6.9.0" "@willbooster/eslint-config-ts-react": "npm:10.1.7" "@willbooster/prettier-config": "npm:9.1.1" babel-loader: "npm:9.1.3" - build-ts: "npm:11.0.4" + build-ts: "npm:11.0.5" eslint: "npm:8.52.0" eslint-config-prettier: "npm:9.0.0" eslint-import-resolver-typescript: "npm:3.6.1" @@ -6437,11 +6446,11 @@ __metadata: dependencies: "@types/eslint": "npm:8.44.6" "@types/micromatch": "npm:4.0.4" - "@typescript-eslint/eslint-plugin": "npm:6.8.0" - "@typescript-eslint/parser": "npm:6.8.0" + "@typescript-eslint/eslint-plugin": "npm:6.9.0" + "@typescript-eslint/parser": "npm:6.9.0" "@willbooster/eslint-config-ts": "npm:10.5.0" "@willbooster/prettier-config": "npm:9.1.1" - build-ts: "npm:11.0.4" + build-ts: "npm:11.0.5" eslint: "npm:8.52.0" eslint-config-prettier: "npm:9.0.0" eslint-import-resolver-typescript: "npm:3.6.1" @@ -6465,13 +6474,14 @@ __metadata: "@types/eslint": "npm:8.44.6" "@types/kill-port": "npm:2.0.2" "@types/micromatch": "npm:4.0.4" - "@types/node": "npm:20.8.7" + "@types/node": "npm:20.8.8" "@types/yargs": "npm:17.0.29" - "@typescript-eslint/eslint-plugin": "npm:6.8.0" - "@typescript-eslint/parser": "npm:6.8.0" + "@typescript-eslint/eslint-plugin": "npm:6.9.0" + "@typescript-eslint/parser": "npm:6.9.0" "@willbooster/eslint-config-ts": "npm:10.5.0" "@willbooster/prettier-config": "npm:9.1.1" - build-ts: "npm:11.0.4" + at-decorators: "npm:1.2.0" + build-ts: "npm:11.0.5" chalk: "npm:5.3.0" dotenv: "npm:16.3.1" eslint: "npm:8.52.0" @@ -7320,6 +7330,13 @@ __metadata: languageName: node linkType: hard +"at-decorators@npm:1.2.0": + version: 1.2.0 + resolution: "at-decorators@npm:1.2.0" + checksum: 33298e3b762fa3e150d7df23a29b20fdda484d484bf0c0cb9d8ea1042c937ceb163dcf504e7a79febcdb1669369116d50a3a376fb0c55ecc0b03eeb2cb3a2b96 + languageName: node + linkType: hard + "at-least-node@npm:^1.0.0": version: 1.0.0 resolution: "at-least-node@npm:1.0.0" @@ -7927,9 +7944,9 @@ __metadata: languageName: node linkType: hard -"build-ts@npm:11.0.4": - version: 11.0.4 - resolution: "build-ts@npm:11.0.4" +"build-ts@npm:11.0.5": + version: 11.0.5 + resolution: "build-ts@npm:11.0.5" dependencies: "@babel/core": "npm:7.23.2" "@babel/plugin-proposal-decorators": "npm:7.23.2" @@ -7966,7 +7983,7 @@ __metadata: yargs: "npm:17.7.2" bin: build-ts: bin/index.js - checksum: 9c0851f833315bbe97a2c61f014b4d3998746a39c82f546e0ce404ccc305f072cdf2a3efa7783555ce7f94ae787daf7c4456bc30718acb51878ad8865ed23e98 + checksum: 00774fbe7569cccc84f14cfe9779e45d0f9ddca8b1a7419593571238dc0efee7063fffe2dd7f83a7931b3734f5f827c98b50470688aff70cb2747bd5c03b60cb languageName: node linkType: hard @@ -8992,7 +9009,7 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:^8.0.0, cosmiconfig@npm:^8.2.0": +"cosmiconfig@npm:^8.0.0, cosmiconfig@npm:^8.3.6": version: 8.3.6 resolution: "cosmiconfig@npm:8.3.6" dependencies: @@ -9466,7 +9483,7 @@ __metadata: languageName: node linkType: hard -"detect-newline@npm:^4.0.0": +"detect-newline@npm:^4.0.0, detect-newline@npm:^4.0.1": version: 4.0.1 resolution: "detect-newline@npm:4.0.1" checksum: 1cc1082e88ad477f30703ae9f23bd3e33816ea2db6a35333057e087d72d466f5a777809b71f560118ecff935d2c712f5b59e1008a8b56a900909d8fd4621c603 @@ -20945,9 +20962,9 @@ __metadata: version: 0.0.0-use.local resolution: "willbooster-shared@workspace:." dependencies: - "@qiwi/multi-semantic-release": "npm:7.1.0" + "@qiwi/multi-semantic-release": "npm:7.1.1" "@types/eslint": "npm:8.44.6" - "@typescript-eslint/parser": "npm:6.8.0" + "@typescript-eslint/parser": "npm:6.9.0" "@willbooster/prettier-config": "npm:9.1.1" conventional-changelog-conventionalcommits: "npm:6.1.0" eslint: "npm:8.52.0" From 5cfc2dd743f8a70de8d34cd409a182784c8791b1 Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Wed, 25 Oct 2023 18:01:53 +0900 Subject: [PATCH 02/21] . --- package.json | 2 +- packages/shared-lib-blitz-next/package.json | 4 +- packages/shared-lib-node/package.json | 4 +- packages/shared-lib-node/src/env.ts | 43 +++++++-- packages/shared-lib-node/src/index.ts | 8 +- packages/shared-lib-react/package.json | 6 +- packages/shared-lib/package.json | 4 +- packages/wb/package.json | 4 +- packages/wb/src/commands/buildIfNeeded.ts | 51 ++++++---- .../wb/src/commands/optimizeForDockerBuild.ts | 28 ++---- packages/wb/src/commands/prisma.ts | 76 +++++++++++---- packages/wb/src/commands/retry.ts | 14 ++- packages/wb/src/commands/setup.ts | 94 ++++++++++--------- packages/wb/src/commands/start.ts | 90 ++++++++++-------- packages/wb/src/index.ts | 21 +++-- packages/wb/src/project.ts | 45 ++++++++- packages/wb/src/scripts/dockerScripts.ts | 10 +- .../scripts/execution/baseExecutionScripts.ts | 2 +- .../wb/src/scripts/execution/blitzScripts.ts | 3 +- .../scripts/execution/httpServerScripts.ts | 2 +- .../wb/src/scripts/execution/nextScripts.ts | 2 +- .../src/scripts/execution/plainAppScripts.ts | 2 +- .../wb/src/scripts/execution/remixScripts.ts | 2 +- packages/wb/src/scripts/prismaScripts.ts | 2 +- packages/wb/src/scripts/run.ts | 2 +- packages/wb/src/utils.ts | 43 --------- yarn.lock | 68 ++++++++------ 27 files changed, 385 insertions(+), 247 deletions(-) delete mode 100644 packages/wb/src/utils.ts diff --git a/package.json b/package.json index 159f109d..56d60878 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "@qiwi/multi-semantic-release": "7.1.1", "@types/eslint": "8.44.6", "@typescript-eslint/parser": "6.9.0", - "@willbooster/prettier-config": "9.1.1", + "@willbooster/prettier-config": "9.1.2", "conventional-changelog-conventionalcommits": "6.1.0", "eslint": "8.52.0", "husky": "8.0.3", diff --git a/packages/shared-lib-blitz-next/package.json b/packages/shared-lib-blitz-next/package.json index e06ca9f7..40d0999e 100644 --- a/packages/shared-lib-blitz-next/package.json +++ b/packages/shared-lib-blitz-next/package.json @@ -40,8 +40,8 @@ "@types/micromatch": "4.0.4", "@typescript-eslint/eslint-plugin": "6.9.0", "@typescript-eslint/parser": "6.9.0", - "@willbooster/eslint-config-ts": "10.5.0", - "@willbooster/prettier-config": "9.1.1", + "@willbooster/eslint-config-ts": "10.5.1", + "@willbooster/prettier-config": "9.1.2", "blitz": "2.0.0-beta.34", "build-ts": "11.0.5", "eslint": "8.52.0", diff --git a/packages/shared-lib-node/package.json b/packages/shared-lib-node/package.json index 73bb63d1..8e1f9390 100644 --- a/packages/shared-lib-node/package.json +++ b/packages/shared-lib-node/package.json @@ -45,8 +45,8 @@ "@types/node": "20.8.8", "@typescript-eslint/eslint-plugin": "6.9.0", "@typescript-eslint/parser": "6.9.0", - "@willbooster/eslint-config-ts": "10.5.0", - "@willbooster/prettier-config": "9.1.1", + "@willbooster/eslint-config-ts": "10.5.1", + "@willbooster/prettier-config": "9.1.2", "build-ts": "11.0.5", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", diff --git a/packages/shared-lib-node/src/env.ts b/packages/shared-lib-node/src/env.ts index f2ada47e..be3be54d 100644 --- a/packages/shared-lib-node/src/env.ts +++ b/packages/shared-lib-node/src/env.ts @@ -3,12 +3,12 @@ import path from 'node:path'; import { config } from 'dotenv'; interface Options { - env?: (string | number)[]; - cascadeEnv?: string; - cascadeNodeEnv?: boolean; - autoCascadeEnv?: boolean; - checkEnv?: string; - verbose?: boolean; + env: (string | number)[]; + cascadeEnv: string; + cascadeNodeEnv: boolean; + autoCascadeEnv: boolean; + checkEnv: string; + verbose: boolean; } export const yargsOptionsBuilderForEnv = { @@ -40,8 +40,8 @@ export const yargsOptionsBuilderForEnv = { /** * This function loads environment variables from `.env` files. * */ -export function loadEnvironmentVariables(argv: Options, cwd: string, orgCwd?: string): Record { - let envPaths = (argv.env ?? []).map((envPath) => path.resolve(orgCwd ?? cwd, envPath.toString())); +export function loadEnvironmentVariables(argv: Partial, cwd: string): Record { + let envPaths = (argv.env ?? []).map((envPath) => path.resolve(cwd, envPath.toString())); const cascade = argv.cascadeEnv ?? (argv.cascadeNodeEnv @@ -115,3 +115,30 @@ export function removeNpmAndYarnEnvironmentVariables(envVars: Record = new Map(); + +/** + * This function saves the current state of environment variables. + * It can be used to restore the environment variables to this state later. + */ +export function saveEnvironmentVariables(): void { + savedEnvVars.clear(); + for (const [key, value] of Object.entries(process.env)) { + savedEnvVars.set(key, value); + } +} + +/** + * Restores the environment variables to the state saved by `saveEnvironmentVariables`. + * If a variable was not saved, it will be deleted. + */ +export function restoreEnvironmentVariables(): void { + for (const [key, value] of savedEnvVars.entries()) { + if (savedEnvVars.has(key)) { + process.env[key] = value; + } else { + delete process.env[key]; + } + } +} diff --git a/packages/shared-lib-node/src/index.ts b/packages/shared-lib-node/src/index.ts index 0e6bf274..20388bb5 100644 --- a/packages/shared-lib-node/src/index.ts +++ b/packages/shared-lib-node/src/index.ts @@ -1,4 +1,10 @@ -export { loadEnvironmentVariables, removeNpmAndYarnEnvironmentVariables, yargsOptionsBuilderForEnv } from './env.js'; +export { + loadEnvironmentVariables, + removeNpmAndYarnEnvironmentVariables, + saveEnvironmentVariables, + restoreEnvironmentVariables, + yargsOptionsBuilderForEnv, +} from './env.js'; export { existsAsync } from './exists.js'; export { calculateHashFromFiles, canSkipSeed, updateHashFromFiles } from './hash.js'; export { spawnAsync } from './spawn.js'; diff --git a/packages/shared-lib-react/package.json b/packages/shared-lib-react/package.json index 187dc1d7..e9183870 100644 --- a/packages/shared-lib-react/package.json +++ b/packages/shared-lib-react/package.json @@ -34,7 +34,7 @@ "prettier": "@willbooster/prettier-config", "devDependencies": { "@babel/core": "7.23.2", - "@mdx-js/react": "2.3.0", + "@mdx-js/react": "3.0.0", "@storybook/addon-actions": "7.5.1", "@storybook/addon-docs": "7.5.1", "@storybook/addon-essentials": "7.5.1", @@ -50,8 +50,8 @@ "@types/react-dom": "18.2.14", "@typescript-eslint/eslint-plugin": "6.9.0", "@typescript-eslint/parser": "6.9.0", - "@willbooster/eslint-config-ts-react": "10.1.7", - "@willbooster/prettier-config": "9.1.1", + "@willbooster/eslint-config-ts-react": "10.1.9", + "@willbooster/prettier-config": "9.1.2", "babel-loader": "9.1.3", "build-ts": "11.0.5", "eslint": "8.52.0", diff --git a/packages/shared-lib/package.json b/packages/shared-lib/package.json index 4dbe8799..0164c609 100644 --- a/packages/shared-lib/package.json +++ b/packages/shared-lib/package.json @@ -40,8 +40,8 @@ "@types/micromatch": "4.0.4", "@typescript-eslint/eslint-plugin": "6.9.0", "@typescript-eslint/parser": "6.9.0", - "@willbooster/eslint-config-ts": "10.5.0", - "@willbooster/prettier-config": "9.1.1", + "@willbooster/eslint-config-ts": "10.5.1", + "@willbooster/prettier-config": "9.1.2", "build-ts": "11.0.5", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", diff --git a/packages/wb/package.json b/packages/wb/package.json index e859f481..793e2882 100644 --- a/packages/wb/package.json +++ b/packages/wb/package.json @@ -38,8 +38,8 @@ "@types/yargs": "17.0.29", "@typescript-eslint/eslint-plugin": "6.9.0", "@typescript-eslint/parser": "6.9.0", - "@willbooster/eslint-config-ts": "10.5.0", - "@willbooster/prettier-config": "9.1.1", + "@willbooster/eslint-config-ts": "10.5.1", + "@willbooster/prettier-config": "9.1.2", "build-ts": "11.0.5", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", diff --git a/packages/wb/src/commands/buildIfNeeded.ts b/packages/wb/src/commands/buildIfNeeded.ts index 4d4dc31b..2a6cc5c0 100644 --- a/packages/wb/src/commands/buildIfNeeded.ts +++ b/packages/wb/src/commands/buildIfNeeded.ts @@ -8,6 +8,12 @@ import { ignoreEnoentAsync } from '@willbooster/shared-lib/src'; import chalk from 'chalk'; import type { ArgumentsCamelCase, CommandModule, InferredOptionTypes } from 'yargs'; +import type { Project} from '../project.js'; +import { findAllProjects } from '../project.js'; +import type { sharedOptionsBuilder } from '../sharedOptionsBuilder.js'; + +import { prepareForRunningCommand } from './commandUtils.js'; + const builder = { command: { description: 'A build command', @@ -28,28 +34,39 @@ export const buildIfNeededCommand: CommandModule - argv: Partial>> + argv: Partial>> ): Promise { - if (!fs.existsSync(path.join(project.rootDirPath, '.git'))) { - build(argv); - return true; - } + const projects = await findAllProjects(); + if (!projects) return true; - const [canSkip, cacheFilePath, contentHash] = await canSkipBuild(argv); - if (canSkip) { - console.info(chalk.green(`Skip to run '${argv.command}' 💫`)); - return false; - } + const isGitRepo = fs.existsSync(path.join(projects.root.dirPath, '.git')); - if (!build(argv)) return; + let built = false; - if (!argv.dryRun) { - await fs.promises.writeFile(cacheFilePath, contentHash, 'utf8'); + for (const project of prepareForRunningCommand('buildIfNeeded', projects.root, projects.all, argv)) { + if (!isGitRepo) { + if (!build(project, argv)) return; + built = true; + continue; + } + + const [canSkip, cacheFilePath, contentHash] = await canSkipBuild(project, argv); + if (canSkip) { + console.info(chalk.green(`Skip to run '${argv.command}' 💫`)); + continue; + } + + if (!build(project, argv)) return; + built = true; + + if (!argv.dryRun) { + await fs.promises.writeFile(cacheFilePath, contentHash, 'utf8'); + } } - return true; + return built; } -function build(argv: Partial>>): boolean { +function build(project: Project, argv: Partial>>): boolean { console.info(chalk.green(`Run '${argv.command}'`)); if (!argv.dryRun) { const ret = child_process.spawnSync(argv.command ?? '', { @@ -68,6 +85,7 @@ function build(argv: Partial>> ): Promise<[boolean, string, string]> { const cacheDirectoryPath = path.resolve(project.dirPath, 'node_modules', '.cache', 'build'); @@ -86,7 +104,7 @@ export async function canSkipBuild( ); hash.update(environmentJson); - await updateHashWithDiffResult(argv, hash); + await updateHashWithDiffResult(project, argv, hash); const contentHash = hash.digest('hex'); const cachedContentHash = await ignoreEnoentAsync(() => fs.promises.readFile(cacheFilePath, 'utf8')); @@ -110,6 +128,7 @@ const includeSuffix = [ const excludePatterns = ['test/', 'tests/', '__tests__/', 'test-fixtures/', 'package.json']; async function updateHashWithDiffResult( + project: Project, argv: Partial>>, hash: Hash ): Promise { diff --git a/packages/wb/src/commands/optimizeForDockerBuild.ts b/packages/wb/src/commands/optimizeForDockerBuild.ts index eb035aa7..921aef27 100644 --- a/packages/wb/src/commands/optimizeForDockerBuild.ts +++ b/packages/wb/src/commands/optimizeForDockerBuild.ts @@ -5,6 +5,10 @@ import path from 'node:path'; import type { PackageJson } from 'type-fest'; import type { CommandModule, InferredOptionTypes } from 'yargs'; +import { findAllProjects } from '../project.js'; + +import { prepareForRunningCommand } from './commandUtils.js'; + const builder = { outside: { description: 'Whether the optimization is executed outside a docker container or not', @@ -18,25 +22,15 @@ export const optimizeForDockerBuildCommand: CommandModule> describe: 'Apply migration to DB without initializing it', builder, async handler(argv) { - await runWithSpawn(prismaScripts.deploy(), argv); + const [root, ...allProjects] = await findPrismaProjects(); + for (const project of prepareForRunningCommand('prisma deploy', root, allProjects, argv)) { + await runWithSpawn(prismaScripts.deploy(project), argv); + } }, }; @@ -51,7 +57,10 @@ const deployForceCommand: CommandModule describe: 'Apply migration to DB with initializing it', builder, async handler(argv) { - await runWithSpawn(prismaScripts.migrate(), argv); + const [root, ...allProjects] = await findPrismaProjects(); + for (const project of prepareForRunningCommand('prisma migrate', root, allProjects, argv)) { + await runWithSpawn(prismaScripts.migrate(project), argv); + } }, }; @@ -78,7 +93,10 @@ const migrateDevCommand: CommandModule> describe: 'Reset DB', builder, async handler(argv) { - await runWithSpawn(prismaScripts.reset(), argv); + const [root, ...allProjects] = await findPrismaProjects(); + for (const project of prepareForRunningCommand('prisma reset', root, allProjects, argv)) { + await runWithSpawn(prismaScripts.reset(project), argv); + } }, }; @@ -104,9 +125,13 @@ const restoreCommand: CommandModule { + const projects = await findAllProjects(); + if (!projects) return []; + + const prismaProjects = projects.all.filter( + (project) => project.packageJson.dependencies?.['prisma'] || project.packageJson.devDependencies?.['prisma'] + ); + return [projects.root, ...prismaProjects]; +} diff --git a/packages/wb/src/commands/retry.ts b/packages/wb/src/commands/retry.ts index 8bd678ca..72ea73a6 100644 --- a/packages/wb/src/commands/retry.ts +++ b/packages/wb/src/commands/retry.ts @@ -1,7 +1,10 @@ +import { loadEnvironmentVariables } from '@willbooster/shared-lib-node/src'; import chalk from 'chalk'; import type { CommandModule, InferredOptionTypes } from 'yargs'; +import { findAllProjects, findRootAndSelfProjects } from '../project.js'; import { runWithSpawn } from '../scripts/run.js'; +import type { sharedOptionsBuilder } from '../sharedOptionsBuilder.js'; const builder = { retry: { @@ -12,11 +15,20 @@ const builder = { }, } as const; -export const retryCommand: CommandModule> = { +export const retryCommand: CommandModule> = { command: 'retry', describe: 'Retry the given command until it succeeds', builder, async handler(argv) { + const projects = findRootAndSelfProjects(); + if (!projects) return; + + const project = projects.self; + loadEnvironmentVariables(argv, project.dirPath); + if (projects.root !== project) { + loadEnvironmentVariables(argv, projects.root.dirPath); + } + const cmdAndArgs = argv._.slice(1); let lastStatus = 0; for (let i = 0; i < argv.retry; i++) { diff --git a/packages/wb/src/commands/setup.ts b/packages/wb/src/commands/setup.ts index ef16ff5b..670f42fc 100644 --- a/packages/wb/src/commands/setup.ts +++ b/packages/wb/src/commands/setup.ts @@ -4,7 +4,7 @@ import os from 'node:os'; import type { ArgumentsCamelCase, CommandModule, InferredOptionTypes } from 'yargs'; -import { project } from '../project.js'; +import { findAllProjects, project } from '../project.js'; import { promisePool } from '../promisePool.js'; import { runWithSpawn, runWithSpawnInParallel } from '../scripts/run.js'; @@ -21,50 +21,58 @@ export const setupCommand: CommandModule export async function setup(argv: Partial>>): Promise { - const dirents = await fs.readdir(project.dirPath, { withFileTypes: true }); - if (dirents.some((d) => d.isFile() && d.name.includes('-version'))) { - await runWithSpawn('asdf install', argv); - } - if (dirents.some((d) => d.isFile() && d.name === 'pyproject.toml')) { - await runWithSpawnInParallel('poetry config virtualenvs.in-project true', argv); - await runWithSpawnInParallel('poetry config virtualenvs.prefer-active-python true', argv); - const [, version] = child_process.execSync('asdf current python').toString().trim().split(/\s+/); - await runWithSpawnInParallel(`poetry env use ${version}`, argv); - await promisePool.promiseAll(); - await runWithSpawn('poetry run pip install --upgrade pip', argv); - await runWithSpawn('poetry install --ansi', argv); - } + const projects = await findAllProjects(); + if (!projects) return; - if (os.platform() === 'darwin') { - const packages = ['pstree']; - if (project.hasDockerfile) { - packages.push('expect'); + for (const project of projects.all) { + const dirents = await fs.readdir(project.dirPath, { withFileTypes: true }); + if (project === projects.root) { + if (os.platform() === 'darwin') { + const packages = ['pstree']; + if (project.hasDockerfile) { + packages.push('expect'); + } + await runWithSpawnInParallel(`brew install ${packages.join(' ')}`, argv); + } + + if (dirents.some((d) => d.isFile() && d.name.includes('-version'))) { + await runWithSpawn('asdf install', argv); + } } - await runWithSpawnInParallel(`brew install ${packages.join(' ')}`, argv); - } - const deps = project.packageJson.dependencies ?? {}; - const devDeps = project.packageJson.devDependencies || {}; - const scripts = project.packageJson.scripts ?? {}; - const newDeps: string[] = []; - const newDevDeps: string[] = []; - if (deps['blitz'] || deps['next']) { - newDeps.push('pm2'); - newDevDeps.push('concurrently', 'open-cli', 'vitest', 'wait-on'); - } else if (devDeps['@remix-run/dev']) { - newDeps.push('pm2'); - newDevDeps.push('concurrently', 'open-cli', 'vitest', 'wait-on'); - } else if (deps['express'] || deps['fastify']) { - newDeps.push('pm2'); - newDevDeps.push('concurrently', 'vitest', 'wait-on'); - } - if (newDeps.length > 0) { - await runWithSpawn(`yarn add ${newDeps.join(' ')}`, argv); - } - if (newDevDeps.length > 0) { - await runWithSpawn(`yarn add -D ${newDevDeps.join(' ')}`, argv); - } - if (scripts['gen-code']) { - await runWithSpawn('yarn gen-code', argv); + if (dirents.some((d) => d.isFile() && d.name === 'pyproject.toml')) { + await runWithSpawnInParallel('poetry config virtualenvs.in-project true', argv); + await runWithSpawnInParallel('poetry config virtualenvs.prefer-active-python true', argv); + const [, version] = child_process.execSync('asdf current python').toString().trim().split(/\s+/); + await runWithSpawnInParallel(`poetry env use ${version}`, argv); + await promisePool.promiseAll(); + await runWithSpawn('poetry run pip install --upgrade pip', argv); + await runWithSpawn('poetry install --ansi', argv); + } + + const deps = project.packageJson.dependencies ?? {}; + const devDeps = project.packageJson.devDependencies || {}; + const scripts = project.packageJson.scripts ?? {}; + const newDeps: string[] = []; + const newDevDeps: string[] = []; + if (deps['blitz'] || deps['next']) { + newDeps.push('pm2'); + newDevDeps.push('concurrently', 'open-cli', 'vitest', 'wait-on'); + } else if (devDeps['@remix-run/dev']) { + newDeps.push('pm2'); + newDevDeps.push('concurrently', 'open-cli', 'vitest', 'wait-on'); + } else if (deps['express'] || deps['fastify']) { + newDeps.push('pm2'); + newDevDeps.push('concurrently', 'vitest', 'wait-on'); + } + if (newDeps.length > 0) { + await runWithSpawn(`yarn add ${newDeps.join(' ')}`, argv); + } + if (newDevDeps.length > 0) { + await runWithSpawn(`yarn add -D ${newDevDeps.join(' ')}`, argv); + } + if (scripts['gen-code']) { + await runWithSpawn('yarn gen-code', argv); + } } } diff --git a/packages/wb/src/commands/start.ts b/packages/wb/src/commands/start.ts index 968584e0..24197536 100644 --- a/packages/wb/src/commands/start.ts +++ b/packages/wb/src/commands/start.ts @@ -1,7 +1,8 @@ -import { loadEnvironmentVariables } from '@willbooster/shared-lib-node/src'; -import type { CommandModule, InferredOptionTypes } from 'yargs'; +import { loadEnvironmentVariables, restoreEnvironmentVariables } from '@willbooster/shared-lib-node/src'; +import type { ArgumentsCamelCase, CommandModule, InferredOptionTypes } from 'yargs'; -import { project } from '../project.js'; +import type { Project} from '../project.js'; +import { findAllProjects } from '../project.js'; import { normalizeArgs, scriptOptionsBuilder } from '../scripts/builder.js'; import type { BaseExecutionScripts } from '../scripts/execution/baseExecutionScripts.js'; import { blitzScripts } from '../scripts/execution/blitzScripts.js'; @@ -28,53 +29,61 @@ export const startCommand: CommandModule, + project: Project, + rootProject: Project, + argv: ArgumentsCamelCase>, deps: Partial>, env: string ): string { + restoreEnvironmentVariables(); process.env.WB_ENV ||= env; let prefix = `WB_ENV=${process.env.WB_ENV} `; if (deps['next']) { @@ -82,5 +91,8 @@ function configureEnvironmentVariables( prefix += `NEXT_PUBLIC_WB_ENV=${process.env.WB_ENV} `; } loadEnvironmentVariables(argv, project.dirPath); + if (project !== rootProject) { + loadEnvironmentVariables(argv, rootProject.dirPath); + } return prefix; } diff --git a/packages/wb/src/index.ts b/packages/wb/src/index.ts index 281be48a..56a77e9a 100644 --- a/packages/wb/src/index.ts +++ b/packages/wb/src/index.ts @@ -1,6 +1,10 @@ import path from 'node:path'; -import { loadEnvironmentVariables, removeNpmAndYarnEnvironmentVariables } from '@willbooster/shared-lib-node/src'; +import { + loadEnvironmentVariables, + removeNpmAndYarnEnvironmentVariables, + saveEnvironmentVariables, +} from '@willbooster/shared-lib-node/src'; import yargs from 'yargs'; import { hideBin } from 'yargs/helpers'; @@ -12,7 +16,6 @@ import { setupCommand } from './commands/setup.js'; import { startCommand } from './commands/start.js'; import { testCommand } from './commands/test.js'; import { tcCommand, typeCheckCommand } from './commands/typecheck.js'; -import { project } from './project.js'; import { sharedOptionsBuilder } from './sharedOptionsBuilder.js'; await yargs(hideBin(process.argv)) @@ -23,17 +26,17 @@ await yargs(hideBin(process.argv)) if (workingDir) { const dirPath = path.resolve(workingDir); process.chdir(dirPath); - project.dirPath = dirPath; } removeNpmAndYarnEnvironmentVariables(process.env); + saveEnvironmentVariables(); - const command = argv._[0].toString(); - if (['start', 'tc', 'typecheck'].includes(command)) return; - if (command === 'test') { - process.env.WB_ENV ||= 'test'; - } - loadEnvironmentVariables(argv, project.dirPath); + // const command = argv._[0].toString(); + // if (['start', 'tc', 'typecheck'].includes(command)) return; + // if (command === 'test') { + // process.env.WB_ENV ||= 'test'; + // } + // loadEnvironmentVariables(argv, project.dirPath); }) .command(buildIfNeededCommand) .command(optimizeForDockerBuildCommand) diff --git a/packages/wb/src/project.ts b/packages/wb/src/project.ts index 830e28ed..7db2e00d 100644 --- a/packages/wb/src/project.ts +++ b/packages/wb/src/project.ts @@ -11,7 +11,7 @@ export class Project { private _pathByName = new Map(); constructor(dirPath: string) { - this._dirPath = dirPath; + this._dirPath = path.resolve(dirPath); } @memoizeOne @@ -93,3 +93,46 @@ export class Project { return filePath; } } + +export interface FoundProjects { + root: Project; + self: Project; + all: Project[]; +} + +export function findRootAndSelfProjects(): Omit | undefined { + const dirPath = process.cwd(); + if (!fs.existsSync(path.join(dirPath, 'package.json'))) return; + + const thisProject = new Project(dirPath); + let rootProject = thisProject; + if (!thisProject.packageJson.workspaces && path.dirname(dirPath) === 'packages') { + const rootDirPath = path.resolve(dirPath, '..', '..'); + if (fs.existsSync(path.join(rootDirPath, 'package.json'))) { + rootProject = new Project(rootDirPath); + } + } + return { root: rootProject, self: thisProject }; +} + +export async function findAllProjects(): Promise { + const rootAndSelfProjects = findRootAndSelfProjects(); + if (!rootAndSelfProjects) return; + + return { ...rootAndSelfProjects, all: await getAllProjects(rootAndSelfProjects.root) }; +} + +async function getAllProjects(rootProject: Project): Promise { + const allProjects = [rootProject]; + const packageDirPath = path.join(rootProject.dirPath, 'packages'); + const packageDirs = await fs.promises.readdir(packageDirPath, { withFileTypes: true }); + for (const packageDir of packageDirs) { + if (!packageDir.isDirectory()) continue; + + const packageJsonPath = path.join(packageDirPath, 'package.json'); + if (!fs.existsSync(packageJsonPath)) continue; + + allProjects.push(new Project(packageJsonPath)); + } + return allProjects; +} diff --git a/packages/wb/src/scripts/dockerScripts.ts b/packages/wb/src/scripts/dockerScripts.ts index e475f47e..74506aa7 100644 --- a/packages/wb/src/scripts/dockerScripts.ts +++ b/packages/wb/src/scripts/dockerScripts.ts @@ -1,7 +1,7 @@ import path from 'node:path'; -import { Project } from '../project.js'; -import { spawnSyncOnExit } from '../utils.js'; +import { spawnSyncOnExit } from '../processUtils.js'; +import type { Project } from '../project.js'; /** * A collection of scripts for executing Docker commands. @@ -21,7 +21,11 @@ class DockerScripts { --build-arg WB_VERSION=dev .`; } stopAndStart(project: Project, unbuffer = false, additionalOptions = '', additionalArgs = ''): string { - return `${this.stop(project)} && ${unbuffer ? 'unbuffer ' : ''}${this.start(project, additionalOptions, additionalArgs)}`; + return `${this.stop(project)} && ${unbuffer ? 'unbuffer ' : ''}${this.start( + project, + additionalOptions, + additionalArgs + )}`; } start(project: Project, additionalOptions = '', additionalArgs = ''): string { spawnSyncOnExit(this.stop(project)); diff --git a/packages/wb/src/scripts/execution/baseExecutionScripts.ts b/packages/wb/src/scripts/execution/baseExecutionScripts.ts index 43cf27ad..cc382812 100644 --- a/packages/wb/src/scripts/execution/baseExecutionScripts.ts +++ b/packages/wb/src/scripts/execution/baseExecutionScripts.ts @@ -1,6 +1,6 @@ +import type { Project } from '../../project.js'; import type { ScriptArgv } from '../builder.js'; import { dockerScripts } from '../dockerScripts.js'; -import { Project } from '../../project.js'; export interface TestE2EDevOptions { // '--e2e generate' calls 'codegen http://localhost:8080' diff --git a/packages/wb/src/scripts/execution/blitzScripts.ts b/packages/wb/src/scripts/execution/blitzScripts.ts index 691b3efa..63d37155 100644 --- a/packages/wb/src/scripts/execution/blitzScripts.ts +++ b/packages/wb/src/scripts/execution/blitzScripts.ts @@ -1,4 +1,5 @@ -import { project, Project } from '../../project.js'; +import type { Project } from '../../project.js'; +import { project } from '../../project.js'; import type { ScriptArgv } from '../builder.js'; import { prismaScripts } from '../prismaScripts.js'; diff --git a/packages/wb/src/scripts/execution/httpServerScripts.ts b/packages/wb/src/scripts/execution/httpServerScripts.ts index 3e4bfddb..21a2e9d9 100644 --- a/packages/wb/src/scripts/execution/httpServerScripts.ts +++ b/packages/wb/src/scripts/execution/httpServerScripts.ts @@ -1,4 +1,4 @@ -import { Project } from '../../project.js'; +import type { Project } from '../../project.js'; import type { ScriptArgv } from '../builder.js'; import { dockerScripts } from '../dockerScripts.js'; diff --git a/packages/wb/src/scripts/execution/nextScripts.ts b/packages/wb/src/scripts/execution/nextScripts.ts index 3ed2358b..1aec9dad 100644 --- a/packages/wb/src/scripts/execution/nextScripts.ts +++ b/packages/wb/src/scripts/execution/nextScripts.ts @@ -1,4 +1,4 @@ -import { Project } from '../../project.js'; +import type { Project } from '../../project.js'; import type { ScriptArgv } from '../builder.js'; import { prismaScripts } from '../prismaScripts.js'; diff --git a/packages/wb/src/scripts/execution/plainAppScripts.ts b/packages/wb/src/scripts/execution/plainAppScripts.ts index ab7fda3d..48df8413 100644 --- a/packages/wb/src/scripts/execution/plainAppScripts.ts +++ b/packages/wb/src/scripts/execution/plainAppScripts.ts @@ -1,4 +1,4 @@ -import { Project } from '../../project.js'; +import type { Project } from '../../project.js'; import type { ScriptArgv } from '../builder.js'; import { dockerScripts } from '../dockerScripts.js'; diff --git a/packages/wb/src/scripts/execution/remixScripts.ts b/packages/wb/src/scripts/execution/remixScripts.ts index 41bb32ac..57c48e03 100644 --- a/packages/wb/src/scripts/execution/remixScripts.ts +++ b/packages/wb/src/scripts/execution/remixScripts.ts @@ -1,4 +1,4 @@ -import { Project } from '../../project.js'; +import type { Project } from '../../project.js'; import type { ScriptArgv } from '../builder.js'; import { prismaScripts } from '../prismaScripts.js'; diff --git a/packages/wb/src/scripts/prismaScripts.ts b/packages/wb/src/scripts/prismaScripts.ts index 89fd4d64..6d429380 100644 --- a/packages/wb/src/scripts/prismaScripts.ts +++ b/packages/wb/src/scripts/prismaScripts.ts @@ -1,6 +1,6 @@ import path from 'node:path'; -import { Project } from '../project.js'; +import type { Project } from '../project.js'; /** * A collection of scripts for executing Prisma commands. diff --git a/packages/wb/src/scripts/run.ts b/packages/wb/src/scripts/run.ts index 8e7491fc..9a13ce8f 100644 --- a/packages/wb/src/scripts/run.ts +++ b/packages/wb/src/scripts/run.ts @@ -5,10 +5,10 @@ import { spawnAsync } from '@willbooster/shared-lib-node/src'; import chalk from 'chalk'; import type { ArgumentsCamelCase, InferredOptionTypes } from 'yargs'; +import { killPortProcessImmediatelyAndOnExit } from '../processUtils.js'; import { project } from '../project.js'; import { promisePool } from '../promisePool.js'; import type { sharedOptionsBuilder } from '../sharedOptionsBuilder.js'; -import { killPortProcessImmediatelyAndOnExit } from '../utils.js'; interface Options { exitIfFailed?: boolean; diff --git a/packages/wb/src/utils.ts b/packages/wb/src/utils.ts deleted file mode 100644 index 40fb8007..00000000 --- a/packages/wb/src/utils.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { spawnSync } from 'node:child_process'; - -import killPortProcess from 'kill-port'; - -import { printFinishedAndExitIfNeeded, printStart } from './scripts/run.js'; -import { Project } from './project.js'; - -const killed = new Set(); - -export async function killPortProcessImmediatelyAndOnExit(port: number): Promise { - await killPortProcessHandlingErrors(port); - const killFunc = async (): Promise => { - if (killed.has(port)) return; - - killed.add(port); - await killPortProcessHandlingErrors(port); - }; - for (const signal of ['beforeExit', 'SIGINT', 'SIGTERM', 'SIGQUIT']) { - process.on(signal, killFunc); - } -} - -async function killPortProcessHandlingErrors(port: number): Promise { - try { - await killPortProcess(port); - } catch { - // do nothing - } -} - -export function spawnSyncOnExit(project: Project, command: string): void { - const killFunc = async (): Promise => { - if (killed.has(command)) return; - - killed.add(command); - printStart(command); - const { status } = spawnSync(command, { cwd: project.dirPath, shell: true, stdio: 'inherit' }); - printFinishedAndExitIfNeeded(command, status, {}); - }; - for (const signal of ['beforeExit', 'SIGINT', 'SIGTERM', 'SIGQUIT']) { - process.on(signal, killFunc); - } -} diff --git a/yarn.lock b/yarn.lock index 98eae093..aa791f6c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2578,7 +2578,19 @@ __metadata: languageName: node linkType: hard -"@mdx-js/react@npm:2.3.0, @mdx-js/react@npm:^2.1.5": +"@mdx-js/react@npm:3.0.0": + version: 3.0.0 + resolution: "@mdx-js/react@npm:3.0.0" + dependencies: + "@types/mdx": "npm:^2.0.0" + peerDependencies: + "@types/react": ">=16" + react: ">=16" + checksum: 865f6ebc7ae83c6cb9f7e92db4eddd3f85cd1664391643b4736887ddc32b0ddb5aec012db6fbc9b486b552e08e6d5ad800450fcd9d51c20665667ff0f174d966 + languageName: node + linkType: hard + +"@mdx-js/react@npm:^2.1.5": version: 2.3.0 resolution: "@mdx-js/react@npm:2.3.0" dependencies: @@ -6274,15 +6286,15 @@ __metadata: languageName: node linkType: hard -"@willbooster/eslint-config-ts-react@npm:10.1.7": - version: 10.1.7 - resolution: "@willbooster/eslint-config-ts-react@npm:10.1.7" +"@willbooster/eslint-config-ts-react@npm:10.1.9": + version: 10.1.9 + resolution: "@willbooster/eslint-config-ts-react@npm:10.1.9" dependencies: - "@willbooster/eslint-config-ts": "npm:10.5.0" + "@willbooster/eslint-config-ts": "npm:10.5.1" peerDependencies: "@typescript-eslint/eslint-plugin": ">=5" "@typescript-eslint/parser": ">=5" - "@willbooster/prettier-config": 9.1.1 + "@willbooster/prettier-config": 9.1.2 eslint: ">=8" eslint-config-prettier: ">=8" eslint-import-resolver-typescript: ">=2" @@ -6292,17 +6304,17 @@ __metadata: eslint-plugin-sort-class-members: ">=1.14" eslint-plugin-sort-destructure-keys: ">=1.4" typescript: ">=4" - checksum: 690c19491ad1b32ab8afdda2fb11ecab644d37d53ff3bb4d45569ab268fd1fb771bdd63cdf4c63407076e5967c95fcc3dcf4b1ac35aed7532276abaa058acea7 + checksum: 04fdc77d172fd95d958751d971752a67dc5a256c9cc7a0633187dd995c0f056a229db7c0e06008621afa2a307b179049ff5e77eb98a59222d1508252e6b8c85d languageName: node linkType: hard -"@willbooster/eslint-config-ts@npm:10.5.0": - version: 10.5.0 - resolution: "@willbooster/eslint-config-ts@npm:10.5.0" +"@willbooster/eslint-config-ts@npm:10.5.1": + version: 10.5.1 + resolution: "@willbooster/eslint-config-ts@npm:10.5.1" peerDependencies: "@typescript-eslint/eslint-plugin": ">=5" "@typescript-eslint/parser": ">=5" - "@willbooster/prettier-config": 9.1.1 + "@willbooster/prettier-config": 9.1.2 eslint: ">=8" eslint-config-prettier: ">=8" eslint-import-resolver-typescript: ">=2" @@ -6310,16 +6322,16 @@ __metadata: eslint-plugin-sort-class-members: ">=1.14" eslint-plugin-sort-destructure-keys: ">=1.4" typescript: ">=4" - checksum: a4b861ae04d5a73223e7c948492774b048b85410ad0957ecc3b795980efe94f10d8426197c8a6dc85baf872a9faae4c60c167ea2381f1bf054ee83561e158276 + checksum: abf880f446eaeab3cff1c63d34f3018737717d00b8a4d3524e6406f48db0d8b96287e425aef9c8328b6cb19e3ba2170d45ba208bc38acd5f97a72160faa84bbd languageName: node linkType: hard -"@willbooster/prettier-config@npm:9.1.1": - version: 9.1.1 - resolution: "@willbooster/prettier-config@npm:9.1.1" +"@willbooster/prettier-config@npm:9.1.2": + version: 9.1.2 + resolution: "@willbooster/prettier-config@npm:9.1.2" peerDependencies: prettier: ">=2" - checksum: 28e8237e9c7d180e723ea10e7a9710c318320b8fada694d6b15d8baa867339f4236f28e6c5254fc12a3725264e399ca7e3e43b94b043eff608c262693d8aab42 + checksum: 814c5ca454f809f391b1884a9243764aaa3bd2d2ccbc853be925bf7d1cb395c0d2a5df9165eb2239cf72fa19b56b22597d375221674c229da6ffcc55cdcdc9dc languageName: node linkType: hard @@ -6331,8 +6343,8 @@ __metadata: "@types/micromatch": "npm:4.0.4" "@typescript-eslint/eslint-plugin": "npm:6.9.0" "@typescript-eslint/parser": "npm:6.9.0" - "@willbooster/eslint-config-ts": "npm:10.5.0" - "@willbooster/prettier-config": "npm:9.1.1" + "@willbooster/eslint-config-ts": "npm:10.5.1" + "@willbooster/prettier-config": "npm:9.1.2" blitz: "npm:2.0.0-beta.34" build-ts: "npm:11.0.5" eslint: "npm:8.52.0" @@ -6370,8 +6382,8 @@ __metadata: "@types/node": "npm:20.8.8" "@typescript-eslint/eslint-plugin": "npm:6.9.0" "@typescript-eslint/parser": "npm:6.9.0" - "@willbooster/eslint-config-ts": "npm:10.5.0" - "@willbooster/prettier-config": "npm:9.1.1" + "@willbooster/eslint-config-ts": "npm:10.5.1" + "@willbooster/prettier-config": "npm:9.1.2" build-ts: "npm:11.0.5" dotenv: "npm:16.3.1" eslint: "npm:8.52.0" @@ -6396,7 +6408,7 @@ __metadata: resolution: "@willbooster/shared-lib-react@workspace:packages/shared-lib-react" dependencies: "@babel/core": "npm:7.23.2" - "@mdx-js/react": "npm:2.3.0" + "@mdx-js/react": "npm:3.0.0" "@storybook/addon-actions": "npm:7.5.1" "@storybook/addon-docs": "npm:7.5.1" "@storybook/addon-essentials": "npm:7.5.1" @@ -6412,8 +6424,8 @@ __metadata: "@types/react-dom": "npm:18.2.14" "@typescript-eslint/eslint-plugin": "npm:6.9.0" "@typescript-eslint/parser": "npm:6.9.0" - "@willbooster/eslint-config-ts-react": "npm:10.1.7" - "@willbooster/prettier-config": "npm:9.1.1" + "@willbooster/eslint-config-ts-react": "npm:10.1.9" + "@willbooster/prettier-config": "npm:9.1.2" babel-loader: "npm:9.1.3" build-ts: "npm:11.0.5" eslint: "npm:8.52.0" @@ -6448,8 +6460,8 @@ __metadata: "@types/micromatch": "npm:4.0.4" "@typescript-eslint/eslint-plugin": "npm:6.9.0" "@typescript-eslint/parser": "npm:6.9.0" - "@willbooster/eslint-config-ts": "npm:10.5.0" - "@willbooster/prettier-config": "npm:9.1.1" + "@willbooster/eslint-config-ts": "npm:10.5.1" + "@willbooster/prettier-config": "npm:9.1.2" build-ts: "npm:11.0.5" eslint: "npm:8.52.0" eslint-config-prettier: "npm:9.0.0" @@ -6478,8 +6490,8 @@ __metadata: "@types/yargs": "npm:17.0.29" "@typescript-eslint/eslint-plugin": "npm:6.9.0" "@typescript-eslint/parser": "npm:6.9.0" - "@willbooster/eslint-config-ts": "npm:10.5.0" - "@willbooster/prettier-config": "npm:9.1.1" + "@willbooster/eslint-config-ts": "npm:10.5.1" + "@willbooster/prettier-config": "npm:9.1.2" at-decorators: "npm:1.2.0" build-ts: "npm:11.0.5" chalk: "npm:5.3.0" @@ -20965,7 +20977,7 @@ __metadata: "@qiwi/multi-semantic-release": "npm:7.1.1" "@types/eslint": "npm:8.44.6" "@typescript-eslint/parser": "npm:6.9.0" - "@willbooster/prettier-config": "npm:9.1.1" + "@willbooster/prettier-config": "npm:9.1.2" conventional-changelog-conventionalcommits: "npm:6.1.0" eslint: "npm:8.52.0" husky: "npm:8.0.3" From 74e597c35f2257a1b2c1fdb63a0aeab4ccf82a17 Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Thu, 26 Oct 2023 18:06:52 +0900 Subject: [PATCH 03/21] . --- packages/wb/src/commands/commandUtils.ts | 29 ++++++++++++++++ packages/wb/src/processUtils.ts | 43 ++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 packages/wb/src/commands/commandUtils.ts create mode 100644 packages/wb/src/processUtils.ts diff --git a/packages/wb/src/commands/commandUtils.ts b/packages/wb/src/commands/commandUtils.ts new file mode 100644 index 00000000..941485ee --- /dev/null +++ b/packages/wb/src/commands/commandUtils.ts @@ -0,0 +1,29 @@ +import { loadEnvironmentVariables, restoreEnvironmentVariables } from '@willbooster/shared-lib-node/src'; +import type { ArgumentsCamelCase, InferredOptionTypes } from 'yargs'; + +import type { Project } from '../project.js'; +import type { sharedOptionsBuilder } from '../sharedOptionsBuilder.js'; + +export function* prepareForRunningCommand( + commandName: string, + rootProject: Project, + projects: Project[], + argv: Partial>>, + loadingEnvironmentVariables = true +): Generator { + for (const project of projects) { + console.info(`Running "${commandName}" for ${project.name} ...`); + + if (project !== rootProject) { + restoreEnvironmentVariables(); + } + if (loadingEnvironmentVariables) { + loadEnvironmentVariables(argv, project.dirPath); + if (project !== rootProject) { + loadEnvironmentVariables(argv, rootProject.dirPath); + } + } + + yield project; + } +} diff --git a/packages/wb/src/processUtils.ts b/packages/wb/src/processUtils.ts new file mode 100644 index 00000000..600f72d8 --- /dev/null +++ b/packages/wb/src/processUtils.ts @@ -0,0 +1,43 @@ +import { spawnSync } from 'node:child_process'; + +import killPortProcess from 'kill-port'; + +import type { Project } from './project.js'; +import { printFinishedAndExitIfNeeded, printStart } from './scripts/run.js'; + +const killed = new Set(); + +export async function killPortProcessImmediatelyAndOnExit(port: number): Promise { + await killPortProcessHandlingErrors(port); + const killFunc = async (): Promise => { + if (killed.has(port)) return; + + killed.add(port); + await killPortProcessHandlingErrors(port); + }; + for (const signal of ['beforeExit', 'SIGINT', 'SIGTERM', 'SIGQUIT']) { + process.on(signal, killFunc); + } +} + +async function killPortProcessHandlingErrors(port: number): Promise { + try { + await killPortProcess(port); + } catch { + // do nothing + } +} + +export function spawnSyncOnExit(project: Project, command: string): void { + const killFunc = async (): Promise => { + if (killed.has(command)) return; + + killed.add(command); + printStart(command); + const { status } = spawnSync(command, { cwd: project.dirPath, shell: true, stdio: 'inherit' }); + printFinishedAndExitIfNeeded(command, status, {}); + }; + for (const signal of ['beforeExit', 'SIGINT', 'SIGTERM', 'SIGQUIT']) { + process.on(signal, killFunc); + } +} From 087bdee072b7dbad4fe1984510c08b3506a2042e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 16:41:03 +0000 Subject: [PATCH 04/21] fix(deps): update all non-major dependencies (#192) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/shared-lib-node/package.json | 2 +- packages/shared-lib-react/package.json | 2 +- packages/wb/package.json | 4 +- packages/wb/test-fixtures/blitz/package.json | 8 +-- yarn.lock | 53 ++++++++++++++------ 5 files changed, 47 insertions(+), 22 deletions(-) diff --git a/packages/shared-lib-node/package.json b/packages/shared-lib-node/package.json index 8e1f9390..d2969bfa 100644 --- a/packages/shared-lib-node/package.json +++ b/packages/shared-lib-node/package.json @@ -42,7 +42,7 @@ "devDependencies": { "@types/eslint": "8.44.6", "@types/micromatch": "4.0.4", - "@types/node": "20.8.8", + "@types/node": "20.8.9", "@typescript-eslint/eslint-plugin": "6.9.0", "@typescript-eslint/parser": "6.9.0", "@willbooster/eslint-config-ts": "10.5.1", diff --git a/packages/shared-lib-react/package.json b/packages/shared-lib-react/package.json index e9183870..fe130133 100644 --- a/packages/shared-lib-react/package.json +++ b/packages/shared-lib-react/package.json @@ -46,7 +46,7 @@ "@storybook/testing-library": "0.2.2", "@types/eslint": "8.44.6", "@types/micromatch": "4.0.4", - "@types/react": "18.2.31", + "@types/react": "18.2.33", "@types/react-dom": "18.2.14", "@typescript-eslint/eslint-plugin": "6.9.0", "@typescript-eslint/parser": "6.9.0", diff --git a/packages/wb/package.json b/packages/wb/package.json index 793e2882..356eae84 100644 --- a/packages/wb/package.json +++ b/packages/wb/package.json @@ -34,7 +34,7 @@ "@types/eslint": "8.44.6", "@types/kill-port": "2.0.2", "@types/micromatch": "4.0.4", - "@types/node": "20.8.8", + "@types/node": "20.8.9", "@types/yargs": "17.0.29", "@typescript-eslint/eslint-plugin": "6.9.0", "@typescript-eslint/parser": "6.9.0", @@ -52,7 +52,7 @@ "micromatch": "4.0.5", "prettier": "3.0.3", "sort-package-json": "2.6.0", - "type-fest": "4.5.0", + "type-fest": "4.6.0", "typescript": "5.2.2", "vitest": "0.34.6", "yargs": "17.7.2" diff --git a/packages/wb/test-fixtures/blitz/package.json b/packages/wb/test-fixtures/blitz/package.json index 2db17771..b1fa8cf9 100644 --- a/packages/wb/test-fixtures/blitz/package.json +++ b/packages/wb/test-fixtures/blitz/package.json @@ -14,16 +14,16 @@ "dependencies": { "@blitzjs/auth": "2.0.0-beta.34", "@blitzjs/next": "2.0.0-beta.34", - "@prisma/client": "5.4.2", + "@prisma/client": "5.5.2", "blitz": "2.0.0-beta.34", "next": "13.5.6", - "prisma": "5.4.2", + "prisma": "5.5.2", "react": "18.2.0", "react-dom": "18.2.0" }, "devDependencies": { - "@types/node": "18.18.6", - "@types/react": "18.2.31", + "@types/node": "18.18.7", + "@types/react": "18.2.33", "typescript": "5.2.2" } } diff --git a/yarn.lock b/yarn.lock index aa791f6c..59120607 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5593,12 +5593,12 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:20.8.8": - version: 20.8.8 - resolution: "@types/node@npm:20.8.8" +"@types/node@npm:20.8.9": + version: 20.8.9 + resolution: "@types/node@npm:20.8.9" dependencies: - undici-types: "npm:~5.25.1" - checksum: 739b3d6f4aa760d72373d504d91adec86ac2eab502f68a80214711983e7d1886fd276ade78a276a2affe4942a55ad65cf655c3aa9464d1150f6405445c5ba635 + undici-types: "npm:~5.26.4" + checksum: 6fb5604ac087c8be9aeb9ee1413fae2e691c603c9a691bd722e113597b883f21e8380a44d114ab894b435a491bfc939c8478cd57bcf890c585b961343b124964 languageName: node linkType: hard @@ -5690,7 +5690,7 @@ __metadata: languageName: node linkType: hard -"@types/react@npm:*, @types/react@npm:18.2.31, @types/react@npm:>=16": +"@types/react@npm:*, @types/react@npm:>=16": version: 18.2.31 resolution: "@types/react@npm:18.2.31" dependencies: @@ -5701,6 +5701,17 @@ __metadata: languageName: node linkType: hard +"@types/react@npm:18.2.33": + version: 18.2.33 + resolution: "@types/react@npm:18.2.33" + dependencies: + "@types/prop-types": "npm:*" + "@types/scheduler": "npm:*" + csstype: "npm:^3.0.2" + checksum: d3392785660d78121541403a5d1da57dc79e8ce402769251a626aa06a6886a6aaead868a01ee473661380ddd4ac79743de78853d69f652544da191d435f78afb + languageName: node + linkType: hard + "@types/resolve@npm:1.20.2": version: 1.20.2 resolution: "@types/resolve@npm:1.20.2" @@ -6379,7 +6390,7 @@ __metadata: dependencies: "@types/eslint": "npm:8.44.6" "@types/micromatch": "npm:4.0.4" - "@types/node": "npm:20.8.8" + "@types/node": "npm:20.8.9" "@typescript-eslint/eslint-plugin": "npm:6.9.0" "@typescript-eslint/parser": "npm:6.9.0" "@willbooster/eslint-config-ts": "npm:10.5.1" @@ -6420,7 +6431,7 @@ __metadata: "@storybook/testing-library": "npm:0.2.2" "@types/eslint": "npm:8.44.6" "@types/micromatch": "npm:4.0.4" - "@types/react": "npm:18.2.31" + "@types/react": "npm:18.2.33" "@types/react-dom": "npm:18.2.14" "@typescript-eslint/eslint-plugin": "npm:6.9.0" "@typescript-eslint/parser": "npm:6.9.0" @@ -6486,7 +6497,7 @@ __metadata: "@types/eslint": "npm:8.44.6" "@types/kill-port": "npm:2.0.2" "@types/micromatch": "npm:4.0.4" - "@types/node": "npm:20.8.8" + "@types/node": "npm:20.8.9" "@types/yargs": "npm:17.0.29" "@typescript-eslint/eslint-plugin": "npm:6.9.0" "@typescript-eslint/parser": "npm:6.9.0" @@ -6510,7 +6521,7 @@ __metadata: prettier: "npm:3.0.3" sort-package-json: "npm:2.6.0" tree-kill: "npm:1.2.2" - type-fest: "npm:4.5.0" + type-fest: "npm:4.6.0" typescript: "npm:5.2.2" vitest: "npm:0.34.6" yargs: "npm:17.7.2" @@ -19876,10 +19887,10 @@ __metadata: languageName: node linkType: hard -"type-fest@npm:4.5.0, type-fest@npm:^4.2.0": - version: 4.5.0 - resolution: "type-fest@npm:4.5.0" - checksum: 8f45700dcfbdd03f2882a9e47e5ef21b8f879c4731633ed5ed43f4887b866d936ff27af0999afaa486a5683c03a45bd25bcf4d021ad9ac2486899867bfec91e3 +"type-fest@npm:4.6.0": + version: 4.6.0 + resolution: "type-fest@npm:4.6.0" + checksum: 6f34c3cdb95948821fdfc5a70481791de99b2ba840fad87ac3fbdf77941e556eaeaa03c2ed136b366436560702004af7687d59b03d4f181c28289db1af903179 languageName: node linkType: hard @@ -19953,6 +19964,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^4.2.0": + version: 4.5.0 + resolution: "type-fest@npm:4.5.0" + checksum: 8f45700dcfbdd03f2882a9e47e5ef21b8f879c4731633ed5ed43f4887b866d936ff27af0999afaa486a5683c03a45bd25bcf4d021ad9ac2486899867bfec91e3 + languageName: node + linkType: hard + "type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" @@ -20079,6 +20097,13 @@ __metadata: languageName: node linkType: hard +"undici-types@npm:~5.26.4": + version: 5.26.5 + resolution: "undici-types@npm:5.26.5" + checksum: bb673d7876c2d411b6eb6c560e0c571eef4a01c1c19925175d16e3a30c4c428181fb8d7ae802a261f283e4166a0ac435e2f505743aa9e45d893f9a3df017b501 + languageName: node + linkType: hard + "unfetch@npm:^4.2.0": version: 4.2.0 resolution: "unfetch@npm:4.2.0" From bc2e251303adbc95ad6d9221ec873fc0b30943d5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 20:03:51 +0000 Subject: [PATCH 05/21] chore(deps): update dependency build-ts to v11.0.6 (#194) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/shared-lib-blitz-next/package.json | 2 +- packages/shared-lib-node/package.json | 2 +- packages/shared-lib-react/package.json | 2 +- packages/shared-lib/package.json | 2 +- packages/wb/package.json | 2 +- yarn.lock | 18 +++++++++--------- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/shared-lib-blitz-next/package.json b/packages/shared-lib-blitz-next/package.json index 40d0999e..eac0f21e 100644 --- a/packages/shared-lib-blitz-next/package.json +++ b/packages/shared-lib-blitz-next/package.json @@ -43,7 +43,7 @@ "@willbooster/eslint-config-ts": "10.5.1", "@willbooster/prettier-config": "9.1.2", "blitz": "2.0.0-beta.34", - "build-ts": "11.0.5", + "build-ts": "11.0.6", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/shared-lib-node/package.json b/packages/shared-lib-node/package.json index d2969bfa..33771698 100644 --- a/packages/shared-lib-node/package.json +++ b/packages/shared-lib-node/package.json @@ -47,7 +47,7 @@ "@typescript-eslint/parser": "6.9.0", "@willbooster/eslint-config-ts": "10.5.1", "@willbooster/prettier-config": "9.1.2", - "build-ts": "11.0.5", + "build-ts": "11.0.6", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/shared-lib-react/package.json b/packages/shared-lib-react/package.json index fe130133..bde9ea43 100644 --- a/packages/shared-lib-react/package.json +++ b/packages/shared-lib-react/package.json @@ -53,7 +53,7 @@ "@willbooster/eslint-config-ts-react": "10.1.9", "@willbooster/prettier-config": "9.1.2", "babel-loader": "9.1.3", - "build-ts": "11.0.5", + "build-ts": "11.0.6", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/shared-lib/package.json b/packages/shared-lib/package.json index 0164c609..98d2434a 100644 --- a/packages/shared-lib/package.json +++ b/packages/shared-lib/package.json @@ -42,7 +42,7 @@ "@typescript-eslint/parser": "6.9.0", "@willbooster/eslint-config-ts": "10.5.1", "@willbooster/prettier-config": "9.1.2", - "build-ts": "11.0.5", + "build-ts": "11.0.6", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/wb/package.json b/packages/wb/package.json index 356eae84..9f3e8a2e 100644 --- a/packages/wb/package.json +++ b/packages/wb/package.json @@ -40,7 +40,7 @@ "@typescript-eslint/parser": "6.9.0", "@willbooster/eslint-config-ts": "10.5.1", "@willbooster/prettier-config": "9.1.2", - "build-ts": "11.0.5", + "build-ts": "11.0.6", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/yarn.lock b/yarn.lock index 59120607..c58aa04d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6357,7 +6357,7 @@ __metadata: "@willbooster/eslint-config-ts": "npm:10.5.1" "@willbooster/prettier-config": "npm:9.1.2" blitz: "npm:2.0.0-beta.34" - build-ts: "npm:11.0.5" + build-ts: "npm:11.0.6" eslint: "npm:8.52.0" eslint-config-prettier: "npm:9.0.0" eslint-import-resolver-typescript: "npm:3.6.1" @@ -6395,7 +6395,7 @@ __metadata: "@typescript-eslint/parser": "npm:6.9.0" "@willbooster/eslint-config-ts": "npm:10.5.1" "@willbooster/prettier-config": "npm:9.1.2" - build-ts: "npm:11.0.5" + build-ts: "npm:11.0.6" dotenv: "npm:16.3.1" eslint: "npm:8.52.0" eslint-config-prettier: "npm:9.0.0" @@ -6438,7 +6438,7 @@ __metadata: "@willbooster/eslint-config-ts-react": "npm:10.1.9" "@willbooster/prettier-config": "npm:9.1.2" babel-loader: "npm:9.1.3" - build-ts: "npm:11.0.5" + build-ts: "npm:11.0.6" eslint: "npm:8.52.0" eslint-config-prettier: "npm:9.0.0" eslint-import-resolver-typescript: "npm:3.6.1" @@ -6473,7 +6473,7 @@ __metadata: "@typescript-eslint/parser": "npm:6.9.0" "@willbooster/eslint-config-ts": "npm:10.5.1" "@willbooster/prettier-config": "npm:9.1.2" - build-ts: "npm:11.0.5" + build-ts: "npm:11.0.6" eslint: "npm:8.52.0" eslint-config-prettier: "npm:9.0.0" eslint-import-resolver-typescript: "npm:3.6.1" @@ -6504,7 +6504,7 @@ __metadata: "@willbooster/eslint-config-ts": "npm:10.5.1" "@willbooster/prettier-config": "npm:9.1.2" at-decorators: "npm:1.2.0" - build-ts: "npm:11.0.5" + build-ts: "npm:11.0.6" chalk: "npm:5.3.0" dotenv: "npm:16.3.1" eslint: "npm:8.52.0" @@ -7967,9 +7967,9 @@ __metadata: languageName: node linkType: hard -"build-ts@npm:11.0.5": - version: 11.0.5 - resolution: "build-ts@npm:11.0.5" +"build-ts@npm:11.0.6": + version: 11.0.6 + resolution: "build-ts@npm:11.0.6" dependencies: "@babel/core": "npm:7.23.2" "@babel/plugin-proposal-decorators": "npm:7.23.2" @@ -8006,7 +8006,7 @@ __metadata: yargs: "npm:17.7.2" bin: build-ts: bin/index.js - checksum: 00774fbe7569cccc84f14cfe9779e45d0f9ddca8b1a7419593571238dc0efee7063fffe2dd7f83a7931b3734f5f827c98b50470688aff70cb2747bd5c03b60cb + checksum: dad4c6f67a709c267c79f0333c05cda50f9cce53e3e3091f8067dac5409503a3c94f477f65618bc23de8e23ba7f836fa1cfbadd0feccec22b1aec0d4f8674735 languageName: node linkType: hard From f52432e730b576d64df538934b8bd84e81f4bfbf Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 20:04:11 +0000 Subject: [PATCH 06/21] chore(deps): update dependency @types/node to v20 (#195) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- packages/wb/test-fixtures/blitz/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wb/test-fixtures/blitz/package.json b/packages/wb/test-fixtures/blitz/package.json index b1fa8cf9..63c09e1f 100644 --- a/packages/wb/test-fixtures/blitz/package.json +++ b/packages/wb/test-fixtures/blitz/package.json @@ -22,7 +22,7 @@ "react-dom": "18.2.0" }, "devDependencies": { - "@types/node": "18.18.7", + "@types/node": "20.8.9", "@types/react": "18.2.33", "typescript": "5.2.2" } From 3d12803b2cc3572359d9aa000b5d38881333f9ba Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Sat, 28 Oct 2023 22:01:30 +0900 Subject: [PATCH 07/21] . --- packages/shared-lib-blitz-next/package.json | 2 +- packages/shared-lib-node/package.json | 2 +- packages/shared-lib-react/package.json | 2 +- packages/shared-lib/package.json | 2 +- packages/wb/package.json | 2 +- yarn.lock | 18 +++++++++--------- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/shared-lib-blitz-next/package.json b/packages/shared-lib-blitz-next/package.json index eac0f21e..17674f8d 100644 --- a/packages/shared-lib-blitz-next/package.json +++ b/packages/shared-lib-blitz-next/package.json @@ -43,7 +43,7 @@ "@willbooster/eslint-config-ts": "10.5.1", "@willbooster/prettier-config": "9.1.2", "blitz": "2.0.0-beta.34", - "build-ts": "11.0.6", + "build-ts": "11.0.8", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/shared-lib-node/package.json b/packages/shared-lib-node/package.json index 33771698..afee315d 100644 --- a/packages/shared-lib-node/package.json +++ b/packages/shared-lib-node/package.json @@ -47,7 +47,7 @@ "@typescript-eslint/parser": "6.9.0", "@willbooster/eslint-config-ts": "10.5.1", "@willbooster/prettier-config": "9.1.2", - "build-ts": "11.0.6", + "build-ts": "11.0.8", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/shared-lib-react/package.json b/packages/shared-lib-react/package.json index bde9ea43..68d814f6 100644 --- a/packages/shared-lib-react/package.json +++ b/packages/shared-lib-react/package.json @@ -53,7 +53,7 @@ "@willbooster/eslint-config-ts-react": "10.1.9", "@willbooster/prettier-config": "9.1.2", "babel-loader": "9.1.3", - "build-ts": "11.0.6", + "build-ts": "11.0.8", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/shared-lib/package.json b/packages/shared-lib/package.json index 98d2434a..28ac0ec7 100644 --- a/packages/shared-lib/package.json +++ b/packages/shared-lib/package.json @@ -42,7 +42,7 @@ "@typescript-eslint/parser": "6.9.0", "@willbooster/eslint-config-ts": "10.5.1", "@willbooster/prettier-config": "9.1.2", - "build-ts": "11.0.6", + "build-ts": "11.0.8", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/wb/package.json b/packages/wb/package.json index 9f3e8a2e..13e3b725 100644 --- a/packages/wb/package.json +++ b/packages/wb/package.json @@ -40,7 +40,7 @@ "@typescript-eslint/parser": "6.9.0", "@willbooster/eslint-config-ts": "10.5.1", "@willbooster/prettier-config": "9.1.2", - "build-ts": "11.0.6", + "build-ts": "11.0.8", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/yarn.lock b/yarn.lock index c58aa04d..d2f83573 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6357,7 +6357,7 @@ __metadata: "@willbooster/eslint-config-ts": "npm:10.5.1" "@willbooster/prettier-config": "npm:9.1.2" blitz: "npm:2.0.0-beta.34" - build-ts: "npm:11.0.6" + build-ts: "npm:11.0.8" eslint: "npm:8.52.0" eslint-config-prettier: "npm:9.0.0" eslint-import-resolver-typescript: "npm:3.6.1" @@ -6395,7 +6395,7 @@ __metadata: "@typescript-eslint/parser": "npm:6.9.0" "@willbooster/eslint-config-ts": "npm:10.5.1" "@willbooster/prettier-config": "npm:9.1.2" - build-ts: "npm:11.0.6" + build-ts: "npm:11.0.8" dotenv: "npm:16.3.1" eslint: "npm:8.52.0" eslint-config-prettier: "npm:9.0.0" @@ -6438,7 +6438,7 @@ __metadata: "@willbooster/eslint-config-ts-react": "npm:10.1.9" "@willbooster/prettier-config": "npm:9.1.2" babel-loader: "npm:9.1.3" - build-ts: "npm:11.0.6" + build-ts: "npm:11.0.8" eslint: "npm:8.52.0" eslint-config-prettier: "npm:9.0.0" eslint-import-resolver-typescript: "npm:3.6.1" @@ -6473,7 +6473,7 @@ __metadata: "@typescript-eslint/parser": "npm:6.9.0" "@willbooster/eslint-config-ts": "npm:10.5.1" "@willbooster/prettier-config": "npm:9.1.2" - build-ts: "npm:11.0.6" + build-ts: "npm:11.0.8" eslint: "npm:8.52.0" eslint-config-prettier: "npm:9.0.0" eslint-import-resolver-typescript: "npm:3.6.1" @@ -6504,7 +6504,7 @@ __metadata: "@willbooster/eslint-config-ts": "npm:10.5.1" "@willbooster/prettier-config": "npm:9.1.2" at-decorators: "npm:1.2.0" - build-ts: "npm:11.0.6" + build-ts: "npm:11.0.8" chalk: "npm:5.3.0" dotenv: "npm:16.3.1" eslint: "npm:8.52.0" @@ -7967,9 +7967,9 @@ __metadata: languageName: node linkType: hard -"build-ts@npm:11.0.6": - version: 11.0.6 - resolution: "build-ts@npm:11.0.6" +"build-ts@npm:11.0.8": + version: 11.0.8 + resolution: "build-ts@npm:11.0.8" dependencies: "@babel/core": "npm:7.23.2" "@babel/plugin-proposal-decorators": "npm:7.23.2" @@ -8006,7 +8006,7 @@ __metadata: yargs: "npm:17.7.2" bin: build-ts: bin/index.js - checksum: dad4c6f67a709c267c79f0333c05cda50f9cce53e3e3091f8067dac5409503a3c94f477f65618bc23de8e23ba7f836fa1cfbadd0feccec22b1aec0d4f8674735 + checksum: f5ae1efe8d8f8c558e3fd6fff16c6732024b5eb25e94a73f02f8b10102268d104ccfe7762ee0496902add2faf5296bbf3dd76ebf0e46f1ebbc4c3a8338681204 languageName: node linkType: hard From f2df03bb85a1f9eff41a4448ec0604653846176c Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Mon, 30 Oct 2023 12:23:53 +0900 Subject: [PATCH 08/21] . --- packages/shared-lib-blitz-next/package.json | 2 +- packages/shared-lib-node/package.json | 2 +- packages/shared-lib-react/package.json | 2 +- packages/shared-lib/package.json | 2 +- packages/wb/package.json | 2 +- yarn.lock | 25 ++++++++++----------- 6 files changed, 17 insertions(+), 18 deletions(-) diff --git a/packages/shared-lib-blitz-next/package.json b/packages/shared-lib-blitz-next/package.json index 17674f8d..25dddd70 100644 --- a/packages/shared-lib-blitz-next/package.json +++ b/packages/shared-lib-blitz-next/package.json @@ -50,7 +50,7 @@ "eslint-plugin-import": "2.29.0", "eslint-plugin-sort-class-members": "1.19.0", "eslint-plugin-sort-destructure-keys": "1.5.0", - "eslint-plugin-unicorn": "48.0.1", + "eslint-plugin-unicorn": "49.0.0", "lint-staged": "15.0.2", "micromatch": "4.0.5", "prettier": "3.0.3", diff --git a/packages/shared-lib-node/package.json b/packages/shared-lib-node/package.json index afee315d..bb418769 100644 --- a/packages/shared-lib-node/package.json +++ b/packages/shared-lib-node/package.json @@ -54,7 +54,7 @@ "eslint-plugin-import": "2.29.0", "eslint-plugin-sort-class-members": "1.19.0", "eslint-plugin-sort-destructure-keys": "1.5.0", - "eslint-plugin-unicorn": "48.0.1", + "eslint-plugin-unicorn": "49.0.0", "lint-staged": "15.0.2", "micromatch": "4.0.5", "prettier": "3.0.3", diff --git a/packages/shared-lib-react/package.json b/packages/shared-lib-react/package.json index 68d814f6..2f88c2ba 100644 --- a/packages/shared-lib-react/package.json +++ b/packages/shared-lib-react/package.json @@ -63,7 +63,7 @@ "eslint-plugin-sort-class-members": "1.19.0", "eslint-plugin-sort-destructure-keys": "1.5.0", "eslint-plugin-storybook": "0.6.15", - "eslint-plugin-unicorn": "48.0.1", + "eslint-plugin-unicorn": "49.0.0", "lint-staged": "15.0.2", "micromatch": "4.0.5", "prettier": "3.0.3", diff --git a/packages/shared-lib/package.json b/packages/shared-lib/package.json index 28ac0ec7..43dfef7f 100644 --- a/packages/shared-lib/package.json +++ b/packages/shared-lib/package.json @@ -49,7 +49,7 @@ "eslint-plugin-import": "2.29.0", "eslint-plugin-sort-class-members": "1.19.0", "eslint-plugin-sort-destructure-keys": "1.5.0", - "eslint-plugin-unicorn": "48.0.1", + "eslint-plugin-unicorn": "49.0.0", "lint-staged": "15.0.2", "micromatch": "4.0.5", "prettier": "3.0.3", diff --git a/packages/wb/package.json b/packages/wb/package.json index 13e3b725..6958c413 100644 --- a/packages/wb/package.json +++ b/packages/wb/package.json @@ -47,7 +47,7 @@ "eslint-plugin-import": "2.29.0", "eslint-plugin-sort-class-members": "1.19.0", "eslint-plugin-sort-destructure-keys": "1.5.0", - "eslint-plugin-unicorn": "48.0.1", + "eslint-plugin-unicorn": "49.0.0", "lint-staged": "15.0.2", "micromatch": "4.0.5", "prettier": "3.0.3", diff --git a/yarn.lock b/yarn.lock index 6ba0bc87..b3afad07 100644 --- a/yarn.lock +++ b/yarn.lock @@ -328,7 +328,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.10.4, @babel/helper-validator-identifier@npm:^7.22.20, @babel/helper-validator-identifier@npm:^7.22.5": +"@babel/helper-validator-identifier@npm:^7.10.4, @babel/helper-validator-identifier@npm:^7.22.20": version: 7.22.20 resolution: "@babel/helper-validator-identifier@npm:7.22.20" checksum: dcad63db345fb110e032de46c3688384b0008a42a4845180ce7cd62b1a9c0507a1bed727c4d1060ed1a03ae57b4d918570259f81724aaac1a5b776056f37504e @@ -6452,7 +6452,7 @@ __metadata: eslint-plugin-import: "npm:2.29.0" eslint-plugin-sort-class-members: "npm:1.19.0" eslint-plugin-sort-destructure-keys: "npm:1.5.0" - eslint-plugin-unicorn: "npm:48.0.1" + eslint-plugin-unicorn: "npm:49.0.0" lint-staged: "npm:15.0.2" micromatch: "npm:4.0.5" prettier: "npm:3.0.3" @@ -6491,7 +6491,7 @@ __metadata: eslint-plugin-import: "npm:2.29.0" eslint-plugin-sort-class-members: "npm:1.19.0" eslint-plugin-sort-destructure-keys: "npm:1.5.0" - eslint-plugin-unicorn: "npm:48.0.1" + eslint-plugin-unicorn: "npm:49.0.0" lint-staged: "npm:15.0.2" micromatch: "npm:4.0.5" prettier: "npm:3.0.3" @@ -6536,7 +6536,7 @@ __metadata: eslint-plugin-sort-class-members: "npm:1.19.0" eslint-plugin-sort-destructure-keys: "npm:1.5.0" eslint-plugin-storybook: "npm:0.6.15" - eslint-plugin-unicorn: "npm:48.0.1" + eslint-plugin-unicorn: "npm:49.0.0" lint-staged: "npm:15.0.2" micromatch: "npm:4.0.5" prettier: "npm:3.0.3" @@ -6568,7 +6568,7 @@ __metadata: eslint-plugin-import: "npm:2.29.0" eslint-plugin-sort-class-members: "npm:1.19.0" eslint-plugin-sort-destructure-keys: "npm:1.5.0" - eslint-plugin-unicorn: "npm:48.0.1" + eslint-plugin-unicorn: "npm:49.0.0" lint-staged: "npm:15.0.2" micromatch: "npm:4.0.5" prettier: "npm:3.0.3" @@ -6601,7 +6601,7 @@ __metadata: eslint-plugin-import: "npm:2.29.0" eslint-plugin-sort-class-members: "npm:1.19.0" eslint-plugin-sort-destructure-keys: "npm:1.5.0" - eslint-plugin-unicorn: "npm:48.0.1" + eslint-plugin-unicorn: "npm:49.0.0" kill-port: "npm:2.0.1" lint-staged: "npm:15.0.2" micromatch: "npm:4.0.5" @@ -10797,11 +10797,11 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-unicorn@npm:48.0.1": - version: 48.0.1 - resolution: "eslint-plugin-unicorn@npm:48.0.1" +"eslint-plugin-unicorn@npm:49.0.0": + version: 49.0.0 + resolution: "eslint-plugin-unicorn@npm:49.0.0" dependencies: - "@babel/helper-validator-identifier": "npm:^7.22.5" + "@babel/helper-validator-identifier": "npm:^7.22.20" "@eslint-community/eslint-utils": "npm:^4.4.0" ci-info: "npm:^3.8.0" clean-regexp: "npm:^1.0.0" @@ -10809,7 +10809,6 @@ __metadata: indent-string: "npm:^4.0.0" is-builtin-module: "npm:^3.2.1" jsesc: "npm:^3.0.2" - lodash: "npm:^4.17.21" pluralize: "npm:^8.0.0" read-pkg-up: "npm:^7.0.1" regexp-tree: "npm:^0.1.27" @@ -10817,8 +10816,8 @@ __metadata: semver: "npm:^7.5.4" strip-indent: "npm:^3.0.0" peerDependencies: - eslint: ">=8.44.0" - checksum: 158a9fc41c213a2d4a4d7ed9c866c86f9f1901d7f7371c60f3e18d05be73cb6982b72c33a679955142116032127835f8550b466484885c0cedb2e7ed951136ac + eslint: ">=8.52.0" + checksum: e5dea3f3aeef197bfdb17b69bed955d18b8c19cef95fb66292d340899a1132fdee1a1de1ef2806f6055d95fd23b7e6140299183790f06a673919dd751ecb8bfd languageName: node linkType: hard From e70c11bc13fe77968bd27279fca25ef55b08dbaf Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Mon, 30 Oct 2023 12:24:30 +0900 Subject: [PATCH 09/21] . --- packages/wb/src/commands/buildIfNeeded.ts | 2 +- packages/wb/src/commands/prisma.ts | 4 ++-- packages/wb/src/commands/retry.ts | 2 +- packages/wb/src/commands/setup.ts | 2 +- packages/wb/src/commands/start.ts | 2 +- packages/wb/src/index.ts | 6 +----- packages/wb/src/scripts/execution/blitzScripts.ts | 1 - 7 files changed, 7 insertions(+), 12 deletions(-) diff --git a/packages/wb/src/commands/buildIfNeeded.ts b/packages/wb/src/commands/buildIfNeeded.ts index 2a6cc5c0..ce417ffa 100644 --- a/packages/wb/src/commands/buildIfNeeded.ts +++ b/packages/wb/src/commands/buildIfNeeded.ts @@ -8,7 +8,7 @@ import { ignoreEnoentAsync } from '@willbooster/shared-lib/src'; import chalk from 'chalk'; import type { ArgumentsCamelCase, CommandModule, InferredOptionTypes } from 'yargs'; -import type { Project} from '../project.js'; +import type { Project } from '../project.js'; import { findAllProjects } from '../project.js'; import type { sharedOptionsBuilder } from '../sharedOptionsBuilder.js'; diff --git a/packages/wb/src/commands/prisma.ts b/packages/wb/src/commands/prisma.ts index 6058c87a..f60e5fec 100644 --- a/packages/wb/src/commands/prisma.ts +++ b/packages/wb/src/commands/prisma.ts @@ -1,7 +1,7 @@ import type { CommandModule, InferredOptionTypes } from 'yargs'; -import type { Project} from '../project.js'; -import { FoundProjects, findAllProjects, project } from '../project.js'; +import type { Project } from '../project.js'; +import { findAllProjects } from '../project.js'; import { prismaScripts } from '../scripts/prismaScripts.js'; import { runWithSpawn } from '../scripts/run.js'; diff --git a/packages/wb/src/commands/retry.ts b/packages/wb/src/commands/retry.ts index 72ea73a6..4925b1bd 100644 --- a/packages/wb/src/commands/retry.ts +++ b/packages/wb/src/commands/retry.ts @@ -2,7 +2,7 @@ import { loadEnvironmentVariables } from '@willbooster/shared-lib-node/src'; import chalk from 'chalk'; import type { CommandModule, InferredOptionTypes } from 'yargs'; -import { findAllProjects, findRootAndSelfProjects } from '../project.js'; +import { findRootAndSelfProjects } from '../project.js'; import { runWithSpawn } from '../scripts/run.js'; import type { sharedOptionsBuilder } from '../sharedOptionsBuilder.js'; diff --git a/packages/wb/src/commands/setup.ts b/packages/wb/src/commands/setup.ts index 670f42fc..df0e5696 100644 --- a/packages/wb/src/commands/setup.ts +++ b/packages/wb/src/commands/setup.ts @@ -4,7 +4,7 @@ import os from 'node:os'; import type { ArgumentsCamelCase, CommandModule, InferredOptionTypes } from 'yargs'; -import { findAllProjects, project } from '../project.js'; +import { findAllProjects } from '../project.js'; import { promisePool } from '../promisePool.js'; import { runWithSpawn, runWithSpawnInParallel } from '../scripts/run.js'; diff --git a/packages/wb/src/commands/start.ts b/packages/wb/src/commands/start.ts index 24197536..c70f64a2 100644 --- a/packages/wb/src/commands/start.ts +++ b/packages/wb/src/commands/start.ts @@ -1,7 +1,7 @@ import { loadEnvironmentVariables, restoreEnvironmentVariables } from '@willbooster/shared-lib-node/src'; import type { ArgumentsCamelCase, CommandModule, InferredOptionTypes } from 'yargs'; -import type { Project} from '../project.js'; +import type { Project } from '../project.js'; import { findAllProjects } from '../project.js'; import { normalizeArgs, scriptOptionsBuilder } from '../scripts/builder.js'; import type { BaseExecutionScripts } from '../scripts/execution/baseExecutionScripts.js'; diff --git a/packages/wb/src/index.ts b/packages/wb/src/index.ts index 56a77e9a..99b08306 100644 --- a/packages/wb/src/index.ts +++ b/packages/wb/src/index.ts @@ -1,10 +1,6 @@ import path from 'node:path'; -import { - loadEnvironmentVariables, - removeNpmAndYarnEnvironmentVariables, - saveEnvironmentVariables, -} from '@willbooster/shared-lib-node/src'; +import { removeNpmAndYarnEnvironmentVariables, saveEnvironmentVariables } from '@willbooster/shared-lib-node/src'; import yargs from 'yargs'; import { hideBin } from 'yargs/helpers'; diff --git a/packages/wb/src/scripts/execution/blitzScripts.ts b/packages/wb/src/scripts/execution/blitzScripts.ts index 63d37155..944f3d3e 100644 --- a/packages/wb/src/scripts/execution/blitzScripts.ts +++ b/packages/wb/src/scripts/execution/blitzScripts.ts @@ -1,5 +1,4 @@ import type { Project } from '../../project.js'; -import { project } from '../../project.js'; import type { ScriptArgv } from '../builder.js'; import { prismaScripts } from '../prismaScripts.js'; From a0005e96aeb8a0cb1f73bc48facf0620a5bbbcb9 Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Mon, 30 Oct 2023 12:37:58 +0900 Subject: [PATCH 10/21] . --- packages/shared-lib-node/tests/env.test.ts | 6 +----- packages/wb/src/sharedOptionsBuilder.ts | 1 + 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/shared-lib-node/tests/env.test.ts b/packages/shared-lib-node/tests/env.test.ts index d0c98f7d..bde0d44b 100644 --- a/packages/shared-lib-node/tests/env.test.ts +++ b/packages/shared-lib-node/tests/env.test.ts @@ -38,11 +38,7 @@ describe('loadEnvironmentVariables()', () => { it('should load env vars with --env=test-fixtures/app2/.env --auto-cascade-env, WB_ENV=test and NODE_ENV=production', () => { process.env.WB_ENV = 'test'; process.env.NODE_ENV = 'production'; - const envVars = loadEnvironmentVariables( - { autoCascadeEnv: true, env: ['.env'] }, - 'test-fixtures/app1', - 'test-fixtures/app2' - ); + const envVars = loadEnvironmentVariables({ autoCascadeEnv: true, env: ['../app2/.env'] }, 'test-fixtures/app1'); expect(envVars).toEqual({ NAME: 'app2', ENV: 'test2' }); }); }); diff --git a/packages/wb/src/sharedOptionsBuilder.ts b/packages/wb/src/sharedOptionsBuilder.ts index afeb2242..3a6f2da5 100644 --- a/packages/wb/src/sharedOptionsBuilder.ts +++ b/packages/wb/src/sharedOptionsBuilder.ts @@ -2,6 +2,7 @@ import { yargsOptionsBuilderForEnv } from '@willbooster/shared-lib-node/src'; export const sharedOptionsBuilder = { ...yargsOptionsBuilderForEnv, + // This option is for debugging mainly. 'working-dir': { description: 'A working directory', type: 'string', From 43d0d3d94c350736c2c9d09a83551571867bac57 Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Mon, 30 Oct 2023 18:54:41 +0900 Subject: [PATCH 11/21] . --- packages/shared-lib-node/src/env.ts | 101 +++++---- packages/shared-lib-node/src/index.ts | 6 +- packages/shared-lib-node/tests/env.test.ts | 19 +- packages/wb/package.json | 2 +- packages/wb/src/commands/buildIfNeeded.ts | 12 +- packages/wb/src/commands/commandUtils.ts | 22 +- .../wb/src/commands/optimizeForDockerBuild.ts | 4 +- packages/wb/src/commands/prisma.ts | 62 +++--- packages/wb/src/commands/retry.ts | 15 +- packages/wb/src/commands/setup.ts | 22 +- packages/wb/src/commands/start.ts | 38 ++-- packages/wb/src/commands/test.ts | 209 ++++++++++-------- packages/wb/src/commands/typecheck.ts | 53 +++-- packages/wb/src/index.ts | 10 +- packages/wb/src/processUtils.ts | 12 +- packages/wb/src/project.ts | 52 +++-- packages/wb/src/scripts/dockerScripts.ts | 2 +- .../wb/src/scripts/execution/blitzScripts.ts | 8 +- .../wb/src/scripts/execution/nextScripts.ts | 4 +- .../wb/src/scripts/execution/remixScripts.ts | 4 +- packages/wb/src/scripts/run.ts | 54 ++--- packages/wb/src/sharedOptionsBuilder.ts | 5 - packages/wb/tests/buildIfNeeded.test.ts | 35 ++- packages/wb/tests/setup.test.ts | 7 +- packages/wb/tests/shared.ts | 12 +- packages/wb/tests/typecheck.test.ts | 10 +- 26 files changed, 398 insertions(+), 382 deletions(-) diff --git a/packages/shared-lib-node/src/env.ts b/packages/shared-lib-node/src/env.ts index be3be54d..e255f765 100644 --- a/packages/shared-lib-node/src/env.ts +++ b/packages/shared-lib-node/src/env.ts @@ -1,15 +1,9 @@ +import fs from 'node:fs'; import path from 'node:path'; -import { config } from 'dotenv'; - -interface Options { - env: (string | number)[]; - cascadeEnv: string; - cascadeNodeEnv: boolean; - autoCascadeEnv: boolean; - checkEnv: string; - verbose: boolean; -} +import type { DotenvPopulateInput } from 'dotenv'; +import { parse, populate } from 'dotenv'; +import type { ArgumentsCamelCase, InferredOptionTypes } from 'yargs'; export const yargsOptionsBuilderForEnv = { env: { @@ -30,17 +24,29 @@ export const yargsOptionsBuilderForEnv = { type: 'boolean', default: true, }, + 'include-root-env': { + description: 'Include .env files in root directory if the project is in a monorepo and --env option is not used.', + type: 'boolean', + default: true, + }, 'check-env': { description: 'Check whether the keys of the loaded .env files are same with the given .env file.', type: 'string', default: '.env.example', }, + verbose: { + description: 'Whether to show verbose information', + type: 'boolean', + alias: 'v', + }, } as const; +export type EnvReaderOptions = Partial>>; + /** - * This function loads environment variables from `.env` files. + * This function reads environment variables from `.env` files. Note it does not assign them in `process.env`. * */ -export function loadEnvironmentVariables(argv: Partial, cwd: string): Record { +export function readEnvironmentVariables(argv: EnvReaderOptions, cwd: string, cache = true): Record { let envPaths = (argv.env ?? []).map((envPath) => path.resolve(cwd, envPath.toString())); const cascade = argv.cascadeEnv ?? @@ -50,7 +56,15 @@ export function loadEnvironmentVariables(argv: Partial, cwd: string): R ? process.env.WB_ENV || process.env.NODE_ENV || 'development' : undefined); if (typeof cascade === 'string') { - if (envPaths.length === 0) envPaths.push(path.join(cwd, '.env')); + if (envPaths.length === 0) { + envPaths.push(path.join(cwd, '.env')); + if (argv.includeRootEnv) { + const rootPath = path.resolve(cwd, '..', '..'); + if (fs.existsSync(path.join(rootPath, 'package.json'))) { + envPaths.push(path.join(rootPath, '.env')); + } + } + } envPaths = envPaths.flatMap((envPath) => cascade ? [`${envPath}.${cascade}.local`, `${envPath}.local`, `${envPath}.${cascade}`, envPath] @@ -60,13 +74,13 @@ export function loadEnvironmentVariables(argv: Partial, cwd: string): R envPaths = envPaths.map((envPath) => path.relative(cwd, envPath)); if (argv.verbose) { console.info(`WB_ENV: ${process.env.WB_ENV}, NODE_ENV: ${process.env.NODE_ENV}`); - console.info('Loading env files:', envPaths); + console.info('Reading env files:', envPaths); } let envVars: Record = {}; const orgEnvVars = { ...process.env }; for (const envPath of envPaths) { - envVars = { ...config({ path: path.join(cwd, envPath) }).parsed, ...envVars }; + envVars = { ...readEnvFile(path.join(cwd, envPath), cache), ...envVars }; let count = 0; for (const [key, value] of Object.entries(envVars)) { if (orgEnvVars[key] !== value) { @@ -75,12 +89,12 @@ export function loadEnvironmentVariables(argv: Partial, cwd: string): R } } if (count > 0) { - console.info(`Loaded ${count} environment variables:`, envPath); + console.info(`Read ${count} environment variables:`, envPath); } } if (argv.checkEnv) { - const exampleKeys = Object.keys(config({ path: path.join(cwd, argv.checkEnv) }).parsed || {}); + const exampleKeys = Object.keys(readEnvFile(path.join(cwd, argv.checkEnv), cache) || {}); const missingKeys = exampleKeys.filter((key) => !(key in envVars)); if (missingKeys.length > 0) { throw new Error(`Missing environment variables in [${envPaths.join(', ')}]: [${missingKeys.join(', ')}]`); @@ -89,6 +103,32 @@ export function loadEnvironmentVariables(argv: Partial, cwd: string): R return envVars; } +/** + * This function read environment variables from `.env` files and assign them in `process.env`. + * */ +export function readAndApplyEnvironmentVariables( + argv: EnvReaderOptions, + cwd: string, + cache = true +): Record { + const envVars = readEnvironmentVariables(argv, cwd, cache); + populate(process.env as DotenvPopulateInput, envVars); + return process.env; +} + +const cachedEnvVars = new Map>(); + +function readEnvFile(filePath: string, cache = true): Record { + const cached = cache && cachedEnvVars.get(filePath); + if (cached) return cached; + + const parsed = parse(filePath); + if (cache) { + cachedEnvVars.set(filePath, parsed); + } + return parsed; +} + /** * This function removes environment variables related to npm and yarn from the given environment variables. * */ @@ -115,30 +155,3 @@ export function removeNpmAndYarnEnvironmentVariables(envVars: Record = new Map(); - -/** - * This function saves the current state of environment variables. - * It can be used to restore the environment variables to this state later. - */ -export function saveEnvironmentVariables(): void { - savedEnvVars.clear(); - for (const [key, value] of Object.entries(process.env)) { - savedEnvVars.set(key, value); - } -} - -/** - * Restores the environment variables to the state saved by `saveEnvironmentVariables`. - * If a variable was not saved, it will be deleted. - */ -export function restoreEnvironmentVariables(): void { - for (const [key, value] of savedEnvVars.entries()) { - if (savedEnvVars.has(key)) { - process.env[key] = value; - } else { - delete process.env[key]; - } - } -} diff --git a/packages/shared-lib-node/src/index.ts b/packages/shared-lib-node/src/index.ts index 20388bb5..ced9dcbb 100644 --- a/packages/shared-lib-node/src/index.ts +++ b/packages/shared-lib-node/src/index.ts @@ -1,9 +1,9 @@ export { - loadEnvironmentVariables, + readEnvironmentVariables, + readAndApplyEnvironmentVariables, removeNpmAndYarnEnvironmentVariables, - saveEnvironmentVariables, - restoreEnvironmentVariables, yargsOptionsBuilderForEnv, + EnvReaderOptions, } from './env.js'; export { existsAsync } from './exists.js'; export { calculateHashFromFiles, canSkipSeed, updateHashFromFiles } from './hash.js'; diff --git a/packages/shared-lib-node/tests/env.test.ts b/packages/shared-lib-node/tests/env.test.ts index bde0d44b..9f527a13 100644 --- a/packages/shared-lib-node/tests/env.test.ts +++ b/packages/shared-lib-node/tests/env.test.ts @@ -1,44 +1,47 @@ import { beforeEach, describe, expect, it } from 'vitest'; -import { loadEnvironmentVariables } from '../src/env.js'; +import { readAndApplyEnvironmentVariables } from '../src/env.js'; -describe('loadEnvironmentVariables()', () => { +describe('readAndApplyEnvironmentVariables()', () => { beforeEach(() => { process.env.WB_ENV = ''; process.env.NODE_ENV = ''; }); it('should load no env vars with empty options', () => { - const envVars = loadEnvironmentVariables({}, 'test-fixtures/app1'); + const envVars = readAndApplyEnvironmentVariables({}, 'test-fixtures/app1'); expect(envVars).toEqual({}); }); it('should load env vars with --auto-cascade-env', () => { - const envVars = loadEnvironmentVariables({ autoCascadeEnv: true }, 'test-fixtures/app1'); + const envVars = readAndApplyEnvironmentVariables({ autoCascadeEnv: true }, 'test-fixtures/app1'); expect(envVars).toEqual({ NAME: 'app1', ENV: 'development1' }); }); it('should load env vars with --cascade-env=production', () => { - const envVars = loadEnvironmentVariables({ cascadeEnv: 'production', env: ['.env'] }, 'test-fixtures/app1'); + const envVars = readAndApplyEnvironmentVariables({ cascadeEnv: 'production', env: ['.env'] }, 'test-fixtures/app1'); expect(envVars).toEqual({ NAME: 'app1', ENV: 'production1' }); }); it('should load env vars with --cascade-node-env and NODE_ENV=""', () => { process.env.NODE_ENV = ''; - const envVars = loadEnvironmentVariables({ cascadeNodeEnv: true, env: ['.env'] }, 'test-fixtures/app1'); + const envVars = readAndApplyEnvironmentVariables({ cascadeNodeEnv: true, env: ['.env'] }, 'test-fixtures/app1'); expect(envVars).toEqual({ NAME: 'app1', ENV: 'development1' }); }); it('should load env vars with --cascade-node-env and NODE_ENV=test', () => { process.env.NODE_ENV = 'test'; - const envVars = loadEnvironmentVariables({ cascadeNodeEnv: true, env: ['.env'] }, 'test-fixtures/app1'); + const envVars = readAndApplyEnvironmentVariables({ cascadeNodeEnv: true, env: ['.env'] }, 'test-fixtures/app1'); expect(envVars).toEqual({ NAME: 'app1', ENV: 'test1' }); }); it('should load env vars with --env=test-fixtures/app2/.env --auto-cascade-env, WB_ENV=test and NODE_ENV=production', () => { process.env.WB_ENV = 'test'; process.env.NODE_ENV = 'production'; - const envVars = loadEnvironmentVariables({ autoCascadeEnv: true, env: ['../app2/.env'] }, 'test-fixtures/app1'); + const envVars = readAndApplyEnvironmentVariables( + { autoCascadeEnv: true, env: ['../app2/.env'] }, + 'test-fixtures/app1' + ); expect(envVars).toEqual({ NAME: 'app2', ENV: 'test2' }); }); }); diff --git a/packages/wb/package.json b/packages/wb/package.json index 6958c413..187c3901 100644 --- a/packages/wb/package.json +++ b/packages/wb/package.json @@ -23,7 +23,6 @@ }, "prettier": "@willbooster/prettier-config", "dependencies": { - "at-decorators": "1.2.0", "chalk": "5.3.0", "dotenv": "16.3.1", "kill-port": "2.0.1", @@ -40,6 +39,7 @@ "@typescript-eslint/parser": "6.9.0", "@willbooster/eslint-config-ts": "10.5.1", "@willbooster/prettier-config": "9.1.2", + "at-decorators": "1.2.0", "build-ts": "11.0.8", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", diff --git a/packages/wb/src/commands/buildIfNeeded.ts b/packages/wb/src/commands/buildIfNeeded.ts index ce417ffa..5909fe60 100644 --- a/packages/wb/src/commands/buildIfNeeded.ts +++ b/packages/wb/src/commands/buildIfNeeded.ts @@ -34,16 +34,16 @@ export const buildIfNeededCommand: CommandModule - argv: Partial>> + argv: Partial>>, + dirPath?: string ): Promise { - const projects = await findAllProjects(); + const projects = await findAllProjects(argv, dirPath); if (!projects) return true; const isGitRepo = fs.existsSync(path.join(projects.root.dirPath, '.git')); let built = false; - - for (const project of prepareForRunningCommand('buildIfNeeded', projects.root, projects.all, argv)) { + for (const project of prepareForRunningCommand('buildIfNeeded', projects.all)) { if (!isGitRepo) { if (!build(project, argv)) return; built = true; @@ -98,7 +98,7 @@ export async function canSkipBuild( hash.update(commitHash); const environmentJson = JSON.stringify( - Object.entries(process.env) + Object.entries(project.env) .filter(([key]) => !ignoringEnvVarNames.has(key)) .sort(([key1], [key2]) => key1.localeCompare(key2)) ); @@ -142,7 +142,7 @@ async function updateHashWithDiffResult( .trim() .split('\n') .map((filePath) => - process.env.WB_ENV === 'test' ? filePath.replace(/packages\/scripts\/test-fixtures\/[^/]+\//, '') : filePath + project.env.WB_ENV === 'test' ? filePath.replace(/packages\/scripts\/test-fixtures\/[^/]+\//, '') : filePath ); const filteredFilePaths = filePaths.filter( (filePath) => diff --git a/packages/wb/src/commands/commandUtils.ts b/packages/wb/src/commands/commandUtils.ts index 941485ee..d76d51e9 100644 --- a/packages/wb/src/commands/commandUtils.ts +++ b/packages/wb/src/commands/commandUtils.ts @@ -1,29 +1,9 @@ -import { loadEnvironmentVariables, restoreEnvironmentVariables } from '@willbooster/shared-lib-node/src'; -import type { ArgumentsCamelCase, InferredOptionTypes } from 'yargs'; - import type { Project } from '../project.js'; -import type { sharedOptionsBuilder } from '../sharedOptionsBuilder.js'; -export function* prepareForRunningCommand( - commandName: string, - rootProject: Project, - projects: Project[], - argv: Partial>>, - loadingEnvironmentVariables = true -): Generator { +export function* prepareForRunningCommand(commandName: string, projects: Project[]): Generator { for (const project of projects) { console.info(`Running "${commandName}" for ${project.name} ...`); - if (project !== rootProject) { - restoreEnvironmentVariables(); - } - if (loadingEnvironmentVariables) { - loadEnvironmentVariables(argv, project.dirPath); - if (project !== rootProject) { - loadEnvironmentVariables(argv, rootProject.dirPath); - } - } - yield project; } } diff --git a/packages/wb/src/commands/optimizeForDockerBuild.ts b/packages/wb/src/commands/optimizeForDockerBuild.ts index 921aef27..601ec46c 100644 --- a/packages/wb/src/commands/optimizeForDockerBuild.ts +++ b/packages/wb/src/commands/optimizeForDockerBuild.ts @@ -22,14 +22,14 @@ export const optimizeForDockerBuildCommand: CommandModule> describe: 'Apply migration to DB without initializing it', builder, async handler(argv) { - const [root, ...allProjects] = await findPrismaProjects(); - for (const project of prepareForRunningCommand('prisma deploy', root, allProjects, argv)) { - await runWithSpawn(prismaScripts.deploy(project), argv); + const allProjects = await findPrismaProjects(argv); + for (const project of prepareForRunningCommand('prisma deploy', allProjects)) { + await runWithSpawn(prismaScripts.deploy(project), project, argv); } }, }; @@ -57,9 +58,9 @@ const deployForceCommand: CommandModule describe: 'Apply migration to DB with initializing it', builder, async handler(argv) { - const [root, ...allProjects] = await findPrismaProjects(); - for (const project of prepareForRunningCommand('prisma migrate', root, allProjects, argv)) { - await runWithSpawn(prismaScripts.migrate(project), argv); + const allProjects = await findPrismaProjects(argv); + for (const project of prepareForRunningCommand('prisma migrate', allProjects)) { + await runWithSpawn(prismaScripts.migrate(project), project, argv); } }, }; @@ -93,9 +94,9 @@ const migrateDevCommand: CommandModule> describe: 'Reset DB', builder, async handler(argv) { - const [root, ...allProjects] = await findPrismaProjects(); - for (const project of prepareForRunningCommand('prisma reset', root, allProjects, argv)) { - await runWithSpawn(prismaScripts.reset(project), argv); + const allProjects = await findPrismaProjects(argv); + for (const project of prepareForRunningCommand('prisma reset', allProjects)) { + await runWithSpawn(prismaScripts.reset(project), project, argv); } }, }; @@ -125,12 +126,12 @@ const restoreCommand: CommandModule { - const projects = await findAllProjects(); +async function findPrismaProjects(argv: EnvReaderOptions): Promise { + const projects = await findAllProjects(argv); if (!projects) return []; - const prismaProjects = projects.all.filter( + return projects.all.filter( (project) => project.packageJson.dependencies?.['prisma'] || project.packageJson.devDependencies?.['prisma'] ); - return [projects.root, ...prismaProjects]; } diff --git a/packages/wb/src/commands/retry.ts b/packages/wb/src/commands/retry.ts index 4925b1bd..2c4b60c8 100644 --- a/packages/wb/src/commands/retry.ts +++ b/packages/wb/src/commands/retry.ts @@ -1,8 +1,7 @@ -import { loadEnvironmentVariables } from '@willbooster/shared-lib-node/src'; import chalk from 'chalk'; import type { CommandModule, InferredOptionTypes } from 'yargs'; -import { findRootAndSelfProjects } from '../project.js'; +import { findSelfProject } from '../project.js'; import { runWithSpawn } from '../scripts/run.js'; import type { sharedOptionsBuilder } from '../sharedOptionsBuilder.js'; @@ -20,14 +19,8 @@ export const retryCommand: CommandModule export async function setup(argv: Partial>>): Promise { - const projects = await findAllProjects(); + const projects = await findAllProjects(argv); if (!projects) return; for (const project of projects.all) { @@ -32,22 +32,22 @@ export async function setup(argv: Partial d.isFile() && d.name.includes('-version'))) { - await runWithSpawn('asdf install', argv); + await runWithSpawn('asdf install', project, argv); } } if (dirents.some((d) => d.isFile() && d.name === 'pyproject.toml')) { - await runWithSpawnInParallel('poetry config virtualenvs.in-project true', argv); - await runWithSpawnInParallel('poetry config virtualenvs.prefer-active-python true', argv); + await runWithSpawnInParallel('poetry config virtualenvs.in-project true', project, argv); + await runWithSpawnInParallel('poetry config virtualenvs.prefer-active-python true', project, argv); const [, version] = child_process.execSync('asdf current python').toString().trim().split(/\s+/); - await runWithSpawnInParallel(`poetry env use ${version}`, argv); + await runWithSpawnInParallel(`poetry env use ${version}`, project, argv); await promisePool.promiseAll(); - await runWithSpawn('poetry run pip install --upgrade pip', argv); - await runWithSpawn('poetry install --ansi', argv); + await runWithSpawn('poetry run pip install --upgrade pip', project, argv); + await runWithSpawn('poetry install --ansi', project, argv); } const deps = project.packageJson.dependencies ?? {}; @@ -66,13 +66,13 @@ export async function setup(argv: Partial 0) { - await runWithSpawn(`yarn add ${newDeps.join(' ')}`, argv); + await runWithSpawn(`yarn add ${newDeps.join(' ')}`, project, argv); } if (newDevDeps.length > 0) { - await runWithSpawn(`yarn add -D ${newDevDeps.join(' ')}`, argv); + await runWithSpawn(`yarn add -D ${newDevDeps.join(' ')}`, project, argv); } if (scripts['gen-code']) { - await runWithSpawn('yarn gen-code', argv); + await runWithSpawn('yarn gen-code', project, argv); } } } diff --git a/packages/wb/src/commands/start.ts b/packages/wb/src/commands/start.ts index c70f64a2..6cee7030 100644 --- a/packages/wb/src/commands/start.ts +++ b/packages/wb/src/commands/start.ts @@ -1,5 +1,4 @@ -import { loadEnvironmentVariables, restoreEnvironmentVariables } from '@willbooster/shared-lib-node/src'; -import type { ArgumentsCamelCase, CommandModule, InferredOptionTypes } from 'yargs'; +import type { CommandModule, InferredOptionTypes } from 'yargs'; import type { Project } from '../project.js'; import { findAllProjects } from '../project.js'; @@ -29,7 +28,7 @@ export const startCommand: CommandModule>, - deps: Partial>, - env: string -): string { - restoreEnvironmentVariables(); - process.env.WB_ENV ||= env; - let prefix = `WB_ENV=${process.env.WB_ENV} `; +function configureEnvironmentVariables(project: Project, deps: Partial>, wbEnv: string): string { + project.env.WB_ENV ||= wbEnv; + let prefix = `WB_ENV=${project.env.WB_ENV} `; if (deps['next']) { - process.env.NEXT_PUBLIC_WB_ENV = process.env.WB_ENV; - prefix += `NEXT_PUBLIC_WB_ENV=${process.env.WB_ENV} `; - } - loadEnvironmentVariables(argv, project.dirPath); - if (project !== rootProject) { - loadEnvironmentVariables(argv, rootProject.dirPath); + project.env.NEXT_PUBLIC_WB_ENV = project.env.WB_ENV; + prefix += `NEXT_PUBLIC_WB_ENV=${project.env.WB_ENV} `; } return prefix; } diff --git a/packages/wb/src/commands/test.ts b/packages/wb/src/commands/test.ts index 1878ff40..71daff18 100644 --- a/packages/wb/src/commands/test.ts +++ b/packages/wb/src/commands/test.ts @@ -3,7 +3,8 @@ import path from 'node:path'; import { existsAsync } from '@willbooster/shared-lib-node/src'; import type { ArgumentsCamelCase, CommandModule, InferredOptionTypes } from 'yargs'; -import { project } from '../project.js'; +import type { Project } from '../project.js'; +import { findAllProjects } from '../project.js'; import { promisePool } from '../promisePool.js'; import { dockerScripts } from '../scripts/dockerScripts.js'; import type { BaseExecutionScripts } from '../scripts/execution/baseExecutionScripts.js'; @@ -12,7 +13,8 @@ import { httpServerScripts } from '../scripts/execution/httpServerScripts.js'; import { nextScripts } from '../scripts/execution/nextScripts.js'; import { plainAppScripts } from '../scripts/execution/plainAppScripts.js'; import { remixScripts } from '../scripts/execution/remixScripts.js'; -import { runOnEachWorkspaceIfNeeded, runWithSpawn, runWithSpawnInParallel } from '../scripts/run.js'; +import { runWithSpawn, runWithSpawnInParallel } from '../scripts/run.js'; +import type { sharedOptionsBuilder } from '../sharedOptionsBuilder.js'; const builder = { ci: { @@ -38,7 +40,7 @@ const builder = { }, } as const; -export const testCommand: CommandModule> = { +export const testCommand: CommandModule> = { command: 'test', describe: 'Test project', builder, @@ -47,124 +49,153 @@ export const testCommand: CommandModule>): Promise { - process.env['FORCE_COLOR'] = '3'; - await runOnEachWorkspaceIfNeeded(argv); - - const deps = project.packageJson.dependencies || {}; - const devDeps = project.packageJson.devDependencies || {}; - let scripts: BaseExecutionScripts; - if (deps['blitz']) { - scripts = blitzScripts; - } else if (deps['next']) { - scripts = nextScripts; - } else if (devDeps['@remix-run/dev']) { - scripts = remixScripts; - } else if ((deps['express'] || deps['fastify']) && !deps['firebase-functions']) { - scripts = httpServerScripts; - } else { - scripts = plainAppScripts; - } +export async function test( + argv: ArgumentsCamelCase> +): Promise { + const projects = await findAllProjects(argv); + if (!projects) return; - const promises: Promise[] = []; - if (argv.ci) { - const unitTestsExistPromise = existsAsync(path.join(project.dirPath, 'tests', 'unit')); - const e2eTestsExistPromise = existsAsync(path.join(project.dirPath, 'tests', 'e2e')); + for (const project of projects.all) { + console.info(`Running "test" for ${project.name} ...`); - await runWithSpawnInParallel(dockerScripts.stopAll(), argv); - if (argv.unit !== false && (await unitTestsExistPromise)) { - await runWithSpawnInParallel(scripts.testUnit(argv), argv, { timeout: argv.unitTimeout }); - } - if (argv.start !== false) { - await runWithSpawnInParallel(scripts.testStart(argv), argv); - } - await promisePool.promiseAll(); - // Check playwright installation because --ci includes --e2e implicitly - if (argv.e2e !== 'none' && (await e2eTestsExistPromise)) { - if (project.hasDockerfile) { - await runWithSpawn(`${scripts.buildDocker()}`, argv); - } - const options = project.hasDockerfile - ? { - startCommand: dockerScripts.stopAndStart(true), - } - : {}; - process.exitCode = await runWithSpawn(scripts.testE2E(argv, options), argv, { exitIfFailed: false }); - await runWithSpawn(dockerScripts.stop(), argv); + if (projects.all.length > 1) { + // Disable interactive mode + project.env['CI'] = '1'; } - return; - } + project.env['FORCE_COLOR'] ||= '3'; + project.env.WB_ENV ||= 'test'; - if (argv.unit || (!argv.start && argv.e2e === undefined)) { - promises.push(runWithSpawn(scripts.testUnit(argv), argv, { timeout: argv.unitTimeout })); - } - if (argv.start) { - promises.push(runWithSpawn(scripts.testStart(argv), argv)); - } - await Promise.all(promises); - // Don't check playwright installation because --e2e is set explicitly - switch (argv.e2e) { - case undefined: - case 'none': { - return; - } - case '': - case 'headless': { - await runWithSpawn(scripts.testE2E(argv, {}), argv); - return; + const deps = project.packageJson.dependencies || {}; + const devDeps = project.packageJson.devDependencies || {}; + let scripts: BaseExecutionScripts; + if (deps['blitz']) { + scripts = blitzScripts; + } else if (deps['next']) { + scripts = nextScripts; + } else if (devDeps['@remix-run/dev']) { + scripts = remixScripts; + } else if ((deps['express'] || deps['fastify']) && !deps['firebase-functions']) { + scripts = httpServerScripts; + } else { + scripts = plainAppScripts; } - case 'headless-dev': { - await runWithSpawn(scripts.testE2EDev(argv, {}), argv); + + const promises: Promise[] = []; + if (argv.ci) { + const unitTestsExistPromise = existsAsync(path.join(project.dirPath, 'tests', 'unit')); + const e2eTestsExistPromise = existsAsync(path.join(project.dirPath, 'tests', 'e2e')); + + await runWithSpawnInParallel(dockerScripts.stopAll(), project, argv); + if (argv.unit !== false && (await unitTestsExistPromise)) { + await runWithSpawnInParallel(scripts.testUnit(project, argv), project, argv, { timeout: argv.unitTimeout }); + } + if (argv.start !== false) { + await runWithSpawnInParallel(scripts.testStart(project, argv), project, argv); + } + await promisePool.promiseAll(); + // Check playwright installation because --ci includes --e2e implicitly + if (argv.e2e !== 'none' && (await e2eTestsExistPromise)) { + if (project.hasDockerfile) { + await runWithSpawn(`${scripts.buildDocker(project)}`, project, argv); + } + const options = project.hasDockerfile + ? { + startCommand: dockerScripts.stopAndStart(project), + } + : {}; + process.exitCode = await runWithSpawn(scripts.testE2E(project, argv, options), project, argv, { + exitIfFailed: false, + }); + await runWithSpawn(dockerScripts.stop(project), project, argv); + } return; } - case 'docker': { - await testOnDocker(argv, scripts); - return; + + if (argv.unit || (!argv.start && argv.e2e === undefined)) { + promises.push(runWithSpawn(scripts.testUnit(project, argv), project, argv, { timeout: argv.unitTimeout })); } - case 'docker-debug': { - await testOnDocker(argv, scripts, 'PWDEBUG=1 '); - return; + if (argv.start) { + promises.push(runWithSpawn(scripts.testStart(project, argv), project, argv)); } - } - if (deps['blitz'] || deps['next'] || devDeps['@remix-run/dev']) { + await Promise.all(promises); + // Don't check playwright installation because --e2e is set explicitly switch (argv.e2e) { - case 'headed': { - await runWithSpawn(scripts.testE2E(argv, { playwrightArgs: 'test tests/e2e --headed' }), argv); + case undefined: + case 'none': { return; } - case 'headed-dev': { - await runWithSpawn(scripts.testE2EDev(argv, { playwrightArgs: 'test tests/e2e --headed' }), argv); + case '': + case 'headless': { + await runWithSpawn(scripts.testE2E(project, argv, {}), project, argv); return; } - case 'debug': { - await runWithSpawn(`PWDEBUG=1 ${scripts.testE2E(argv, {})}`, argv); + case 'headless-dev': { + await runWithSpawn(scripts.testE2EDev(project, argv, {}), project, argv); return; } - case 'generate': { - await runWithSpawn(scripts.testE2E(argv, { playwrightArgs: 'codegen http://localhost:8080' }), argv); + case 'docker': { + await testOnDocker(project, argv, scripts); return; } - case 'trace': { - await runWithSpawn(`playwright show-trace`, argv); + case 'docker-debug': { + await testOnDocker(project, argv, scripts, 'PWDEBUG=1 '); return; } } + if (deps['blitz'] || deps['next'] || devDeps['@remix-run/dev']) { + switch (argv.e2e) { + case 'headed': { + await runWithSpawn( + scripts.testE2E(project, argv, { playwrightArgs: 'test tests/e2e --headed' }), + project, + argv + ); + return; + } + case 'headed-dev': { + await runWithSpawn( + scripts.testE2EDev(project, argv, { playwrightArgs: 'test tests/e2e --headed' }), + project, + argv + ); + return; + } + case 'debug': { + await runWithSpawn(`PWDEBUG=1 ${scripts.testE2E(project, argv, {})}`, project, argv); + return; + } + case 'generate': { + await runWithSpawn( + scripts.testE2E(project, argv, { playwrightArgs: 'codegen http://localhost:8080' }), + project, + argv + ); + return; + } + case 'trace': { + await runWithSpawn(`playwright show-trace`, project, argv); + return; + } + } + } + throw new Error(`Unknown e2e mode: ${argv.e2e}`); } - throw new Error(`Unknown e2e mode: ${argv.e2e}`); } async function testOnDocker( + project: Project, argv: ArgumentsCamelCase>, scripts: BaseExecutionScripts, prefix = '' ): Promise { - await runWithSpawn(`${scripts.buildDocker()}`, argv); + await runWithSpawn(`${scripts.buildDocker(project)}`, project, argv); process.exitCode = await runWithSpawn( - `${prefix}${scripts.testE2E(argv, { - startCommand: dockerScripts.stopAndStart(true), + `${prefix}${scripts.testE2E(project, argv, { + startCommand: dockerScripts.stopAndStart(project), })}`, + project, argv, { exitIfFailed: false } ); - await runWithSpawn(dockerScripts.stop(), argv); + await runWithSpawn(dockerScripts.stop(project), project, argv); } diff --git a/packages/wb/src/commands/typecheck.ts b/packages/wb/src/commands/typecheck.ts index 276579bb..5bfd902e 100644 --- a/packages/wb/src/commands/typecheck.ts +++ b/packages/wb/src/commands/typecheck.ts @@ -4,39 +4,56 @@ import chalk from 'chalk'; import type { PackageJson } from 'type-fest'; import type { CommandModule, InferredOptionTypes } from 'yargs'; -import { project } from '../project.js'; +import { findAllProjects } from '../project.js'; import { runWithSpawn } from '../scripts/run.js'; +import type { sharedOptionsBuilder } from '../sharedOptionsBuilder.js'; const builder = {} as const; -export const typeCheckCommand: CommandModule> = { +export const typeCheckCommand: CommandModule< + unknown, + InferredOptionTypes +> = { command: 'typecheck', describe: 'Run type checking. .env-related options are ignored.', builder, async handler(argv) { - const commands: string[] = []; - if (project.packageJson.workspaces) { - commands.push(`yarn workspaces foreach --all --parallel --exclude ${project.name} --verbose run typecheck`); - } else { - if (project.packageJson.dependencies?.typescript || project.packageJson.devDependencies?.typescript) { - commands.push('tsc --noEmit --Pretty'); + const projects = await findAllProjects(argv); + 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'; } - if (project.packageJson.devDependencies?.pyright) { - commands.push('pyright'); + 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.dependencies?.typescript || project.packageJson.devDependencies?.typescript) { + commands.push('tsc --noEmit --Pretty'); + } + if (project.packageJson.devDependencies?.pyright) { + commands.push('pyright'); + } } - } - process.exitCode = await runWithSpawn(commands.join(' && '), argv); - if (process.exitCode !== 0) { - const packageJson = JSON.parse(await fs.readFile('package.json', 'utf8')) as PackageJson; - const deps = packageJson.dependencies || {}; - if (deps['blitz']) { - console.info(chalk.yellow('Please try "yarn gen-code" if you face unknown type errors.')); + const exitCode = await runWithSpawn(commands.join(' && '), project, argv); + if (exitCode !== 0) { + const packageJson = JSON.parse(await fs.readFile('package.json', 'utf8')) as PackageJson; + const deps = packageJson.dependencies || {}; + if (deps['blitz']) { + console.info(chalk.yellow('Please try "yarn gen-code" if you face unknown type errors.')); + } } } }, }; -export const tcCommand: CommandModule> = { +export const tcCommand: CommandModule> = { ...typeCheckCommand, command: 'tc', }; diff --git a/packages/wb/src/index.ts b/packages/wb/src/index.ts index 99b08306..61d0f67a 100644 --- a/packages/wb/src/index.ts +++ b/packages/wb/src/index.ts @@ -1,6 +1,6 @@ import path from 'node:path'; -import { removeNpmAndYarnEnvironmentVariables, saveEnvironmentVariables } from '@willbooster/shared-lib-node/src'; +import { removeNpmAndYarnEnvironmentVariables } from '@willbooster/shared-lib-node/src'; import yargs from 'yargs'; import { hideBin } from 'yargs/helpers'; @@ -25,14 +25,6 @@ await yargs(hideBin(process.argv)) } removeNpmAndYarnEnvironmentVariables(process.env); - saveEnvironmentVariables(); - - // const command = argv._[0].toString(); - // if (['start', 'tc', 'typecheck'].includes(command)) return; - // if (command === 'test') { - // process.env.WB_ENV ||= 'test'; - // } - // loadEnvironmentVariables(argv, project.dirPath); }) .command(buildIfNeededCommand) .command(optimizeForDockerBuildCommand) diff --git a/packages/wb/src/processUtils.ts b/packages/wb/src/processUtils.ts index 600f72d8..985a0ec8 100644 --- a/packages/wb/src/processUtils.ts +++ b/packages/wb/src/processUtils.ts @@ -28,14 +28,14 @@ async function killPortProcessHandlingErrors(port: number): Promise { } } -export function spawnSyncOnExit(project: Project, command: string): void { +export function spawnSyncOnExit(script: string, project: Project): void { const killFunc = async (): Promise => { - if (killed.has(command)) return; + if (killed.has(script)) return; - killed.add(command); - printStart(command); - const { status } = spawnSync(command, { cwd: project.dirPath, shell: true, stdio: 'inherit' }); - printFinishedAndExitIfNeeded(command, status, {}); + killed.add(script); + printStart(script, project); + const { status } = spawnSync(script, { cwd: project.dirPath, shell: true, stdio: 'inherit' }); + printFinishedAndExitIfNeeded(script, status, {}); }; for (const signal of ['beforeExit', 'SIGINT', 'SIGTERM', 'SIGQUIT']) { process.on(signal, killFunc); diff --git a/packages/wb/src/project.ts b/packages/wb/src/project.ts index 7db2e00d..86d4f611 100644 --- a/packages/wb/src/project.ts +++ b/packages/wb/src/project.ts @@ -1,6 +1,8 @@ import fs from 'node:fs'; import path from 'node:path'; +import type { EnvReaderOptions } from '@willbooster/shared-lib-node/src'; +import { readEnvironmentVariables } from '@willbooster/shared-lib-node/src'; import { memoizeOne } from 'at-decorators'; import type { PackageJson } from 'type-fest'; @@ -9,9 +11,11 @@ import type { ScriptArgv } from './scripts/builder.js'; export class Project { private _dirPath: string; private _pathByName = new Map(); + private _argv: EnvReaderOptions; - constructor(dirPath: string) { + constructor(dirPath: string, argv: EnvReaderOptions) { this._dirPath = path.resolve(dirPath); + this._argv = argv; } @memoizeOne @@ -62,6 +66,11 @@ export class Project { return index === -1 ? name : name.slice(index + 1); } + @memoizeOne + get env(): Record { + return readEnvironmentVariables(this._argv, this.dirPath); + } + @memoizeOne get packageJson(): PackageJson { return JSON.parse(fs.readFileSync(path.join(this.dirPath, 'package.json'), 'utf8')); @@ -100,29 +109,46 @@ export interface FoundProjects { all: Project[]; } -export function findRootAndSelfProjects(): Omit | undefined { +export function findSelfProject(argv: EnvReaderOptions): Project | undefined { const dirPath = process.cwd(); if (!fs.existsSync(path.join(dirPath, 'package.json'))) return; - const thisProject = new Project(dirPath); + return new Project(dirPath, argv); +} + +export async function findAllProjects(argv: EnvReaderOptions, dirPath?: string): Promise { + const rootAndSelfProjects = findRootAndSelfProjects(argv, dirPath); + if (!rootAndSelfProjects) return; + + return { + ...rootAndSelfProjects, + all: + rootAndSelfProjects.root === rootAndSelfProjects.self + ? await getAllProjects(argv, rootAndSelfProjects.root) + : [rootAndSelfProjects.self], + }; +} + +export function findRootAndSelfProjects( + argv: EnvReaderOptions, + dirPath?: string +): Omit | undefined { + // Tests pass dirPath + dirPath ??= process.cwd(); + if (!fs.existsSync(path.join(dirPath, 'package.json'))) return; + + const thisProject = new Project(dirPath, argv); let rootProject = thisProject; if (!thisProject.packageJson.workspaces && path.dirname(dirPath) === 'packages') { const rootDirPath = path.resolve(dirPath, '..', '..'); if (fs.existsSync(path.join(rootDirPath, 'package.json'))) { - rootProject = new Project(rootDirPath); + rootProject = new Project(rootDirPath, argv); } } return { root: rootProject, self: thisProject }; } -export async function findAllProjects(): Promise { - const rootAndSelfProjects = findRootAndSelfProjects(); - if (!rootAndSelfProjects) return; - - return { ...rootAndSelfProjects, all: await getAllProjects(rootAndSelfProjects.root) }; -} - -async function getAllProjects(rootProject: Project): Promise { +async function getAllProjects(argv: EnvReaderOptions, rootProject: Project): Promise { const allProjects = [rootProject]; const packageDirPath = path.join(rootProject.dirPath, 'packages'); const packageDirs = await fs.promises.readdir(packageDirPath, { withFileTypes: true }); @@ -132,7 +158,7 @@ async function getAllProjects(rootProject: Project): Promise { const packageJsonPath = path.join(packageDirPath, 'package.json'); if (!fs.existsSync(packageJsonPath)) continue; - allProjects.push(new Project(packageJsonPath)); + allProjects.push(new Project(packageJsonPath, argv)); } return allProjects; } diff --git a/packages/wb/src/scripts/dockerScripts.ts b/packages/wb/src/scripts/dockerScripts.ts index 74506aa7..97689bdb 100644 --- a/packages/wb/src/scripts/dockerScripts.ts +++ b/packages/wb/src/scripts/dockerScripts.ts @@ -28,7 +28,7 @@ class DockerScripts { )}`; } start(project: Project, additionalOptions = '', additionalArgs = ''): string { - spawnSyncOnExit(this.stop(project)); + spawnSyncOnExit(this.stop(project), project); return `docker run --rm -it -p 8080:8080 --name ${project.nameWithoutNamespace} ${additionalOptions} ${project.nameWithoutNamespace} ${additionalArgs}`; } diff --git a/packages/wb/src/scripts/execution/blitzScripts.ts b/packages/wb/src/scripts/execution/blitzScripts.ts index 944f3d3e..f4bd8c16 100644 --- a/packages/wb/src/scripts/execution/blitzScripts.ts +++ b/packages/wb/src/scripts/execution/blitzScripts.ts @@ -24,10 +24,10 @@ class BlitzScripts extends BaseExecutionScripts { override startProduction(project: Project, argv: ScriptArgv, port: number): string { const appEnv = process.env.WB_ENV ? `APP_ENV=${process.env.WB_ENV} ` : ''; return `${appEnv}NODE_ENV=production YARN concurrently --raw --kill-others-on-fail - "${prismaScripts.reset()} && ${project.getBuildCommand( + "${prismaScripts.reset(project)} && ${project.getBuildCommand( argv )} && PORT=${port} pm2-runtime start ${project.findFile('ecosystem.config.cjs')} ${argv.normalizedArgsText ?? ''}" - "${this.waitAndOpenApp(argv, port)}"`; + "${this.waitAndOpenApp(project, argv, port)}"`; } override testE2E( @@ -35,7 +35,7 @@ class BlitzScripts extends BaseExecutionScripts { argv: ScriptArgv, { playwrightArgs = 'test tests/e2e', - startCommand = `${prismaScripts.reset()} && ${project.getBuildCommand( + startCommand = `${prismaScripts.reset(project)} && ${project.getBuildCommand( argv )} && pm2-runtime start ${project.findFile('ecosystem.config.cjs')}`, }: TestE2EOptions @@ -56,7 +56,7 @@ class BlitzScripts extends BaseExecutionScripts { } override testStart(project: Project, argv: ScriptArgv): string { - return `YARN concurrently --kill-others --raw --success first "blitz dev" "${this.waitApp(argv)}"`; + return `YARN concurrently --kill-others --raw --success first "blitz dev" "${this.waitApp(project, argv)}"`; } } diff --git a/packages/wb/src/scripts/execution/nextScripts.ts b/packages/wb/src/scripts/execution/nextScripts.ts index 1aec9dad..c2a8f8c2 100644 --- a/packages/wb/src/scripts/execution/nextScripts.ts +++ b/packages/wb/src/scripts/execution/nextScripts.ts @@ -22,7 +22,7 @@ class NextScripts extends BaseExecutionScripts { override startProduction(project: Project, argv: ScriptArgv, port: number): string { return `NODE_ENV=production YARN concurrently --raw --kill-others-on-fail - "${prismaScripts.reset()} && ${project.getBuildCommand( + "${prismaScripts.reset(project)} && ${project.getBuildCommand( argv )} && PORT=${port} pm2-runtime start ${project.findFile('ecosystem.config.cjs')} ${argv.normalizedArgsText ?? ''}" "${this.waitAndOpenApp(project, argv, port)}"`; @@ -33,7 +33,7 @@ class NextScripts extends BaseExecutionScripts { argv: ScriptArgv, { playwrightArgs = 'test tests/e2e', - startCommand = `${prismaScripts.reset()} && ${project.getBuildCommand( + startCommand = `${prismaScripts.reset(project)} && ${project.getBuildCommand( argv )} && pm2-runtime start ${project.findFile('ecosystem.config.cjs')}`, }: TestE2EOptions diff --git a/packages/wb/src/scripts/execution/remixScripts.ts b/packages/wb/src/scripts/execution/remixScripts.ts index 57c48e03..5c407406 100644 --- a/packages/wb/src/scripts/execution/remixScripts.ts +++ b/packages/wb/src/scripts/execution/remixScripts.ts @@ -22,7 +22,7 @@ class RemixScripts extends BaseExecutionScripts { override startProduction(project: Project, argv: ScriptArgv, port: number): string { return `NODE_ENV=production YARN concurrently --raw --kill-others-on-fail - "${prismaScripts.reset()} && ${project.getBuildCommand( + "${prismaScripts.reset(project)} && ${project.getBuildCommand( argv )} && PORT=${port} pm2-runtime start ${project.findFile('ecosystem.config.cjs')} ${argv.normalizedArgsText ?? ''}" "${this.waitAndOpenApp(project, argv, port)}"`; @@ -33,7 +33,7 @@ class RemixScripts extends BaseExecutionScripts { argv: ScriptArgv, { playwrightArgs = 'test tests/e2e', - startCommand = `${prismaScripts.reset()} && ${project.getBuildCommand( + startCommand = `${prismaScripts.reset(project)} && ${project.getBuildCommand( argv )} && pm2-runtime start ${project.findFile('ecosystem.config.cjs')}`, }: TestE2EOptions diff --git a/packages/wb/src/scripts/run.ts b/packages/wb/src/scripts/run.ts index 9a13ce8f..671d651c 100644 --- a/packages/wb/src/scripts/run.ts +++ b/packages/wb/src/scripts/run.ts @@ -6,7 +6,7 @@ import chalk from 'chalk'; import type { ArgumentsCamelCase, InferredOptionTypes } from 'yargs'; import { killPortProcessImmediatelyAndOnExit } from '../processUtils.js'; -import { project } from '../project.js'; +import type { Project } from '../project.js'; import { promisePool } from '../promisePool.js'; import type { sharedOptionsBuilder } from '../sharedOptionsBuilder.js'; @@ -21,13 +21,14 @@ const defaultOptions: Options = { export async function runWithSpawn( script: string, + project: Project, argv: Partial>>, opts: Options = defaultOptions ): Promise { - const [printableScript, runnableScript] = normalizeScript(script); - printStart(printableScript); + const [printableScript, runnableScript] = normalizeScript(script, project); + printStart(printableScript, project); if (argv.verbose) { - printStart(runnableScript, 'Start (raw)', true); + printStart(runnableScript, project, 'Start (raw)', true); } if (argv.dryRun) { printFinishedAndExitIfNeeded(printableScript, 0, opts); @@ -40,6 +41,7 @@ export async function runWithSpawn( } const ret = await spawnAsync(runnableScript, undefined, { cwd: project.dirPath, + env: project.env, shell: true, stdio: 'inherit', timeout: opts?.timeout, @@ -50,38 +52,19 @@ export async function runWithSpawn( return ret.status ?? 1; } -export async function runOnEachWorkspaceIfNeeded( - argv: Partial>> -): Promise { - if (!project.packageJson.workspaces) return; - - const args = process.argv.slice(2); - const index = args.findIndex((arg) => ['-w', '--working-dir', '--workingDir'].includes(arg)); - if (index >= 0) { - args.splice(index, 2); - } - - // Disable interactive mode - process.env['CI'] = '1'; - await runWithSpawn( - ['yarn', 'workspaces', 'foreach', '--all', '--exclude', project.name, '--verbose', 'run', 'wb', ...args].join(' '), - argv - ); - process.exit(0); -} - export function runWithSpawnInParallel( script: string, + project: Project, argv: Partial>>, opts: Options = defaultOptions ): Promise { return promisePool.run(async () => { - const [printableScript, runnableScript] = normalizeScript(script); - printStart(printableScript, 'Start (parallel)', true); + const [printableScript, runnableScript] = normalizeScript(script, project); + printStart(printableScript, project, 'Start (parallel)', true); if (argv.dryRun) { - printStart(printableScript, 'Started (log)'); + printStart(printableScript, project, 'Started (log)'); if (argv.verbose) { - printStart(runnableScript, 'Started (raw)', true); + printStart(runnableScript, project, 'Started (raw)', true); } printFinishedAndExitIfNeeded(printableScript, 0, opts); return; @@ -89,6 +72,7 @@ export function runWithSpawnInParallel( const ret = await spawnAsync(runnableScript, undefined, { cwd: project.dirPath, + env: project.env, shell: true, stdio: 'pipe', timeout: opts?.timeout, @@ -96,9 +80,9 @@ export function runWithSpawnInParallel( killOnExit: true, verbose: argv.verbose, }); - printStart(printableScript, 'Started (log)'); + printStart(printableScript, project, 'Started (log)'); if (argv.verbose) { - printStart(runnableScript, 'Started (raw)', true); + printStart(runnableScript, project, 'Started (raw)', true); } const out = ret.stdout.trim(); if (out) console.info(out); @@ -106,8 +90,8 @@ export function runWithSpawnInParallel( }); } -function normalizeScript(script: string): [string, string] { - const binExists = addBinPathsToEnv(); +function normalizeScript(script: string, project: Project): [string, string] { + const binExists = addBinPathsToEnv(project); const newScript = script .replaceAll('\n', '') .replaceAll(/\s\s+/g, ' ') @@ -116,7 +100,7 @@ function normalizeScript(script: string): [string, string] { return [newScript.replaceAll('YARN ', 'yarn '), newScript.replaceAll('YARN ', binExists ? '' : 'yarn ')]; } -export function printStart(normalizedScript: string, prefix = 'Start', weak = false): void { +export function printStart(normalizedScript: string, project: Project, prefix = 'Start', weak = false): void { console.info( '\n' + (weak ? chalk.gray : chalk.cyan)(chalk.bold(`${prefix}:`), normalizedScript) + @@ -142,7 +126,7 @@ export function printFinishedAndExitIfNeeded( let addedBinPaths = false; let binFound = false; -function addBinPathsToEnv(): boolean { +function addBinPathsToEnv(project: Project): boolean { if (addedBinPaths) return binFound; addedBinPaths = true; @@ -150,7 +134,7 @@ function addBinPathsToEnv(): boolean { for (;;) { const binPath = path.join(currentPath, 'node_modules', '.bin'); if (fs.existsSync(binPath)) { - process.env.PATH = `${binPath}:${process.env.PATH}`; + project.env.PATH = `${binPath}:${project.env.PATH}`; binFound = true; } diff --git a/packages/wb/src/sharedOptionsBuilder.ts b/packages/wb/src/sharedOptionsBuilder.ts index 3a6f2da5..2c4f454e 100644 --- a/packages/wb/src/sharedOptionsBuilder.ts +++ b/packages/wb/src/sharedOptionsBuilder.ts @@ -13,9 +13,4 @@ export const sharedOptionsBuilder = { type: 'boolean', alias: 'd', }, - verbose: { - description: 'Whether to show verbose information', - type: 'boolean', - alias: 'v', - }, } as const; diff --git a/packages/wb/tests/buildIfNeeded.test.ts b/packages/wb/tests/buildIfNeeded.test.ts index 0131821c..5ab156bc 100644 --- a/packages/wb/tests/buildIfNeeded.test.ts +++ b/packages/wb/tests/buildIfNeeded.test.ts @@ -5,35 +5,34 @@ import path from 'node:path'; import { describe, expect, it } from 'vitest'; import { buildIfNeeded } from '../src/commands/buildIfNeeded.js'; -import { project } from '../src/project.js'; import { initializeProjectDirectory, tempDir } from './shared.js'; describe('buildIfNeeded', () => { it('app', async () => { - project.dirPath = path.join(tempDir, 'app'); - await initializeProjectDirectory(); + const dirPath = path.join(tempDir, 'app'); + await initializeProjectDirectory(dirPath); - child_process.execSync('git init', { cwd: project.dirPath, stdio: 'inherit' }); - child_process.execSync('git add -A', { cwd: project.dirPath, stdio: 'inherit' }); - child_process.execSync('git config user.email "bot@willbooster.com"', { cwd: project.dirPath, stdio: 'inherit' }); - child_process.execSync('git config user.name "WillBooster Inc."', { cwd: project.dirPath, stdio: 'inherit' }); - child_process.execSync('git add -A', { cwd: project.dirPath, stdio: 'inherit' }); - child_process.execSync('git commit -m .', { cwd: project.dirPath, stdio: 'inherit' }); + child_process.execSync('git init', { cwd: dirPath, stdio: 'inherit' }); + child_process.execSync('git add -A', { cwd: dirPath, stdio: 'inherit' }); + child_process.execSync('git config user.email "bot@willbooster.com"', { cwd: dirPath, stdio: 'inherit' }); + child_process.execSync('git config user.name "WillBooster Inc."', { cwd: dirPath, stdio: 'inherit' }); + child_process.execSync('git add -A', { cwd: dirPath, stdio: 'inherit' }); + child_process.execSync('git commit -m .', { cwd: dirPath, stdio: 'inherit' }); const command = 'echo build'; - expect(await buildIfNeeded({ command })).toBe(true); - expect(await buildIfNeeded({ command })).toBe(false); + expect(await buildIfNeeded({ command }, dirPath)).toBe(true); + expect(await buildIfNeeded({ command }, dirPath)).toBe(false); - await fs.promises.writeFile(path.join(project.dirPath, 'index.js'), `console.log('Hello'); console.log('Hello');`); - expect(await buildIfNeeded({ command })).toBe(true); - expect(await buildIfNeeded({ command })).toBe(false); + await fs.promises.writeFile(path.join(dirPath, 'index.js'), `console.log('Hello'); console.log('Hello');`); + expect(await buildIfNeeded({ command }, dirPath)).toBe(true); + expect(await buildIfNeeded({ command }, dirPath)).toBe(false); - await fs.promises.writeFile(path.join(project.dirPath, 'README.md'), `# test-fixtures/app/`); - expect(await buildIfNeeded({ command })).toBe(false); + await fs.promises.writeFile(path.join(dirPath, 'README.md'), `# test-fixtures/app/`); + expect(await buildIfNeeded({ command }, dirPath)).toBe(false); await fs.promises.writeFile( - path.join(project.dirPath, 'package.json'), + path.join(dirPath, 'package.json'), JSON.stringify( { name: '@test-fixtures/app2', @@ -42,6 +41,6 @@ describe('buildIfNeeded', () => { 2 ) ); - expect(await buildIfNeeded({ command })).toBe(false); + expect(await buildIfNeeded({ command }, dirPath)).toBe(false); }); }, 30_000); diff --git a/packages/wb/tests/setup.test.ts b/packages/wb/tests/setup.test.ts index b70d21e0..b90a29f7 100644 --- a/packages/wb/tests/setup.test.ts +++ b/packages/wb/tests/setup.test.ts @@ -4,7 +4,6 @@ import path from 'node:path'; import { describe, expect, it } from 'vitest'; import { setup } from '../src/commands/setup.js'; -import { project } from '../src/project.js'; import { initializeProjectDirectory, tempDir } from './shared.js'; @@ -12,11 +11,11 @@ describe('setup', () => { it( 'blitz', async () => { - project.dirPath = path.join(tempDir, 'blitz'); - await initializeProjectDirectory(); + const dirPath = path.join(tempDir, 'blitz'); + await initializeProjectDirectory(dirPath); await setup({}); - const ret = child_process.spawnSync(`yarn start test -w ${project.dirPath} --ci`, { + const ret = child_process.spawnSync(`yarn start test -w ${dirPath} --ci`, { shell: true, stdio: 'inherit', }); diff --git a/packages/wb/tests/shared.ts b/packages/wb/tests/shared.ts index 631aee60..c96e8ffc 100644 --- a/packages/wb/tests/shared.ts +++ b/packages/wb/tests/shared.ts @@ -2,21 +2,19 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; -import { project } from '../src/project.js'; - export const tempDir = path.join(os.tmpdir(), 'shared'); -export async function initializeProjectDirectory(): Promise { - await fs.promises.rm(project.dirPath, { recursive: true, force: true }); - await fs.promises.cp(path.join('test-fixtures', path.basename(project.dirPath)), project.dirPath, { +export async function initializeProjectDirectory(dirPath: string): Promise { + await fs.promises.rm(dirPath, { recursive: true, force: true }); + await fs.promises.cp(path.join('test-fixtures', path.basename(dirPath)), dirPath, { force: true, recursive: true, }); - await fs.promises.cp(path.join('..', '..', '.yarn'), path.join(project.dirPath, '.yarn'), { + await fs.promises.cp(path.join('..', '..', '.yarn'), path.join(dirPath, '.yarn'), { force: true, recursive: true, }); - await fs.promises.cp(path.join('..', '..', '.yarnrc.yml'), path.join(project.dirPath, '.yarnrc.yml'), { + await fs.promises.cp(path.join('..', '..', '.yarnrc.yml'), path.join(dirPath, '.yarnrc.yml'), { force: true, }); } diff --git a/packages/wb/tests/typecheck.test.ts b/packages/wb/tests/typecheck.test.ts index f4feef12..cfe2510f 100644 --- a/packages/wb/tests/typecheck.test.ts +++ b/packages/wb/tests/typecheck.test.ts @@ -3,28 +3,26 @@ import path from 'node:path'; import { describe, expect, it } from 'vitest'; -import { project } from '../src/project.js'; - import { initializeProjectDirectory, tempDir } from './shared.js'; describe('typecheck', () => { it( 'monorepo', async () => { - project.dirPath = path.join(tempDir, 'monorepo'); - await initializeProjectDirectory(); + const dirPath = path.join(tempDir, 'monorepo'); + await initializeProjectDirectory(dirPath); // '--no-immutable' avoid blocking 'yarn install' even on CI child_process.spawnSync('yarn --no-immutable', { shell: true, stdio: 'inherit', - cwd: project.dirPath, + cwd: dirPath, }); child_process.spawnSync('yarn build', { shell: true, stdio: 'inherit', }); - const ret = child_process.spawnSync(`node dist/index.js typecheck -w ${project.dirPath}`, { + const ret = child_process.spawnSync(`node dist/index.js typecheck -w ${dirPath}`, { shell: true, stdio: 'inherit', }); From 601450facd51795c1b36771df402b7c6b33b6c6b Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Mon, 30 Oct 2023 20:04:51 +0900 Subject: [PATCH 12/21] . --- packages/shared-lib-blitz-next/package.json | 2 +- packages/shared-lib-node/package.json | 2 +- packages/shared-lib-node/src/index.ts | 2 +- packages/shared-lib-react/package.json | 14 +- packages/shared-lib/package.json | 2 +- packages/wb/package.json | 4 +- packages/wb/src/project.ts | 58 +- packages/wb/tsconfig.json | 2 +- yarn.lock | 574 ++++++++++---------- 9 files changed, 357 insertions(+), 303 deletions(-) diff --git a/packages/shared-lib-blitz-next/package.json b/packages/shared-lib-blitz-next/package.json index 25dddd70..cfcff754 100644 --- a/packages/shared-lib-blitz-next/package.json +++ b/packages/shared-lib-blitz-next/package.json @@ -43,7 +43,7 @@ "@willbooster/eslint-config-ts": "10.5.1", "@willbooster/prettier-config": "9.1.2", "blitz": "2.0.0-beta.34", - "build-ts": "11.0.8", + "build-ts": "11.0.9", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/shared-lib-node/package.json b/packages/shared-lib-node/package.json index bb418769..d60bf35b 100644 --- a/packages/shared-lib-node/package.json +++ b/packages/shared-lib-node/package.json @@ -47,7 +47,7 @@ "@typescript-eslint/parser": "6.9.0", "@willbooster/eslint-config-ts": "10.5.1", "@willbooster/prettier-config": "9.1.2", - "build-ts": "11.0.8", + "build-ts": "11.0.9", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/shared-lib-node/src/index.ts b/packages/shared-lib-node/src/index.ts index ced9dcbb..19110a4a 100644 --- a/packages/shared-lib-node/src/index.ts +++ b/packages/shared-lib-node/src/index.ts @@ -3,8 +3,8 @@ export { readAndApplyEnvironmentVariables, removeNpmAndYarnEnvironmentVariables, yargsOptionsBuilderForEnv, - EnvReaderOptions, } from './env.js'; +export type { EnvReaderOptions } from './env.js'; export { existsAsync } from './exists.js'; export { calculateHashFromFiles, canSkipSeed, updateHashFromFiles } from './hash.js'; export { spawnAsync } from './spawn.js'; diff --git a/packages/shared-lib-react/package.json b/packages/shared-lib-react/package.json index 2f88c2ba..95bf7f59 100644 --- a/packages/shared-lib-react/package.json +++ b/packages/shared-lib-react/package.json @@ -35,14 +35,14 @@ "devDependencies": { "@babel/core": "7.23.2", "@mdx-js/react": "3.0.0", - "@storybook/addon-actions": "7.5.1", - "@storybook/addon-docs": "7.5.1", - "@storybook/addon-essentials": "7.5.1", - "@storybook/addon-interactions": "7.5.1", - "@storybook/addon-links": "7.5.1", + "@storybook/addon-actions": "7.5.2", + "@storybook/addon-docs": "7.5.2", + "@storybook/addon-essentials": "7.5.2", + "@storybook/addon-interactions": "7.5.2", + "@storybook/addon-links": "7.5.2", "@storybook/builder-webpack4": "6.5.16", "@storybook/manager-webpack4": "6.5.16", - "@storybook/react": "7.5.1", + "@storybook/react": "7.5.2", "@storybook/testing-library": "0.2.2", "@types/eslint": "8.44.6", "@types/micromatch": "4.0.4", @@ -53,7 +53,7 @@ "@willbooster/eslint-config-ts-react": "10.1.9", "@willbooster/prettier-config": "9.1.2", "babel-loader": "9.1.3", - "build-ts": "11.0.8", + "build-ts": "11.0.9", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/shared-lib/package.json b/packages/shared-lib/package.json index 43dfef7f..b5997bd4 100644 --- a/packages/shared-lib/package.json +++ b/packages/shared-lib/package.json @@ -42,7 +42,7 @@ "@typescript-eslint/parser": "6.9.0", "@willbooster/eslint-config-ts": "10.5.1", "@willbooster/prettier-config": "9.1.2", - "build-ts": "11.0.8", + "build-ts": "11.0.9", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/wb/package.json b/packages/wb/package.json index 187c3901..94881530 100644 --- a/packages/wb/package.json +++ b/packages/wb/package.json @@ -39,8 +39,8 @@ "@typescript-eslint/parser": "6.9.0", "@willbooster/eslint-config-ts": "10.5.1", "@willbooster/prettier-config": "9.1.2", - "at-decorators": "1.2.0", - "build-ts": "11.0.8", + "at-decorators": "1.2.2", + "build-ts": "11.0.9", "eslint": "8.52.0", "eslint-config-prettier": "9.0.0", "eslint-import-resolver-typescript": "3.6.1", diff --git a/packages/wb/src/project.ts b/packages/wb/src/project.ts index 86d4f611..2e969726 100644 --- a/packages/wb/src/project.ts +++ b/packages/wb/src/project.ts @@ -3,11 +3,65 @@ import path from 'node:path'; import type { EnvReaderOptions } from '@willbooster/shared-lib-node/src'; import { readEnvironmentVariables } from '@willbooster/shared-lib-node/src'; -import { memoizeOne } from 'at-decorators'; import type { PackageJson } from 'type-fest'; import type { ScriptArgv } from './scripts/builder.js'; +/** + * A memoization decorator/function that caches the results of the latest method/getter/function call to improve performance. + * This decorator/function can be applied to methods and getters in a class as a decorator, and functions without context as a function. + * The cache only stores the latest value. When a new value is computed, the previous cached value is replaced. + * + * @template This The type of the `this` context within the method, getter or function. + * @template Args The types of the arguments to the method, getter or function. + * @template Return The return type of the method, getter or function. + * + * @param {Function | keyof This} target The method, function or the name of getter to be memoized. + * @param {ClassMethodDecoratorContext | ClassGetterDecoratorContext} [context] The context in which the decorator is being applied. Optional for standard functions. + * + * @returns {Function} A new function that wraps the original method or getter, function with caching logic. + */ +export function memoizeOne( + target: ((this: This, ...args: Args) => Return) | ((...args: Args) => Return) | keyof This, + context?: + | ClassMethodDecoratorContext Return> + | ClassGetterDecoratorContext +): (this: This, ...args: Args) => Return { + let lastCache: Return; + + if (context?.kind === 'getter') { + let cached = false; + return function (this: This): Return { + console.log(`Entering getter ${String(context.name)}.`); + + if (!cached) { + cached = true; + lastCache = (target as (this: This) => Return).call(this); + } + + console.log(`Exiting getter ${String(context.name)}.`); + return lastCache; + }; + } + + let lastCacheKey: string; + + return function (this: This, ...args: Args): Return { + console.log(`Entering ${context ? `method ${String(context.name)}` : 'function'}(${JSON.stringify(args)}).`); + + const key = JSON.stringify(args); + if (lastCacheKey !== key) { + lastCacheKey = key; + lastCache = context + ? (target as (this: This, ...args: Args) => Return).call(this, ...args) + : (target as (...args: Args) => Return)(...args); + } + + console.log(`Exiting ${context ? `method ${String(context.name)}` : 'function'}.`); + return lastCache; + }; +} + export class Project { private _dirPath: string; private _pathByName = new Map(); @@ -139,7 +193,7 @@ export function findRootAndSelfProjects( const thisProject = new Project(dirPath, argv); let rootProject = thisProject; - if (!thisProject.packageJson.workspaces && path.dirname(dirPath) === 'packages') { + 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/tsconfig.json b/packages/wb/tsconfig.json index 3b6f0ef1..18d308ba 100644 --- a/packages/wb/tsconfig.json +++ b/packages/wb/tsconfig.json @@ -12,7 +12,7 @@ "skipLibCheck": true, "sourceMap": true, "strict": true, - "target": "ESNext", + "target": "ES2022", "typeRoots": ["../../node_modules/@types", "../../@types", "./@types"] }, "include": ["scripts/**/*", "src/**/*", "tests/**/*"] diff --git a/yarn.lock b/yarn.lock index b3afad07..142f59f9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4059,18 +4059,18 @@ __metadata: languageName: node linkType: hard -"@storybook/addon-actions@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/addon-actions@npm:7.5.1" +"@storybook/addon-actions@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/addon-actions@npm:7.5.2" dependencies: - "@storybook/client-logger": "npm:7.5.1" - "@storybook/components": "npm:7.5.1" - "@storybook/core-events": "npm:7.5.1" + "@storybook/client-logger": "npm:7.5.2" + "@storybook/components": "npm:7.5.2" + "@storybook/core-events": "npm:7.5.2" "@storybook/global": "npm:^5.0.0" - "@storybook/manager-api": "npm:7.5.1" - "@storybook/preview-api": "npm:7.5.1" - "@storybook/theming": "npm:7.5.1" - "@storybook/types": "npm:7.5.1" + "@storybook/manager-api": "npm:7.5.2" + "@storybook/preview-api": "npm:7.5.2" + "@storybook/theming": "npm:7.5.2" + "@storybook/types": "npm:7.5.2" dequal: "npm:^2.0.2" lodash: "npm:^4.17.21" polished: "npm:^4.2.2" @@ -4087,22 +4087,22 @@ __metadata: optional: true react-dom: optional: true - checksum: 9248c4c9e32a6fedd73a370b4b255ba36cbb8f253da910a7892270cc1010d9eadf3f8154efc4c2b46a8e82f03ee3ee42e7fb845d8d829adc513f686ffa7c7877 + checksum: 9bc4806dbcbedb6fa745ce011c1119ef20414bfd6e53f29d5f2b25753d0e2884b8f65e9529f8f33d625dce62ab1f264d582f1c9e1fa818c0f99b9cffb5dbf426 languageName: node linkType: hard -"@storybook/addon-backgrounds@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/addon-backgrounds@npm:7.5.1" +"@storybook/addon-backgrounds@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/addon-backgrounds@npm:7.5.2" dependencies: - "@storybook/client-logger": "npm:7.5.1" - "@storybook/components": "npm:7.5.1" - "@storybook/core-events": "npm:7.5.1" + "@storybook/client-logger": "npm:7.5.2" + "@storybook/components": "npm:7.5.2" + "@storybook/core-events": "npm:7.5.2" "@storybook/global": "npm:^5.0.0" - "@storybook/manager-api": "npm:7.5.1" - "@storybook/preview-api": "npm:7.5.1" - "@storybook/theming": "npm:7.5.1" - "@storybook/types": "npm:7.5.1" + "@storybook/manager-api": "npm:7.5.2" + "@storybook/preview-api": "npm:7.5.2" + "@storybook/theming": "npm:7.5.2" + "@storybook/types": "npm:7.5.2" memoizerific: "npm:^1.11.3" ts-dedent: "npm:^2.0.0" peerDependencies: @@ -4113,24 +4113,24 @@ __metadata: optional: true react-dom: optional: true - checksum: 6701e538983007f8c8b6c63f496c3639945d0336e3e14ae1cff885cff84c0b2dab4b8e9d6bdc5a8a8a9d51693796ffed95334b2ca4f6dee8d8a3cf50d02f20b2 + checksum: ba15b33ea3367b8b13c0ce7688ef8a06999ca8b029aa238a3d90ef45e056e29a48008d724cc9c27072c6651eee1b24c611ab9946974306dd2faf9c39540e4167 languageName: node linkType: hard -"@storybook/addon-controls@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/addon-controls@npm:7.5.1" +"@storybook/addon-controls@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/addon-controls@npm:7.5.2" dependencies: - "@storybook/blocks": "npm:7.5.1" - "@storybook/client-logger": "npm:7.5.1" - "@storybook/components": "npm:7.5.1" - "@storybook/core-common": "npm:7.5.1" - "@storybook/core-events": "npm:7.5.1" - "@storybook/manager-api": "npm:7.5.1" - "@storybook/node-logger": "npm:7.5.1" - "@storybook/preview-api": "npm:7.5.1" - "@storybook/theming": "npm:7.5.1" - "@storybook/types": "npm:7.5.1" + "@storybook/blocks": "npm:7.5.2" + "@storybook/client-logger": "npm:7.5.2" + "@storybook/components": "npm:7.5.2" + "@storybook/core-common": "npm:7.5.2" + "@storybook/core-events": "npm:7.5.2" + "@storybook/manager-api": "npm:7.5.2" + "@storybook/node-logger": "npm:7.5.2" + "@storybook/preview-api": "npm:7.5.2" + "@storybook/theming": "npm:7.5.2" + "@storybook/types": "npm:7.5.2" lodash: "npm:^4.17.21" ts-dedent: "npm:^2.0.0" peerDependencies: @@ -4141,29 +4141,29 @@ __metadata: optional: true react-dom: optional: true - checksum: ae4b7cdd547845820ab877ffb529c69cc1123776608bf84c673e7d5a10d6f2a6f3dc4e0e96514bfbbc261cca6274d9e5d931ce9e27b07dfc429953b37c59c707 + checksum: aadb53e36c576bce85998df5536d0f9e4fd07e826d2afad5c83ebab643396b8f9e2a021c67dafa31488f6435136ce09f8a65c74588cd78ed2406520504e6f138 languageName: node linkType: hard -"@storybook/addon-docs@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/addon-docs@npm:7.5.1" +"@storybook/addon-docs@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/addon-docs@npm:7.5.2" dependencies: "@jest/transform": "npm:^29.3.1" "@mdx-js/react": "npm:^2.1.5" - "@storybook/blocks": "npm:7.5.1" - "@storybook/client-logger": "npm:7.5.1" - "@storybook/components": "npm:7.5.1" - "@storybook/csf-plugin": "npm:7.5.1" - "@storybook/csf-tools": "npm:7.5.1" + "@storybook/blocks": "npm:7.5.2" + "@storybook/client-logger": "npm:7.5.2" + "@storybook/components": "npm:7.5.2" + "@storybook/csf-plugin": "npm:7.5.2" + "@storybook/csf-tools": "npm:7.5.2" "@storybook/global": "npm:^5.0.0" "@storybook/mdx2-csf": "npm:^1.0.0" - "@storybook/node-logger": "npm:7.5.1" - "@storybook/postinstall": "npm:7.5.1" - "@storybook/preview-api": "npm:7.5.1" - "@storybook/react-dom-shim": "npm:7.5.1" - "@storybook/theming": "npm:7.5.1" - "@storybook/types": "npm:7.5.1" + "@storybook/node-logger": "npm:7.5.2" + "@storybook/postinstall": "npm:7.5.2" + "@storybook/preview-api": "npm:7.5.2" + "@storybook/react-dom-shim": "npm:7.5.2" + "@storybook/theming": "npm:7.5.2" + "@storybook/types": "npm:7.5.2" fs-extra: "npm:^11.1.0" remark-external-links: "npm:^8.0.0" remark-slug: "npm:^6.0.0" @@ -4171,60 +4171,60 @@ __metadata: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: ae0662ed91f6420110d2707133feb976644bb9536fa9601437a905c4e13f72ef1aec3540e209276ec429356bf8073dd02143ba40aeac9881381802d5429da633 - languageName: node - linkType: hard - -"@storybook/addon-essentials@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/addon-essentials@npm:7.5.1" - dependencies: - "@storybook/addon-actions": "npm:7.5.1" - "@storybook/addon-backgrounds": "npm:7.5.1" - "@storybook/addon-controls": "npm:7.5.1" - "@storybook/addon-docs": "npm:7.5.1" - "@storybook/addon-highlight": "npm:7.5.1" - "@storybook/addon-measure": "npm:7.5.1" - "@storybook/addon-outline": "npm:7.5.1" - "@storybook/addon-toolbars": "npm:7.5.1" - "@storybook/addon-viewport": "npm:7.5.1" - "@storybook/core-common": "npm:7.5.1" - "@storybook/manager-api": "npm:7.5.1" - "@storybook/node-logger": "npm:7.5.1" - "@storybook/preview-api": "npm:7.5.1" + checksum: c4f973b687fc0e5011e000fe20f53a14d7837d596cc8d9872b0261cc2d57d7ef8d9f3de9389c9e3c0e3a7a434af24f9a05aca8dddc6f2cf6f2f5055f54ee95ef + languageName: node + linkType: hard + +"@storybook/addon-essentials@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/addon-essentials@npm:7.5.2" + dependencies: + "@storybook/addon-actions": "npm:7.5.2" + "@storybook/addon-backgrounds": "npm:7.5.2" + "@storybook/addon-controls": "npm:7.5.2" + "@storybook/addon-docs": "npm:7.5.2" + "@storybook/addon-highlight": "npm:7.5.2" + "@storybook/addon-measure": "npm:7.5.2" + "@storybook/addon-outline": "npm:7.5.2" + "@storybook/addon-toolbars": "npm:7.5.2" + "@storybook/addon-viewport": "npm:7.5.2" + "@storybook/core-common": "npm:7.5.2" + "@storybook/manager-api": "npm:7.5.2" + "@storybook/node-logger": "npm:7.5.2" + "@storybook/preview-api": "npm:7.5.2" ts-dedent: "npm:^2.0.0" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 9abf4a5bc62e1884393ca33a1ac9d3ca69a36bcaca51281dbe59e3c2f61e30acd8ddc3e99150fa5d88d999036f9899c711573ebb439cecda5dc359ab307c18da + checksum: 9c14d331047818bbd2d369de2790206a7769598fa45d24a41f5b985e11f2a389b50be4f4636396e2f19dd19a00c71f54efda05acab8ee86764379aef4c9cd630 languageName: node linkType: hard -"@storybook/addon-highlight@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/addon-highlight@npm:7.5.1" +"@storybook/addon-highlight@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/addon-highlight@npm:7.5.2" dependencies: - "@storybook/core-events": "npm:7.5.1" + "@storybook/core-events": "npm:7.5.2" "@storybook/global": "npm:^5.0.0" - "@storybook/preview-api": "npm:7.5.1" - checksum: c15ac6b84c2ca2c91bdce71b8ebcb331cdbd85ade0cd1f7c4e4bc6b2b63d2639daf58405f54728ccae0c48db8d82626312f29ff589b8e24559f6407a4caab1f3 + "@storybook/preview-api": "npm:7.5.2" + checksum: bb97505e425f37cdad2ab8ea3159da6a93fe827cf6e7077c13e325f57ee033321ba9e7c1f08f082bdaf5c872f4ee884697e040d8054113bf73fdad10b2b65b10 languageName: node linkType: hard -"@storybook/addon-interactions@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/addon-interactions@npm:7.5.1" +"@storybook/addon-interactions@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/addon-interactions@npm:7.5.2" dependencies: - "@storybook/client-logger": "npm:7.5.1" - "@storybook/components": "npm:7.5.1" - "@storybook/core-common": "npm:7.5.1" - "@storybook/core-events": "npm:7.5.1" + "@storybook/client-logger": "npm:7.5.2" + "@storybook/components": "npm:7.5.2" + "@storybook/core-common": "npm:7.5.2" + "@storybook/core-events": "npm:7.5.2" "@storybook/global": "npm:^5.0.0" - "@storybook/instrumenter": "npm:7.5.1" - "@storybook/manager-api": "npm:7.5.1" - "@storybook/preview-api": "npm:7.5.1" - "@storybook/theming": "npm:7.5.1" - "@storybook/types": "npm:7.5.1" + "@storybook/instrumenter": "npm:7.5.2" + "@storybook/manager-api": "npm:7.5.2" + "@storybook/preview-api": "npm:7.5.2" + "@storybook/theming": "npm:7.5.2" + "@storybook/types": "npm:7.5.2" jest-mock: "npm:^27.0.6" polished: "npm:^4.2.2" ts-dedent: "npm:^2.2.0" @@ -4236,22 +4236,22 @@ __metadata: optional: true react-dom: optional: true - checksum: 6ac3528e2f4a2eb29a14949e07982ac8246623dc45a9956c86180efcd78d57aeea0e49748d56d5031d145b4e0da989df52b4e6ef04276c3a6844e52e8aec3d12 + checksum: 06feadb68a482698cce2d1cc0ccbe85af5ee9b69183768686ee0ef1fb049c28acd546cb04419e45ee6a43262724eb27a9c930f7ec936222f78ca7e77f83f23d6 languageName: node linkType: hard -"@storybook/addon-links@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/addon-links@npm:7.5.1" +"@storybook/addon-links@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/addon-links@npm:7.5.2" dependencies: - "@storybook/client-logger": "npm:7.5.1" - "@storybook/core-events": "npm:7.5.1" + "@storybook/client-logger": "npm:7.5.2" + "@storybook/core-events": "npm:7.5.2" "@storybook/csf": "npm:^0.1.0" "@storybook/global": "npm:^5.0.0" - "@storybook/manager-api": "npm:7.5.1" - "@storybook/preview-api": "npm:7.5.1" - "@storybook/router": "npm:7.5.1" - "@storybook/types": "npm:7.5.1" + "@storybook/manager-api": "npm:7.5.2" + "@storybook/preview-api": "npm:7.5.2" + "@storybook/router": "npm:7.5.2" + "@storybook/types": "npm:7.5.2" prop-types: "npm:^15.7.2" ts-dedent: "npm:^2.0.0" peerDependencies: @@ -4262,21 +4262,21 @@ __metadata: optional: true react-dom: optional: true - checksum: ea438d8e07a3daa338c4be948300ae07ddda85166e128de2e385a9caea0faba3797215a8ce255e4c15a486b5c844de49c7c1a60170c34d96ee00e261e0c19eae + checksum: 20a33a8912e956856cf5f3f2931451fd19deab923729da0ac178f3cd78983faed94e312eaf80ebc76a9423b280a678335d24ff6202b28ec49affb66c7e402449 languageName: node linkType: hard -"@storybook/addon-measure@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/addon-measure@npm:7.5.1" +"@storybook/addon-measure@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/addon-measure@npm:7.5.2" dependencies: - "@storybook/client-logger": "npm:7.5.1" - "@storybook/components": "npm:7.5.1" - "@storybook/core-events": "npm:7.5.1" + "@storybook/client-logger": "npm:7.5.2" + "@storybook/components": "npm:7.5.2" + "@storybook/core-events": "npm:7.5.2" "@storybook/global": "npm:^5.0.0" - "@storybook/manager-api": "npm:7.5.1" - "@storybook/preview-api": "npm:7.5.1" - "@storybook/types": "npm:7.5.1" + "@storybook/manager-api": "npm:7.5.2" + "@storybook/preview-api": "npm:7.5.2" + "@storybook/types": "npm:7.5.2" tiny-invariant: "npm:^1.3.1" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4286,21 +4286,21 @@ __metadata: optional: true react-dom: optional: true - checksum: 0600db8c5a60a710e65e14cb21b1663f513d2574472f39bb4dc5b654c38982f3b6da7ea7769bfeb892a77303e9c9189b469ed5d46c501921b44c3124eff65e05 + checksum: b05f74e6a3333fd88b0c47c83a6ff2e713869b02577b3c382b063a8398a175be58d4547b5e8da26f24da5406ed6ae6c83139fc2b60e92de51c53c1e6f3927575 languageName: node linkType: hard -"@storybook/addon-outline@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/addon-outline@npm:7.5.1" +"@storybook/addon-outline@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/addon-outline@npm:7.5.2" dependencies: - "@storybook/client-logger": "npm:7.5.1" - "@storybook/components": "npm:7.5.1" - "@storybook/core-events": "npm:7.5.1" + "@storybook/client-logger": "npm:7.5.2" + "@storybook/components": "npm:7.5.2" + "@storybook/core-events": "npm:7.5.2" "@storybook/global": "npm:^5.0.0" - "@storybook/manager-api": "npm:7.5.1" - "@storybook/preview-api": "npm:7.5.1" - "@storybook/types": "npm:7.5.1" + "@storybook/manager-api": "npm:7.5.2" + "@storybook/preview-api": "npm:7.5.2" + "@storybook/types": "npm:7.5.2" ts-dedent: "npm:^2.0.0" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4310,19 +4310,19 @@ __metadata: optional: true react-dom: optional: true - checksum: 0183e8778ea8a5ef8a1fc914e06a9c93156bcce5faf374390c93398b1fc276e075b4e0b9b6690c3bfec09d70611fc8cda13ad3ad2beaf9e041e5c358c774e2d4 + checksum: 1b4e0e0acced77a2cdf8656fcc606ae0ab87ffe634c0b87d031f564c0c94c2f9277b5ad205d702172b04584b3b9b3ebd32d71158354e07d38065b0b3538878c7 languageName: node linkType: hard -"@storybook/addon-toolbars@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/addon-toolbars@npm:7.5.1" +"@storybook/addon-toolbars@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/addon-toolbars@npm:7.5.2" dependencies: - "@storybook/client-logger": "npm:7.5.1" - "@storybook/components": "npm:7.5.1" - "@storybook/manager-api": "npm:7.5.1" - "@storybook/preview-api": "npm:7.5.1" - "@storybook/theming": "npm:7.5.1" + "@storybook/client-logger": "npm:7.5.2" + "@storybook/components": "npm:7.5.2" + "@storybook/manager-api": "npm:7.5.2" + "@storybook/preview-api": "npm:7.5.2" + "@storybook/theming": "npm:7.5.2" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -4331,21 +4331,21 @@ __metadata: optional: true react-dom: optional: true - checksum: 3db60ffda02fb77321257a88eee9ae396d2cbe0e4f063b9565adbd646c55a02bad00b282173282a6e41f0ae1a154dcfe5fcaff79399f0670d2fd9d56f567e54e + checksum: 885f32b39e8789cfb94d2f6df0502326e573b3c0296f61c7fb7efd32e8128ea7b3597da9b82b7e8e1093df7327fbb30201820b635f3458c5f4bc87a63c19f755 languageName: node linkType: hard -"@storybook/addon-viewport@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/addon-viewport@npm:7.5.1" +"@storybook/addon-viewport@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/addon-viewport@npm:7.5.2" dependencies: - "@storybook/client-logger": "npm:7.5.1" - "@storybook/components": "npm:7.5.1" - "@storybook/core-events": "npm:7.5.1" + "@storybook/client-logger": "npm:7.5.2" + "@storybook/components": "npm:7.5.2" + "@storybook/core-events": "npm:7.5.2" "@storybook/global": "npm:^5.0.0" - "@storybook/manager-api": "npm:7.5.1" - "@storybook/preview-api": "npm:7.5.1" - "@storybook/theming": "npm:7.5.1" + "@storybook/manager-api": "npm:7.5.2" + "@storybook/preview-api": "npm:7.5.2" + "@storybook/theming": "npm:7.5.2" memoizerific: "npm:^1.11.3" prop-types: "npm:^15.7.2" peerDependencies: @@ -4356,7 +4356,7 @@ __metadata: optional: true react-dom: optional: true - checksum: 2dad5761e5cf951d221084470076f7c587b07f50f064eba16317d31a3f1b80f694f286f1843fb9d4830649d7e57f76290c43de30cdb0856d99515c77c81db155 + checksum: 74c0c95434165ee1395282dcc5c5397bb00bc0c4637793ad936f10cd06701b3e05534d446def741b31240e840325740bf6f6f3bbf2d61d30b8b84bcb6d09ae4a languageName: node linkType: hard @@ -4410,21 +4410,21 @@ __metadata: languageName: node linkType: hard -"@storybook/blocks@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/blocks@npm:7.5.1" +"@storybook/blocks@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/blocks@npm:7.5.2" dependencies: - "@storybook/channels": "npm:7.5.1" - "@storybook/client-logger": "npm:7.5.1" - "@storybook/components": "npm:7.5.1" - "@storybook/core-events": "npm:7.5.1" + "@storybook/channels": "npm:7.5.2" + "@storybook/client-logger": "npm:7.5.2" + "@storybook/components": "npm:7.5.2" + "@storybook/core-events": "npm:7.5.2" "@storybook/csf": "npm:^0.1.0" - "@storybook/docs-tools": "npm:7.5.1" + "@storybook/docs-tools": "npm:7.5.2" "@storybook/global": "npm:^5.0.0" - "@storybook/manager-api": "npm:7.5.1" - "@storybook/preview-api": "npm:7.5.1" - "@storybook/theming": "npm:7.5.1" - "@storybook/types": "npm:7.5.1" + "@storybook/manager-api": "npm:7.5.2" + "@storybook/preview-api": "npm:7.5.2" + "@storybook/theming": "npm:7.5.2" + "@storybook/types": "npm:7.5.2" "@types/lodash": "npm:^4.14.167" color-convert: "npm:^2.0.1" dequal: "npm:^2.0.2" @@ -4440,7 +4440,7 @@ __metadata: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 47542bc96d54fa858a98496560c656ae9eaa16ecb9c359d1490b9c7a260c63b065b7f5930f8df7d6b0b8ecdf994997edaf969f73805054b1c4bf9ed120b9a412 + checksum: 51feb0e4f9a2e1ec237a9d4357d874d194ee3e65e8a274314115cb778bb5f498c85ab5a27caf02d6aab6441d06eb4718638e22c682c5c2538072a49c1f9ca2c8 languageName: node linkType: hard @@ -4544,17 +4544,17 @@ __metadata: languageName: node linkType: hard -"@storybook/channels@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/channels@npm:7.5.1" +"@storybook/channels@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/channels@npm:7.5.2" dependencies: - "@storybook/client-logger": "npm:7.5.1" - "@storybook/core-events": "npm:7.5.1" + "@storybook/client-logger": "npm:7.5.2" + "@storybook/core-events": "npm:7.5.2" "@storybook/global": "npm:^5.0.0" qs: "npm:^6.10.0" telejson: "npm:^7.2.0" tiny-invariant: "npm:^1.3.1" - checksum: 25ea5765241ec71c8eb23bd98455054a155d9017a8235729f0b14c1592cc3ce264e0843bdd265a63d900c02c5470635e74ea8b1bff78f86c41ac46be1abfa932 + checksum: f6a9a32d94d28a1f07912383025072c5ba9c7be7759e2abdcfedc1be04ecbe8de58cc12d29e43adfdedfeb944b58e64f109337bd6c4a62caceb742c7d2b7ee96 languageName: node linkType: hard @@ -4599,12 +4599,12 @@ __metadata: languageName: node linkType: hard -"@storybook/client-logger@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/client-logger@npm:7.5.1" +"@storybook/client-logger@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/client-logger@npm:7.5.2" dependencies: "@storybook/global": "npm:^5.0.0" - checksum: aedb53847d282152afc5d8f5c1eef7107d2c6d788322bfa7e672f11079daa9cda3bd2f485291bf9553c86a1c92cff8431961bfce92ea5515b2806fd72da217e7 + checksum: 29ff2e4469125b733c0aa3aa51f927f0c140402be9613d35b378eb0824f7c23ab9a295d1b7c217254a1ff9d1517baa107ada9e601680637ada9fcfec5978bdb7 languageName: node linkType: hard @@ -4627,24 +4627,24 @@ __metadata: languageName: node linkType: hard -"@storybook/components@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/components@npm:7.5.1" +"@storybook/components@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/components@npm:7.5.2" dependencies: "@radix-ui/react-select": "npm:^1.2.2" "@radix-ui/react-toolbar": "npm:^1.0.4" - "@storybook/client-logger": "npm:7.5.1" + "@storybook/client-logger": "npm:7.5.2" "@storybook/csf": "npm:^0.1.0" "@storybook/global": "npm:^5.0.0" - "@storybook/theming": "npm:7.5.1" - "@storybook/types": "npm:7.5.1" + "@storybook/theming": "npm:7.5.2" + "@storybook/types": "npm:7.5.2" memoizerific: "npm:^1.11.3" use-resize-observer: "npm:^9.1.0" util-deprecate: "npm:^1.0.2" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 04699e50746e9953763b5644e9219095daba7ec96b4977b7113ad5e1c794a31fc233bec452eb09d5cc06c92525d0143d2601a6870be190fb9743dcd4d486e423 + checksum: b2779724251938a5ae235c0f93ccdf9fbe535772eee3929f9e7770c8bedecc809cdf9b363e100234083d2c02fe1c4604377c45c12c6afec222895dcf70be8271 languageName: node linkType: hard @@ -4683,13 +4683,13 @@ __metadata: languageName: node linkType: hard -"@storybook/core-client@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/core-client@npm:7.5.1" +"@storybook/core-client@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/core-client@npm:7.5.2" dependencies: - "@storybook/client-logger": "npm:7.5.1" - "@storybook/preview-api": "npm:7.5.1" - checksum: eb89a2ffad9646a4ba96471bbaa605e314cd6afbfe23fa3ddb4a0128e343a5d7dee7c0f5a5a28e2a2bea3c9d96d9505d9139efe05b0d24f863e25ce174eef042 + "@storybook/client-logger": "npm:7.5.2" + "@storybook/preview-api": "npm:7.5.2" + checksum: 01ccb726ab15a776be8f9ade5293969f5f75e5f2bf62d795164b7e3e4f283b0136380467de9057761f886a54d1c8083aac6d1268473ce4bbb94fa3d61f075edf languageName: node linkType: hard @@ -4757,13 +4757,13 @@ __metadata: languageName: node linkType: hard -"@storybook/core-common@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/core-common@npm:7.5.1" +"@storybook/core-common@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/core-common@npm:7.5.2" dependencies: - "@storybook/core-events": "npm:7.5.1" - "@storybook/node-logger": "npm:7.5.1" - "@storybook/types": "npm:7.5.1" + "@storybook/core-events": "npm:7.5.2" + "@storybook/node-logger": "npm:7.5.2" + "@storybook/types": "npm:7.5.2" "@types/find-cache-dir": "npm:^3.2.1" "@types/node": "npm:^18.0.0" "@types/node-fetch": "npm:^2.6.4" @@ -4784,7 +4784,7 @@ __metadata: pretty-hrtime: "npm:^1.0.3" resolve-from: "npm:^5.0.0" ts-dedent: "npm:^2.0.0" - checksum: 7d0af920e2b6ad591e580f922c51cf433da035b34e7b26c576b84f2d90ea9a8b3e6dfe6b6b89ef6f2909a4dae959db51ac639dc7943839f6c1fce244cb907172 + checksum: 189b80f0b66e36adfe3b0a1c753185001981ea7ae815e4f475ba9733a5f5a6676a64e97fcea94a4a4de9ac32e6deb4c76ad76b6c7547fe97ba1635b7778ac78c languageName: node linkType: hard @@ -4797,39 +4797,39 @@ __metadata: languageName: node linkType: hard -"@storybook/core-events@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/core-events@npm:7.5.1" +"@storybook/core-events@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/core-events@npm:7.5.2" dependencies: ts-dedent: "npm:^2.0.0" - checksum: 5d0b21480b437922527236cce0522c849fe4972bd073e74b322b5c77015ec2b447931ad67ef4ddd4cfdc16a7e6fe42ca12905338099902258c664c5c7238b3e2 + checksum: eb2e2cae5412ce18283cafa0c68f048145b23c79e626d8e76625e24d2a8f8ac171d5fd0d42d47ad4d1bfba278f436d5761cba866faebc04fbdaae55a60d41411 languageName: node linkType: hard -"@storybook/csf-plugin@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/csf-plugin@npm:7.5.1" +"@storybook/csf-plugin@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/csf-plugin@npm:7.5.2" dependencies: - "@storybook/csf-tools": "npm:7.5.1" + "@storybook/csf-tools": "npm:7.5.2" unplugin: "npm:^1.3.1" - checksum: 979060ef98e48d60645a265ad7f4eb7fadf760617612dc70b1c5b7368aa389795da0e7e8817a29b0b055a90e781de23ae24bc18f16679947a988bf327ece2af5 + checksum: 497f1b6086051919deb9350de9a3f3c6dcc9411f247f4729bb5920c7ddc8adffcc0456b9baf096edc5b75fbd3693a4b6662c2e4c9aeb9bee4f19e22fa866fc7a languageName: node linkType: hard -"@storybook/csf-tools@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/csf-tools@npm:7.5.1" +"@storybook/csf-tools@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/csf-tools@npm:7.5.2" dependencies: "@babel/generator": "npm:^7.22.9" "@babel/parser": "npm:^7.22.7" "@babel/traverse": "npm:^7.22.8" "@babel/types": "npm:^7.22.5" "@storybook/csf": "npm:^0.1.0" - "@storybook/types": "npm:7.5.1" + "@storybook/types": "npm:7.5.2" fs-extra: "npm:^11.1.0" recast: "npm:^0.23.1" ts-dedent: "npm:^2.0.0" - checksum: ec0c5100379beeb691b3bad6e9368f2946d1487f748562a3b4e2871af3541db13d26bd2a413b7dcbb756a6af874f161c091035a21fb60263795504636e640a82 + checksum: c1e70e7151b82cc2f5c66d7dbab45c29e1cf31d88ef2060fe32bd8e6e3f3746f2f9cacac9956856aceb23953ed781caeda4c70e3783f3e296dd1578a51d8be0b languageName: node linkType: hard @@ -4860,17 +4860,17 @@ __metadata: languageName: node linkType: hard -"@storybook/docs-tools@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/docs-tools@npm:7.5.1" +"@storybook/docs-tools@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/docs-tools@npm:7.5.2" dependencies: - "@storybook/core-common": "npm:7.5.1" - "@storybook/preview-api": "npm:7.5.1" - "@storybook/types": "npm:7.5.1" + "@storybook/core-common": "npm:7.5.2" + "@storybook/preview-api": "npm:7.5.2" + "@storybook/types": "npm:7.5.2" "@types/doctrine": "npm:^0.0.3" doctrine: "npm:^3.0.0" lodash: "npm:^4.17.21" - checksum: 7eccd668ac4fc50730482025044c3ebff96bd07bf9cfbee5212c4b89ebb3e18b3730c217044094bf3cf1114d4d4cabccb92485698b176222ec4a80dd19128a04 + checksum: a314844ab89f7cf88c39d0da1b87058e4f2e0b08e172f636eb8d020ab88f42e5859d5a93068b4eae16d61d20f0f254ed87a85bba0bbcfa38034a9c60d1769126 languageName: node linkType: hard @@ -4881,31 +4881,31 @@ __metadata: languageName: node linkType: hard -"@storybook/instrumenter@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/instrumenter@npm:7.5.1" +"@storybook/instrumenter@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/instrumenter@npm:7.5.2" dependencies: - "@storybook/channels": "npm:7.5.1" - "@storybook/client-logger": "npm:7.5.1" - "@storybook/core-events": "npm:7.5.1" + "@storybook/channels": "npm:7.5.2" + "@storybook/client-logger": "npm:7.5.2" + "@storybook/core-events": "npm:7.5.2" "@storybook/global": "npm:^5.0.0" - "@storybook/preview-api": "npm:7.5.1" - checksum: 57af56556fccb03a646c4ef2db546cced728460a29987c6d18e43450e93d864c73302a470f2b790cd1383d265946c1ef07dddb7f55523ebf51f431f9a1ae4bb1 + "@storybook/preview-api": "npm:7.5.2" + checksum: e7d5a92e8ddc66f82cd2be1baad99b1622d37081d21c37cf960c6e2e1360f8a9c4a7e26f1254aa7d881b060a9e1dea578f9b8d321a9cf1114dad45772abb9ea5 languageName: node linkType: hard -"@storybook/manager-api@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/manager-api@npm:7.5.1" +"@storybook/manager-api@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/manager-api@npm:7.5.2" dependencies: - "@storybook/channels": "npm:7.5.1" - "@storybook/client-logger": "npm:7.5.1" - "@storybook/core-events": "npm:7.5.1" + "@storybook/channels": "npm:7.5.2" + "@storybook/client-logger": "npm:7.5.2" + "@storybook/core-events": "npm:7.5.2" "@storybook/csf": "npm:^0.1.0" "@storybook/global": "npm:^5.0.0" - "@storybook/router": "npm:7.5.1" - "@storybook/theming": "npm:7.5.1" - "@storybook/types": "npm:7.5.1" + "@storybook/router": "npm:7.5.2" + "@storybook/theming": "npm:7.5.2" + "@storybook/types": "npm:7.5.2" dequal: "npm:^2.0.2" lodash: "npm:^4.17.21" memoizerific: "npm:^1.11.3" @@ -4916,7 +4916,7 @@ __metadata: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: ae2ea9081fc660bd7350eafeebe39275f2358f368dffa3f9117f385adc5eed399e0b33a8b26d5ea38e09d0088edcbeebd605d046b8ee87689b42cc77b3825598 + checksum: 13d2a04d2cce0ab35632dd48009a94f1335925fe83670982b0a906bf86881b4282c0a38074d2cffa195077c8025ab056be5d8d3516e6222e671b19bec4d92321 languageName: node linkType: hard @@ -4989,30 +4989,30 @@ __metadata: languageName: node linkType: hard -"@storybook/node-logger@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/node-logger@npm:7.5.1" - checksum: 4977191230f3a34efb644218c1092c293757be358224ce7cca8ad32e1f84f18c51b7bc564728b5b9350d4f1bb0c2feb8b08e22d29741c10e40c7c79c20a56a5d +"@storybook/node-logger@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/node-logger@npm:7.5.2" + checksum: 5ce6fb2d159d5a1f5396aa2e6b2e4d0b8a34f3458c3cdc7a0075eccf81668caffdcdeddab91ef144edfac5e341d9a6a18f77c43ba86076b14f124ce6fe7a863d languageName: node linkType: hard -"@storybook/postinstall@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/postinstall@npm:7.5.1" - checksum: 07793a47dd50b48005d61b9560c2a3647dc3bd73ffc8f14773211d7dd1b09e9a193b069e28304d6f0a46b6e9b1daca0740869e8af78b4642247daaab78bc0e7e +"@storybook/postinstall@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/postinstall@npm:7.5.2" + checksum: 2e7672e9408b2ba23bcaee8708634bced01c8a4e9acd1f4da2c67d241586fda8230450f5360a4699e49c5ba9b1a053e89cb6cc8cb9aa630feb05a7a5e7fa8ca0 languageName: node linkType: hard -"@storybook/preview-api@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/preview-api@npm:7.5.1" +"@storybook/preview-api@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/preview-api@npm:7.5.2" dependencies: - "@storybook/channels": "npm:7.5.1" - "@storybook/client-logger": "npm:7.5.1" - "@storybook/core-events": "npm:7.5.1" + "@storybook/channels": "npm:7.5.2" + "@storybook/client-logger": "npm:7.5.2" + "@storybook/core-events": "npm:7.5.2" "@storybook/csf": "npm:^0.1.0" "@storybook/global": "npm:^5.0.0" - "@storybook/types": "npm:7.5.1" + "@storybook/types": "npm:7.5.2" "@types/qs": "npm:^6.9.5" dequal: "npm:^2.0.2" lodash: "npm:^4.17.21" @@ -5021,7 +5021,7 @@ __metadata: synchronous-promise: "npm:^2.0.15" ts-dedent: "npm:^2.0.0" util-deprecate: "npm:^1.0.2" - checksum: dd600eeaf752def91b81816bdfe353edf4217a81fca76535e9bec98fff4d4614ada2eded486f0404c6e3304ef734d2945cf8e93bff7ab1753d2b75acd2925415 + checksum: 2b4f07dfb08bdf4eecaa475f946b8217a052f309759413c0c311f7bff28350975b789fe34f3a02ba43f40b3d0b59a302406a4144ea9d64c651813d7280e3d0aa languageName: node linkType: hard @@ -5052,27 +5052,27 @@ __metadata: languageName: node linkType: hard -"@storybook/react-dom-shim@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/react-dom-shim@npm:7.5.1" +"@storybook/react-dom-shim@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/react-dom-shim@npm:7.5.2" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 4ae5e7501495f16ddd2906ea0d95b496c3c99d18cc4198b97c58c81bd59c0ca5c803fe262f9023d8125060523e7234e4dc82d75c019a3a185cf071ddaa3a6c03 + checksum: 89d67d86be2855c2a494dd39f6c1068f54676a5d091e9a56f2ab7be2ae0d08a86cc56ae6e7432a37e4ff9e547f789ccd8afe54e8d96d734f9dd395caa98cd55f languageName: node linkType: hard -"@storybook/react@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/react@npm:7.5.1" +"@storybook/react@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/react@npm:7.5.2" dependencies: - "@storybook/client-logger": "npm:7.5.1" - "@storybook/core-client": "npm:7.5.1" - "@storybook/docs-tools": "npm:7.5.1" + "@storybook/client-logger": "npm:7.5.2" + "@storybook/core-client": "npm:7.5.2" + "@storybook/docs-tools": "npm:7.5.2" "@storybook/global": "npm:^5.0.0" - "@storybook/preview-api": "npm:7.5.1" - "@storybook/react-dom-shim": "npm:7.5.1" - "@storybook/types": "npm:7.5.1" + "@storybook/preview-api": "npm:7.5.2" + "@storybook/react-dom-shim": "npm:7.5.2" + "@storybook/types": "npm:7.5.2" "@types/escodegen": "npm:^0.0.6" "@types/estree": "npm:^0.0.51" "@types/node": "npm:^18.0.0" @@ -5094,7 +5094,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: b9bca9e619ba96b574f6098af12b6bda0fa5f792c35750656fa8b67b390e91e202c2ca5b841b04b90b9db091454b5c57eac1e58a74fd5e072ed0715d71c176a3 + checksum: af1a3d5d13c36155ae9717ec233fd272b351784f5ed60b8dd5fbe5c37aa025924b38e6348e9e6616091f3d6b90219b91ccf4b11e31fcef8e24a4c414cecb63dd languageName: node linkType: hard @@ -5114,17 +5114,17 @@ __metadata: languageName: node linkType: hard -"@storybook/router@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/router@npm:7.5.1" +"@storybook/router@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/router@npm:7.5.2" dependencies: - "@storybook/client-logger": "npm:7.5.1" + "@storybook/client-logger": "npm:7.5.2" memoizerific: "npm:^1.11.3" qs: "npm:^6.10.0" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 52f84e2c53d919d492d38cd18df745b82ec1d61b959a78bbf48664e48414b77da8474f009c6fb10f8dba6d4c6eb29fd44a1c6d3e10b37bac2b3a451113177c2f + checksum: 2746875990210cbcb96be8a5b014fc8314c2fc2e5c19b42cce0e3accea2b0f70bafe5b2342d3d93f686cbbe3977d82553c722947efb1e213ce82accfbad93678 languageName: node linkType: hard @@ -5192,30 +5192,30 @@ __metadata: languageName: node linkType: hard -"@storybook/theming@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/theming@npm:7.5.1" +"@storybook/theming@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/theming@npm:7.5.2" dependencies: "@emotion/use-insertion-effect-with-fallbacks": "npm:^1.0.0" - "@storybook/client-logger": "npm:7.5.1" + "@storybook/client-logger": "npm:7.5.2" "@storybook/global": "npm:^5.0.0" memoizerific: "npm:^1.11.3" peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - checksum: 2b59ac6bb41a024ca31e5a39daa1b46c52da03bc1d69f3e3f91173621a0d1928a722acebe63d1ff84f50e0bbc0a661f5f48bde36a40292e40c670674bdeaf53a + checksum: 1b113f32fcda056ba6e61806de71f35795260285b3467d30654e42d2c6e0b639baacc7ce62970dfbc7bee6fd1f823c410f85bd4db0c853bb8751206d033d2e7e languageName: node linkType: hard -"@storybook/types@npm:7.5.1": - version: 7.5.1 - resolution: "@storybook/types@npm:7.5.1" +"@storybook/types@npm:7.5.2": + version: 7.5.2 + resolution: "@storybook/types@npm:7.5.2" dependencies: - "@storybook/channels": "npm:7.5.1" + "@storybook/channels": "npm:7.5.2" "@types/babel__core": "npm:^7.0.0" "@types/express": "npm:^4.7.0" file-system-cache: "npm:2.3.0" - checksum: 8f3aeb459f0b1af5c6ed8c6bf79d1be9089078733ef2b7e6353862d1238d0bc5a303749210ad268a220e9b79c9ebc6b5f8ef7e1fef423a5d7e4bb6c3ed627bfc + checksum: 482ee61ebdce9f04a2d5f839e2da5653bab63cf0c9acda6a7a7876fd16ae32f1db9a979358343495d979af266c5c1fbd7dffae17c7910118877cc3daca7e4337 languageName: node linkType: hard @@ -6445,7 +6445,7 @@ __metadata: "@willbooster/eslint-config-ts": "npm:10.5.1" "@willbooster/prettier-config": "npm:9.1.2" blitz: "npm:2.0.0-beta.34" - build-ts: "npm:11.0.8" + build-ts: "npm:11.0.9" eslint: "npm:8.52.0" eslint-config-prettier: "npm:9.0.0" eslint-import-resolver-typescript: "npm:3.6.1" @@ -6483,7 +6483,7 @@ __metadata: "@typescript-eslint/parser": "npm:6.9.0" "@willbooster/eslint-config-ts": "npm:10.5.1" "@willbooster/prettier-config": "npm:9.1.2" - build-ts: "npm:11.0.8" + build-ts: "npm:11.0.9" dotenv: "npm:16.3.1" eslint: "npm:8.52.0" eslint-config-prettier: "npm:9.0.0" @@ -6508,14 +6508,14 @@ __metadata: dependencies: "@babel/core": "npm:7.23.2" "@mdx-js/react": "npm:3.0.0" - "@storybook/addon-actions": "npm:7.5.1" - "@storybook/addon-docs": "npm:7.5.1" - "@storybook/addon-essentials": "npm:7.5.1" - "@storybook/addon-interactions": "npm:7.5.1" - "@storybook/addon-links": "npm:7.5.1" + "@storybook/addon-actions": "npm:7.5.2" + "@storybook/addon-docs": "npm:7.5.2" + "@storybook/addon-essentials": "npm:7.5.2" + "@storybook/addon-interactions": "npm:7.5.2" + "@storybook/addon-links": "npm:7.5.2" "@storybook/builder-webpack4": "npm:6.5.16" "@storybook/manager-webpack4": "npm:6.5.16" - "@storybook/react": "npm:7.5.1" + "@storybook/react": "npm:7.5.2" "@storybook/testing-library": "npm:0.2.2" "@types/eslint": "npm:8.44.6" "@types/micromatch": "npm:4.0.4" @@ -6526,7 +6526,7 @@ __metadata: "@willbooster/eslint-config-ts-react": "npm:10.1.9" "@willbooster/prettier-config": "npm:9.1.2" babel-loader: "npm:9.1.3" - build-ts: "npm:11.0.8" + build-ts: "npm:11.0.9" eslint: "npm:8.52.0" eslint-config-prettier: "npm:9.0.0" eslint-import-resolver-typescript: "npm:3.6.1" @@ -6561,7 +6561,7 @@ __metadata: "@typescript-eslint/parser": "npm:6.9.0" "@willbooster/eslint-config-ts": "npm:10.5.1" "@willbooster/prettier-config": "npm:9.1.2" - build-ts: "npm:11.0.8" + build-ts: "npm:11.0.9" eslint: "npm:8.52.0" eslint-config-prettier: "npm:9.0.0" eslint-import-resolver-typescript: "npm:3.6.1" @@ -6591,8 +6591,8 @@ __metadata: "@typescript-eslint/parser": "npm:6.9.0" "@willbooster/eslint-config-ts": "npm:10.5.1" "@willbooster/prettier-config": "npm:9.1.2" - at-decorators: "npm:1.2.0" - build-ts: "npm:11.0.8" + at-decorators: "npm:1.2.2" + build-ts: "npm:11.0.9" chalk: "npm:5.3.0" dotenv: "npm:16.3.1" eslint: "npm:8.52.0" @@ -7441,10 +7441,10 @@ __metadata: languageName: node linkType: hard -"at-decorators@npm:1.2.0": - version: 1.2.0 - resolution: "at-decorators@npm:1.2.0" - checksum: 33298e3b762fa3e150d7df23a29b20fdda484d484bf0c0cb9d8ea1042c937ceb163dcf504e7a79febcdb1669369116d50a3a376fb0c55ecc0b03eeb2cb3a2b96 +"at-decorators@npm:1.2.2": + version: 1.2.2 + resolution: "at-decorators@npm:1.2.2" + checksum: 0aa7f7da923f11176442182d01fdda199a6e2e96d7c8f4497ba464ee79acd94f7af22560ccfdcc903ab7ad7b95a313c4e2b00cd7defbb95a3c4fb85166222213 languageName: node linkType: hard @@ -8067,9 +8067,9 @@ __metadata: languageName: node linkType: hard -"build-ts@npm:11.0.8": - version: 11.0.8 - resolution: "build-ts@npm:11.0.8" +"build-ts@npm:11.0.9": + version: 11.0.9 + resolution: "build-ts@npm:11.0.9" dependencies: "@babel/core": "npm:7.23.2" "@babel/plugin-proposal-decorators": "npm:7.23.2" @@ -8106,7 +8106,7 @@ __metadata: yargs: "npm:17.7.2" bin: build-ts: bin/index.js - checksum: f5ae1efe8d8f8c558e3fd6fff16c6732024b5eb25e94a73f02f8b10102268d104ccfe7762ee0496902add2faf5296bbf3dd76ebf0e46f1ebbc4c3a8338681204 + checksum: 23a7abdf2f4bb6fcc322397b800b19ef178d7de26573d9b0370bd61701f4bb6679ee0c5c81dce69f3ae0ffb6d48dba4e2b18d79b6c2d189e1c2de385a0efa55f languageName: node linkType: hard From 8602e461cd8ba85853271a2fab03ed4a828bc3e3 Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Mon, 30 Oct 2023 20:06:17 +0900 Subject: [PATCH 13/21] . --- packages/wb/src/project.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/wb/src/project.ts b/packages/wb/src/project.ts index 2e969726..b789dd18 100644 --- a/packages/wb/src/project.ts +++ b/packages/wb/src/project.ts @@ -205,6 +205,8 @@ export function findRootAndSelfProjects( async function getAllProjects(argv: EnvReaderOptions, rootProject: Project): Promise { const allProjects = [rootProject]; const packageDirPath = path.join(rootProject.dirPath, 'packages'); + if (!fs.existsSync(packageDirPath)) return []; + const packageDirs = await fs.promises.readdir(packageDirPath, { withFileTypes: true }); for (const packageDir of packageDirs) { if (!packageDir.isDirectory()) continue; From cc702f539068cf08dffbaa3f11d7535dd616d0c3 Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Mon, 30 Oct 2023 22:00:50 +0900 Subject: [PATCH 14/21] . --- packages/shared-lib-node/src/env.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/shared-lib-node/src/env.ts b/packages/shared-lib-node/src/env.ts index e255f765..bd8c208a 100644 --- a/packages/shared-lib-node/src/env.ts +++ b/packages/shared-lib-node/src/env.ts @@ -1,8 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; -import type { DotenvPopulateInput } from 'dotenv'; -import { parse, populate } from 'dotenv'; +import { config } from 'dotenv'; import type { ArgumentsCamelCase, InferredOptionTypes } from 'yargs'; export const yargsOptionsBuilderForEnv = { @@ -112,8 +111,8 @@ export function readAndApplyEnvironmentVariables( cache = true ): Record { const envVars = readEnvironmentVariables(argv, cwd, cache); - populate(process.env as DotenvPopulateInput, envVars); - return process.env; + Object.assign(process.env, envVars); + return envVars; } const cachedEnvVars = new Map>(); @@ -122,7 +121,7 @@ function readEnvFile(filePath: string, cache = true): Record { const cached = cache && cachedEnvVars.get(filePath); if (cached) return cached; - const parsed = parse(filePath); + const parsed = config({ path: path.resolve(filePath), processEnv: {} }).parsed ?? {}; if (cache) { cachedEnvVars.set(filePath, parsed); } From debceaf8d79745ee25c3f0563f40a9a7b3affb58 Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Mon, 30 Oct 2023 22:12:12 +0900 Subject: [PATCH 15/21] . --- packages/wb/src/commands/typecheck.ts | 4 +- packages/wb/src/project.ts | 58 +-------------------------- packages/wb/tests/typecheck.test.ts | 1 + 3 files changed, 5 insertions(+), 58 deletions(-) diff --git a/packages/wb/src/commands/typecheck.ts b/packages/wb/src/commands/typecheck.ts index 5bfd902e..a215eee2 100644 --- a/packages/wb/src/commands/typecheck.ts +++ b/packages/wb/src/commands/typecheck.ts @@ -22,13 +22,13 @@ export const typeCheckCommand: CommandModule< if (!projects) return; for (const project of projects.all) { - console.info(`Running "typecheck" for ${project.name} ...`); + console.info(`Running typecheck for ${project.name} ...`); if (projects.all.length > 1) { // Disable interactive mode project.env['CI'] = '1'; } - project.env['FORCE_COLOR'] = '3'; + project.env['FORCE_COLOR'] ||= '3'; const commands: string[] = []; if (project.packageJson.workspaces) { diff --git a/packages/wb/src/project.ts b/packages/wb/src/project.ts index b789dd18..744f6cbe 100644 --- a/packages/wb/src/project.ts +++ b/packages/wb/src/project.ts @@ -3,65 +3,11 @@ import path from 'node:path'; import type { EnvReaderOptions } from '@willbooster/shared-lib-node/src'; import { readEnvironmentVariables } from '@willbooster/shared-lib-node/src'; +import { memoizeOne } from 'at-decorators'; import type { PackageJson } from 'type-fest'; import type { ScriptArgv } from './scripts/builder.js'; -/** - * A memoization decorator/function that caches the results of the latest method/getter/function call to improve performance. - * This decorator/function can be applied to methods and getters in a class as a decorator, and functions without context as a function. - * The cache only stores the latest value. When a new value is computed, the previous cached value is replaced. - * - * @template This The type of the `this` context within the method, getter or function. - * @template Args The types of the arguments to the method, getter or function. - * @template Return The return type of the method, getter or function. - * - * @param {Function | keyof This} target The method, function or the name of getter to be memoized. - * @param {ClassMethodDecoratorContext | ClassGetterDecoratorContext} [context] The context in which the decorator is being applied. Optional for standard functions. - * - * @returns {Function} A new function that wraps the original method or getter, function with caching logic. - */ -export function memoizeOne( - target: ((this: This, ...args: Args) => Return) | ((...args: Args) => Return) | keyof This, - context?: - | ClassMethodDecoratorContext Return> - | ClassGetterDecoratorContext -): (this: This, ...args: Args) => Return { - let lastCache: Return; - - if (context?.kind === 'getter') { - let cached = false; - return function (this: This): Return { - console.log(`Entering getter ${String(context.name)}.`); - - if (!cached) { - cached = true; - lastCache = (target as (this: This) => Return).call(this); - } - - console.log(`Exiting getter ${String(context.name)}.`); - return lastCache; - }; - } - - let lastCacheKey: string; - - return function (this: This, ...args: Args): Return { - console.log(`Entering ${context ? `method ${String(context.name)}` : 'function'}(${JSON.stringify(args)}).`); - - const key = JSON.stringify(args); - if (lastCacheKey !== key) { - lastCacheKey = key; - lastCache = context - ? (target as (this: This, ...args: Args) => Return).call(this, ...args) - : (target as (...args: Args) => Return)(...args); - } - - console.log(`Exiting ${context ? `method ${String(context.name)}` : 'function'}.`); - return lastCache; - }; -} - export class Project { private _dirPath: string; private _pathByName = new Map(); @@ -122,7 +68,7 @@ export class Project { @memoizeOne get env(): Record { - return readEnvironmentVariables(this._argv, this.dirPath); + return { ...readEnvironmentVariables(this._argv, this.dirPath), ...process.env }; } @memoizeOne diff --git a/packages/wb/tests/typecheck.test.ts b/packages/wb/tests/typecheck.test.ts index cfe2510f..59a2470f 100644 --- a/packages/wb/tests/typecheck.test.ts +++ b/packages/wb/tests/typecheck.test.ts @@ -26,6 +26,7 @@ describe('typecheck', () => { shell: true, stdio: 'inherit', }); + console.log(ret); expect(ret.status).toBe(0); }, 5 * 60 * 1000 From 98600cbf4e222846ae320115130d272fdb91384a Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Mon, 30 Oct 2023 22:18:41 +0900 Subject: [PATCH 16/21] . --- packages/wb/src/project.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/wb/src/project.ts b/packages/wb/src/project.ts index 744f6cbe..aa256dbf 100644 --- a/packages/wb/src/project.ts +++ b/packages/wb/src/project.ts @@ -151,7 +151,7 @@ export function findRootAndSelfProjects( async function getAllProjects(argv: EnvReaderOptions, rootProject: Project): Promise { const allProjects = [rootProject]; const packageDirPath = path.join(rootProject.dirPath, 'packages'); - if (!fs.existsSync(packageDirPath)) return []; + if (!fs.existsSync(packageDirPath)) return allProjects; const packageDirs = await fs.promises.readdir(packageDirPath, { withFileTypes: true }); for (const packageDir of packageDirs) { From f5b09cfb4ac4ebe07daedc28896740071776150b Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Mon, 30 Oct 2023 22:24:39 +0900 Subject: [PATCH 17/21] . --- packages/wb/src/commands/buildIfNeeded.ts | 36 +++++++++++------------ packages/wb/src/commands/setup.ts | 7 +++-- packages/wb/src/project.ts | 20 +++++++------ packages/wb/tests/setup.test.ts | 2 +- packages/wb/tests/shared.ts | 3 ++ 5 files changed, 38 insertions(+), 30 deletions(-) diff --git a/packages/wb/src/commands/buildIfNeeded.ts b/packages/wb/src/commands/buildIfNeeded.ts index 5909fe60..a94a5a11 100644 --- a/packages/wb/src/commands/buildIfNeeded.ts +++ b/packages/wb/src/commands/buildIfNeeded.ts @@ -32,12 +32,28 @@ export const buildIfNeededCommand: CommandModule>>): boolean { + console.info(chalk.green(`Run '${argv.command}'`)); + if (!argv.dryRun) { + const ret = child_process.spawnSync(argv.command ?? '', { + cwd: project.dirPath, + shell: true, + stdio: 'inherit', + }); + if (ret.status !== 0) { + process.exitCode = ret.status ?? 1; + return false; + } + } + return true; +} + export async function buildIfNeeded( // Test code requires Partial<...> argv: Partial>>, - dirPath?: string + projectPathForTesting?: string ): Promise { - const projects = await findAllProjects(argv, dirPath); + const projects = await findAllProjects(argv, projectPathForTesting); if (!projects) return true; const isGitRepo = fs.existsSync(path.join(projects.root.dirPath, '.git')); @@ -66,22 +82,6 @@ export async function buildIfNeeded( return built; } -function build(project: Project, argv: Partial>>): boolean { - console.info(chalk.green(`Run '${argv.command}'`)); - if (!argv.dryRun) { - const ret = child_process.spawnSync(argv.command ?? '', { - cwd: project.dirPath, - shell: true, - stdio: 'inherit', - }); - if (ret.status !== 0) { - process.exitCode = ret.status ?? 1; - return false; - } - } - return true; -} - const ignoringEnvVarNames = new Set(['CI', 'PWDEBUG', 'TMPDIR']); export async function canSkipBuild( diff --git a/packages/wb/src/commands/setup.ts b/packages/wb/src/commands/setup.ts index ae9db734..e4986625 100644 --- a/packages/wb/src/commands/setup.ts +++ b/packages/wb/src/commands/setup.ts @@ -20,8 +20,11 @@ export const setupCommand: CommandModule -export async function setup(argv: Partial>>): Promise { - const projects = await findAllProjects(argv); +export async function setup( + argv: Partial>>, + projectPathForTesting?: string +): Promise { + const projects = await findAllProjects(argv, projectPathForTesting); if (!projects) return; for (const project of projects.all) { diff --git a/packages/wb/src/project.ts b/packages/wb/src/project.ts index aa256dbf..294e3109 100644 --- a/packages/wb/src/project.ts +++ b/packages/wb/src/project.ts @@ -116,8 +116,11 @@ export function findSelfProject(argv: EnvReaderOptions): Project | undefined { return new Project(dirPath, argv); } -export async function findAllProjects(argv: EnvReaderOptions, dirPath?: string): Promise { - const rootAndSelfProjects = findRootAndSelfProjects(argv, dirPath); +export async function findAllProjects( + argv: EnvReaderOptions, + projectPathForTesting?: string +): Promise { + const rootAndSelfProjects = findRootAndSelfProjects(argv, projectPathForTesting); if (!rootAndSelfProjects) return; return { @@ -131,16 +134,15 @@ export async function findAllProjects(argv: EnvReaderOptions, dirPath?: string): export function findRootAndSelfProjects( argv: EnvReaderOptions, - dirPath?: string + projectPathForTesting?: string ): Omit | undefined { - // Tests pass dirPath - dirPath ??= process.cwd(); - if (!fs.existsSync(path.join(dirPath, 'package.json'))) return; + projectPathForTesting ??= process.cwd(); + if (!fs.existsSync(path.join(projectPathForTesting, 'package.json'))) return; - const thisProject = new Project(dirPath, argv); + const thisProject = new Project(projectPathForTesting, argv); let rootProject = thisProject; - if (!thisProject.packageJson.workspaces && path.dirname(dirPath).endsWith('/packages')) { - const rootDirPath = path.resolve(dirPath, '..', '..'); + if (!thisProject.packageJson.workspaces && path.dirname(projectPathForTesting).endsWith('/packages')) { + const rootDirPath = path.resolve(projectPathForTesting, '..', '..'); if (fs.existsSync(path.join(rootDirPath, 'package.json'))) { rootProject = new Project(rootDirPath, argv); } diff --git a/packages/wb/tests/setup.test.ts b/packages/wb/tests/setup.test.ts index b90a29f7..60e94bb3 100644 --- a/packages/wb/tests/setup.test.ts +++ b/packages/wb/tests/setup.test.ts @@ -14,7 +14,7 @@ describe('setup', () => { const dirPath = path.join(tempDir, 'blitz'); await initializeProjectDirectory(dirPath); - await setup({}); + await setup({}, dirPath); const ret = child_process.spawnSync(`yarn start test -w ${dirPath} --ci`, { shell: true, stdio: 'inherit', diff --git a/packages/wb/tests/shared.ts b/packages/wb/tests/shared.ts index c96e8ffc..d73e4eb9 100644 --- a/packages/wb/tests/shared.ts +++ b/packages/wb/tests/shared.ts @@ -2,6 +2,8 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; +import { removeNpmAndYarnEnvironmentVariables } from '@willbooster/shared-lib-node/src'; + export const tempDir = path.join(os.tmpdir(), 'shared'); export async function initializeProjectDirectory(dirPath: string): Promise { @@ -17,4 +19,5 @@ export async function initializeProjectDirectory(dirPath: string): Promise await fs.promises.cp(path.join('..', '..', '.yarnrc.yml'), path.join(dirPath, '.yarnrc.yml'), { force: true, }); + removeNpmAndYarnEnvironmentVariables(process.env); } From 2e82118e423903c4dc5364ff0a6faeb44a26068c Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Mon, 30 Oct 2023 22:26:21 +0900 Subject: [PATCH 18/21] . --- packages/shared-lib-node/src/env.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/shared-lib-node/src/env.ts b/packages/shared-lib-node/src/env.ts index bd8c208a..9cd6a831 100644 --- a/packages/shared-lib-node/src/env.ts +++ b/packages/shared-lib-node/src/env.ts @@ -45,7 +45,11 @@ export type EnvReaderOptions = Partial { +export function readEnvironmentVariables( + argv: EnvReaderOptions, + cwd: string, + cacheEnabled = true +): Record { let envPaths = (argv.env ?? []).map((envPath) => path.resolve(cwd, envPath.toString())); const cascade = argv.cascadeEnv ?? @@ -79,7 +83,7 @@ export function readEnvironmentVariables(argv: EnvReaderOptions, cwd: string, ca let envVars: Record = {}; const orgEnvVars = { ...process.env }; for (const envPath of envPaths) { - envVars = { ...readEnvFile(path.join(cwd, envPath), cache), ...envVars }; + envVars = { ...readEnvFile(path.join(cwd, envPath), cacheEnabled), ...envVars }; let count = 0; for (const [key, value] of Object.entries(envVars)) { if (orgEnvVars[key] !== value) { @@ -93,7 +97,7 @@ export function readEnvironmentVariables(argv: EnvReaderOptions, cwd: string, ca } if (argv.checkEnv) { - const exampleKeys = Object.keys(readEnvFile(path.join(cwd, argv.checkEnv), cache) || {}); + const exampleKeys = Object.keys(readEnvFile(path.join(cwd, argv.checkEnv), cacheEnabled) || {}); const missingKeys = exampleKeys.filter((key) => !(key in envVars)); if (missingKeys.length > 0) { throw new Error(`Missing environment variables in [${envPaths.join(', ')}]: [${missingKeys.join(', ')}]`); @@ -108,21 +112,21 @@ export function readEnvironmentVariables(argv: EnvReaderOptions, cwd: string, ca export function readAndApplyEnvironmentVariables( argv: EnvReaderOptions, cwd: string, - cache = true + cacheEnabled = true ): Record { - const envVars = readEnvironmentVariables(argv, cwd, cache); + const envVars = readEnvironmentVariables(argv, cwd, cacheEnabled); Object.assign(process.env, envVars); return envVars; } const cachedEnvVars = new Map>(); -function readEnvFile(filePath: string, cache = true): Record { - const cached = cache && cachedEnvVars.get(filePath); +function readEnvFile(filePath: string, cacheEnabled = true): Record { + const cached = cacheEnabled && cachedEnvVars.get(filePath); if (cached) return cached; const parsed = config({ path: path.resolve(filePath), processEnv: {} }).parsed ?? {}; - if (cache) { + if (cacheEnabled) { cachedEnvVars.set(filePath, parsed); } return parsed; From 11766a9867d902746ed9b692ffa7a9e53208714b Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Mon, 30 Oct 2023 22:27:50 +0900 Subject: [PATCH 19/21] . --- packages/shared-lib-node/src/env.ts | 2 +- packages/shared-lib-node/src/index.ts | 2 +- packages/shared-lib-node/tests/env.test.ts | 17 ++++++++++------- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/packages/shared-lib-node/src/env.ts b/packages/shared-lib-node/src/env.ts index 9cd6a831..e8e8b4aa 100644 --- a/packages/shared-lib-node/src/env.ts +++ b/packages/shared-lib-node/src/env.ts @@ -109,7 +109,7 @@ export function readEnvironmentVariables( /** * This function read environment variables from `.env` files and assign them in `process.env`. * */ -export function readAndApplyEnvironmentVariables( +export function readAndUpdateEnvironmentVariables( argv: EnvReaderOptions, cwd: string, cacheEnabled = true diff --git a/packages/shared-lib-node/src/index.ts b/packages/shared-lib-node/src/index.ts index 19110a4a..f8c95ba5 100644 --- a/packages/shared-lib-node/src/index.ts +++ b/packages/shared-lib-node/src/index.ts @@ -1,6 +1,6 @@ export { readEnvironmentVariables, - readAndApplyEnvironmentVariables, + readAndUpdateEnvironmentVariables, removeNpmAndYarnEnvironmentVariables, yargsOptionsBuilderForEnv, } from './env.js'; diff --git a/packages/shared-lib-node/tests/env.test.ts b/packages/shared-lib-node/tests/env.test.ts index 9f527a13..2f1b871f 100644 --- a/packages/shared-lib-node/tests/env.test.ts +++ b/packages/shared-lib-node/tests/env.test.ts @@ -1,6 +1,6 @@ import { beforeEach, describe, expect, it } from 'vitest'; -import { readAndApplyEnvironmentVariables } from '../src/env.js'; +import { readAndUpdateEnvironmentVariables } from '../src/env.js'; describe('readAndApplyEnvironmentVariables()', () => { beforeEach(() => { @@ -9,36 +9,39 @@ describe('readAndApplyEnvironmentVariables()', () => { }); it('should load no env vars with empty options', () => { - const envVars = readAndApplyEnvironmentVariables({}, 'test-fixtures/app1'); + const envVars = readAndUpdateEnvironmentVariables({}, 'test-fixtures/app1'); expect(envVars).toEqual({}); }); it('should load env vars with --auto-cascade-env', () => { - const envVars = readAndApplyEnvironmentVariables({ autoCascadeEnv: true }, 'test-fixtures/app1'); + const envVars = readAndUpdateEnvironmentVariables({ autoCascadeEnv: true }, 'test-fixtures/app1'); expect(envVars).toEqual({ NAME: 'app1', ENV: 'development1' }); }); it('should load env vars with --cascade-env=production', () => { - const envVars = readAndApplyEnvironmentVariables({ cascadeEnv: 'production', env: ['.env'] }, 'test-fixtures/app1'); + const envVars = readAndUpdateEnvironmentVariables( + { cascadeEnv: 'production', env: ['.env'] }, + 'test-fixtures/app1' + ); expect(envVars).toEqual({ NAME: 'app1', ENV: 'production1' }); }); it('should load env vars with --cascade-node-env and NODE_ENV=""', () => { process.env.NODE_ENV = ''; - const envVars = readAndApplyEnvironmentVariables({ cascadeNodeEnv: true, env: ['.env'] }, 'test-fixtures/app1'); + const envVars = readAndUpdateEnvironmentVariables({ cascadeNodeEnv: true, env: ['.env'] }, 'test-fixtures/app1'); expect(envVars).toEqual({ NAME: 'app1', ENV: 'development1' }); }); it('should load env vars with --cascade-node-env and NODE_ENV=test', () => { process.env.NODE_ENV = 'test'; - const envVars = readAndApplyEnvironmentVariables({ cascadeNodeEnv: true, env: ['.env'] }, 'test-fixtures/app1'); + const envVars = readAndUpdateEnvironmentVariables({ cascadeNodeEnv: true, env: ['.env'] }, 'test-fixtures/app1'); expect(envVars).toEqual({ NAME: 'app1', ENV: 'test1' }); }); it('should load env vars with --env=test-fixtures/app2/.env --auto-cascade-env, WB_ENV=test and NODE_ENV=production', () => { process.env.WB_ENV = 'test'; process.env.NODE_ENV = 'production'; - const envVars = readAndApplyEnvironmentVariables( + const envVars = readAndUpdateEnvironmentVariables( { autoCascadeEnv: true, env: ['../app2/.env'] }, 'test-fixtures/app1' ); From f93365e5627b8517937ab70dc8af694c441e6b78 Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Mon, 30 Oct 2023 22:28:21 +0900 Subject: [PATCH 20/21] . --- packages/shared-lib-node/src/env.ts | 2 +- packages/shared-lib-node/src/index.ts | 2 +- packages/shared-lib-node/tests/env.test.ts | 17 +++++++---------- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/packages/shared-lib-node/src/env.ts b/packages/shared-lib-node/src/env.ts index e8e8b4aa..9cd6a831 100644 --- a/packages/shared-lib-node/src/env.ts +++ b/packages/shared-lib-node/src/env.ts @@ -109,7 +109,7 @@ export function readEnvironmentVariables( /** * This function read environment variables from `.env` files and assign them in `process.env`. * */ -export function readAndUpdateEnvironmentVariables( +export function readAndApplyEnvironmentVariables( argv: EnvReaderOptions, cwd: string, cacheEnabled = true diff --git a/packages/shared-lib-node/src/index.ts b/packages/shared-lib-node/src/index.ts index f8c95ba5..19110a4a 100644 --- a/packages/shared-lib-node/src/index.ts +++ b/packages/shared-lib-node/src/index.ts @@ -1,6 +1,6 @@ export { readEnvironmentVariables, - readAndUpdateEnvironmentVariables, + readAndApplyEnvironmentVariables, removeNpmAndYarnEnvironmentVariables, yargsOptionsBuilderForEnv, } from './env.js'; diff --git a/packages/shared-lib-node/tests/env.test.ts b/packages/shared-lib-node/tests/env.test.ts index 2f1b871f..9f527a13 100644 --- a/packages/shared-lib-node/tests/env.test.ts +++ b/packages/shared-lib-node/tests/env.test.ts @@ -1,6 +1,6 @@ import { beforeEach, describe, expect, it } from 'vitest'; -import { readAndUpdateEnvironmentVariables } from '../src/env.js'; +import { readAndApplyEnvironmentVariables } from '../src/env.js'; describe('readAndApplyEnvironmentVariables()', () => { beforeEach(() => { @@ -9,39 +9,36 @@ describe('readAndApplyEnvironmentVariables()', () => { }); it('should load no env vars with empty options', () => { - const envVars = readAndUpdateEnvironmentVariables({}, 'test-fixtures/app1'); + const envVars = readAndApplyEnvironmentVariables({}, 'test-fixtures/app1'); expect(envVars).toEqual({}); }); it('should load env vars with --auto-cascade-env', () => { - const envVars = readAndUpdateEnvironmentVariables({ autoCascadeEnv: true }, 'test-fixtures/app1'); + const envVars = readAndApplyEnvironmentVariables({ autoCascadeEnv: true }, 'test-fixtures/app1'); expect(envVars).toEqual({ NAME: 'app1', ENV: 'development1' }); }); it('should load env vars with --cascade-env=production', () => { - const envVars = readAndUpdateEnvironmentVariables( - { cascadeEnv: 'production', env: ['.env'] }, - 'test-fixtures/app1' - ); + const envVars = readAndApplyEnvironmentVariables({ cascadeEnv: 'production', env: ['.env'] }, 'test-fixtures/app1'); expect(envVars).toEqual({ NAME: 'app1', ENV: 'production1' }); }); it('should load env vars with --cascade-node-env and NODE_ENV=""', () => { process.env.NODE_ENV = ''; - const envVars = readAndUpdateEnvironmentVariables({ cascadeNodeEnv: true, env: ['.env'] }, 'test-fixtures/app1'); + const envVars = readAndApplyEnvironmentVariables({ cascadeNodeEnv: true, env: ['.env'] }, 'test-fixtures/app1'); expect(envVars).toEqual({ NAME: 'app1', ENV: 'development1' }); }); it('should load env vars with --cascade-node-env and NODE_ENV=test', () => { process.env.NODE_ENV = 'test'; - const envVars = readAndUpdateEnvironmentVariables({ cascadeNodeEnv: true, env: ['.env'] }, 'test-fixtures/app1'); + const envVars = readAndApplyEnvironmentVariables({ cascadeNodeEnv: true, env: ['.env'] }, 'test-fixtures/app1'); expect(envVars).toEqual({ NAME: 'app1', ENV: 'test1' }); }); it('should load env vars with --env=test-fixtures/app2/.env --auto-cascade-env, WB_ENV=test and NODE_ENV=production', () => { process.env.WB_ENV = 'test'; process.env.NODE_ENV = 'production'; - const envVars = readAndUpdateEnvironmentVariables( + const envVars = readAndApplyEnvironmentVariables( { autoCascadeEnv: true, env: ['../app2/.env'] }, 'test-fixtures/app1' ); From 57fee7a233be890ba29052ce80c45b9ed2e9f017 Mon Sep 17 00:00:00 2001 From: "Sakamoto, Kazunori" Date: Mon, 30 Oct 2023 22:41:57 +0900 Subject: [PATCH 21/21] . --- packages/wb/src/commands/buildIfNeeded.ts | 41 ++++++++----------- packages/wb/src/commands/setup.ts | 4 +- packages/wb/src/commands/start.ts | 5 ++- packages/wb/src/commands/test.ts | 18 ++++---- packages/wb/src/commands/typecheck.ts | 22 +++++----- packages/wb/src/project.ts | 23 +++++------ packages/wb/src/scripts/dockerScripts.ts | 2 +- .../scripts/execution/baseExecutionScripts.ts | 8 ++-- .../wb/src/scripts/execution/blitzScripts.ts | 4 +- .../scripts/execution/httpServerScripts.ts | 4 +- 10 files changed, 62 insertions(+), 69 deletions(-) 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"`;