fix(core): automatically add root to the project.json projects (#9977)

* fix(core): automatically add root to the project.json projects

* chore(core): move project-configuration generator utils to nx package

* fix(core): add migrations to remove root
This commit is contained in:
Jason Jean 2022-04-28 13:24:35 -04:00 committed by GitHub
parent c3d30a4fc7
commit 5e23c07077
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 338 additions and 175 deletions

View File

@ -182,7 +182,6 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
// check project configuration // check project configuration
const projectConfig = readJson(`apps/${project}/project.json`); const projectConfig = readJson(`apps/${project}/project.json`);
expect(projectConfig.root).toEqual(`apps/${project}`);
expect(projectConfig.sourceRoot).toEqual(`apps/${project}/src`); expect(projectConfig.sourceRoot).toEqual(`apps/${project}/src`);
expect(projectConfig.targets.build).toEqual({ expect(projectConfig.targets.build).toEqual({
executor: '@angular-devkit/build-angular:browser', executor: '@angular-devkit/build-angular:browser',
@ -259,7 +258,6 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
// check e2e project config // check e2e project config
const e2eProjectConfig = readJson(`apps/${project}-e2e/project.json`); const e2eProjectConfig = readJson(`apps/${project}-e2e/project.json`);
expect(e2eProjectConfig.root).toEqual(`apps/${project}-e2e`);
expect(e2eProjectConfig.targets.e2e).toEqual({ expect(e2eProjectConfig.targets.e2e).toEqual({
executor: '@angular-devkit/build-angular:protractor', executor: '@angular-devkit/build-angular:protractor',
options: { options: {
@ -356,7 +354,6 @@ describe('convert Angular CLI workspace to an Nx workspace', () => {
// check e2e project config // check e2e project config
const e2eProjectConfig = readJson(`apps/${project}-e2e/project.json`); const e2eProjectConfig = readJson(`apps/${project}-e2e/project.json`);
expect(e2eProjectConfig.root).toEqual(`apps/${e2eProject}`);
expect(e2eProjectConfig.targets['cypress-run']).toEqual({ expect(e2eProjectConfig.targets['cypress-run']).toEqual({
executor: '@nrwl/cypress:cypress', executor: '@nrwl/cypress:cypress',
options: { options: {

View File

@ -282,7 +282,7 @@ describe('Nx Plugin', () => {
checkFilesExist(`libs/subdir/${plugin}/package.json`); checkFilesExist(`libs/subdir/${plugin}/package.json`);
const pluginProject = readProjectConfig(`subdir-${plugin}`); const pluginProject = readProjectConfig(`subdir-${plugin}`);
const pluginE2EProject = readProjectConfig(`subdir-${plugin}-e2e`); const pluginE2EProject = readProjectConfig(`subdir-${plugin}-e2e`);
expect(pluginProject.root).toBe(`libs/subdir/${plugin}`); expect(pluginProject.targets).toBeDefined();
expect(pluginE2EProject).toBeTruthy(); expect(pluginE2EProject).toBeTruthy();
}, 90000); }, 90000);
}); });

View File

@ -318,7 +318,6 @@ describe('move project', () => {
expect(workspaceJson.projects[`${lib1}-data-access`]).toBeUndefined(); expect(workspaceJson.projects[`${lib1}-data-access`]).toBeUndefined();
const project = readProjectConfig(newName); const project = readProjectConfig(newName);
expect(project).toBeTruthy(); expect(project).toBeTruthy();
expect(project.root).toBe(newPath);
expect(project.sourceRoot).toBe(`${newPath}/src`); expect(project.sourceRoot).toBe(`${newPath}/src`);
expect(project.targets.lint.options.lintFilePatterns).toEqual([ expect(project.targets.lint.options.lintFilePatterns).toEqual([
`libs/shared/${lib1}/data-access/**/*.ts`, `libs/shared/${lib1}/data-access/**/*.ts`,
@ -445,7 +444,6 @@ describe('move project', () => {
expect(workspaceJson.projects[`${lib1}-data-access`]).toBeUndefined(); expect(workspaceJson.projects[`${lib1}-data-access`]).toBeUndefined();
const project = readProjectConfig(newName); const project = readProjectConfig(newName);
expect(project).toBeTruthy(); expect(project).toBeTruthy();
expect(project.root).toBe(newPath);
expect(project.sourceRoot).toBe(`${newPath}/src`); expect(project.sourceRoot).toBe(`${newPath}/src`);
expect(project.tags).toEqual([]); expect(project.tags).toEqual([]);
const lib3Config = readProjectConfig(lib3); const lib3Config = readProjectConfig(lib3);
@ -578,7 +576,6 @@ describe('move project', () => {
expect(workspaceJson.projects[`${lib1}-data-access`]).toBeUndefined(); expect(workspaceJson.projects[`${lib1}-data-access`]).toBeUndefined();
const project = readProjectConfig(newName); const project = readProjectConfig(newName);
expect(project).toBeTruthy(); expect(project).toBeTruthy();
expect(project.root).toBe(newPath);
expect(project.sourceRoot).toBe(`${newPath}/src`); expect(project.sourceRoot).toBe(`${newPath}/src`);
expect(project.targets.lint.options.lintFilePatterns).toEqual([ expect(project.targets.lint.options.lintFilePatterns).toEqual([
`packages/shared/${lib1}/data-access/**/*.ts`, `packages/shared/${lib1}/data-access/**/*.ts`,

View File

@ -46,6 +46,9 @@ function updateAppAndE2EProjectConfigurations(
options.ngCliSchematicAppRoot, options.ngCliSchematicAppRoot,
options.appProjectRoot options.appProjectRoot
); );
// project already has the right root, but the above function, makes it incorrect.
// This corrects it.
project.root = options.appProjectRoot;
} }
delete project.targets.test; delete project.targets.test;

View File

@ -138,6 +138,9 @@ function fixProjectWorkspaceConfig(host: Tree, options: NormalizedSchema) {
options.ngCliSchematicLibRoot, options.ngCliSchematicLibRoot,
options.projectRoot options.projectRoot
); );
// project already has the right root, but the above function, makes it incorrect.
// This corrects it.
project.root = options.projectRoot;
} }
if (!options.publishable && !options.buildable) { if (!options.publishable && !options.buildable) {

View File

@ -12,7 +12,7 @@
/** /**
* @category Tree * @category Tree
*/ */
export type { Tree, FileChange } from 'nx/src/config/tree'; export type { Tree, FileChange } from 'nx/src/generators/tree';
/** /**
* @category Workspace * @category Workspace
@ -113,7 +113,7 @@ export { generateFiles } from './src/generators/generate-files';
/** /**
* @category Generators * @category Generators
*/ */
export type { WorkspaceConfiguration } from './src/generators/project-configuration'; export type { WorkspaceConfiguration } from 'nx/src/generators/utils/project-configuration';
/** /**
* @category Generators * @category Generators
@ -127,7 +127,7 @@ export {
updateWorkspaceConfiguration, updateWorkspaceConfiguration,
getProjects, getProjects,
isStandaloneProject, isStandaloneProject,
} from './src/generators/project-configuration'; } from 'nx/src/generators/utils/project-configuration';
/** /**
* @category Generators * @category Generators
@ -185,7 +185,7 @@ export { ProjectGraphBuilder } from 'nx/src/project-graph/project-graph-builder'
/** /**
* @category Utils * @category Utils
*/ */
export { readJson, writeJson, updateJson } from './src/utils/json'; export { readJson, writeJson, updateJson } from 'nx/src/generators/utils/json';
/** /**
* @category Utils * @category Utils

View File

@ -1,14 +1,14 @@
import type { Tree } from 'nx/src/config/tree'; import type { Tree } from 'nx/src/generators/tree';
import * as path from 'path'; import * as path from 'path';
import type * as Prettier from 'prettier'; import type * as Prettier from 'prettier';
import { getWorkspacePath } from '../utils/get-workspace-layout'; import { readJson, updateJson, writeJson } from 'nx/src/generators/utils/json';
import { readJson, updateJson, writeJson } from '../utils/json';
import { sortObjectByKeys } from 'nx/src/utils/object-sort';
import { import {
getWorkspacePath,
readWorkspaceConfiguration, readWorkspaceConfiguration,
updateWorkspaceConfiguration, updateWorkspaceConfiguration,
WorkspaceConfiguration, WorkspaceConfiguration,
} from './project-configuration'; } from 'nx/src/generators/utils/project-configuration';
import { sortObjectByKeys } from 'nx/src/utils/object-sort';
/** /**
* Formats all the created or updated files using Prettier * Formats all the created or updated files using Prettier

View File

@ -1,5 +1,5 @@
import type { Tree } from 'nx/src/config/tree'; import type { Tree } from 'nx/src/generators/tree';
import { createTree } from '../tests/create-tree'; import { createTree } from 'nx/src/generators/testing-utils/create-tree';
import { generateFiles } from './generate-files'; import { generateFiles } from './generate-files';
import { join } from 'path'; import { join } from 'path';
import * as FileType from 'file-type'; import * as FileType from 'file-type';

View File

@ -1,6 +1,6 @@
import { readFileSync, readdirSync, statSync } from 'fs'; import { readFileSync, readdirSync, statSync } from 'fs';
import * as path from 'path'; import * as path from 'path';
import type { Tree } from 'nx/src/config/tree'; import type { Tree } from 'nx/src/generators/tree';
import { logger } from 'nx/src/utils/logger'; import { logger } from 'nx/src/utils/logger';
const binaryExts = new Set([ const binaryExts = new Set([

View File

@ -1,4 +1,4 @@
import type { Tree } from 'nx/src/config/tree'; import type { Tree } from 'nx/src/generators/tree';
/** /**
* Rename and transpile any new typescript files created to javascript files * Rename and transpile any new typescript files created to javascript files

View File

@ -1,5 +1,5 @@
import type { Tree } from 'nx/src/config/tree'; import type { Tree } from 'nx/src/generators/tree';
import { updateJson } from '../utils/json'; import { updateJson } from 'nx/src/generators/utils/json';
export function updateTsConfigsToJs( export function updateTsConfigsToJs(
tree: Tree, tree: Tree,

View File

@ -1,5 +1,5 @@
import { createTree } from '../tests/create-tree'; import { createTree } from 'nx/src/generators/testing-utils/create-tree';
import type { Tree } from 'nx/src/config/tree'; import type { Tree } from 'nx/src/generators/tree';
import { visitNotIgnoredFiles } from './visit-not-ignored-files'; import { visitNotIgnoredFiles } from './visit-not-ignored-files';
describe('visitNotIgnoredFiles', () => { describe('visitNotIgnoredFiles', () => {

View File

@ -1,4 +1,4 @@
import type { Tree } from 'nx/src/config/tree'; import type { Tree } from 'nx/src/generators/tree';
import ignore, { Ignore } from 'ignore'; import ignore, { Ignore } from 'ignore';
import { join, relative, sep } from 'path'; import { join, relative, sep } from 'path';

View File

@ -1,4 +1,4 @@
import type { Tree } from 'nx/src/config/tree'; import type { Tree } from 'nx/src/generators/tree';
import { execSync } from 'child_process'; import { execSync } from 'child_process';
import { join } from 'path'; import { join } from 'path';
import { import {

View File

@ -1,9 +1,11 @@
import { RawWorkspaceJsonConfiguration } from 'nx/src/config/workspace-json-project-json'; import {
getWorkspacePath,
readNxJson,
shouldDefaultToUsingStandaloneConfigs,
} from 'nx/src/generators/utils/project-configuration';
import type { Tree } from 'nx/src/generators/tree';
import { readNxJson } from '../generators/project-configuration'; export { getWorkspacePath } from 'nx/src/generators/utils/project-configuration';
import { readJson } from './json';
import type { Tree } from 'nx/src/config/tree';
/** /**
* Returns workspace defaults. It includes defaults folders for apps and libs, * Returns workspace defaults. It includes defaults folders for apps and libs,
@ -23,37 +25,10 @@ export function getWorkspaceLayout(tree: Tree): {
npmScope: string; npmScope: string;
} { } {
const nxJson = readNxJson(tree); const nxJson = readNxJson(tree);
const workspacePath = getWorkspacePath(tree);
const rawWorkspace =
workspacePath && tree.exists(workspacePath)
? readJson<RawWorkspaceJsonConfiguration>(tree, workspacePath)
: null;
return { return {
appsDir: nxJson?.workspaceLayout?.appsDir ?? 'apps', appsDir: nxJson?.workspaceLayout?.appsDir ?? 'apps',
libsDir: nxJson?.workspaceLayout?.libsDir ?? 'libs', libsDir: nxJson?.workspaceLayout?.libsDir ?? 'libs',
npmScope: nxJson?.npmScope ?? '', npmScope: nxJson?.npmScope ?? '',
standaloneAsDefault: !rawWorkspace standaloneAsDefault: shouldDefaultToUsingStandaloneConfigs(tree),
? true // if workspace.json doesn't exist, all projects **must** be standalone
: Object.values(rawWorkspace.projects).reduce(
// default for second, third... projects should be based on all projects being defined as a path
// for configuration read from ng schematics, this is determined by configFilePath's presence
(allStandalone, next) =>
allStandalone &&
(typeof next === 'string' || 'configFilePath' in next),
// default for first project should be true if using Nx Schema
rawWorkspace.version > 1
),
}; };
} }
export function getWorkspacePath(
tree: Tree
): '/angular.json' | '/workspace.json' | null {
const possibleFiles: ('/angular.json' | '/workspace.json')[] = [
'/angular.json',
'/workspace.json',
];
return possibleFiles.filter((path) => tree.exists(path))[0];
}

View File

@ -1,9 +1,13 @@
import { logger, stripIndent } from 'nx/src/utils/logger'; import { logger, stripIndent } from 'nx/src/utils/logger';
import type { FileChange, Tree, TreeWriteOptions } from 'nx/src/config/tree'; import type {
FileChange,
Tree,
TreeWriteOptions,
} from 'nx/src/generators/tree';
import { toNewFormat, toOldFormatOrNull } from 'nx/src/config/workspaces'; import { toNewFormat, toOldFormatOrNull } from 'nx/src/config/workspaces';
import { Generator, GeneratorCallback } from 'nx/src/config/misc-interfaces'; import { Generator, GeneratorCallback } from 'nx/src/config/misc-interfaces';
import { parseJson, serializeJson } from 'nx/src/utils/json'; import { parseJson, serializeJson } from 'nx/src/utils/json';
import { join, relative } from 'path'; import { join, relative, dirname } from 'path';
class RunCallbackTask { class RunCallbackTask {
constructor(private callback: GeneratorCallback) {} constructor(private callback: GeneratorCallback) {}
@ -192,9 +196,10 @@ class DevkitTreeFromAngularDevkitTree implements Tree {
const w = parseJson(content.toString()); const w = parseJson(content.toString());
for (const [project, configuration] of Object.entries(w.projects)) { for (const [project, configuration] of Object.entries(w.projects)) {
if (typeof configuration === 'string') { if (typeof configuration === 'string') {
w.projects[project] = parseJson( w.projects[project] = {
this.tree.read(`${configuration}/project.json`) root: configuration,
); ...parseJson(this.tree.read(`${configuration}/project.json`)),
};
w.projects[project].configFilePath = `${configuration}/project.json`; w.projects[project].configFilePath = `${configuration}/project.json`;
} }
} }

View File

@ -1,4 +1,4 @@
import { Tree } from 'nx/src/config/tree'; import { Tree } from 'nx/src/generators/tree';
import { relative } from 'path'; import { relative } from 'path';
import { visitNotIgnoredFiles } from '../generators/visit-not-ignored-files'; import { visitNotIgnoredFiles } from '../generators/visit-not-ignored-files';
import { normalizePath } from 'nx/src/utils/path'; import { normalizePath } from 'nx/src/utils/path';

View File

@ -1,7 +1,7 @@
import type { Tree } from 'nx/src/config/tree'; import type { Tree } from 'nx/src/generators/tree';
import { readJson, writeJson } from './json'; import { readJson, writeJson } from 'nx/src/generators/utils/json';
import { addDependenciesToPackageJson } from './package-json'; import { addDependenciesToPackageJson } from './package-json';
import { createTree } from '../tests/create-tree'; import { createTree } from 'nx/src/generators/testing-utils/create-tree';
describe('addDependenciesToPackageJson', () => { describe('addDependenciesToPackageJson', () => {
let tree: Tree; let tree: Tree;

View File

@ -1,6 +1,6 @@
import { readJson, updateJson } from './json'; import { readJson, updateJson } from 'nx/src/generators/utils/json';
import { installPackagesTask } from '../tasks/install-packages-task'; import { installPackagesTask } from '../tasks/install-packages-task';
import type { Tree } from 'nx/src/config/tree'; import type { Tree } from 'nx/src/generators/tree';
import { GeneratorCallback } from 'nx/src/config/misc-interfaces'; import { GeneratorCallback } from 'nx/src/config/misc-interfaces';
/** /**

View File

@ -1,2 +1,2 @@
export { createTreeWithEmptyWorkspace } from './src/tests/create-tree-with-empty-workspace'; export { createTreeWithEmptyWorkspace } from 'nx/src/generators/testing-utils/create-tree-with-empty-workspace';
export { createTree } from './src/tests/create-tree'; export { createTree } from 'nx/src/generators/testing-utils/create-tree';

View File

@ -7,7 +7,7 @@ const mockResolveConfig = jest.fn(() =>
); );
import { Tree } from '@nrwl/devkit'; import { Tree } from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from 'packages/devkit/src/tests/create-tree-with-empty-workspace'; import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import update from './update-base-jest-config'; import update from './update-base-jest-config';
describe('update 12.6.0', () => { describe('update 12.6.0', () => {

View File

@ -1,3 +1,10 @@
{ {
"migrations": {} "generators": {
"14-0-4-remove-root": {
"cli": "nx",
"version": "14.0.4",
"description": "Remove root property from project.json files",
"factory": "./src/migrations/update-14-0-4/remove-roots"
}
}
} }

View File

@ -0,0 +1,12 @@
import path = require('path');
import json = require('./migrations.json');
describe('Node migrations', () => {
it('should have valid paths', () => {
Object.values(json.generators).forEach((m) => {
expect(() =>
require.resolve(path.join(__dirname, `${m.factory}.ts`))
).not.toThrow();
});
});
});

View File

@ -15,7 +15,7 @@ import { createConsoleLogger, NodeJsSyncHost } from '@angular-devkit/core/node';
import { Stats } from 'fs'; import { Stats } from 'fs';
import { detectPackageManager } from '../utils/package-manager'; import { detectPackageManager } from '../utils/package-manager';
import { GenerateOptions } from '../command-line/generate'; import { GenerateOptions } from '../command-line/generate';
import { FileChange, Tree } from '../config/tree'; import { FileChange, Tree } from '../generators/tree';
import { import {
buildWorkspaceConfigurationFromGlobs, buildWorkspaceConfigurationFromGlobs,
globForProjectFiles, globForProjectFiles,
@ -497,6 +497,7 @@ export class NxScopedHost extends virtualFs.ScopedHost<any> {
// project was read from a project.json file // project was read from a project.json file
const configPath = projectConfig.configFilePath; const configPath = projectConfig.configFilePath;
const fileConfigObject = { ...projectConfig }; const fileConfigObject = { ...projectConfig };
delete fileConfigObject.root; // remove the root before writing
delete fileConfigObject.configFilePath; // remove the configFilePath before writing delete fileConfigObject.configFilePath; // remove the configFilePath before writing
const projectJsonWrite = super.write( const projectJsonWrite = super.write(
configPath, configPath,
@ -539,6 +540,7 @@ export class NxScopedHost extends virtualFs.ScopedHost<any> {
map((x) => ({ map((x) => ({
project, project,
projectConfig: { projectConfig: {
root: dirname(configFilePath),
...parseJson(Buffer.from(x).toString()), ...parseJson(Buffer.from(x).toString()),
configFilePath, configFilePath,
}, },
@ -600,9 +602,10 @@ export class NxScopeHostUsedForWrappedSchematics extends NxScopedHost {
const nxJsonInTree = nxJsonChange const nxJsonInTree = nxJsonChange
? parseJson(nxJsonChange.content.toString()) ? parseJson(nxJsonChange.content.toString())
: parseJson(this.host.read('nx.json').toString()); : parseJson(this.host.read('nx.json').toString());
const readJsonWithHost = (file) => const readJsonWithHost = (file) => ({
parseJson(this.host.read(file).toString()); root: dirname(file),
...parseJson(this.host.read(file).toString()),
});
const staticProjects = buildWorkspaceConfigurationFromGlobs( const staticProjects = buildWorkspaceConfigurationFromGlobs(
nxJsonInTree, nxJsonInTree,
globForProjectFiles(this.host.root).filter( globForProjectFiles(this.host.root).filter(
@ -1214,6 +1217,7 @@ function saveWorkspaceConfigurationInWrappedSchematic(
) { ) {
const path = config.configFilePath || join(config.root, 'project.json'); const path = config.configFilePath || join(config.root, 'project.json');
workspace.projects[project] = normalize(dirname(path)); workspace.projects[project] = normalize(dirname(path));
delete config.root; // remove the root before writing
delete config.configFilePath; delete config.configFilePath;
host.write(path, serializeJson(config)); host.write(path, serializeJson(config));
} }

View File

@ -5,7 +5,7 @@ import {
Schema, Schema,
} from '../utils/params'; } from '../utils/params';
import { Workspaces } from '../config/workspaces'; import { Workspaces } from '../config/workspaces';
import { FileChange, flushChanges, FsTree } from '../config/tree'; import { FileChange, flushChanges, FsTree } from '../generators/tree';
import { logger } from '../utils/logger'; import { logger } from '../utils/logger';
import * as chalk from 'chalk'; import * as chalk from 'chalk';
import { workspaceRoot } from '../utils/app-root'; import { workspaceRoot } from '../utils/app-root';

View File

@ -8,7 +8,7 @@ import {
PackageJsonUpdateForPackage, PackageJsonUpdateForPackage,
} from '../config/misc-interfaces'; } from '../config/misc-interfaces';
import { NxJsonConfiguration } from '../config/nx-json'; import { NxJsonConfiguration } from '../config/nx-json';
import { flushChanges, FsTree } from '../config/tree'; import { flushChanges, FsTree } from '../generators/tree';
import { import {
extractFileFromTarball, extractFileFromTarball,
JsonReadOptions, JsonReadOptions,

View File

@ -25,6 +25,7 @@ import {
CustomHasher, CustomHasher,
} from './misc-interfaces'; } from './misc-interfaces';
import { PackageJson } from '../utils/package-json'; import { PackageJson } from '../utils/package-json';
import { sortObjectByKeys } from 'nx/src/utils/object-sort';
export function workspaceConfigName(root: string) { export function workspaceConfigName(root: string) {
if (existsSync(path.join(root, 'angular.json'))) { if (existsSync(path.join(root, 'angular.json'))) {
@ -316,7 +317,13 @@ function findFullGeneratorName(
} }
export function reformattedWorkspaceJsonOrNull(w: any) { export function reformattedWorkspaceJsonOrNull(w: any) {
return w.version === 2 ? toNewFormatOrNull(w) : toOldFormatOrNull(w); const workspaceJson =
w.version === 2 ? toNewFormatOrNull(w) : toOldFormatOrNull(w);
if (workspaceJson?.projects) {
workspaceJson.projects = sortObjectByKeys(workspaceJson.projects);
}
return workspaceJson;
} }
export function toNewFormat(w: any): WorkspaceJsonConfiguration { export function toNewFormat(w: any): WorkspaceJsonConfiguration {
@ -411,7 +418,10 @@ function inlineProjectConfigurations(w: any, root: string = workspaceRoot) {
if (typeof config === 'string') { if (typeof config === 'string') {
const configFilePath = path.join(root, config, 'project.json'); const configFilePath = path.join(root, config, 'project.json');
const fileConfig = readJsonFile(configFilePath); const fileConfig = readJsonFile(configFilePath);
w.projects[project] = fileConfig; w.projects[project] = {
root: config,
...fileConfig,
};
} }
} }
); );
@ -642,6 +652,9 @@ export function buildWorkspaceConfigurationFromGlobs(
// directory as a package.json should overwrite the inferred package.json // directory as a package.json should overwrite the inferred package.json
// project configuration. // project configuration.
const configuration = readJson(file); const configuration = readJson(file);
configuration.root = directory;
let name = configuration.name; let name = configuration.name;
if (!configuration.name) { if (!configuration.name) {
name = toProjectName(file, nxJson); name = toProjectName(file, nxJson);

View File

@ -0,0 +1,55 @@
import type { Tree } from '../tree';
import * as path from 'path';
import type * as Prettier from 'prettier';
/**
* Formats all the created or updated files using Prettier
* @param tree - the file system tree
*/
export async function formatChangedFilesWithPrettierIfAvailable(
tree: Tree
): Promise<void> {
let prettier: typeof Prettier;
try {
prettier = await import('prettier');
} catch {}
if (!prettier) return;
const files = new Set(
tree.listChanges().filter((file) => file.type !== 'DELETE')
);
await Promise.all(
Array.from(files).map(async (file) => {
const systemPath = path.join(tree.root, file.path);
let options: any = {
filepath: systemPath,
};
const resolvedOptions = await prettier.resolveConfig(systemPath, {
editorconfig: true,
});
if (!resolvedOptions) {
return;
}
options = {
...options,
...resolvedOptions,
};
const support = await prettier.getFileInfo(systemPath, options);
if (support.ignored || !support.inferredParser) {
return;
}
try {
tree.write(
file.path,
prettier.format(file.content.toString('utf-8'), options)
);
} catch (e) {
console.warn(`Could not format ${file.path}. Error: "${e.message}"`);
}
})
);
}

View File

@ -1,5 +1,5 @@
import { FsTree } from 'nx/src/config/tree'; import { FsTree } from 'nx/src/generators/tree';
import type { Tree } from 'nx/src/config/tree'; import type { Tree } from 'nx/src/generators/tree';
/** /**
* Creates a host for testing. * Creates a host for testing.

View File

@ -1,5 +1,5 @@
import { FsTree } from 'nx/src/config/tree'; import { FsTree } from 'nx/src/generators/tree';
import type { Tree } from 'nx/src/config/tree'; import type { Tree } from 'nx/src/generators/tree';
/** /**
* Creates a host for testing. * Creates a host for testing.

View File

@ -1,6 +1,6 @@
import type { Tree } from 'nx/src/config/tree'; import type { Tree } from '../tree';
import { parseJson, serializeJson } from 'nx/src/utils/json'; import { parseJson, serializeJson } from '../../utils/json';
import type { JsonParseOptions, JsonSerializeOptions } from 'nx/src/utils/json'; import type { JsonParseOptions, JsonSerializeOptions } from '../../utils/json';
/** /**
* Reads a json file, removes all comments and parses JSON. * Reads a json file, removes all comments and parses JSON.

View File

@ -1,11 +1,12 @@
import { Tree } from 'nx/src/config/tree'; import { Tree } from '../tree';
import { ProjectConfiguration } from 'nx/src/config/workspace-json-project-json'; import { ProjectConfiguration } from '../../config/workspace-json-project-json';
import { createTreeWithEmptyWorkspace } from '../tests/create-tree-with-empty-workspace'; import { createTreeWithEmptyWorkspace } from '../testing-utils/create-tree-with-empty-workspace';
import { readJson, updateJson } from '../utils/json'; import { readJson, updateJson } from '../utils/json';
import { import {
addProjectConfiguration, addProjectConfiguration,
getProjects, getProjects,
getWorkspacePath,
readProjectConfiguration, readProjectConfiguration,
readWorkspaceConfiguration, readWorkspaceConfiguration,
removeProjectConfiguration, removeProjectConfiguration,
@ -13,7 +14,6 @@ import {
updateWorkspaceConfiguration, updateWorkspaceConfiguration,
WorkspaceConfiguration, WorkspaceConfiguration,
} from './project-configuration'; } from './project-configuration';
import { getWorkspacePath } from '../utils/get-workspace-layout';
type ProjectConfigurationV1 = Pick< type ProjectConfigurationV1 = Pick<
ProjectConfiguration, ProjectConfiguration,
@ -301,6 +301,7 @@ describe('project configuration', () => {
addProjectConfiguration(tree, 'test', baseTestProjectConfigV2, true); addProjectConfiguration(tree, 'test', baseTestProjectConfigV2, true);
const expectedProjectConfig = { const expectedProjectConfig = {
...baseTestProjectConfigV2, ...baseTestProjectConfigV2,
root: undefined,
targets: { build: { executor: '' } }, targets: { build: { executor: '' } },
}; };
updateProjectConfiguration(tree, 'test', expectedProjectConfig); updateProjectConfiguration(tree, 'test', expectedProjectConfig);
@ -471,6 +472,7 @@ describe('project configuration', () => {
addProjectConfiguration(tree, 'test', baseTestProjectConfigV2, true); addProjectConfiguration(tree, 'test', baseTestProjectConfigV2, true);
const expectedProjectConfig = { const expectedProjectConfig = {
...baseTestProjectConfigV2, ...baseTestProjectConfigV2,
root: undefined,
targets: { build: { executor: '' } }, targets: { build: { executor: '' } },
}; };
updateProjectConfiguration(tree, 'test', expectedProjectConfig); updateProjectConfiguration(tree, 'test', expectedProjectConfig);

View File

@ -4,23 +4,19 @@ import {
globForProjectFiles, globForProjectFiles,
reformattedWorkspaceJsonOrNull, reformattedWorkspaceJsonOrNull,
toNewFormat, toNewFormat,
} from 'nx/src/config/workspaces'; } from '../../config/workspaces';
import { basename, dirname, relative } from 'path'; import { basename, dirname, relative } from 'path';
import { import { readJson, updateJson, writeJson } from './json';
getWorkspaceLayout,
getWorkspacePath,
} from '../utils/get-workspace-layout';
import { readJson, updateJson, writeJson } from '../utils/json';
import type { Tree } from 'nx/src/config/tree'; import type { Tree } from '../tree';
import type { NxJsonConfiguration } from 'nx/src/config/nx-json'; import type { NxJsonConfiguration } from '../../config/nx-json';
import { joinPathFragments } from 'nx/src/utils/path'; import { joinPathFragments } from '../../utils/path';
import { import {
ProjectConfiguration, ProjectConfiguration,
RawWorkspaceJsonConfiguration, RawWorkspaceJsonConfiguration,
WorkspaceJsonConfiguration, WorkspaceJsonConfiguration,
} from 'nx/src/config/workspace-json-project-json'; } from '../../config/workspace-json-project-json';
export type WorkspaceConfiguration = Omit< export type WorkspaceConfiguration = Omit<
WorkspaceJsonConfiguration, WorkspaceJsonConfiguration,
@ -45,8 +41,7 @@ export function addProjectConfiguration(
projectConfiguration: ProjectConfiguration, projectConfiguration: ProjectConfiguration,
standalone?: boolean standalone?: boolean
): void { ): void {
const workspaceLayout = getWorkspaceLayout(tree); standalone = standalone ?? shouldDefaultToUsingStandaloneConfigs(tree);
standalone = standalone ?? workspaceLayout.standaloneAsDefault;
setProjectConfiguration( setProjectConfiguration(
tree, tree,
projectName, projectName,
@ -358,7 +353,7 @@ function addProjectToWorkspaceJson(
workspaceJson.projects[projectName] = project.root; workspaceJson.projects[projectName] = project.root;
} }
// update the project.json file // update the project.json file
writeJson(tree, configFile, project); writeJson(tree, configFile, { ...project, root: undefined });
} }
} else if (mode === 'delete') { } else if (mode === 'delete') {
delete workspaceJson.projects[projectName]; delete workspaceJson.projects[projectName];
@ -399,10 +394,10 @@ function inlineProjectConfigurationsWithTree(
Object.entries(workspaceJson.projects || {}).forEach(([project, config]) => { Object.entries(workspaceJson.projects || {}).forEach(([project, config]) => {
if (typeof config === 'string') { if (typeof config === 'string') {
const configFileLocation = joinPathFragments(config, 'project.json'); const configFileLocation = joinPathFragments(config, 'project.json');
workspaceJson.projects[project] = readJson<ProjectConfiguration>( workspaceJson.projects[project] = {
tree, root: config,
configFileLocation ...readJson<ProjectConfiguration>(tree, configFileLocation),
); };
} }
}); });
return workspaceJson as WorkspaceJsonConfiguration; return workspaceJson as WorkspaceJsonConfiguration;
@ -550,3 +545,33 @@ function validateProjectConfigurationOperationsWithoutWorkspaceJson(
); );
} }
} }
export function shouldDefaultToUsingStandaloneConfigs(tree: Tree): boolean {
const workspacePath = getWorkspacePath(tree);
const rawWorkspace =
workspacePath && tree.exists(workspacePath)
? readJson<RawWorkspaceJsonConfiguration>(tree, workspacePath)
: null;
return !rawWorkspace
? true // if workspace.json doesn't exist, all projects **must** be standalone
: Object.values(rawWorkspace.projects).reduce(
// default for second, third... projects should be based on all projects being defined as a path
// for configuration read from ng schematics, this is determined by configFilePath's presence
(allStandalone, next) =>
allStandalone &&
(typeof next === 'string' || 'configFilePath' in next),
// default for first project should be true if using Nx Schema
rawWorkspace.version > 1
);
}
export function getWorkspacePath(
tree: Tree
): '/angular.json' | '/workspace.json' | null {
const possibleFiles: ('/angular.json' | '/workspace.json')[] = [
'/angular.json',
'/workspace.json',
];
return possibleFiles.filter((path) => tree.exists(path))[0];
}

View File

@ -0,0 +1,48 @@
import { Tree } from '../../generators/tree';
import { createTreeWithEmptyWorkspace } from '../../generators/testing-utils/create-tree-with-empty-workspace';
import { addProjectConfiguration } from '../../generators/utils/project-configuration';
import { readJson, updateJson } from '../../generators/utils/json';
import removeRoots from './remove-roots';
describe('remove-roots >', () => {
let tree: Tree;
describe('projects with project.json configs', () => {
beforeEach(() => {
tree = createTreeWithEmptyWorkspace(2);
});
it('should remove the root property', async () => {
addProjectConfiguration(tree, 'proj1', {
root: 'proj1',
});
updateJson(tree, 'proj1/project.json', (config) => ({
...config,
root: 'proj1',
}));
await removeRoots(tree);
expect(readJson(tree, 'proj1/project.json').root).toBeUndefined();
});
});
describe('projects with project.json configs', () => {
beforeEach(() => {
tree = createTreeWithEmptyWorkspace(1);
});
it('should remove the root property', async () => {
addProjectConfiguration(tree, 'proj1', {
root: 'proj1',
});
await removeRoots(tree);
expect(readJson(tree, 'workspace.json').projects.proj1.root).toEqual(
'proj1'
);
});
});
});

View File

@ -0,0 +1,15 @@
import { Tree } from '../../generators/tree';
import {
getProjects,
updateProjectConfiguration,
} from '../../generators/utils/project-configuration';
import { formatChangedFilesWithPrettierIfAvailable } from '../../generators/internal-utils/format-changed-files-with-prettier-if-available';
export default async function (tree: Tree) {
// This looks like it does nothing, but this will actually effectively migrate over all the configs that need to be moved over, but won't touch configs that don't need to be moved
for (const [projName, projConfig] of getProjects(tree)) {
updateProjectConfiguration(tree, projName, projConfig);
}
await formatChangedFilesWithPrettierIfAvailable(tree);
}

View File

@ -4,24 +4,20 @@ exports[`Set the projectBuildConfig option in the Storybook configuration for An
Object { Object {
"projects": Object { "projects": Object {
"main-app": Object { "main-app": Object {
"prefix": "katst", "architect": Object {
"projectType": "application",
"root": "apps/main-app",
"sourceRoot": "apps/main-app/src",
"targets": Object {
"build": Object { "build": Object {
"executor": "@angular-devkit/build-angular:browser", "builder": "@angular-devkit/build-angular:browser",
"outputs": Array [ "outputs": Array [
"{options.outputPath}", "{options.outputPath}",
], ],
}, },
"build-storybook": Object { "build-storybook": Object {
"builder": "@nrwl/storybook:build",
"configurations": Object { "configurations": Object {
"ci": Object { "ci": Object {
"quiet": true, "quiet": true,
}, },
}, },
"executor": "@nrwl/storybook:build",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "apps/main-app/.storybook", "configFolder": "apps/main-app/.storybook",
@ -35,12 +31,12 @@ Object {
], ],
}, },
"storybook": Object { "storybook": Object {
"builder": "@nrwl/storybook:storybook",
"configurations": Object { "configurations": Object {
"ci": Object { "ci": Object {
"quiet": true, "quiet": true,
}, },
}, },
"executor": "@nrwl/storybook:storybook",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "apps/main-app/.storybook", "configFolder": "apps/main-app/.storybook",
@ -51,19 +47,20 @@ Object {
}, },
}, },
}, },
"prefix": "katst",
"projectType": "application",
"root": "apps/main-app",
"sourceRoot": "apps/main-app/src",
}, },
"ui-one": Object { "ui-one": Object {
"projectType": "library", "architect": Object {
"root": "libs/ui/one",
"sourceRoot": "libs/ui/one/src",
"targets": Object {
"build-storybook": Object { "build-storybook": Object {
"builder": "@nrwl/storybook:build",
"configurations": Object { "configurations": Object {
"ci": Object { "ci": Object {
"quiet": true, "quiet": true,
}, },
}, },
"executor": "@nrwl/storybook:build",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "libs/ui/one/.storybook", "configFolder": "libs/ui/one/.storybook",
@ -77,7 +74,7 @@ Object {
], ],
}, },
"storybook": Object { "storybook": Object {
"executor": "@nrwl/storybook:storybook", "builder": "@nrwl/storybook:storybook",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "libs/ui/one/.storybook", "configFolder": "libs/ui/one/.storybook",
@ -88,19 +85,19 @@ Object {
}, },
}, },
}, },
"projectType": "library",
"root": "libs/ui/one",
"sourceRoot": "libs/ui/one/src",
}, },
"ui-three": Object { "ui-three": Object {
"projectType": "library", "architect": Object {
"root": "libs/ui/three",
"sourceRoot": "libs/ui/three/src",
"targets": Object {
"build-storybook": Object { "build-storybook": Object {
"builder": "@nrwl/storybook:build",
"configurations": Object { "configurations": Object {
"ci": Object { "ci": Object {
"quiet": true, "quiet": true,
}, },
}, },
"executor": "@nrwl/storybook:build",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "libs/ui/three/.storybook", "configFolder": "libs/ui/three/.storybook",
@ -114,7 +111,7 @@ Object {
], ],
}, },
"storybook": Object { "storybook": Object {
"executor": "@nrwl/storybook:storybook", "builder": "@nrwl/storybook:storybook",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "libs/ui/three/.storybook", "configFolder": "libs/ui/three/.storybook",
@ -125,19 +122,19 @@ Object {
}, },
}, },
}, },
"projectType": "library",
"root": "libs/ui/three",
"sourceRoot": "libs/ui/three/src",
}, },
"ui-two": Object { "ui-two": Object {
"projectType": "library", "architect": Object {
"root": "libs/ui/two",
"sourceRoot": "libs/ui/two/src",
"targets": Object {
"build-storybook": Object { "build-storybook": Object {
"builder": "@nrwl/storybook:build",
"configurations": Object { "configurations": Object {
"ci": Object { "ci": Object {
"quiet": true, "quiet": true,
}, },
}, },
"executor": "@nrwl/storybook:build",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "libs/ui/two/.storybook", "configFolder": "libs/ui/two/.storybook",
@ -151,7 +148,7 @@ Object {
], ],
}, },
"storybook": Object { "storybook": Object {
"executor": "@nrwl/storybook:storybook", "builder": "@nrwl/storybook:storybook",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "libs/ui/two/.storybook", "configFolder": "libs/ui/two/.storybook",
@ -162,6 +159,9 @@ Object {
}, },
}, },
}, },
"projectType": "library",
"root": "libs/ui/two",
"sourceRoot": "libs/ui/two/src",
}, },
}, },
"version": 1, "version": 1,
@ -172,18 +172,14 @@ exports[`Set the projectBuildConfig option in the Storybook configuration for An
Object { Object {
"projects": Object { "projects": Object {
"main-app": Object { "main-app": Object {
"prefix": "katst", "architect": Object {
"projectType": "application",
"root": "apps/main-app",
"sourceRoot": "apps/main-app/src",
"targets": Object {
"lmfkcn": Object { "lmfkcn": Object {
"builder": "@nrwl/storybook:storybook",
"configurations": Object { "configurations": Object {
"ci": Object { "ci": Object {
"quiet": true, "quiet": true,
}, },
}, },
"executor": "@nrwl/storybook:storybook",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "apps/main-app/.storybook", "configFolder": "apps/main-app/.storybook",
@ -194,18 +190,18 @@ Object {
}, },
}, },
"njdfvndfjnv": Object { "njdfvndfjnv": Object {
"executor": "@angular-devkit/build-angular:browser", "builder": "@angular-devkit/build-angular:browser",
"outputs": Array [ "outputs": Array [
"{options.outputPath}", "{options.outputPath}",
], ],
}, },
"odmwjbc": Object { "odmwjbc": Object {
"builder": "@nrwl/storybook:build",
"configurations": Object { "configurations": Object {
"ci": Object { "ci": Object {
"quiet": true, "quiet": true,
}, },
}, },
"executor": "@nrwl/storybook:build",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "apps/main-app/.storybook", "configFolder": "apps/main-app/.storybook",
@ -219,19 +215,20 @@ Object {
], ],
}, },
}, },
"prefix": "katst",
"projectType": "application",
"root": "apps/main-app",
"sourceRoot": "apps/main-app/src",
}, },
"ui-one": Object { "ui-one": Object {
"projectType": "library", "architect": Object {
"root": "libs/ui/one",
"sourceRoot": "libs/ui/one/src",
"targets": Object {
"asdgsdfg": Object { "asdgsdfg": Object {
"builder": "@nrwl/storybook:build",
"configurations": Object { "configurations": Object {
"ci": Object { "ci": Object {
"quiet": true, "quiet": true,
}, },
}, },
"executor": "@nrwl/storybook:build",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "libs/ui/one/.storybook", "configFolder": "libs/ui/one/.storybook",
@ -245,7 +242,7 @@ Object {
], ],
}, },
"trthrngb": Object { "trthrngb": Object {
"executor": "@nrwl/storybook:storybook", "builder": "@nrwl/storybook:storybook",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "libs/ui/one/.storybook", "configFolder": "libs/ui/one/.storybook",
@ -256,19 +253,19 @@ Object {
}, },
}, },
}, },
"projectType": "library",
"root": "libs/ui/one",
"sourceRoot": "libs/ui/one/src",
}, },
"ui-three": Object { "ui-three": Object {
"projectType": "library", "architect": Object {
"root": "libs/ui/three",
"sourceRoot": "libs/ui/three/src",
"targets": Object {
"aaaa": Object { "aaaa": Object {
"builder": "@nrwl/storybook:build",
"configurations": Object { "configurations": Object {
"ci": Object { "ci": Object {
"quiet": true, "quiet": true,
}, },
}, },
"executor": "@nrwl/storybook:build",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "libs/ui/three/.storybook", "configFolder": "libs/ui/three/.storybook",
@ -282,7 +279,7 @@ Object {
], ],
}, },
"nmkgd": Object { "nmkgd": Object {
"executor": "@nrwl/storybook:storybook", "builder": "@nrwl/storybook:storybook",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "libs/ui/three/.storybook", "configFolder": "libs/ui/three/.storybook",
@ -293,14 +290,14 @@ Object {
}, },
}, },
}, },
"projectType": "library",
"root": "libs/ui/three",
"sourceRoot": "libs/ui/three/src",
}, },
"ui-two": Object { "ui-two": Object {
"projectType": "library", "architect": Object {
"root": "libs/ui/two",
"sourceRoot": "libs/ui/two/src",
"targets": Object {
"sdft": Object { "sdft": Object {
"executor": "@nrwl/storybook:storybook", "builder": "@nrwl/storybook:storybook",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "libs/ui/two/.storybook", "configFolder": "libs/ui/two/.storybook",
@ -311,12 +308,12 @@ Object {
}, },
}, },
"thjkkb": Object { "thjkkb": Object {
"builder": "@nrwl/storybook:build",
"configurations": Object { "configurations": Object {
"ci": Object { "ci": Object {
"quiet": true, "quiet": true,
}, },
}, },
"executor": "@nrwl/storybook:build",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "libs/ui/two/.storybook", "configFolder": "libs/ui/two/.storybook",
@ -330,6 +327,9 @@ Object {
], ],
}, },
}, },
"projectType": "library",
"root": "libs/ui/two",
"sourceRoot": "libs/ui/two/src",
}, },
}, },
"version": 1, "version": 1,
@ -340,18 +340,14 @@ exports[`Set the projectBuildConfig option in the Storybook configuration for An
Object { Object {
"projects": Object { "projects": Object {
"main-app": Object { "main-app": Object {
"prefix": "katst", "architect": Object {
"projectType": "application",
"root": "apps/main-app",
"sourceRoot": "apps/main-app/src",
"targets": Object {
"storybook": Object { "storybook": Object {
"builder": "@nrwl/storybook:storybook",
"configurations": Object { "configurations": Object {
"ci": Object { "ci": Object {
"quiet": true, "quiet": true,
}, },
}, },
"executor": "@nrwl/storybook:storybook",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "apps/main-app/.storybook", "configFolder": "apps/main-app/.storybook",
@ -361,6 +357,10 @@ Object {
}, },
}, },
}, },
"prefix": "katst",
"projectType": "application",
"root": "apps/main-app",
"sourceRoot": "apps/main-app/src",
}, },
"ui-one": Object { "ui-one": Object {
"projectType": "library", "projectType": "library",
@ -386,7 +386,7 @@ Object {
], ],
}, },
"storybook": Object { "storybook": Object {
"executor": "@nrwl/storybook:storybook", "builder": "@nrwl/storybook:storybook",
"options": Object { "options": Object {
"config": Object { "config": Object {
"configFolder": "libs/ui/one/.storybook", "configFolder": "libs/ui/one/.storybook",
@ -398,6 +398,5 @@ Object {
}, },
}, },
}, },
"version": undefined,
} }
`; `;

View File

@ -1,6 +1,5 @@
import { Tree, writeJson } from '@nrwl/devkit'; import { readJson, Tree, writeJson } from '@nrwl/devkit';
import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing';
import { readWorkspace } from 'packages/devkit/src/generators/project-configuration';
import setProjectBuildConfig from './set-project-build-config'; import setProjectBuildConfig from './set-project-build-config';
import * as defaultConfig from './test-configs/default-config.json'; import * as defaultConfig from './test-configs/default-config.json';
import * as customNames from './test-configs/custom-names-config.json'; import * as customNames from './test-configs/custom-names-config.json';
@ -17,13 +16,13 @@ describe('Set the projectBuildConfig option in the Storybook configuration for A
it(`should set the projectBuildConfig in the Storybook config according to the type of project`, async () => { it(`should set the projectBuildConfig in the Storybook config according to the type of project`, async () => {
writeJson(tree, 'workspace.json', defaultConfig); writeJson(tree, 'workspace.json', defaultConfig);
await setProjectBuildConfig(tree); await setProjectBuildConfig(tree);
expect(readWorkspace(tree)).toMatchSnapshot(); expect(readJson(tree, 'workspace.json')).toMatchSnapshot();
}); });
it(`should still set the projectBuildConfig even if target names are not the default`, async () => { it(`should still set the projectBuildConfig even if target names are not the default`, async () => {
writeJson(tree, 'workspace.json', customNames); writeJson(tree, 'workspace.json', customNames);
await setProjectBuildConfig(tree); await setProjectBuildConfig(tree);
expect(readWorkspace(tree)).toMatchSnapshot(); expect(readJson(tree, 'workspace.json')).toMatchSnapshot();
}); });
}); });
@ -35,7 +34,7 @@ describe('Set the projectBuildConfig option in the Storybook configuration for A
it(`should not change their Storybook configuration`, async () => { it(`should not change their Storybook configuration`, async () => {
await setProjectBuildConfig(tree); await setProjectBuildConfig(tree);
expect(readWorkspace(tree)).toMatchSnapshot(); expect(readJson(tree, 'workspace.json')).toMatchSnapshot();
}); });
}); });
}); });

View File

@ -85,6 +85,7 @@ describe('convert-to-nx-project', () => {
getProjectConfigurationPath(config) getProjectConfigurationPath(config)
); );
delete config.root;
expect(config).toEqual(newConfigFile); expect(config).toEqual(newConfigFile);
}); });
@ -112,6 +113,7 @@ describe('convert-to-nx-project', () => {
tree, tree,
getProjectConfigurationPath(config) getProjectConfigurationPath(config)
); );
delete config.root;
expect(config).toEqual(newConfigFile); expect(config).toEqual(newConfigFile);
} }
}); });

View File

@ -68,6 +68,8 @@ To upgrade change the version number at the top of ${getWorkspacePath(
continue; continue;
} }
delete configuration.root;
writeJson(host, configPath, configuration); writeJson(host, configPath, configuration);
updateJson(host, getWorkspacePath(host), (value) => { updateJson(host, getWorkspacePath(host), (value) => {