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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions packages/shared-lib-node/src/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export const yargsOptionsBuilderForEnv = {
type: 'string',
default: '.env.example',
},
'quiet-env': {
description: 'Suppress .env file loading information.',
type: 'boolean',
},
verbose: {
description: 'Whether to show verbose information',
type: 'boolean',
Expand Down Expand Up @@ -77,7 +81,8 @@ export function readEnvironmentVariables(
);
}
envPaths = envPaths.filter((envPath) => fs.existsSync(envPath)).map((envPath) => path.relative(cwd, envPath));
if (argv.verbose) {
const shouldSuppressOutput = shouldSuppressEnvironmentOutput(argv);
if (argv.verbose && !shouldSuppressOutput) {
console.info(`WB_ENV: ${process.env.WB_ENV}, NODE_ENV: ${process.env.NODE_ENV}`);
console.info('Reading env files:', envPaths.join(', '));
}
Expand All @@ -93,11 +98,11 @@ export function readEnvironmentVariables(
}
}
envPathAndLoadedEnvVarNames.push([envPath, keys]);
if (argv.verbose && keys.length > 0) {
if (argv.verbose && !shouldSuppressOutput && keys.length > 0) {
console.info(`Read ${keys.length} environment variables from ${envPath}`);
}
}
if (!argv.verbose) {
if (!argv.verbose && !shouldSuppressOutput) {
console.info(
`Read env files: ${envPathAndLoadedEnvVarNames.map(([envPath, keys]) => (keys.length > 0 ? `${envPath} (${keys.join(', ')})` : envPath)).join(', ') || 'nothing'}`
);
Expand All @@ -113,6 +118,11 @@ export function readEnvironmentVariables(
return [expand({ parsed: envVars, processEnv: {} }).parsed ?? envVars, envPathAndLoadedEnvVarNames];
}

export function shouldSuppressEnvironmentOutput(argv: EnvReaderOptions): boolean {
const outputOptions = argv as EnvReaderOptions & { quietEnv?: boolean; silent?: boolean };
return outputOptions.quietEnv === true || (outputOptions.quietEnv !== false && outputOptions.silent === true);
}

/**
* This function read environment variables from `.env` files and assign them in `process.env`.
* */
Expand Down
1 change: 1 addition & 0 deletions packages/shared-lib-node/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export {
readEnvironmentVariables,
readAndApplyEnvironmentVariables,
removeNpmAndYarnEnvironmentVariables,
shouldSuppressEnvironmentOutput,
yargsOptionsBuilderForEnv,
} from './env.js';
export type { EnvReaderOptions } from './env.js';
Expand Down
17 changes: 16 additions & 1 deletion packages/wb/src/commands/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export async function test(argv: TestCommandArgv): Promise<void> {
const targets =
unitTargets.length > 0 ? unitTargets : defaultUnitTargets.length > 0 ? defaultUnitTargets : undefined;
const unitArgv = { ...argv, targets };
await runTestCommand(scripts.testUnit(project, unitArgv), project, argv, { timeout: argv.unitTimeout });
await runUnitTestCommand(scripts.testUnit(project, unitArgv), project, argv, { timeout: argv.unitTimeout });
}
// Skip e2e tests if not needed or no e2e directory exists
if (!shouldRunE2e || !fs.existsSync(path.join(project.dirPath, 'test', 'e2e'))) {
Expand Down Expand Up @@ -283,6 +283,21 @@ function runTestCommand(
});
}

function runUnitTestCommand(
script: string,
project: Project,
argv: Parameters<typeof runWithSpawn>[2],
options: Parameters<typeof runWithSpawn>[3] = {}
): Promise<number> {
return runWithSpawn(script, project, argv, {
...options,
omitSilentStart: true,
printSilentOutputOnFailureOnly: true,
silentProgressIntervalMs: 10_000,
silentSuccessMessage: 'Unit tests passed.',
});
}

function dedupeNoisyTestOutput(output: string): string {
const recentPrintedLines: string[] = [];
const recentPrintedLineSet = new Set<string>();
Expand Down
8 changes: 5 additions & 3 deletions packages/wb/src/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ 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 { readEnvironmentVariables, shouldSuppressEnvironmentOutput } from '@willbooster/shared-lib-node/src';
import { memoizeOne } from 'at-decorators';
import { globby } from 'globby';
import type { PackageJson } from 'type-fest';
Expand Down Expand Up @@ -110,8 +110,10 @@ export class Project {
if (!this.loadEnv) return process.env;

const [envVars, envPathAndLoadedEnvVarCountPairs] = readEnvironmentVariables(this.argv, this.dirPath);
for (const [envPath, count] of envPathAndLoadedEnvVarCountPairs) {
console.info(`Loaded ${count} environment variables from ${envPath}`);
if (!shouldSuppressEnvironmentOutput(this.argv)) {
for (const [envPath, count] of envPathAndLoadedEnvVarCountPairs) {
console.info(`Loaded ${count} environment variables from ${envPath}`);
}
}
return { ...envVars, ...process.env };
}
Expand Down
39 changes: 33 additions & 6 deletions packages/wb/src/scripts/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ interface Options {
exitIfFailed?: boolean;
onSignal?: (signal: NodeJS.Signals | null) => void;
forceColor?: boolean;
omitSilentStart?: boolean;
processSilentOutput?: (output: string) => string;
printRawOutput?: boolean;
printSilentOutputOnFailureOnly?: boolean;
silentProgressIntervalMs?: number;
silentSuccessMessage?: string;
timeout?: number;
}

Expand All @@ -32,7 +36,9 @@ export async function runWithSpawn(
opts: Options = defaultOptions
): Promise<number> {
const normalizedScript = normalizeScript(script, project);
printStart(normalizedScript.printable, project, argv.silent ? 'Command' : 'Start');
if (!(argv.silent && opts.omitSilentStart && !argv.dryRun)) {
printStart(normalizedScript.printable, project, argv.silent ? 'Command' : 'Start');
}
if (argv.verbose) {
printStart(normalizedScript.runnable, project, 'Start (raw)', true);
}
Expand All @@ -41,7 +47,17 @@ export async function runWithSpawn(
return 0;
}

const shouldProcessSilentOutput = Boolean(argv.silent && opts.processSilentOutput);
const shouldProcessSilentOutput = Boolean(
argv.silent && (opts.processSilentOutput ?? opts.printSilentOutputOnFailureOnly)
);
let wroteSilentProgress = false;
const progressTimer =
argv.silent && opts.silentProgressIntervalMs
? setInterval(() => {
process.stdout.write('.');
wroteSilentProgress = true;
}, opts.silentProgressIntervalMs)
: undefined;
const ret = await spawnAsync(normalizedScript.runnable, undefined, {
cwd: project.dirPath,
env: configureEnv(project.env, opts),
Expand All @@ -54,17 +70,28 @@ export async function runWithSpawn(
printingStderr: argv.silent && !shouldProcessSilentOutput,
omitBlankLinesWhilePrinting: argv.silent,
verbose: argv.verbose,
}).finally(() => {
if (progressTimer) {
clearInterval(progressTimer);
}
});
if (shouldProcessSilentOutput) {
const output = opts.processSilentOutput?.(ret.stdout).trim();
const exitCode = ret.status ?? 1;
if (wroteSilentProgress) {
process.stdout.write('\n');
}
if (shouldProcessSilentOutput && (!opts.printSilentOutputOnFailureOnly || exitCode !== 0)) {
const output = (opts.processSilentOutput ? opts.processSilentOutput(ret.stdout) : ret.stdout).trim();
if (output) {
process.stdout.write(output);
process.stdout.write('\n');
}
}
if (argv.silent && exitCode === 0 && opts.silentSuccessMessage) {
console.info(chalk.green(opts.silentSuccessMessage));
}
opts.onSignal?.(ret.signal);
printFinishedAndExitIfNeeded(normalizedScript.printable, ret.status, opts, { silentSuccess: argv.silent });
return ret.status ?? 1;
printFinishedAndExitIfNeeded(normalizedScript.printable, exitCode, opts, { silentSuccess: argv.silent });
return exitCode;
}

export function runWithSpawnInParallel(
Expand Down
6 changes: 6 additions & 0 deletions packages/wb/src/sharedOptionsBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ export function buildEnvReaderOptionArgs(argv: EnvReaderOptions): string[] {
}
}
}
if (
(argv as EnvReaderOptions & { silent?: boolean }).silent === true &&
getOptionValue(argv, 'quiet-env') === undefined
) {
args.push('--quiet-env');
}
return args;
}

Expand Down
1 change: 1 addition & 0 deletions packages/wbfy/src/generators/yarnrc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export async function generateYarnrcYml(config: PackageConfig): Promise<void> {
// To deal with CVE like https://nextjs.org/blog/CVE-2025-66478
'next',
'@next/*',
'@types/*',
'@typescript/*',
'@oxfmt/*',
'@oxlint/*',
Expand Down
Loading