Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add second level of --verbose to workspaces foreach to permit specifying less logging. #6034

Merged
merged 2 commits into from
Jan 3, 2024
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
23 changes: 23 additions & 0 deletions .yarn/versions/07edaf86.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
releases:
"@yarnpkg/cli": minor
"@yarnpkg/plugin-workspace-tools": minor

declined:
- "@yarnpkg/plugin-compat"
- "@yarnpkg/plugin-constraints"
- "@yarnpkg/plugin-dlx"
- "@yarnpkg/plugin-essentials"
- "@yarnpkg/plugin-init"
- "@yarnpkg/plugin-interactive-tools"
- "@yarnpkg/plugin-nm"
- "@yarnpkg/plugin-npm-cli"
- "@yarnpkg/plugin-pack"
- "@yarnpkg/plugin-patch"
- "@yarnpkg/plugin-pnp"
- "@yarnpkg/plugin-pnpm"
- "@yarnpkg/plugin-stage"
- "@yarnpkg/plugin-typescript"
- "@yarnpkg/plugin-version"
- "@yarnpkg/builder"
- "@yarnpkg/core"
- "@yarnpkg/doctor"
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ Done
}
`;

exports[`Commands workspace foreach should prefix the output with run with --verbose 1`] = `
exports[`Commands workspace foreach should prefix the output and include timing information when run with -vv (two verbose levels) 1`] = `
{
"code": 0,
"stderr": "",
Expand Down Expand Up @@ -266,6 +266,22 @@ Done
}
`;

exports[`Commands workspace foreach should prefix the output when run with one --verbose 1`] = `
{
"code": 0,
"stderr": "",
"stdout": "[workspace-a]: Test Workspace A
[workspace-b]: Test Workspace B
[workspace-c]: Test Workspace C
[workspace-d]: Test Workspace D
[workspace-e]: Test Workspace E
[workspace-f]: Test Workspace F
[workspace-g]: Test Workspace G
Done
",
}
`;

exports[`Commands workspace foreach should run execute global scripts even on workspaces that don't declare them 1`] = `
{
"code": 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,9 @@ describe(`Commands`, () => {
),
);


test(
`should prefix the output with run with --verbose`,
`should prefix the output when run with one --verbose`,
makeTemporaryEnv(
{
private: true,
Expand All @@ -232,6 +233,22 @@ describe(`Commands`, () => {
),
);

test(
`should prefix the output and include timing information when run with -vv (two verbose levels)`,
makeTemporaryEnv(
{
private: true,
workspaces: [`packages/*`],
},
async ({path, run}) => {
await setupWorkspaces(path);
await run(`install`);

await expect(run(`workspaces`, `foreach`, `--all`, `-vv`, `run`, `print`)).resolves.toMatchSnapshot();
},
),
);

test(
`should not include the prefix or a ➤ character when run with --no-verbose`,
makeTemporaryEnv(
Expand Down Expand Up @@ -259,7 +276,7 @@ describe(`Commands`, () => {
await setupWorkspaces(path);
await run(`install`);

await expect(run(`workspaces`, `foreach`, `--all`, `--verbose`, `--include`, `workspace-a`, `--include`, `packages/workspace-b`, `run`, `print`)).resolves.toMatchSnapshot();
await expect(run(`workspaces`, `foreach`, `--all`, `-vv`, `--include`, `workspace-a`, `--include`, `packages/workspace-b`, `run`, `print`)).resolves.toMatchSnapshot();
},
),
);
Expand All @@ -275,7 +292,7 @@ describe(`Commands`, () => {
await setupWorkspaces(path);
await run(`install`);

await expect(run(`workspaces`, `foreach`, `--all`, `--verbose`, `--include`, `packages/workspace-c/**`, `run`, `print`)).resolves.toMatchSnapshot();
await expect(run(`workspaces`, `foreach`, `--all`, `-vv`, `--include`, `packages/workspace-c/**`, `run`, `print`)).resolves.toMatchSnapshot();
},
),
);
Expand All @@ -291,7 +308,7 @@ describe(`Commands`, () => {
await setupWorkspaces(path);
await run(`install`);

await expect(run(`workspaces`, `foreach`, `--all`, `--verbose`, `--exclude`, `workspace-a`, `--exclude`, `packages/workspace-b`, `run`, `print`)).resolves.toMatchSnapshot();
await expect(run(`workspaces`, `foreach`, `--all`, `-vv`, `--exclude`, `workspace-a`, `--exclude`, `packages/workspace-b`, `run`, `print`)).resolves.toMatchSnapshot();
},
),
);
Expand Down Expand Up @@ -359,7 +376,7 @@ describe(`Commands`, () => {
await setupWorkspaces(path);
await run(`install`);

const {code, stdout, stderr} = await run(`workspaces`, `foreach`, `--all`, `--parallel`, `--jobs`, `unlimited`, `--verbose`, `run`, `print`);
const {code, stdout, stderr} = await run(`workspaces`, `foreach`, `--all`, `--parallel`, `--jobs`, `unlimited`, `-vv`, `run`, `print`);

// We don't care what order they start in, just that they all started at the beginning.
const first7Lines = stdout.split(`\n`).slice(0, 7).sort().join(`\n`);
Expand Down
30 changes: 16 additions & 14 deletions packages/plugin-workspace-tools/sources/commands/foreach.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export default class WorkspacesForeachCommand extends BaseCommand {

- The command may apply to only some workspaces through the use of \`--include\` which acts as a whitelist. The \`--exclude\` flag will do the opposite and will be a list of packages that mustn't execute the script. Both flags accept glob patterns (if valid Idents and supported by [micromatch](https://github.com/micromatch/micromatch)). Make sure to escape the patterns, to prevent your own shell from trying to expand them.

Adding the \`-v,--verbose\` flag (automatically enabled in interactive terminal environments) will cause Yarn to print more information; in particular the name of the workspace that generated the output will be printed at the front of each line.
The \`-v,--verbose\` flag can be passed up to twice: once to prefix output lines with the originating workspace's name, and again to include start/finish/timing log lines. Maximum verbosity is enabled by default in terminal environments.

If the command is \`run\` and the script being run does not exist the child workspace will be skipped without error.
`,
Expand Down Expand Up @@ -83,8 +83,8 @@ export default class WorkspacesForeachCommand extends BaseCommand {
description: `Run the command on all workspaces of the current worktree`,
});

verbose = Option.Boolean(`-v,--verbose`, {
description: `Prefix each output line with the name of the originating workspace`,
verbose = Option.Counter(`-v,--verbose`, {
description: `Increase level of logging verbosity up to 2 times`,
});

parallel = Option.Boolean(`-p,--parallel`, false, {
Expand Down Expand Up @@ -275,8 +275,10 @@ export default class WorkspacesForeachCommand extends BaseCommand {
if (this.dryRun)
return 0;

// --verbose is automatically enabled in TTYs
const verbose = this.verbose ?? (this.context.stdout as WriteStream).isTTY;
// Default to maximum verbosity in terminal environments.
const verbosity = this.verbose ?? ((this.context.stdout as WriteStream).isTTY ? Infinity : 0);
const label = verbosity > 0;
const timing = verbosity > 1;

const concurrency = this.parallel ?
(this.jobs === `unlimited`
Expand Down Expand Up @@ -308,17 +310,17 @@ export default class WorkspacesForeachCommand extends BaseCommand {
if (abortNextCommands)
return -1;

if (!parallel && verbose && commandIndex > 1)
if (!parallel && timing && commandIndex > 1)
report.reportSeparator();

const prefix = getPrefix(workspace, {configuration, verbose, commandIndex});
const prefix = getPrefix(workspace, {configuration, label, commandIndex});

const [stdout, stdoutEnd] = createStream(report, {prefix, interlaced});
const [stderr, stderrEnd] = createStream(report, {prefix, interlaced});

try {
if (verbose)
report.reportInfo(null, `${prefix} Process started`);
if (timing)
report.reportInfo(null, `${prefix ? `${prefix} ` : ``}Process started`);

const start = Date.now();

Expand All @@ -335,9 +337,9 @@ export default class WorkspacesForeachCommand extends BaseCommand {
await stderrEnd;

const end = Date.now();
if (verbose) {
if (timing) {
const timerMessage = configuration.get(`enableTimers`) ? `, completed in ${formatUtils.pretty(configuration, end - start, formatUtils.Type.DURATION)}` : ``;
report.reportInfo(null, `${prefix} Process exited (exit code ${exitCode})${timerMessage}`);
report.reportInfo(null, `${prefix ? `${prefix} ` : ``}Process exited (exit code ${exitCode})${timerMessage}`);
}

if (exitCode === 130) {
Expand Down Expand Up @@ -475,11 +477,11 @@ function createStream(report: Report, {prefix, interlaced}: {prefix: string | nu
type GetPrefixOptions = {
configuration: Configuration;
commandIndex: number;
verbose: boolean;
label: boolean;
};

function getPrefix(workspace: Workspace, {configuration, commandIndex, verbose}: GetPrefixOptions) {
if (!verbose)
function getPrefix(workspace: Workspace, {configuration, commandIndex, label}: GetPrefixOptions) {
if (!label)
return null;

const name = structUtils.stringifyIdent(workspace.anchoredLocator);
Expand Down
Loading