Skip to content

Commit

Permalink
feat(core): introduce an explicit variable for deciding on how output…
Browse files Browse the repository at this point in the history
… is printed
  • Loading branch information
vsavkin committed May 5, 2022
1 parent c428751 commit 5346084
Show file tree
Hide file tree
Showing 12 changed files with 130 additions and 100 deletions.
8 changes: 8 additions & 0 deletions docs/generated/cli/affected.md
Expand Up @@ -109,6 +109,14 @@ Default: false

Isolate projects which previously failed

### output-style

Type: string

Choices: [dynamic, static, stream]

Defines how Nx emits outputs tasks logs

### parallel

Type: string
Expand Down
8 changes: 8 additions & 0 deletions docs/generated/cli/run-many.md
Expand Up @@ -73,6 +73,14 @@ Default: false

Only run the target on projects which previously failed

### output-style

Type: string

Choices: [dynamic, static, stream]

Defines how Nx emits outputs tasks logs

### parallel

Type: string
Expand Down
10 changes: 5 additions & 5 deletions packages/nx/bin/run-executor.ts
Expand Up @@ -3,7 +3,7 @@ import { appendFileSync, openSync, writeFileSync } from 'fs';
if (process.env.NX_TERMINAL_OUTPUT_PATH) {
setUpOutputWatching(
process.env.NX_TERMINAL_CAPTURE_STDERR === 'true',
process.env.NX_FORWARD_OUTPUT === 'true'
process.env.NX_STREAM_OUTPUT === 'true'
);
}

Expand Down Expand Up @@ -45,13 +45,13 @@ function requireCli() {
* We need to collect all stdout and stderr and store it, so the caching mechanism
* could store it.
*
* Writing stdout and stderr into different stream is too risky when using TTY.
* Writing stdout and stderr into different streams is too risky when using TTY.
*
* So we are simply monkey-patching the Javascript object. In this case the actual output will always be correct.
* And the cached output should be correct unless the CLI bypasses process.stdout or console.log and uses some
* C-binary to write to stdout.
*/
function setUpOutputWatching(captureStderr: boolean, forwardOutput: boolean) {
function setUpOutputWatching(captureStderr: boolean, streamOutput: boolean) {
const stdoutWrite = process.stdout._write;
const stderrWrite = process.stderr._write;

Expand All @@ -67,7 +67,7 @@ function setUpOutputWatching(captureStderr: boolean, forwardOutput: boolean) {
) => {
onlyStdout.push(chunk);
appendFileSync(stdoutAndStderrLogFileHandle, chunk);
if (forwardOutput) {
if (streamOutput) {
stdoutWrite.apply(process.stdout, [chunk, encoding, callback]);
} else {
callback();
Expand All @@ -80,7 +80,7 @@ function setUpOutputWatching(captureStderr: boolean, forwardOutput: boolean) {
callback: Function
) => {
appendFileSync(stdoutAndStderrLogFileHandle, chunk);
if (forwardOutput) {
if (streamOutput) {
stderrWrite.apply(process.stderr, [chunk, encoding, callback]);
} else {
callback();
Expand Down
1 change: 0 additions & 1 deletion packages/nx/src/command-line/affected.ts
Expand Up @@ -107,7 +107,6 @@ export async function affected(
env,
nxArgs,
overrides,
nxArgs.hideCachedOutput ? 'hide-cached-output' : 'default',
null
);
break;
Expand Down
29 changes: 23 additions & 6 deletions packages/nx/src/command-line/nx-commands.ts
Expand Up @@ -72,7 +72,9 @@ ${daemonHelpOutput}
describe: 'Run target for multiple listed projects',
builder: (yargs) =>
linkToNxDevAndExamples(
withRunManyOptions(withParallelOption(withTargetOption(yargs))),
withRunManyOptions(
withOutputStyleOption(withParallelOption(withTargetOption(yargs)))
),
'run-many'
),
handler: async (args) => (await import('./run-many')).runMany({ ...args }),
Expand All @@ -82,7 +84,9 @@ ${daemonHelpOutput}
describe: 'Run target for affected projects',
builder: (yargs) =>
linkToNxDevAndExamples(
withAffectedOptions(withParallelOption(withTargetOption(yargs))),
withAffectedOptions(
withOutputStyleOption(withParallelOption(withTargetOption(yargs)))
),
'affected'
),
handler: async (args) =>
Expand All @@ -93,7 +97,7 @@ ${daemonHelpOutput}
describe: false,
builder: (yargs) =>
linkToNxDevAndExamples(
withAffectedOptions(withParallelOption(yargs)),
withAffectedOptions(withOutputStyleOption(withParallelOption(yargs))),
'affected'
),
handler: async (args) =>
Expand All @@ -107,7 +111,7 @@ ${daemonHelpOutput}
describe: false,
builder: (yargs) =>
linkToNxDevAndExamples(
withAffectedOptions(withParallelOption(yargs)),
withAffectedOptions(withOutputStyleOption(withParallelOption(yargs))),
'affected'
),
handler: async (args) =>
Expand All @@ -121,7 +125,7 @@ ${daemonHelpOutput}
describe: false,
builder: (yargs) =>
linkToNxDevAndExamples(
withAffectedOptions(withParallelOption(yargs)),
withAffectedOptions(withOutputStyleOption(withParallelOption(yargs))),
'affected'
),
handler: async (args) =>
Expand All @@ -135,7 +139,7 @@ ${daemonHelpOutput}
describe: false,
builder: (yargs) =>
linkToNxDevAndExamples(
withAffectedOptions(withParallelOption(yargs)),
withAffectedOptions(withOutputStyleOption(withParallelOption(yargs))),
'affected'
),
handler: async (args) =>
Expand Down Expand Up @@ -524,6 +528,14 @@ function withParallelOption(yargs: yargs.Argv): yargs.Argv {
});
}

function withOutputStyleOption(yargs: yargs.Argv): yargs.Argv {
return yargs.option('output-style', {
describe: 'Defines how Nx emits outputs tasks logs',
type: 'string',
choices: ['dynamic', 'static', 'stream'],
});
}

function withTargetOption(yargs: yargs.Argv): yargs.Argv {
return yargs.option('target', {
describe: 'Task to run for affected projects',
Expand Down Expand Up @@ -596,6 +608,11 @@ function withRunOneOptions(yargs: yargs.Argv) {
.option('project', {
describe: 'Target project',
type: 'string',
})
.option('output-style', {
describe: 'Defines how Nx emits outputs tasks logs',
type: 'string',
choices: ['dynamic', 'static', 'stream', 'compact'],
});

if (executorShouldShowHelp) {
Expand Down
10 changes: 1 addition & 9 deletions packages/nx/src/command-line/run-many.ts
Expand Up @@ -23,15 +23,7 @@ export async function runMany(parsedArgs: yargs.Arguments & RawNxArgs) {
const projects = projectsToRun(nxArgs, projectGraph);
const env = readEnvironment();

await runCommand(
projects,
projectGraph,
env,
nxArgs,
overrides,
nxArgs.hideCachedOutput ? 'hide-cached-output' : 'default',
null
);
await runCommand(projects, projectGraph, env, nxArgs, overrides, null);
}

function projectsToRun(
Expand Down
1 change: 0 additions & 1 deletion packages/nx/src/command-line/run-one.ts
Expand Up @@ -49,7 +49,6 @@ export async function runOne(
env,
nxArgs,
overrides,
'run-one',
opts.project
);
}
Expand Down
52 changes: 30 additions & 22 deletions packages/nx/src/tasks-runner/forked-process-task-runner.ts
Expand Up @@ -96,9 +96,9 @@ export class ForkedProcessTaskRunner {
public forkProcessPipeOutputCapture(
task: Task,
{
forwardOutput,
streamOutput,
temporaryOutputPath,
}: { forwardOutput: boolean; temporaryOutputPath: string }
}: { streamOutput: boolean; temporaryOutputPath: string }
) {
return new Promise<{ code: number; terminalOutput: string }>((res, rej) => {
try {
Expand All @@ -107,34 +107,34 @@ export class ForkedProcessTaskRunner {
task,
task.overrides['verbose'] === true
);

if (forwardOutput) {
if (streamOutput) {
output.logCommand(args.join(' '));
output.addNewline();
}

const p = fork(this.cliPath, serializedArgs, {
stdio: ['inherit', 'pipe', 'pipe', 'ipc'],
env: this.getEnvVariablesForTask(
task,
process.env.FORCE_COLOR === undefined
? 'true'
: process.env.FORCE_COLOR,
undefined,
forwardOutput
null,
null
),
});
this.processes.add(p);
let out = [];
let outWithErr = [];
p.stdout.on('data', (chunk) => {
if (forwardOutput) {
if (streamOutput) {
process.stdout.write(chunk);
}
out.push(chunk.toString());
outWithErr.push(chunk.toString());
});
p.stderr.on('data', (chunk) => {
if (forwardOutput) {
if (streamOutput) {
process.stderr.write(chunk);
}
outWithErr.push(chunk.toString());
Expand All @@ -146,7 +146,7 @@ export class ForkedProcessTaskRunner {
// print all the collected output|
const terminalOutput = outWithErr.join('');

if (!forwardOutput) {
if (!streamOutput) {
this.options.lifeCycle.printTaskTerminalOutput(
task,
code === 0 ? 'success' : 'failure',
Expand All @@ -166,9 +166,9 @@ export class ForkedProcessTaskRunner {
public forkProcessDirectOutputCapture(
task: Task,
{
forwardOutput,
streamOutput,
temporaryOutputPath,
}: { forwardOutput: boolean; temporaryOutputPath: string }
}: { streamOutput: boolean; temporaryOutputPath: string }
) {
return new Promise<{ code: number; terminalOutput: string }>((res, rej) => {
try {
Expand All @@ -177,7 +177,7 @@ export class ForkedProcessTaskRunner {
task,
task.overrides['verbose'] === true
);
if (forwardOutput) {
if (streamOutput) {
output.logCommand(args.join(' '));
output.addNewline();
}
Expand All @@ -187,7 +187,7 @@ export class ForkedProcessTaskRunner {
task,
undefined,
temporaryOutputPath,
forwardOutput
streamOutput
),
});
this.processes.add(p);
Expand All @@ -198,7 +198,7 @@ export class ForkedProcessTaskRunner {
let terminalOutput = '';
try {
terminalOutput = this.readTerminalOutput(temporaryOutputPath);
if (!forwardOutput) {
if (!streamOutput) {
this.options.lifeCycle.printTaskTerminalOutput(
task,
code === 0 ? 'success' : 'failure',
Expand Down Expand Up @@ -252,9 +252,9 @@ export class ForkedProcessTaskRunner {
task: Task,
forceColor: string,
outputPath: string,
forwardOutput: boolean
streamOutput: boolean
) {
return {
const res = {
// Start With Dotenv Variables
...this.getDotenvVariablesForTask(task),
// User Process Env Variables override Dotenv Variables
Expand All @@ -264,15 +264,23 @@ export class ForkedProcessTaskRunner {
task,
forceColor,
outputPath,
forwardOutput
streamOutput
),
};

// we have to delete it because if we invoke Nx from within Nx, we need to reset those values
if (!outputPath) {
delete res.NX_TERMINAL_OUTPUT_PATH;
delete res.NX_STREAM_OUTPUT;
}
delete res.NX_SET_CLI;
return res;
}

private getNxEnvVariablesForForkedProcess(
forceColor: string,
outputPath?: string,
forwardOutput?: boolean
streamOutput?: boolean
) {
const env: NodeJS.ProcessEnv = {
FORCE_COLOR: forceColor,
Expand All @@ -285,8 +293,8 @@ export class ForkedProcessTaskRunner {
if (this.options.captureStderr) {
env.NX_TERMINAL_CAPTURE_STDERR = 'true';
}
if (forwardOutput) {
env.NX_FORWARD_OUTPUT = 'true';
if (streamOutput) {
env.NX_STREAM_OUTPUT = 'true';
}
}
return env;
Expand All @@ -296,7 +304,7 @@ export class ForkedProcessTaskRunner {
task: Task,
forceColor: string,
outputPath: string,
forwardOutput: boolean
streamOutput: boolean
) {
const env: NodeJS.ProcessEnv = {
NX_TASK_TARGET_PROJECT: task.target.project,
Expand All @@ -312,7 +320,7 @@ export class ForkedProcessTaskRunner {
...this.getNxEnvVariablesForForkedProcess(
forceColor,
outputPath,
forwardOutput
streamOutput
),
...env,
};
Expand Down

1 comment on commit 5346084

@vercel
Copy link

@vercel vercel bot commented on 5346084 May 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nx-dev – ./

nx-five.vercel.app
nx-dev-git-master-nrwl.vercel.app
nx-dev-nrwl.vercel.app
nx.dev

Please sign in to comment.