feat(devkit): allow updating package json based projects (#27138)
<!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior Calling `updateProjectConfiguration` on a package json based project fails ## Expected Behavior Calling `updateProjectConfiguration` on a package json based project works ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes #26530
This commit is contained in:
parent
9a556f45b8
commit
3dbbfd73ca
@ -277,5 +277,57 @@ describe('project configuration', () => {
|
|||||||
root: 'proj',
|
root: 'proj',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle reading + writing project configuration', () => {
|
||||||
|
writeJson(tree, 'proj/package.json', {
|
||||||
|
name: 'proj',
|
||||||
|
nx: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
const proj = readProjectConfiguration(tree, 'proj');
|
||||||
|
expect(proj).toEqual({
|
||||||
|
name: 'proj',
|
||||||
|
root: 'proj',
|
||||||
|
});
|
||||||
|
|
||||||
|
updateProjectConfiguration(tree, 'proj', {
|
||||||
|
name: 'proj',
|
||||||
|
root: 'proj',
|
||||||
|
sourceRoot: 'proj/src',
|
||||||
|
targets: {
|
||||||
|
build: {
|
||||||
|
command: 'echo "building"',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const updatedProj = readProjectConfiguration(tree, 'proj');
|
||||||
|
expect(updatedProj).toEqual({
|
||||||
|
name: 'proj',
|
||||||
|
root: 'proj',
|
||||||
|
sourceRoot: 'proj/src',
|
||||||
|
targets: {
|
||||||
|
build: {
|
||||||
|
command: 'echo "building"',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(tree.read('proj/package.json', 'utf-8')).toMatchInlineSnapshot(`
|
||||||
|
"{
|
||||||
|
"name": "proj",
|
||||||
|
"nx": {
|
||||||
|
"sourceRoot": "proj/src",
|
||||||
|
"targets": {
|
||||||
|
"build": {
|
||||||
|
"command": "echo \\"building\\""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
expect(tree.exists('proj/project.json')).toBeFalsy();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,10 +1,7 @@
|
|||||||
import { minimatch } from 'minimatch';
|
import { minimatch } from 'minimatch';
|
||||||
import { basename, join, relative } from 'path';
|
import { basename, dirname, join, relative } from 'path';
|
||||||
|
|
||||||
import {
|
import { getGlobPatternsFromPackageManagerWorkspaces } from '../../plugins/package-json';
|
||||||
buildProjectConfigurationFromPackageJson,
|
|
||||||
getGlobPatternsFromPackageManagerWorkspaces,
|
|
||||||
} from '../../plugins/package-json';
|
|
||||||
import { buildProjectFromProjectJson } from '../../plugins/project-json/build-nodes/project-json';
|
import { buildProjectFromProjectJson } from '../../plugins/project-json/build-nodes/project-json';
|
||||||
import { renamePropertyWithStableKeys } from '../../adapter/angular-json';
|
import { renamePropertyWithStableKeys } from '../../adapter/angular-json';
|
||||||
import {
|
import {
|
||||||
@ -23,6 +20,7 @@ import { readJson, writeJson } from './json';
|
|||||||
import { readNxJson } from './nx-json';
|
import { readNxJson } from './nx-json';
|
||||||
|
|
||||||
import type { Tree } from '../tree';
|
import type { Tree } from '../tree';
|
||||||
|
import { toProjectName } from '../../config/to-project-name';
|
||||||
|
|
||||||
export { readNxJson, updateNxJson } from './nx-json';
|
export { readNxJson, updateNxJson } from './nx-json';
|
||||||
|
|
||||||
@ -82,17 +80,73 @@ export function updateProjectConfiguration(
|
|||||||
projectName: string,
|
projectName: string,
|
||||||
projectConfiguration: ProjectConfiguration
|
projectConfiguration: ProjectConfiguration
|
||||||
): void {
|
): void {
|
||||||
|
if (
|
||||||
|
tree.exists(joinPathFragments(projectConfiguration.root, 'project.json'))
|
||||||
|
) {
|
||||||
|
updateProjectConfigurationInProjectJson(
|
||||||
|
tree,
|
||||||
|
projectName,
|
||||||
|
projectConfiguration
|
||||||
|
);
|
||||||
|
} else if (
|
||||||
|
tree.exists(joinPathFragments(projectConfiguration.root, 'package.json'))
|
||||||
|
) {
|
||||||
|
updateProjectConfigurationInPackageJson(
|
||||||
|
tree,
|
||||||
|
projectName,
|
||||||
|
projectConfiguration
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`Cannot update Project ${projectName} at ${projectConfiguration.root}. It either doesn't exist yet, or may not use project.json for configuration. Use \`addProjectConfiguration()\` instead if you want to create a new project.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateProjectConfigurationInPackageJson(
|
||||||
|
tree: Tree,
|
||||||
|
projectName: string,
|
||||||
|
projectConfiguration: ProjectConfiguration
|
||||||
|
) {
|
||||||
|
const packageJsonFile = joinPathFragments(
|
||||||
|
projectConfiguration.root,
|
||||||
|
'package.json'
|
||||||
|
);
|
||||||
|
|
||||||
|
const packageJson = readJson<PackageJson>(tree, packageJsonFile);
|
||||||
|
|
||||||
|
if (packageJson.name === projectConfiguration.name ?? projectName) {
|
||||||
|
delete projectConfiguration.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
projectConfiguration.targets &&
|
||||||
|
!Object.keys(projectConfiguration.targets).length
|
||||||
|
) {
|
||||||
|
delete projectConfiguration.targets;
|
||||||
|
}
|
||||||
|
|
||||||
|
packageJson.nx = {
|
||||||
|
...packageJson.nx,
|
||||||
|
...projectConfiguration,
|
||||||
|
root: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
writeJson(tree, packageJsonFile, packageJson);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateProjectConfigurationInProjectJson(
|
||||||
|
tree: Tree,
|
||||||
|
projectName: string,
|
||||||
|
projectConfiguration: ProjectConfiguration
|
||||||
|
) {
|
||||||
const projectConfigFile = joinPathFragments(
|
const projectConfigFile = joinPathFragments(
|
||||||
projectConfiguration.root,
|
projectConfiguration.root,
|
||||||
'project.json'
|
'project.json'
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!tree.exists(projectConfigFile)) {
|
|
||||||
throw new Error(
|
|
||||||
`Cannot update Project ${projectName} at ${projectConfiguration.root}. It either doesn't exist yet, or may not use project.json for configuration. Use \`addProjectConfiguration()\` instead if you want to create a new project.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
handleEmptyTargets(projectName, projectConfiguration);
|
handleEmptyTargets(projectName, projectConfiguration);
|
||||||
|
|
||||||
writeJson(tree, projectConfigFile, {
|
writeJson(tree, projectConfigFile, {
|
||||||
name: projectConfiguration.name ?? projectName,
|
name: projectConfiguration.name ?? projectName,
|
||||||
$schema: getRelativeProjectJsonSchemaPath(tree, projectConfiguration),
|
$schema: getRelativeProjectJsonSchemaPath(tree, projectConfiguration),
|
||||||
@ -215,21 +269,22 @@ function readAndCombineAllProjectConfigurations(tree: Tree): {
|
|||||||
);
|
);
|
||||||
} else if (basename(projectFile) === 'package.json') {
|
} else if (basename(projectFile) === 'package.json') {
|
||||||
const packageJson = readJson<PackageJson>(tree, projectFile);
|
const packageJson = readJson<PackageJson>(tree, projectFile);
|
||||||
const config = buildProjectConfigurationFromPackageJson(
|
|
||||||
packageJson,
|
// We don't want to have all of the extra inferred stuff in here, as
|
||||||
tree.root,
|
// when generators update the project they shouldn't inline that stuff.
|
||||||
projectFile,
|
// so rather than using `buildProjectFromPackageJson` and stripping it out
|
||||||
readNxJson(tree)
|
// we are going to build the config manually.
|
||||||
);
|
const config = {
|
||||||
|
root: dirname(projectFile),
|
||||||
|
name: packageJson.name ?? toProjectName(projectFile),
|
||||||
|
...packageJson.nx,
|
||||||
|
};
|
||||||
if (!rootMap[config.root]) {
|
if (!rootMap[config.root]) {
|
||||||
mergeProjectConfigurationIntoRootMap(
|
mergeProjectConfigurationIntoRootMap(
|
||||||
rootMap,
|
rootMap,
|
||||||
// Inferred targets, tags, etc don't show up when running generators
|
// Inferred targets, tags, etc don't show up when running generators
|
||||||
// This is to help avoid running into issues when trying to update the workspace
|
// This is to help avoid running into issues when trying to update the workspace
|
||||||
{
|
config,
|
||||||
name: config.name,
|
|
||||||
root: config.root,
|
|
||||||
},
|
|
||||||
undefined,
|
undefined,
|
||||||
undefined,
|
undefined,
|
||||||
true
|
true
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { existsSync } from 'fs';
|
import { existsSync } from 'fs';
|
||||||
import { dirname, join } from 'path';
|
import { dirname, join } from 'path';
|
||||||
import {
|
import {
|
||||||
InputDefinition,
|
ProjectConfiguration,
|
||||||
ProjectMetadata,
|
ProjectMetadata,
|
||||||
TargetConfiguration,
|
TargetConfiguration,
|
||||||
} from '../config/workspace-json-project-json';
|
} from '../config/workspace-json-project-json';
|
||||||
@ -13,12 +13,8 @@ import {
|
|||||||
getPackageManagerCommand,
|
getPackageManagerCommand,
|
||||||
} from './package-manager';
|
} from './package-manager';
|
||||||
|
|
||||||
export interface NxProjectPackageJsonConfiguration {
|
export interface NxProjectPackageJsonConfiguration
|
||||||
name?: string;
|
extends Partial<ProjectConfiguration> {
|
||||||
implicitDependencies?: string[];
|
|
||||||
tags?: string[];
|
|
||||||
namedInputs?: { [inputName: string]: (string | InputDefinition)[] };
|
|
||||||
targets?: Record<string, TargetConfiguration>;
|
|
||||||
includedScripts?: string[];
|
includedScripts?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user