feat(core): outputs should be able to interpolate project properties
This commit is contained in:
parent
70942802fe
commit
876d4d8a0e
@ -17,6 +17,12 @@
|
||||
"version": "14.2.0-beta.0",
|
||||
"description": "Remove default collection from configuration to switch to prompts for collection",
|
||||
"factory": "./src/migrations/update-14-2-0/remove-default-collection"
|
||||
},
|
||||
"14-2-0-replace-relative-outputs-with-absolute": {
|
||||
"cli": "nx",
|
||||
"version": "14.2.0-beta.5",
|
||||
"description": "Replace all ./ and ../ in outputs with absolute paths",
|
||||
"factory": "./src/migrations/update-14-2-0/replace-all-relative-outputs-with-absolute"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,12 +50,14 @@ function projectsToRun(
|
||||
const allProjects = Object.values(projectGraph.nodes);
|
||||
const excludedProjects = new Set(nxArgs.exclude ?? []);
|
||||
if (nxArgs.all) {
|
||||
return runnableForTarget(allProjects, nxArgs.target).filter(
|
||||
const res = runnableForTarget(allProjects, nxArgs.target).filter(
|
||||
(proj) => !excludedProjects.has(proj.name)
|
||||
);
|
||||
res.sort((a, b) => a.name.localeCompare(b.name));
|
||||
return res;
|
||||
}
|
||||
checkForInvalidProjects(nxArgs, allProjects);
|
||||
let selectedProjects = nxArgs.projects.map((name) =>
|
||||
const selectedProjects = nxArgs.projects.map((name) =>
|
||||
allProjects.find((project) => project.name === name)
|
||||
);
|
||||
return runnableForTarget(selectedProjects, nxArgs.target, true).filter(
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
import { Tree } from '../../generators/tree';
|
||||
import {
|
||||
getProjects,
|
||||
updateProjectConfiguration,
|
||||
} from '../../generators/utils/project-configuration';
|
||||
import { isRelativePath } from 'nx/src/utils/fileutils';
|
||||
import { joinPathFragments } from 'nx/src/utils/path';
|
||||
|
||||
export default async function (tree: Tree) {
|
||||
for (const [name, value] of getProjects(tree).entries()) {
|
||||
for (const t of Object.values(value.targets)) {
|
||||
if (t.outputs) {
|
||||
t.outputs = t.outputs.map((o) =>
|
||||
isRelativePath(o) ? joinPathFragments(value.root, o) : o
|
||||
);
|
||||
}
|
||||
}
|
||||
updateProjectConfiguration(tree, name, value);
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
import { ProjectGraph, ProjectGraphProjectNode } from '../config/project-graph';
|
||||
import { TargetDependencyConfig } from '../config/workspace-json-project-json';
|
||||
import { getDependencyConfigs } from './utils';
|
||||
import { getDependencyConfigs, interpolate } from './utils';
|
||||
import {
|
||||
projectHasTarget,
|
||||
projectHasTargetAndConfiguration,
|
||||
@ -34,7 +34,6 @@ export class ProcessTasks {
|
||||
configuration
|
||||
);
|
||||
const id = this.getId(projectName, target, resolvedConfiguration);
|
||||
debugger;
|
||||
const task = this.createTask(
|
||||
id,
|
||||
this.projectGraph.nodes[projectName],
|
||||
@ -219,23 +218,14 @@ export function createTaskGraph(
|
||||
function interpolateOverrides<T = any>(
|
||||
args: T,
|
||||
projectName: string,
|
||||
projectMetadata: any
|
||||
project: any
|
||||
): T {
|
||||
const interpolatedArgs: T = { ...args };
|
||||
Object.entries(interpolatedArgs).forEach(([name, value]) => {
|
||||
if (typeof value === 'string') {
|
||||
const regex = /{project\.([^}]+)}/g;
|
||||
interpolatedArgs[name] = value.replace(regex, (_, group: string) => {
|
||||
if (group.includes('.')) {
|
||||
throw new Error('Only top-level properties can be interpolated');
|
||||
}
|
||||
|
||||
if (group === 'name') {
|
||||
return projectName;
|
||||
}
|
||||
return projectMetadata[group];
|
||||
});
|
||||
}
|
||||
interpolatedArgs[name] =
|
||||
typeof value === 'string'
|
||||
? interpolate(value, { project: { ...project, name: projectName } })
|
||||
: value;
|
||||
});
|
||||
return interpolatedArgs;
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ describe('utils', () => {
|
||||
name: 'myapp',
|
||||
type: 'app',
|
||||
data: {
|
||||
root: '/myapp',
|
||||
targets: {
|
||||
build: { ...build, executor: '' },
|
||||
},
|
||||
@ -37,6 +38,17 @@ describe('utils', () => {
|
||||
).toEqual(['one', 'two']);
|
||||
});
|
||||
|
||||
it('should return them', () => {
|
||||
expect(
|
||||
getOutputsForTargetAndConfiguration(
|
||||
task,
|
||||
getNode({
|
||||
outputs: ['one', 'two'],
|
||||
})
|
||||
)
|
||||
).toEqual(['one', 'two']);
|
||||
});
|
||||
|
||||
it('should support interpolation based on options', () => {
|
||||
expect(
|
||||
getOutputsForTargetAndConfiguration(
|
||||
@ -51,6 +63,34 @@ describe('utils', () => {
|
||||
).toEqual(['path/one', 'two']);
|
||||
});
|
||||
|
||||
it('should support interpolating root', () => {
|
||||
expect(
|
||||
getOutputsForTargetAndConfiguration(
|
||||
task,
|
||||
getNode({
|
||||
outputs: ['{project.root}/sub', 'two'],
|
||||
options: {
|
||||
myVar: 'one',
|
||||
},
|
||||
})
|
||||
)
|
||||
).toEqual(['/myapp/sub', 'two']);
|
||||
});
|
||||
|
||||
it('should support relative paths', () => {
|
||||
expect(
|
||||
getOutputsForTargetAndConfiguration(
|
||||
task,
|
||||
getNode({
|
||||
outputs: ['./sub', 'two'],
|
||||
options: {
|
||||
myVar: 'one',
|
||||
},
|
||||
})
|
||||
)
|
||||
).toEqual(['/myapp/sub', 'two']);
|
||||
});
|
||||
|
||||
it('should support nested interpolation based on options', () => {
|
||||
expect(
|
||||
getOutputsForTargetAndConfiguration(
|
||||
|
||||
@ -13,6 +13,8 @@ import { getPackageManagerCommand } from '../utils/package-manager';
|
||||
import { ProjectGraph, ProjectGraphProjectNode } from '../config/project-graph';
|
||||
import { TargetDependencyConfig } from '../config/workspace-json-project-json';
|
||||
import { workspaceRoot } from '../utils/workspace-root';
|
||||
import { isRelativePath } from 'nx/src/utils/fileutils';
|
||||
import { joinPathFragments } from 'nx/src/utils/path';
|
||||
|
||||
export function getCommandAsString(task: Task) {
|
||||
const execCommand = getPackageManagerCommand().exec;
|
||||
@ -88,7 +90,15 @@ export function getOutputsForTargetAndConfiguration(
|
||||
|
||||
if (targets?.outputs) {
|
||||
return targets.outputs
|
||||
.map((output: string) => interpolateOutputs(output, options))
|
||||
.map((output: string) => {
|
||||
const interpolated = interpolate(output, {
|
||||
options,
|
||||
project: { ...node.data, name: node.name },
|
||||
});
|
||||
return isRelativePath(interpolated)
|
||||
? joinPathFragments(node.data.root, interpolated)
|
||||
: interpolated;
|
||||
})
|
||||
.filter((output) => !!output);
|
||||
}
|
||||
|
||||
@ -150,17 +160,16 @@ function stringShouldBeWrappedIntoQuotes(str: string) {
|
||||
return str.includes(' ') || str.includes('{') || str.includes('"');
|
||||
}
|
||||
|
||||
function interpolateOutputs(template: string, data: any): string {
|
||||
export function interpolate(template: string, data: any): string {
|
||||
return template.replace(/{([\s\S]+?)}/g, (match: string) => {
|
||||
let value = data;
|
||||
let path = match.slice(1, -1).trim().split('.').slice(1);
|
||||
let path = match.slice(1, -1).trim().split('.');
|
||||
for (let idx = 0; idx < path.length; idx++) {
|
||||
if (!value[path[idx]]) {
|
||||
return;
|
||||
}
|
||||
value = value[path[idx]];
|
||||
}
|
||||
|
||||
return value;
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user