fix(core): honor workspace layout with workspace move schematic

This commit is contained in:
Devin Shoemaker 2020-07-12 10:26:31 -05:00 committed by Jo Hanna Pearce
parent 8a9565de01
commit 921b781ac3
7 changed files with 64 additions and 37 deletions

View File

@ -26,7 +26,7 @@ export function checkDestination(schema: Schema): Rule {
); );
} }
const destination = getDestination(schema, workspace); const destination = getDestination(schema, workspace, tree);
if (tree.getDir(destination).subfiles.length > 0) { if (tree.getDir(destination).subfiles.length > 0) {
throw new Error(`${INVALID_DESTINATION} - Path is not empty.`); throw new Error(`${INVALID_DESTINATION} - Path is not empty.`);

View File

@ -16,7 +16,7 @@ export function moveProject(schema: Schema) {
map((workspace) => { map((workspace) => {
const project = workspace.projects.get(schema.projectName); const project = workspace.projects.get(schema.projectName);
const destination = getDestination(schema, workspace); const destination = getDestination(schema, workspace, tree);
const dir = tree.getDir(project.root); const dir = tree.getDir(project.root);
dir.visit((file) => { dir.visit((file) => {
const newPath = file.replace(project.root, destination); const newPath = file.replace(project.root, destination);

View File

@ -24,7 +24,7 @@ export function updateCypressJson(schema: Schema): Rule {
return from(getWorkspace(tree)).pipe( return from(getWorkspace(tree)).pipe(
map((workspace) => { map((workspace) => {
const project = workspace.projects.get(schema.projectName); const project = workspace.projects.get(schema.projectName);
const destination = getDestination(schema, workspace); const destination = getDestination(schema, workspace, tree);
const cypressJsonPath = path.join(destination, 'cypress.json'); const cypressJsonPath = path.join(destination, 'cypress.json');

View File

@ -19,7 +19,7 @@ export function updateJestConfig(schema: Schema): Rule {
return from(getWorkspace(tree)).pipe( return from(getWorkspace(tree)).pipe(
map((workspace) => { map((workspace) => {
const project = workspace.projects.get(schema.projectName); const project = workspace.projects.get(schema.projectName);
const destination = getDestination(schema, workspace); const destination = getDestination(schema, workspace, tree);
const newProjectName = getNewProjectName(schema.destination); const newProjectName = getNewProjectName(schema.destination);
const jestConfigPath = path.join(destination, 'jest.config.js'); const jestConfigPath = path.join(destination, 'jest.config.js');

View File

@ -20,7 +20,7 @@ export function updateProjectRootFiles(schema: Schema): Rule {
return from(getWorkspace(tree)).pipe( return from(getWorkspace(tree)).pipe(
map((workspace) => { map((workspace) => {
const project = workspace.projects.get(schema.projectName); const project = workspace.projects.get(schema.projectName);
const destination = getDestination(schema, workspace); const destination = getDestination(schema, workspace, tree);
const newRelativeRoot = path const newRelativeRoot = path
.relative(path.join(appRootPath, destination), appRootPath) .relative(path.join(appRootPath, destination), appRootPath)

View File

@ -1,3 +1,4 @@
import { SchematicContext, Tree } from '@angular-devkit/schematics';
import { updateWorkspaceInTree } from '@nrwl/workspace'; import { updateWorkspaceInTree } from '@nrwl/workspace';
import { Schema } from '../schema'; import { Schema } from '../schema';
import { getDestination, getNewProjectName } from './utils'; import { getDestination, getNewProjectName } from './utils';
@ -12,38 +13,40 @@ import { getDestination, getNewProjectName } from './utils';
* @param schema The options provided to the schematic * @param schema The options provided to the schematic
*/ */
export function updateWorkspace(schema: Schema) { export function updateWorkspace(schema: Schema) {
return updateWorkspaceInTree((workspace) => { return (tree: Tree, _context: SchematicContext) => {
const project = workspace.projects[schema.projectName]; return updateWorkspaceInTree((workspace) => {
const newProjectName = getNewProjectName(schema.destination); const project = workspace.projects[schema.projectName];
const newProjectName = getNewProjectName(schema.destination);
// update root path refs in that project only // update root path refs in that project only
const oldProject = JSON.stringify(project); const oldProject = JSON.stringify(project);
const newProject = oldProject.replace( const newProject = oldProject.replace(
new RegExp(project.root, 'g'), new RegExp(project.root, 'g'),
getDestination(schema, workspace) getDestination(schema, workspace, tree)
); );
// rename // rename
delete workspace.projects[schema.projectName]; delete workspace.projects[schema.projectName];
workspace.projects[newProjectName] = JSON.parse(newProject); workspace.projects[newProjectName] = JSON.parse(newProject);
// update target refs // update target refs
const strWorkspace = JSON.stringify(workspace); const strWorkspace = JSON.stringify(workspace);
workspace = JSON.parse( workspace = JSON.parse(
strWorkspace.replace( strWorkspace.replace(
new RegExp(`${schema.projectName}:`, 'g'), new RegExp(`${schema.projectName}:`, 'g'),
`${newProjectName}:` `${newProjectName}:`
) )
); );
// update default project (if necessary) // update default project (if necessary)
if ( if (
workspace.defaultProject && workspace.defaultProject &&
workspace.defaultProject === schema.projectName workspace.defaultProject === schema.projectName
) { ) {
workspace.defaultProject = newProjectName; workspace.defaultProject = newProjectName;
} }
return workspace; return workspace;
}); });
};
} }

View File

@ -1,7 +1,28 @@
import { WorkspaceDefinition } from '@angular-devkit/core/src/workspace'; import { WorkspaceDefinition } from '@angular-devkit/core/src/workspace';
import { Tree } from '@angular-devkit/schematics';
import { NxJson } from '@nrwl/workspace/src/core/shared-interfaces';
import { readJsonInTree } from '@nrwl/workspace/src/utils/ast-utils';
import * as path from 'path'; import * as path from 'path';
import { Schema } from '../schema'; import { Schema } from '../schema';
/**
* This helper function retrieves the users workspace layout from
* `nx.json`. If the user does not have this property defined then
* we assume the default `apps/` and `libs/` layout.
*
* @param host The host tree
*/
export function getWorkspaceLayout(
host: Tree
): { appsDir?: string; libsDir?: string } {
const nxJson = readJsonInTree<NxJson>(host, 'nx.json');
const workspaceLayout = nxJson.workspaceLayout
? nxJson.workspaceLayout
: { appsDir: 'apps', libsDir: 'libs' };
return workspaceLayout;
}
/** /**
* This helper function ensures that we don't move libs or apps * This helper function ensures that we don't move libs or apps
* outside of the folders they should be in. * outside of the folders they should be in.
@ -14,7 +35,8 @@ import { Schema } from '../schema';
*/ */
export function getDestination( export function getDestination(
schema: Schema, schema: Schema,
workspace: WorkspaceDefinition | any workspace: WorkspaceDefinition | any,
host: Tree
): string { ): string {
const project = workspace.projects.get const project = workspace.projects.get
? workspace.projects.get(schema.projectName) ? workspace.projects.get(schema.projectName)
@ -23,9 +45,11 @@ export function getDestination(
? project.extensions['projectType'] ? project.extensions['projectType']
: project.projectType; : project.projectType;
let rootFolder = 'libs'; const workspaceLayout = getWorkspaceLayout(host);
let rootFolder = workspaceLayout.libsDir;
if (projectType === 'application') { if (projectType === 'application') {
rootFolder = 'apps'; rootFolder = workspaceLayout.appsDir;
} }
return path.join(rootFolder, schema.destination).split(path.sep).join('/'); return path.join(rootFolder, schema.destination).split(path.sep).join('/');
} }