Skip to content

Commit

Permalink
feat(core): support different workspace layouts
Browse files Browse the repository at this point in the history
  • Loading branch information
vsavkin committed May 17, 2020
1 parent 6e8d461 commit a95cba3
Show file tree
Hide file tree
Showing 26 changed files with 231 additions and 105 deletions.
4 changes: 2 additions & 2 deletions e2e/angular-package.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { toClassName } from '@nrwl/workspace';
import {
ensureProject,
forEachCli,
newProject,
readJson,
runCLI,
uniq,
Expand Down Expand Up @@ -30,7 +30,7 @@ forEachCli('angular', (cli) => {
childLib = uniq('childlib');
childLib2 = uniq('childlib2');

ensureProject();
newProject();

runCLI(
`generate @nrwl/angular:library ${parentLib} --publishable=true --no-interactive`
Expand Down
2 changes: 1 addition & 1 deletion e2e/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ forEachCli(() => {

describe('migrate', () => {
it('should run migrations', () => {
ensureProject();
newProject();

updateFile(
`./node_modules/migrate-parent-package/package.json`,
Expand Down
78 changes: 78 additions & 0 deletions e2e/custom-layout.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import {
checkFilesExist,
forEachCli,
newProject,
readFile,
readJson,
runCLI,
runCLIAsync,
uniq,
updateFile,
} from './utils';

forEachCli('nx', () => {
describe('custom workspace layout', () => {
it('should work', async () => {
newProject();

const nxJson = readJson('nx.json');
nxJson.workspaceLayout = {
libsDir: 'packages',
appsDir: 'packages',
};

updateFile('nx.json', JSON.stringify(nxJson));

const reactApp = uniq('reactapp');
const reactLib = uniq('reactlib');

const ngApp = uniq('ngapp');
const ngLib = uniq('nglib');

const expressApp = uniq('expessapp');
const expressLib = uniq('expresslib');

runCLI(`generate @nrwl/react:app ${reactApp} --no-interactive`);
runCLI(`generate @nrwl/react:lib ${reactLib} --no-interactive`);

runCLI(`generate @nrwl/angular:app ${ngApp} --no-interactive`);
runCLI(`generate @nrwl/angular:lib ${ngLib} --no-interactive`);

runCLI(`generate @nrwl/express:app ${expressApp} --no-interactive`);
runCLI(`generate @nrwl/express:lib ${expressLib} --no-interactive`);

checkFilesExist(
`packages/${reactLib}/src/index.ts`,
`packages/${reactApp}/src/main.tsx`,
`packages/${reactApp}-e2e/cypress.json`,

`packages/${ngLib}/src/index.ts`,
`packages/${ngApp}/src/main.ts`,
`packages/${ngApp}-e2e/cypress.json`,

`packages/${expressLib}/src/index.ts`,
`packages/${expressApp}/src/main.ts`
);

const workspaceJson = readFile('workspace.json');
expect(workspaceJson).not.toContain('apps/');
expect(workspaceJson).not.toContain('libs/');

const libTestResults = await runCLIAsync(`test ${expressLib}`);
expect(libTestResults.stdout).toContain(
'No tests found, exiting with code 0'
);

const appBuildResults = await runCLIAsync(`build ${expressApp}`);
expect(appBuildResults.stdout).toContain(`nx run ${expressApp}:build`);

checkFilesExist(`dist/packages/${expressApp}/main.js`);
}, 1000000);
});
});

forEachCli('angular', () => {
describe('custom workspace layout', () => {
it('should work', () => {});
});
});
1 change: 1 addition & 0 deletions e2e/react.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
checkFilesExist,
ensureProject,
forEachCli,
newProject,
readFile,
readJson,
renameFile,
Expand Down
15 changes: 9 additions & 6 deletions e2e/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,9 @@ export function newProject(): void {
cleanup();
if (!directoryExists(tmpBackupProjPath())) {
runNew('--collection=@nrwl/workspace --npmScope=proj', true);

const packages = getDirectories('./build/packages')
.filter((pkg) => !pkg.startsWith('create-'))
.map((pkg) => `@nrwl/${pkg}`);
yarnAdd(packages.join(' '));
yarnAdd(
`@nrwl/angular @nrwl/express @nrwl/nest @nrwl/next @nrwl/react @nrwl/storybook @nrwl/nx-plugin @nrwl/bazel`
);

execSync(`mv ${tmpProjPath()} ${tmpBackupProjPath()}`);
}
Expand All @@ -185,7 +183,9 @@ export function newProject(): void {
* If one is not found, it creates a new project.
*/
export function ensureProject(): void {
// if (!directoryExists(tmpProjPath())) {
newProject();
// }
}

export function supportUi() {
Expand Down Expand Up @@ -271,7 +271,10 @@ export function runCLI(
/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
''
);
console.log(r);

if (process.env.VERBOSE_OUTPUT) {
console.log(r);
}

const needsMaxWorkers = /g.*(express|nest|node|web|react):app.*/;
if (needsMaxWorkers.test(command)) {
Expand Down
5 changes: 3 additions & 2 deletions packages/angular/src/schematics/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
insertImport,
getProjectConfig,
updateWorkspaceInTree,
appsDir,
} from '@nrwl/workspace/src/utils/ast-utils';

interface NormalizedSchema extends Schema {
Expand Down Expand Up @@ -760,8 +761,8 @@ function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {
e2eProjectName = `${appProjectName}-e2e`;
}

const appProjectRoot = `apps/${appDirectory}`;
const e2eProjectRoot = `apps/${appDirectory}-e2e`;
const appProjectRoot = `${appsDir(host)}/${appDirectory}`;
const e2eProjectRoot = `${appsDir(host)}/${appDirectory}-e2e`;

const parsedTags = options.tags
? options.tags.split(',').map((s) => s.trim())
Expand Down
12 changes: 6 additions & 6 deletions packages/angular/src/schematics/library/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import {
} from '@nrwl/workspace';
import { addUnitTestRunner } from '../init/init';
import { addImportToModule, addRoute } from '../../utils/ast-utils';
import { insertImport } from '@nrwl/workspace/src/utils/ast-utils';
import { insertImport, libsDir } from '@nrwl/workspace/src/utils/ast-utils';

interface NormalizedSchema extends Schema {
name: string;
Expand Down Expand Up @@ -219,11 +219,11 @@ function addChildren(options: NormalizedSchema): Rule {
};
}

function updateNgPackage(options: NormalizedSchema): Rule {
function updateNgPackage(host: Tree, options: NormalizedSchema): Rule {
if (!options.publishable) {
return noop();
}
const dest = `${offsetFromRoot(options.projectRoot)}dist/libs/${
const dest = `${offsetFromRoot(options.projectRoot)}dist/${libsDir(host)}/${
options.projectDirectory
}`;
return chain([
Expand Down Expand Up @@ -395,7 +395,7 @@ function updateProject(options: NormalizedSchema): Rule {
},
};
}),
updateNgPackage(options),
updateNgPackage(host, options),
])(host, context);
};
}
Expand All @@ -408,7 +408,7 @@ function updateTsConfig(options: NormalizedSchema): Rule {
const c = json.compilerOptions;
delete c.paths[options.name];
c.paths[`@${nxJson.npmScope}/${options.projectDirectory}`] = [
`libs/${options.projectDirectory}/src/index.ts`,
`${libsDir(host)}/${options.projectDirectory}/src/index.ts`,
];
return json;
})(host, context);
Expand Down Expand Up @@ -490,7 +490,7 @@ function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {

const projectName = projectDirectory.replace(new RegExp('/', 'g'), '-');
const fileName = options.simpleModuleName ? name : projectName;
const projectRoot = `libs/${projectDirectory}`;
const projectRoot = `${libsDir(host)}/${projectDirectory}`;

const moduleName = `${toClassName(fileName)}Module`;
const parsedTags = options.tags
Expand Down
63 changes: 37 additions & 26 deletions packages/cypress/src/schematics/cypress-project/cypress-project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import {
move,
noop,
Rule,
SchematicContext,
template,
Tree,
url,
} from '@angular-devkit/schematics';
import { join, normalize } from '@angular-devkit/core';
Expand All @@ -21,6 +23,7 @@ import { offsetFromRoot } from '@nrwl/workspace';
import { toFileName } from '@nrwl/workspace';
import { Schema } from './schema';
import { toJS } from '@nrwl/workspace/src/utils/rules/to-js';
import { appsDir } from '@nrwl/workspace/src/utils/ast-utils';

export interface CypressProjectSchema extends Schema {
projectName: string;
Expand All @@ -29,7 +32,6 @@ export interface CypressProjectSchema extends Schema {

function generateFiles(options: CypressProjectSchema): Rule {
return (): Rule => {
// host.delete(`${options.projectRoot}/tsconfig.e2e.json`);
return mergeWith(
apply(url('./files'), [
template({
Expand Down Expand Up @@ -90,38 +92,47 @@ function updateWorkspaceJson(options: CypressProjectSchema): Rule {
}

export default function (options: CypressProjectSchema): Rule {
options = normalizeOptions(options);
return chain([
addLintFiles(options.projectRoot, options.linter, {
localConfig: {
// we need this overrides because we enabled
// allowJS in the tsconfig to allow for JS based
// Cypress tests. That however leads to issues
// with the CommonJS Cypress plugin file
overrides: [
{
files: ['src/plugins/index.js'],
rules: {
'@typescript-eslint/no-var-requires': 'off',
'no-undef': 'off',
return (host: Tree, context: SchematicContext) => {
options = normalizeOptions(host, options);
return chain([
addLintFiles(options.projectRoot, options.linter, {
localConfig: {
// we need this overrides because we enabled
// allowJS in the tsconfig to allow for JS based
// Cypress tests. That however leads to issues
// with the CommonJS Cypress plugin file
overrides: [
{
files: ['src/plugins/index.js'],
rules: {
'@typescript-eslint/no-var-requires': 'off',
'no-undef': 'off',
},
},
},
],
},
}),
generateFiles(options),
updateWorkspaceJson(options),
updateNxJson(options),
]);
],
},
}),
generateFiles(options),
updateWorkspaceJson(options),
updateNxJson(options),
])(host, context);
};
}

function normalizeOptions(options: CypressProjectSchema): CypressProjectSchema {
function normalizeOptions(
host: Tree,
options: CypressProjectSchema
): CypressProjectSchema {
const projectName = options.directory
? toFileName(options.directory) + '-' + options.name
: options.name;
const projectRoot = options.directory
? join(normalize('apps'), toFileName(options.directory), options.name)
: join(normalize('apps'), options.name);
? join(
normalize(appsDir(host)),
toFileName(options.directory),
options.name
)
: join(normalize(appsDir(host)), options.name);
return {
...options,
projectName,
Expand Down
7 changes: 4 additions & 3 deletions packages/express/src/schematics/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Schema } from './schema';
import { updateJsonInTree } from '@nrwl/workspace';
import { toFileName, formatFiles } from '@nrwl/workspace';
import init from '../init/init';
import { appsDir } from '@nrwl/workspace/src/utils/ast-utils';

interface NormalizedSchema extends Schema {
appProjectRoot: Path;
Expand Down Expand Up @@ -52,7 +53,7 @@ server.on('error', console.error);

export default function (schema: Schema): Rule {
return (host: Tree, context: SchematicContext) => {
const options = normalizeOptions(schema);
const options = normalizeOptions(host, schema);
return chain([
init({ ...options, skipFormat: true }),
externalSchematic('@nrwl/node', 'application', schema),
Expand All @@ -63,11 +64,11 @@ export default function (schema: Schema): Rule {
};
}

function normalizeOptions(options: Schema): NormalizedSchema {
function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {
const appDirectory = options.directory
? `${toFileName(options.directory)}/${toFileName(options.name)}`
: toFileName(options.name);
const appProjectRoot = join(normalize('apps'), appDirectory);
const appProjectRoot = join(normalize(appsDir(host)), appDirectory);

return {
...options,
Expand Down
7 changes: 4 additions & 3 deletions packages/nest/src/schematics/application/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { join, normalize, Path } from '@angular-devkit/core';
import { Schema } from './schema';
import { formatFiles, toFileName, updateJsonInTree } from '@nrwl/workspace';
import init from '../init/init';
import { appsDir } from '@nrwl/workspace/src/utils/ast-utils';

interface NormalizedSchema extends Schema {
appProjectRoot: Path;
Expand Down Expand Up @@ -64,7 +65,7 @@ function addAppFiles(options: NormalizedSchema): Rule {

export default function (schema: Schema): Rule {
return (host: Tree, context: SchematicContext) => {
const options = normalizeOptions(schema);
const options = normalizeOptions(host, schema);
return chain([
init({
...options,
Expand All @@ -86,11 +87,11 @@ export default function (schema: Schema): Rule {
};
}

function normalizeOptions(options: Schema): NormalizedSchema {
function normalizeOptions(host: Tree, options: Schema): NormalizedSchema {
const appDirectory = options.directory
? `${toFileName(options.directory)}/${toFileName(options.name)}`
: toFileName(options.name);
const appProjectRoot = join(normalize('apps'), appDirectory);
const appProjectRoot = join(normalize(appsDir(host)), appDirectory);

return {
...options,
Expand Down
Loading

0 comments on commit a95cba3

Please sign in to comment.