Skip to content

Commit

Permalink
feat(core): change exec to run adhoc tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
xiongemi committed Oct 27, 2023
1 parent c884e91 commit 53464ff
Show file tree
Hide file tree
Showing 11 changed files with 458 additions and 68 deletions.
20 changes: 14 additions & 6 deletions docs/generated/cli/exec.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`

## Options

### configuration
### all

Type: `string`
Type: `boolean`

This is the configuration to use when performing tasks on projects
Default: `true`

[deprecated] `run-many` runs all targets on all projects in the workspace if no projects are provided. This option is no longer required.

### exclude

Expand All @@ -35,6 +37,12 @@ Type: `string`

Show the task graph of the command. Pass a file path to save the graph data instead of viewing it in the browser.

### help

Type: `boolean`

Show help

### nxBail

Type: `boolean`
Expand All @@ -55,7 +63,7 @@ Ignore cycles in the task graph

Type: `string`

Choices: [dynamic, static, stream, stream-without-prefixes, compact]
Choices: [dynamic, static, stream, stream-without-prefixes]

Defines how Nx emits outputs tasks logs

Expand All @@ -65,11 +73,11 @@ Type: `string`

Max number of parallel processes [default is 3]

### project
### projects

Type: `string`

Target project
Projects to run. (comma/space delimited project names and/or patterns)

### runner

Expand Down
20 changes: 14 additions & 6 deletions docs/generated/packages/nx/documents/exec.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`

## Options

### configuration
### all

Type: `string`
Type: `boolean`

This is the configuration to use when performing tasks on projects
Default: `true`

[deprecated] `run-many` runs all targets on all projects in the workspace if no projects are provided. This option is no longer required.

### exclude

Expand All @@ -35,6 +37,12 @@ Type: `string`

Show the task graph of the command. Pass a file path to save the graph data instead of viewing it in the browser.

### help

Type: `boolean`

Show help

### nxBail

Type: `boolean`
Expand All @@ -55,7 +63,7 @@ Ignore cycles in the task graph

Type: `string`

Choices: [dynamic, static, stream, stream-without-prefixes, compact]
Choices: [dynamic, static, stream, stream-without-prefixes]

Defines how Nx emits outputs tasks logs

Expand All @@ -65,11 +73,11 @@ Type: `string`

Max number of parallel processes [default is 3]

### project
### projects

Type: `string`

Target project
Projects to run. (comma/space delimited project names and/or patterns)

### runner

Expand Down
58 changes: 55 additions & 3 deletions e2e/nx-run/src/run.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -638,13 +638,21 @@ describe('Nx Running Tests', () => {

describe('exec', () => {
let pkg: string;
let pkg2: string;
let pkgRoot: string;
let pkg2Root: string;
let originalRootPackageJson: PackageJson;

beforeAll(() => {
originalRootPackageJson = readJson<PackageJson>('package.json');
pkg = uniq('package');
pkg2 = uniq('package');
pkgRoot = tmpProjPath(path.join('libs', pkg));
pkg2Root = tmpProjPath(path.join('libs', pkg2));
runCLI(`generate @nx/js:lib ${pkg} --bundler=none --unitTestRunner=none`);
runCLI(
`generate @nx/js:lib ${pkg2} --bundler=none --unitTestRunner=none`
);

updateJson<PackageJson>('package.json', (v) => {
v.workspaces = ['libs/*'];
Expand All @@ -662,6 +670,22 @@ describe('Nx Running Tests', () => {
},
})
);

updateFile(
`libs/${pkg2}/package.json`,
JSON.stringify(<PackageJson>{
name: pkg2,
version: '0.0.1',
scripts: {
build: "nx exec -- echo '$NX_PROJECT_NAME'",
},
})
);

updateJson(`libs/${pkg2}/project.json`, (content) => {
content['implicitDependencies'] = [pkg];
return content;
});
});

afterAll(() => {
Expand All @@ -676,6 +700,36 @@ describe('Nx Running Tests', () => {
expect(output).toContain(`nx run ${pkg}:build`);
});

it('should run adhoc tasks in topological order', () => {
let output = runCLI('exec -- echo HELLO');
expect(output).toContain('HELLO');

output = runCLI(`build ${pkg}`);
expect(output).toContain(pkg);
expect(output).not.toContain(pkg2);

output = runCommand('npm run build', {
cwd: pkgRoot,
});
expect(output).toContain(pkg);
expect(output).not.toContain(pkg2);

output = runCLI(`exec -- echo '$NX_PROJECT_NAME'`);
expect(output.replace(/\s+/g, ' ')).toContain(`${pkg} ${pkg2}`);

output = runCLI("exec -- echo '$NX_PROJECT_ROOT_PATH'");
expect(output.replace(/\s+/g, ' ')).toContain(
`${path.join('libs', pkg)} ${path.join('libs', pkg2)}`
);

output = runCLI(`exec --projects ${pkg} -- echo WORLD`);
expect(output).toContain('WORLD');

output = runCLI(`exec --projects ${pkg} -- echo '$NX_PROJECT_NAME'`);
expect(output).toContain(pkg);
expect(output).not.toContain(pkg2);
});

it('should work for npm scripts with delimiter', () => {
const output = runCommand('npm run build:option', { cwd: pkgRoot });
expect(output).toContain('HELLO WITH OPTION');
Expand All @@ -701,7 +755,6 @@ describe('Nx Running Tests', () => {
});

it('should read outputs', () => {
console.log(pkgRoot);
const nodeCommands = [
"const fs = require('fs')",
"fs.mkdirSync('../../tmp/exec-outputs-test', {recursive: true})",
Expand All @@ -724,10 +777,9 @@ describe('Nx Running Tests', () => {
},
})
);
const out = runCommand('npm run build', {
runCommand('npm run build', {
cwd: pkgRoot,
});
console.log(out);
expect(
fileExists(tmpProjPath('tmp/exec-outputs-test/file.txt'))
).toBeTruthy();
Expand Down
6 changes: 4 additions & 2 deletions packages/nx/src/command-line/exec/command-object.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { CommandModule } from 'yargs';
import {
withRunOneOptions,
withOutputStyleOption,
withOverrides,
withRunManyOptions,
} from '../yargs-utils/shared-options';

export const yargsExecCommand: CommandModule = {
command: 'exec',
describe: 'Executes any command as if it was a target on the project',
builder: (yargs) => withRunOneOptions(yargs),
builder: (yargs) => withRunManyOptions(withOutputStyleOption(yargs)),
handler: async (args) => {
try {
await (await import('./exec')).nxExecCommand(withOverrides(args) as any);
process.exit(0);
} catch (e) {
console.error(e);
process.exit(1);
}
},
Expand Down
Loading

0 comments on commit 53464ff

Please sign in to comment.