build(aio): example-boilerplate is no longer responsible for yarn install (#19511)
The tooling for boilerplate was also running `yarn install` on the examples' shared folder. But since this is handled by `ng-packages-installer` this commit refactors the tools so that the boilerplate no longer does this anymore. PR Close #19511
This commit is contained in:
parent
ca7f2f8c8f
commit
03227e65cf
|
@ -20,10 +20,10 @@
|
||||||
"pree2e": "yarn check-env && yarn ~~update-webdriver",
|
"pree2e": "yarn check-env && yarn ~~update-webdriver",
|
||||||
"e2e": "ng e2e --no-webdriver-update",
|
"e2e": "ng e2e --no-webdriver-update",
|
||||||
"presetup": "yarn ~~check-env && yarn install && yarn boilerplate:remove",
|
"presetup": "yarn ~~check-env && yarn install && yarn boilerplate:remove",
|
||||||
"setup": "yarn aio-use-npm && yarn boilerplate:add",
|
"setup": "yarn aio-use-npm && yarn example-use-npm",
|
||||||
"postsetup": "yarn build-ie-polyfills && yarn generate-plunkers && yarn generate-zips && yarn docs",
|
"postsetup": "yarn boilerplate:add && yarn build-ie-polyfills && yarn generate-plunkers && yarn generate-zips && yarn docs",
|
||||||
"presetup-local": "yarn presetup",
|
"presetup-local": "yarn presetup",
|
||||||
"setup-local": "yarn aio-use-local && yarn boilerplate:add --local",
|
"setup-local": "yarn aio-use-local && yarn example-use-local",
|
||||||
"postsetup-local": "yarn postsetup",
|
"postsetup-local": "yarn postsetup",
|
||||||
"pretest-pwa-score-localhost": "yarn build",
|
"pretest-pwa-score-localhost": "yarn build",
|
||||||
"test-pwa-score-localhost": "concurrently --kill-others --success first \"http-server dist -p 4200 --silent\" \"yarn test-pwa-score http://localhost:4200 90\"",
|
"test-pwa-score-localhost": "concurrently --kill-others --success first \"http-server dist -p 4200 --silent\" \"yarn test-pwa-score http://localhost:4200 90\"",
|
||||||
|
|
|
@ -50,18 +50,18 @@ const EXAMPLE_CONFIG_FILENAME = 'example-config.json';
|
||||||
class ExampleBoilerPlate {
|
class ExampleBoilerPlate {
|
||||||
/**
|
/**
|
||||||
* Add boilerplate files to all the examples
|
* Add boilerplate files to all the examples
|
||||||
*
|
|
||||||
* @param useLocal if true then overwrite the Angular library files with locally built ones
|
|
||||||
*/
|
*/
|
||||||
add(useLocal) {
|
add() {
|
||||||
// Install the shared `node_modules/` (if necessary overwrite Angular packages from npm with local ones).
|
|
||||||
this.installNodeModules(SHARED_PATH, useLocal);
|
|
||||||
|
|
||||||
// Get all the examples folders, indicated by those that contain a `example-config.json` file
|
// Get all the examples folders, indicated by those that contain a `example-config.json` file
|
||||||
const exampleFolders = this.getFoldersContaining(EXAMPLES_BASE_PATH, EXAMPLE_CONFIG_FILENAME, 'node_modules');
|
const exampleFolders = this.getFoldersContaining(EXAMPLES_BASE_PATH, EXAMPLE_CONFIG_FILENAME, 'node_modules');
|
||||||
exampleFolders.forEach(exampleFolder => {
|
exampleFolders.forEach(exampleFolder => {
|
||||||
const exampleConfig = this.loadJsonFile(path.resolve(exampleFolder, EXAMPLE_CONFIG_FILENAME));
|
const exampleConfig = this.loadJsonFile(path.resolve(exampleFolder, EXAMPLE_CONFIG_FILENAME));
|
||||||
|
|
||||||
|
if (!fs.existsSync(SHARED_NODE_MODULES_PATH)) {
|
||||||
|
throw new Error(`The shared node_modules folder for the examples (${SHARED_NODE_MODULES_PATH}) is missing.\n` +
|
||||||
|
`Perhaps you need to run "yarn example-use-npm" or "yarn example-use-local" to install the dependencies?`);
|
||||||
|
}
|
||||||
|
|
||||||
// Link the node modules - requires admin access (on Windows) because it adds symlinks
|
// Link the node modules - requires admin access (on Windows) because it adds symlinks
|
||||||
const destinationNodeModules = path.resolve(exampleFolder, 'node_modules');
|
const destinationNodeModules = path.resolve(exampleFolder, 'node_modules');
|
||||||
fs.ensureSymlinkSync(SHARED_NODE_MODULES_PATH, destinationNodeModules);
|
fs.ensureSymlinkSync(SHARED_NODE_MODULES_PATH, destinationNodeModules);
|
||||||
|
@ -87,20 +87,12 @@ class ExampleBoilerPlate {
|
||||||
main() {
|
main() {
|
||||||
yargs
|
yargs
|
||||||
.usage('$0 <cmd> [args]')
|
.usage('$0 <cmd> [args]')
|
||||||
.command('add [--local]', 'add the boilerplate to each example',
|
.command('add', 'add the boilerplate to each example', () => this.add())
|
||||||
{ local: { describe: 'Use the locally built Angular libraries, rather than ones from npm.' } },
|
|
||||||
argv => this.add(argv.local))
|
|
||||||
.command('remove', 'remove the boilerplate from each example', () => this.remove())
|
.command('remove', 'remove the boilerplate from each example', () => this.remove())
|
||||||
.demandCommand(1, 'Please supply a command from the list above')
|
.demandCommand(1, 'Please supply a command from the list above')
|
||||||
.argv;
|
.argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
installNodeModules(basePath, useLocal) {
|
|
||||||
const tool = 'node tools/ng-packages-installer';
|
|
||||||
const command = useLocal ? 'overwrite' : 'restore';
|
|
||||||
shelljs.exec([tool, command, basePath, '--debug'].join(' '));
|
|
||||||
}
|
|
||||||
|
|
||||||
getFoldersContaining(basePath, filename, ignore) {
|
getFoldersContaining(basePath, filename, ignore) {
|
||||||
const pattern = path.resolve(basePath, '**', filename);
|
const pattern = path.resolve(basePath, '**', filename);
|
||||||
const ignorePattern = path.resolve(basePath, '**', ignore, '**');
|
const ignorePattern = path.resolve(basePath, '**', ignore, '**');
|
||||||
|
|
|
@ -18,27 +18,12 @@ describe('example-boilerplate tool', () => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
spyOn(fs, 'ensureSymlinkSync');
|
spyOn(fs, 'ensureSymlinkSync');
|
||||||
|
spyOn(fs, 'existsSync').and.returnValue(true);
|
||||||
spyOn(exampleBoilerPlate, 'copyFile');
|
spyOn(exampleBoilerPlate, 'copyFile');
|
||||||
spyOn(exampleBoilerPlate, 'getFoldersContaining').and.returnValue(exampleFolders);
|
spyOn(exampleBoilerPlate, 'getFoldersContaining').and.returnValue(exampleFolders);
|
||||||
spyOn(exampleBoilerPlate, 'installNodeModules');
|
|
||||||
spyOn(exampleBoilerPlate, 'loadJsonFile').and.returnValue({});
|
spyOn(exampleBoilerPlate, 'loadJsonFile').and.returnValue({});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should install the npm dependencies into `sharedDir` (and pass the `useLocal` argument through)', () => {
|
|
||||||
exampleBoilerPlate.add();
|
|
||||||
expect(exampleBoilerPlate.installNodeModules).toHaveBeenCalledWith(sharedDir, undefined);
|
|
||||||
|
|
||||||
exampleBoilerPlate.installNodeModules.calls.reset();
|
|
||||||
|
|
||||||
exampleBoilerPlate.add(true);
|
|
||||||
expect(exampleBoilerPlate.installNodeModules).toHaveBeenCalledWith(sharedDir, true);
|
|
||||||
|
|
||||||
exampleBoilerPlate.installNodeModules.calls.reset();
|
|
||||||
|
|
||||||
exampleBoilerPlate.add(false);
|
|
||||||
expect(exampleBoilerPlate.installNodeModules).toHaveBeenCalledWith(sharedDir, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should process all the example folders', () => {
|
it('should process all the example folders', () => {
|
||||||
const examplesDir = path.resolve(__dirname, '../../content/examples');
|
const examplesDir = path.resolve(__dirname, '../../content/examples');
|
||||||
exampleBoilerPlate.add();
|
exampleBoilerPlate.add();
|
||||||
|
@ -53,6 +38,14 @@ describe('example-boilerplate tool', () => {
|
||||||
expect(fs.ensureSymlinkSync).toHaveBeenCalledWith(sharedNodeModulesDir, path.resolve('c/d/node_modules'));
|
expect(fs.ensureSymlinkSync).toHaveBeenCalledWith(sharedNodeModulesDir, path.resolve('c/d/node_modules'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should error if the node_modules folder is missing', () => {
|
||||||
|
fs.existsSync.and.returnValue(false);
|
||||||
|
expect(() => exampleBoilerPlate.add()).toThrowError(
|
||||||
|
`The shared node_modules folder for the examples (${sharedNodeModulesDir}) is missing.\n` +
|
||||||
|
`Perhaps you need to run "yarn example-use-npm" or "yarn example-use-local" to install the dependencies?`);
|
||||||
|
expect(fs.ensureSymlinkSync).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
it('should copy all the source boilerplate files for systemjs', () => {
|
it('should copy all the source boilerplate files for systemjs', () => {
|
||||||
const boilerplateDir = path.resolve(sharedDir, 'boilerplate');
|
const boilerplateDir = path.resolve(sharedDir, 'boilerplate');
|
||||||
exampleBoilerPlate.loadJsonFile.and.callFake(filePath => filePath.indexOf('a/b') !== -1 ? { projectType: 'systemjs' } : {})
|
exampleBoilerPlate.loadJsonFile.and.callFake(filePath => filePath.indexOf('a/b') !== -1 ? { projectType: 'systemjs' } : {})
|
||||||
|
@ -95,28 +88,6 @@ describe('example-boilerplate tool', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('installNodeModules', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
spyOn(shelljs, 'exec');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should overwrite the Angular packages if `useLocal` is true', () => {
|
|
||||||
exampleBoilerPlate.installNodeModules('some/base/path', true);
|
|
||||||
expect(shelljs.exec).toHaveBeenCalledWith('node tools/ng-packages-installer overwrite some/base/path --debug');
|
|
||||||
expect(shelljs.exec.calls.count()).toEqual(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should restore the Angular packages if `useLocal` is not true', () => {
|
|
||||||
exampleBoilerPlate.installNodeModules('some/base/path1');
|
|
||||||
expect(shelljs.exec).toHaveBeenCalledWith('node tools/ng-packages-installer restore some/base/path1 --debug');
|
|
||||||
|
|
||||||
exampleBoilerPlate.installNodeModules('some/base/path2', false);
|
|
||||||
expect(shelljs.exec).toHaveBeenCalledWith('node tools/ng-packages-installer restore some/base/path2 --debug');
|
|
||||||
|
|
||||||
expect(shelljs.exec.calls.count()).toEqual(2);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getFoldersContaining', () => {
|
describe('getFoldersContaining', () => {
|
||||||
it('should use glob.sync', () => {
|
it('should use glob.sync', () => {
|
||||||
spyOn(glob, 'sync').and.returnValue(['a/b/config.json', 'c/d/config.json']);
|
spyOn(glob, 'sync').and.returnValue(['a/b/config.json', 'c/d/config.json']);
|
||||||
|
|
|
@ -4,6 +4,9 @@ const argv = require('yargs').argv;
|
||||||
const globby = require('globby');
|
const globby = require('globby');
|
||||||
const xSpawn = require('cross-spawn');
|
const xSpawn = require('cross-spawn');
|
||||||
const treeKill = require('tree-kill');
|
const treeKill = require('tree-kill');
|
||||||
|
const shelljs = require('shelljs');
|
||||||
|
|
||||||
|
shelljs.set('-e');
|
||||||
|
|
||||||
const AIO_PATH = path.join(__dirname, '../../');
|
const AIO_PATH = path.join(__dirname, '../../');
|
||||||
const SHARED_PATH = path.join(__dirname, '/shared');
|
const SHARED_PATH = path.join(__dirname, '/shared');
|
||||||
|
@ -42,21 +45,18 @@ const IGNORED_EXAMPLES = [ // temporary ignores
|
||||||
* e.g. --shard=1/3 // the second of every three specs: 1, 4, 7, etc
|
* e.g. --shard=1/3 // the second of every three specs: 1, 4, 7, etc
|
||||||
*/
|
*/
|
||||||
function runE2e() {
|
function runE2e() {
|
||||||
let promise = Promise.resolve();
|
|
||||||
if (argv.setup) {
|
if (argv.setup) {
|
||||||
// Run setup.
|
// Run setup.
|
||||||
console.log('runE2e: copy boilerplate');
|
console.log('runE2e: setup boilerplate');
|
||||||
const spawnInfo = spawnExt('yarn', ['boilerplate:add', argv.local ? '--local' : ''], { cwd: AIO_PATH });
|
const installPackagesCommand = `example-use-${argv.local ? 'local' : 'npm'}`;
|
||||||
promise = spawnInfo.promise
|
const addBoilerplateCommand = 'boilerplate:add';
|
||||||
.then(() => {
|
shelljs.exec(`yarn ${installPackagesCommand}`, { cwd: AIO_PATH });
|
||||||
console.log('runE2e: update webdriver');
|
shelljs.exec(`yarn ${addBoilerplateCommand}`, { cwd: AIO_PATH });
|
||||||
return spawnExt('yarn', ['webdriver:update'], { cwd: SHARED_PATH }).promise;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const outputFile = path.join(AIO_PATH, './protractor-results.txt');
|
const outputFile = path.join(AIO_PATH, './protractor-results.txt');
|
||||||
|
|
||||||
return promise
|
return Promise.resolve()
|
||||||
.then(() => findAndRunE2eTests(argv.filter, outputFile, argv.shard))
|
.then(() => findAndRunE2eTests(argv.filter, outputFile, argv.shard))
|
||||||
.then((status) => {
|
.then((status) => {
|
||||||
reportStatus(status, outputFile);
|
reportStatus(status, outputFile);
|
||||||
|
|
Loading…
Reference in New Issue