feat: support for multi projects repos (#10665)
This commit is contained in:
parent
f09077d3bc
commit
6bca1db956
3
packages/ng-schematics/.gitignore
vendored
3
packages/ng-schematics/.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
|
||||
# Sandbox
|
||||
sandbox/
|
||||
sandbox/
|
||||
multi/
|
||||
|
@ -32,28 +32,25 @@ function getExecutable(command: string[]) {
|
||||
const executable = command.shift()!;
|
||||
const error = getError(executable, command);
|
||||
|
||||
if (executable === 'node') {
|
||||
return {
|
||||
executable: executable,
|
||||
args: command,
|
||||
error,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
executable: `./node_modules/.bin/${executable}`,
|
||||
executable,
|
||||
args: command,
|
||||
error,
|
||||
};
|
||||
}
|
||||
|
||||
async function executeCommand(context: BuilderContext, command: string[]) {
|
||||
await new Promise((resolve, reject) => {
|
||||
await new Promise(async (resolve, reject) => {
|
||||
context.logger.debug(`Trying to execute command - ${command.join(' ')}.`);
|
||||
const {executable, args, error} = getExecutable(command);
|
||||
let path = context.workspaceRoot;
|
||||
if (context.target) {
|
||||
const project = await context.getProjectMetadata(context.target.project);
|
||||
path = `${path}/${project['root']}`;
|
||||
}
|
||||
|
||||
const child = spawn(executable, args, {
|
||||
cwd: context.workspaceRoot,
|
||||
cwd: path,
|
||||
stdio: 'inherit',
|
||||
});
|
||||
|
||||
|
@ -10,7 +10,7 @@ describe('App test', function () {
|
||||
setupBrowserHooks();
|
||||
it('is running', async function () {
|
||||
const {page} = getBrowserState();
|
||||
const element = await page.waitForSelector('text/sandbox app is running!');
|
||||
const element = await page.waitForSelector('text/<%= project %> app is running!');
|
||||
|
||||
<% if(testingFramework == 'jasmine' || testingFramework == 'jest') { %>
|
||||
expect(element).not.toBeNull();
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"extends": "<%= tsConfigPath %>",
|
||||
"compilerOptions": {<% if(testingFramework == 'jest') { %>
|
||||
"esModuleInterop": true,<% } %><% if(testingFramework == 'node') { %>
|
||||
"module": "CommonJS",
|
||||
|
@ -29,7 +29,7 @@ import {
|
||||
url,
|
||||
} from '@angular-devkit/schematics';
|
||||
|
||||
import {SchematicsOptions, TestingFramework} from './types.js';
|
||||
import {AngularProject, SchematicsOptions, TestingFramework} from './types.js';
|
||||
|
||||
export interface FilesOptions {
|
||||
projects: Record<string, any>;
|
||||
@ -62,7 +62,7 @@ export function addFiles(
|
||||
): any {
|
||||
return chain(
|
||||
Object.keys(projects).map(name => {
|
||||
const project = projects[name];
|
||||
const project = projects[name] as AngularProject;
|
||||
const projectPath = resolve(getSystemPath(normalize(project.root)));
|
||||
const workspacePath = resolve(getSystemPath(normalize('')));
|
||||
|
||||
@ -72,6 +72,7 @@ export function addFiles(
|
||||
);
|
||||
|
||||
const baseUrl = getProjectBaseUrl(project, options.port);
|
||||
const tsConfigPath = getTsConfigPath(project);
|
||||
|
||||
return mergeWith(
|
||||
apply(url(applyPath), [
|
||||
@ -87,6 +88,7 @@ export function addFiles(
|
||||
...strings,
|
||||
root: project.root ? `${project.root}/` : project.root,
|
||||
baseUrl,
|
||||
tsConfigPath,
|
||||
project: name,
|
||||
relativeToWorkspace,
|
||||
}),
|
||||
@ -109,6 +111,13 @@ function getProjectBaseUrl(project: any, port: number): string {
|
||||
return `${options.protocol}://${options.host}:${options.port}`;
|
||||
}
|
||||
|
||||
function getTsConfigPath(project: AngularProject): string {
|
||||
if (!project.root) {
|
||||
return '../tsconfig.json';
|
||||
}
|
||||
return `../tsconfig.app.json`;
|
||||
}
|
||||
|
||||
export function addBaseFiles(
|
||||
tree: Tree,
|
||||
context: SchematicContext,
|
||||
@ -144,17 +153,33 @@ export function addFrameworkFiles(
|
||||
return addFiles(tree, context, options);
|
||||
}
|
||||
|
||||
export function getScriptFromOptions(options: SchematicsOptions): string[][] {
|
||||
export function getScriptFromOptions(
|
||||
options: SchematicsOptions,
|
||||
root?: string
|
||||
): string[][] {
|
||||
let path = 'node_modules/.bin';
|
||||
if (root && root !== '') {
|
||||
const nested = root
|
||||
.split('/')
|
||||
.map(() => {
|
||||
return '../';
|
||||
})
|
||||
.join('');
|
||||
path = `${nested}${path}`;
|
||||
} else {
|
||||
path = `./${path}`;
|
||||
}
|
||||
|
||||
switch (options.testingFramework) {
|
||||
case TestingFramework.Jasmine:
|
||||
return [[`jasmine`, '--config=./e2e/support/jasmine.json']];
|
||||
return [[`${path}/jasmine`, '--config=./e2e/support/jasmine.json']];
|
||||
case TestingFramework.Jest:
|
||||
return [[`jest`, '-c', 'e2e/jest.config.js']];
|
||||
return [[`${path}/jest`, '-c', 'e2e/jest.config.js']];
|
||||
case TestingFramework.Mocha:
|
||||
return [[`mocha`, '--config=./e2e/.mocharc.js']];
|
||||
return [[`${path}/mocha`, '--config=./e2e/.mocharc.js']];
|
||||
case TestingFramework.Node:
|
||||
return [
|
||||
[`tsc`, '-p', 'e2e/tsconfig.json'],
|
||||
[`${path}/tsc`, '-p', 'e2e/tsconfig.json'],
|
||||
['node', '--test', '--test-reporter', 'spec', 'e2e/build/'],
|
||||
];
|
||||
}
|
||||
|
@ -168,11 +168,14 @@ export function updateAngularJsonScripts(
|
||||
overwrite = true
|
||||
): Tree {
|
||||
const angularJson = getAngularConfig(tree);
|
||||
const commands = getScriptFromOptions(options);
|
||||
const name = getNgCommandName(options);
|
||||
const port = options.port !== 4200 ? Number(options.port) : undefined;
|
||||
|
||||
Object.keys(angularJson['projects']).forEach(project => {
|
||||
const commands = getScriptFromOptions(
|
||||
options,
|
||||
angularJson['projects'][project]!.root
|
||||
);
|
||||
const e2eScript = [
|
||||
{
|
||||
name,
|
||||
|
@ -4,7 +4,6 @@ import {
|
||||
buildTestingTree,
|
||||
getAngularJsonScripts,
|
||||
getPackageJson,
|
||||
getProjectFile,
|
||||
setupHttpHooks,
|
||||
} from './utils.js';
|
||||
|
||||
@ -16,9 +15,9 @@ describe('@puppeteer/ng-schematics: ng-add', () => {
|
||||
const {devDependencies, scripts} = getPackageJson(tree);
|
||||
const {builder, configurations} = getAngularJsonScripts(tree);
|
||||
|
||||
expect(tree.files).toContain(getProjectFile('e2e/tsconfig.json'));
|
||||
expect(tree.files).toContain(getProjectFile('e2e/tests/app.e2e.ts'));
|
||||
expect(tree.files).toContain(getProjectFile('e2e/tests/utils.ts'));
|
||||
expect(tree.files).toContain('/e2e/tsconfig.json');
|
||||
expect(tree.files).toContain('/e2e/tests/app.e2e.ts');
|
||||
expect(tree.files).toContain('/e2e/tests/utils.ts');
|
||||
expect(devDependencies).toContain('puppeteer');
|
||||
expect(scripts['e2e']).toBe('ng e2e');
|
||||
expect(builder).toBe('@puppeteer/ng-schematics:puppeteer');
|
||||
@ -45,7 +44,7 @@ describe('@puppeteer/ng-schematics: ng-add', () => {
|
||||
exportConfig: true,
|
||||
});
|
||||
|
||||
expect(files).toContain(getProjectFile('.puppeteerrc.cjs'));
|
||||
expect(files).toContain('/.puppeteerrc.cjs');
|
||||
});
|
||||
|
||||
it('should not create Puppeteer config', async () => {
|
||||
@ -53,7 +52,7 @@ describe('@puppeteer/ng-schematics: ng-add', () => {
|
||||
exportConfig: false,
|
||||
});
|
||||
|
||||
expect(files).not.toContain(getProjectFile('.puppeteerrc.cjs'));
|
||||
expect(files).not.toContain('/.puppeteerrc.cjs');
|
||||
});
|
||||
|
||||
it('should create Jasmine files and update "package.json"', async () => {
|
||||
@ -63,14 +62,14 @@ describe('@puppeteer/ng-schematics: ng-add', () => {
|
||||
const {devDependencies} = getPackageJson(tree);
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
|
||||
expect(tree.files).toContain(getProjectFile('e2e/support/jasmine.json'));
|
||||
expect(tree.files).toContain(getProjectFile('e2e/helpers/babel.js'));
|
||||
expect(tree.files).toContain('/e2e/support/jasmine.json');
|
||||
expect(tree.files).toContain('/e2e/helpers/babel.js');
|
||||
expect(devDependencies).toContain('jasmine');
|
||||
expect(devDependencies).toContain('@babel/core');
|
||||
expect(devDependencies).toContain('@babel/register');
|
||||
expect(devDependencies).toContain('@babel/preset-typescript');
|
||||
expect(options['commands']).toEqual([
|
||||
[`jasmine`, '--config=./e2e/support/jasmine.json'],
|
||||
[`./node_modules/.bin/jasmine`, '--config=./e2e/support/jasmine.json'],
|
||||
]);
|
||||
});
|
||||
|
||||
@ -81,11 +80,13 @@ describe('@puppeteer/ng-schematics: ng-add', () => {
|
||||
const {devDependencies} = getPackageJson(tree);
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
|
||||
expect(tree.files).toContain(getProjectFile('e2e/jest.config.js'));
|
||||
expect(tree.files).toContain('/e2e/jest.config.js');
|
||||
expect(devDependencies).toContain('jest');
|
||||
expect(devDependencies).toContain('@types/jest');
|
||||
expect(devDependencies).toContain('ts-jest');
|
||||
expect(options['commands']).toEqual([[`jest`, '-c', 'e2e/jest.config.js']]);
|
||||
expect(options['commands']).toEqual([
|
||||
[`./node_modules/.bin/jest`, '-c', 'e2e/jest.config.js'],
|
||||
]);
|
||||
});
|
||||
|
||||
it('should create Mocha files and update "package.json"', async () => {
|
||||
@ -95,15 +96,15 @@ describe('@puppeteer/ng-schematics: ng-add', () => {
|
||||
const {devDependencies} = getPackageJson(tree);
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
|
||||
expect(tree.files).toContain(getProjectFile('e2e/.mocharc.js'));
|
||||
expect(tree.files).toContain(getProjectFile('e2e/babel.js'));
|
||||
expect(tree.files).toContain('/e2e/.mocharc.js');
|
||||
expect(tree.files).toContain('/e2e/babel.js');
|
||||
expect(devDependencies).toContain('mocha');
|
||||
expect(devDependencies).toContain('@types/mocha');
|
||||
expect(devDependencies).toContain('@babel/core');
|
||||
expect(devDependencies).toContain('@babel/register');
|
||||
expect(devDependencies).toContain('@babel/preset-typescript');
|
||||
expect(options['commands']).toEqual([
|
||||
[`mocha`, '--config=./e2e/.mocharc.js'],
|
||||
[`./node_modules/.bin/mocha`, '--config=./e2e/.mocharc.js'],
|
||||
]);
|
||||
});
|
||||
|
||||
@ -113,11 +114,11 @@ describe('@puppeteer/ng-schematics: ng-add', () => {
|
||||
});
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
|
||||
expect(tree.files).toContain(getProjectFile('e2e/.gitignore'));
|
||||
expect(tree.files).not.toContain(getProjectFile('e2e/tests/app.e2e.ts'));
|
||||
expect(tree.files).toContain(getProjectFile('e2e/tests/app.test.ts'));
|
||||
expect(tree.files).toContain('/e2e/.gitignore');
|
||||
expect(tree.files).not.toContain('/e2e/tests/app.e2e.ts');
|
||||
expect(tree.files).toContain('/e2e/tests/app.test.ts');
|
||||
expect(options['commands']).toEqual([
|
||||
[`tsc`, '-p', 'e2e/tsconfig.json'],
|
||||
[`./node_modules/.bin/tsc`, '-p', 'e2e/tsconfig.json'],
|
||||
['node', '--test', '--test-reporter', 'spec', 'e2e/build/'],
|
||||
]);
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import expect from 'expect';
|
||||
|
||||
import {buildTestingTree, getProjectFile, setupHttpHooks} from './utils.js';
|
||||
import {buildTestingTree, setupHttpHooks} from './utils.js';
|
||||
|
||||
describe('@puppeteer/ng-schematics: test', () => {
|
||||
setupHttpHooks();
|
||||
@ -9,10 +9,8 @@ describe('@puppeteer/ng-schematics: test', () => {
|
||||
const tree = await buildTestingTree('test', {
|
||||
name: 'myTest',
|
||||
});
|
||||
expect(tree.files).toContain(getProjectFile('e2e/tests/my-test.e2e.ts'));
|
||||
expect(tree.files).not.toContain(
|
||||
getProjectFile('e2e/tests/my-test.test.ts')
|
||||
);
|
||||
expect(tree.files).toContain('/e2e/tests/my-test.e2e.ts');
|
||||
expect(tree.files).not.toContain('/e2e/tests/my-test.test.ts');
|
||||
});
|
||||
|
||||
it('should create Node file', async () => {
|
||||
@ -20,9 +18,7 @@ describe('@puppeteer/ng-schematics: test', () => {
|
||||
name: 'myTest',
|
||||
testingFramework: 'node',
|
||||
});
|
||||
expect(tree.files).not.toContain(
|
||||
getProjectFile('e2e/tests/my-test.e2e.ts')
|
||||
);
|
||||
expect(tree.files).toContain(getProjectFile('e2e/tests/my-test.test.ts'));
|
||||
expect(tree.files).not.toContain('/e2e/tests/my-test.e2e.ts');
|
||||
expect(tree.files).toContain('/e2e/tests/my-test.test.ts');
|
||||
});
|
||||
});
|
||||
|
@ -8,14 +8,11 @@ import {
|
||||
} from '@angular-devkit/schematics/testing';
|
||||
import sinon from 'sinon';
|
||||
|
||||
const WORKSPACE_OPTIONS = {
|
||||
name: 'workspace',
|
||||
newProjectRoot: 'projects',
|
||||
version: '14.0.0',
|
||||
};
|
||||
|
||||
const APPLICATION_OPTIONS = {
|
||||
name: 'sandbox',
|
||||
directory: '.',
|
||||
createApplication: true,
|
||||
version: '14.0.0',
|
||||
};
|
||||
|
||||
export function setupHttpHooks(): void {
|
||||
@ -34,10 +31,6 @@ export function setupHttpHooks(): void {
|
||||
});
|
||||
}
|
||||
|
||||
export function getProjectFile(file: string): string {
|
||||
return `/${WORKSPACE_OPTIONS.newProjectRoot}/${APPLICATION_OPTIONS.name}/${file}`;
|
||||
}
|
||||
|
||||
export function getAngularJsonScripts(
|
||||
tree: UnitTestTree,
|
||||
isDefault = true
|
||||
@ -85,15 +78,8 @@ export async function buildTestingTree(
|
||||
// Build workspace
|
||||
workingTree = await runner.runExternalSchematic(
|
||||
'@schematics/angular',
|
||||
'workspace',
|
||||
WORKSPACE_OPTIONS
|
||||
);
|
||||
// Build dummy application
|
||||
workingTree = await runner.runExternalSchematic(
|
||||
'@schematics/angular',
|
||||
'application',
|
||||
APPLICATION_OPTIONS,
|
||||
workingTree
|
||||
'ng-new',
|
||||
APPLICATION_OPTIONS
|
||||
);
|
||||
|
||||
if (command !== 'ng-add') {
|
||||
|
Loading…
Reference in New Issue
Block a user