Skip to content

Commit

Permalink
feat(core): prefix outputs and warn on non-prefixed outputs (#12470)
Browse files Browse the repository at this point in the history
  • Loading branch information
FrozenPandaz authored Oct 11, 2022
1 parent 74e898d commit 834e2db
Show file tree
Hide file tree
Showing 23 changed files with 537 additions and 211 deletions.
4 changes: 2 additions & 2 deletions docs/generated/devkit/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1081,7 +1081,7 @@ Prefixes project name with npm scope

### getOutputsForTargetAndConfiguration

**getOutputsForTargetAndConfiguration**(`task`, `node`): `any`
**getOutputsForTargetAndConfiguration**(`task`, `node`): `string`[]

Returns the list of outputs that will be cached.

Expand All @@ -1094,7 +1094,7 @@ Returns the list of outputs that will be cached.

#### Returns

`any`
`string`[]

---

Expand Down
2 changes: 1 addition & 1 deletion docs/generated/packages/devkit.json

Large diffs are not rendered by default.

12 changes: 9 additions & 3 deletions e2e/nx-run/src/cache.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,13 @@ describe('cache', () => {
expect(outputWithBuildApp2Cached).toContain(
'read the output from the cache'
);
expectMatchedOutput(outputWithBuildApp2Cached, [myapp2]);

if (process.platform != 'linux') {
// TODO(vsavkin): This should be always be matched output once you fix output watching on linux
expectMatchedOutput(outputWithBuildApp2Cached, [myapp2]);
} else {
expectCached(outputWithBuildApp2Cached, [myapp2]);
}

// touch package.json
// --------------------------------------------
Expand Down Expand Up @@ -166,7 +172,7 @@ describe('cache', () => {
updateProjectConfig(mylib, (c) => {
c.targets.build = {
executor: 'nx:run-commands',
outputs: ['dist/*.txt'],
outputs: ['{workspaceRoot}/dist/*.txt'],
options: {
commands: [
'rm -rf dist',
Expand Down Expand Up @@ -312,7 +318,7 @@ describe('cache', () => {
expectProjectMatchTaskCacheStatus(
actualOutput,
expectedMatchedOutputProjects,
'local cache'
'existing outputs match the cache'
);
}

Expand Down
2 changes: 1 addition & 1 deletion e2e/nx-run/src/run.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ describe('Nx Running Tests', () => {
];
nxJson.targetDefaults = {
prep: {
outputs: ['one.txt'],
outputs: ['{workspaceRoot}/one.txt'],
},
outside: {
dependsOn: ['prep'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ Object {
"passWithNoTests": true,
},
"outputs": Array [
"coverage/apps/my-dir/my-app",
"{workspaceRoot}/coverage/{projectRoot}",
],
},
},
Expand Down Expand Up @@ -399,7 +399,7 @@ Object {
"passWithNoTests": true,
},
"outputs": Array [
"coverage/apps/my-app",
"{workspaceRoot}/coverage/{projectRoot}",
],
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,7 @@ function fixProjectWorkspaceConfig(
executor: options.publishable
? '@nrwl/angular:package'
: '@nrwl/angular:ng-packagr-lite',
outputs: [
joinPathFragments(
'dist',
getWorkspaceLayout(host).libsDir,
options.projectDirectory
),
],
outputs: ['{workspaceRoot}/dist/{projectRoot}'],
...rest,
};
}
Expand Down
2 changes: 1 addition & 1 deletion packages/angular/src/generators/library/library.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,7 @@ describe('lib', () => {
{
path: 'my-dir/my-lib/project.json',
lookupFn: (json) => json.targets.build.outputs,
expectedValue: ['dist/my-dir/my-lib'],
expectedValue: ['{workspaceRoot}/dist/{projectRoot}'],
},
{
path: 'my-dir/my-lib/tsconfig.lib.json',
Expand Down
24 changes: 20 additions & 4 deletions packages/angular/src/generators/move/lib/update-ng-package.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
getOutputsForTargetAndConfiguration,
normalizePath,
readProjectConfiguration,
Tree,
Expand All @@ -25,10 +26,25 @@ export function updateNgPackage(tree: Tree, schema: Schema): void {
const rootOffset = normalizePath(
relative(join(workspaceRoot, project.root), workspaceRoot)
);
let output = `dist/${project.root}`;
if (project.targets?.build?.outputs?.length > 0) {
output = project.targets.build.outputs[0];
}
const outputs = getOutputsForTargetAndConfiguration(
{
target: {
project: newProjectName,
target: 'build',
},
overrides: {},
},
{
name: newProjectName,
type: 'lib',
data: {
root: project.root,
targets: project.targets,
},
}
);

const output = outputs[0] ?? `dist/${project.root}`;

updateJson(tree, ngPackagePath, (json) => {
json.dest = `${rootOffset}/${output}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Object {
"passWithNoTests": true,
},
"outputs": Array [
"coverage/libs/lib1",
"{workspaceRoot}/coverage/{projectRoot}",
],
}
`;
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ describe('jestProject', () => {
const lib1 = readProjectConfiguration(tree, 'lib1');
expect(lib1.targets.test).toEqual({
executor: '@nrwl/jest:jest',
outputs: ['coverage/libs/lib1'],
outputs: ['{workspaceRoot}/coverage/{projectRoot}'],
options: {
jestConfig: 'libs/lib1/jest.config.ts',
passWithNoTests: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ export function updateWorkspace(tree: Tree, options: JestProjectSchema) {
projectConfig.targets.test = {
executor: '@nrwl/jest:jest',
outputs: [
joinPathFragments(
normalizePath('coverage'),
normalizePath(projectConfig.root)
),
joinPathFragments('{workspaceRoot}', 'coverage', '{projectRoot}'),
],
options: {
jestConfig: joinPathFragments(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ describe('@nrwl/linter:workspace-rules-project', () => {
"passWithNoTests": true,
},
"outputs": Array [
"coverage/tools/eslint-rules",
"{workspaceRoot}/coverage/{projectRoot}",
],
},
},
Expand Down
2 changes: 1 addition & 1 deletion packages/nest/src/generators/library/library.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('lib', () => {
});
expect(workspaceJson.projects[libFileName].architect.test).toEqual({
builder: '@nrwl/jest:jest',
outputs: [`coverage/libs/${libFileName}`],
outputs: [`{workspaceRoot}/coverage/{projectRoot}`],
options: {
jestConfig: `libs/${libFileName}/jest.config.ts`,
passWithNoTests: true,
Expand Down
2 changes: 1 addition & 1 deletion packages/node/src/generators/library/library.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('lib', () => {
});
expect(workspaceJson.projects['my-lib'].architect.test).toEqual({
builder: '@nrwl/jest:jest',
outputs: ['coverage/libs/my-lib'],
outputs: ['{workspaceRoot}/coverage/{projectRoot}'],
options: {
jestConfig: 'libs/my-lib/jest.config.ts',
passWithNoTests: true,
Expand Down
2 changes: 1 addition & 1 deletion packages/nx-plugin/src/generators/plugin/plugin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ describe('NxPlugin Plugin Generator', () => {
});
expect(project.targets.test).toEqual({
executor: '@nrwl/jest:jest',
outputs: ['coverage/libs/my-plugin'],
outputs: ['{workspaceRoot}/coverage/{projectRoot}'],
options: {
jestConfig: 'libs/my-plugin/jest.config.ts',
passWithNoTests: true,
Expand Down
6 changes: 6 additions & 0 deletions packages/nx/migrations.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
"version": "15.0.0-beta.1",
"description": "Replace implicitDependencies with namedInputs + target inputs",
"implementation": "./src/migrations/update-15-0-0/migrate-to-inputs"
},
"15.0.0-prefix-outputs": {
"cli": "nx",
"version": "15.0.0-beta.1",
"description": "Prefix outputs with {workspaceRoot}/{projectRoot} if needed",
"implementation": "./src/migrations/update-15-0-0/prefix-outputs"
}
}
}
96 changes: 96 additions & 0 deletions packages/nx/src/migrations/update-15-0-0/prefix-outputs.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { createTreeWithEmptyWorkspace } from '../../generators/testing-utils/create-tree-with-empty-workspace';
import type { Tree } from '../../generators/tree';
import {
addProjectConfiguration,
readProjectConfiguration,
readWorkspaceConfiguration,
updateWorkspaceConfiguration,
} from '../../generators/utils/project-configuration';
import { writeJson } from '../../generators/utils/json';
import prefixOutputs from './prefix-outputs';
import { validateOutputs } from 'nx/src/tasks-runner/utils';

describe('15.0.0 migration (prefix-outputs)', () => {
let tree: Tree;

beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
});

it('should prefix project outputs', async () => {
addProjectConfiguration(tree, 'proj', {
root: 'proj',
targets: {
build: {
executor: 'nx:run-commands',
outputs: [
'dist',
'dist/{projectRoot}',
'dist/{projectRoot}/**/*.js',
'proj/coverage',
'./test-results',
'{projectRoot}/build',
'{options.outputDirectory}',
],
options: {},
},
},
});

await prefixOutputs(tree);

const updated = readProjectConfiguration(tree, 'proj');

expect(updated.targets.build.outputs).toEqual([
'{workspaceRoot}/dist',
'{workspaceRoot}/dist/{projectRoot}',
'{workspaceRoot}/dist/{projectRoot}/**/*.js',
'{projectRoot}/coverage',
'{projectRoot}/test-results',
'{projectRoot}/build',
'{options.outputDirectory}',
]);

expect(() => validateOutputs(updated.targets.build.outputs)).not.toThrow();
});

it('should prefix target default outputs', async () => {
const workspace = readWorkspaceConfiguration(tree);
updateWorkspaceConfiguration(tree, {
...workspace,
targetDefaults: {
build: {
outputs: ['dist', '{projectRoot}/build', '{options.outputPath}'],
},
},
});

await prefixOutputs(tree);

const updated = readWorkspaceConfiguration(tree);

expect(updated.targetDefaults).toMatchInlineSnapshot(`
Object {
"build": Object {
"outputs": Array [
"{workspaceRoot}/dist",
"{projectRoot}/build",
"{options.outputPath}",
],
},
}
`);
});

it('should not error for package.json projects', async () => {
writeJson(tree, 'proj/package.json', {
name: 'proj',
scripts: {
build: 'echo',
},
});
tree.delete('workspace.json');

await prefixOutputs(tree);
});
});
62 changes: 62 additions & 0 deletions packages/nx/src/migrations/update-15-0-0/prefix-outputs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Tree } from '../../generators/tree';
import { formatChangedFilesWithPrettierIfAvailable } from '../../generators/internal-utils/format-changed-files-with-prettier-if-available';
import {
getProjects,
readWorkspaceConfiguration,
updateProjectConfiguration,
updateWorkspaceConfiguration,
} from '../../generators/utils/project-configuration';
import { joinPathFragments } from '../../utils/path';
import { relative } from 'path';
import {
transformLegacyOutputs,
validateOutputs,
} from 'nx/src/tasks-runner/utils';

export default async function (tree: Tree) {
// If the workspace doesn't have a nx.json, don't make any changes
if (!tree.exists('nx.json')) {
return;
}

const workspaceConfiguration = readWorkspaceConfiguration(tree);

for (const [projectName, project] of getProjects(tree)) {
if (!project.targets) {
continue;
}

for (const [_, target] of Object.entries(project.targets)) {
if (!target.outputs) {
continue;
}

try {
validateOutputs(target.outputs);
} catch (e) {
target.outputs = transformLegacyOutputs(project.root, e);
}
}
updateProjectConfiguration(tree, projectName, project);
}

if (workspaceConfiguration.targetDefaults) {
for (const [_, target] of Object.entries(
workspaceConfiguration.targetDefaults
)) {
if (!target.outputs) {
continue;
}

target.outputs = target.outputs.map((output) => {
return /^{[\s\S]+}/.test(output)
? output
: joinPathFragments('{workspaceRoot}', output);
});
}

updateWorkspaceConfiguration(tree, workspaceConfiguration);
}

await formatChangedFilesWithPrettierIfAvailable(tree);
}
Loading

1 comment on commit 834e2db

@vercel
Copy link

@vercel vercel bot commented on 834e2db Oct 11, 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
nx-dev-git-master-nrwl.vercel.app
nx-dev-nrwl.vercel.app

Please sign in to comment.