From c8c2ab012a3bf69a4e883cb201e20e7f951f0286 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Thu, 27 Jul 2017 08:28:54 +0100 Subject: [PATCH] build(aio): support overriding the Angular packages in examples with locally built ones --- aio/tools/examples/example-boilerplate.js | 41 ++++++++++++++++++- .../examples/example-boilerplate.spec.js | 30 +++++++++++++- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/aio/tools/examples/example-boilerplate.js b/aio/tools/examples/example-boilerplate.js index 08ab293da5..7127f1c968 100644 --- a/aio/tools/examples/example-boilerplate.js +++ b/aio/tools/examples/example-boilerplate.js @@ -27,17 +27,45 @@ const BOILERPLATE_TEST_PATHS = [ 'karma.conf.js' ]; +const ANGULAR_DIST_PATH = path.resolve(__dirname, '../../../dist'); +const ANGULAR_PACKAGES_PATH = path.resolve(ANGULAR_DIST_PATH, 'packages-dist'); +const ANGULAR_PACKAGES = [ + 'animations', + 'common', + 'compiler', + 'compiler-cli', + 'core', + 'forms', + 'http', + 'platform-browser', + 'platform-browser-dynamic', + 'platform-server', + 'router', + 'upgrade', +]; +const ANGULAR_TOOLS_PACKAGES_PATH = path.resolve(ANGULAR_DIST_PATH, 'tools', '@angular'); +const ANGULAR_TOOLS_PACKAGES = [ + 'tsc-wrapped' +]; + const EXAMPLE_CONFIG_FILENAME = 'example-config.json'; class ExampleBoilerPlate { /** * Add boilerplate files to all the examples * + * @param useLocal if true then overwrite the Angular library files with locally built ones */ - add() { + add(useLocal) { // first install the shared node_modules this.installNodeModules(SHARED_PATH); + // Replace the Angular packages with those from the dist folder, if necessary + if (useLocal) { + ANGULAR_PACKAGES.forEach(packageName => this.overridePackage(ANGULAR_PACKAGES_PATH, packageName)); + ANGULAR_TOOLS_PACKAGES.forEach(packageName => this.overridePackage(ANGULAR_TOOLS_PACKAGES_PATH, packageName)); + } + // 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'); exampleFolders.forEach(exampleFolder => { @@ -67,7 +95,9 @@ class ExampleBoilerPlate { main() { yargs .usage('$0 [args]') - .command('add', 'add the boilerplate to each example', argv => this.add(argv.local)) + .command('add [--local]', 'add the boilerplate to each example', + { 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()) .demandCommand(1, 'Please supply a command from the list above') .argv; @@ -77,6 +107,13 @@ class ExampleBoilerPlate { shelljs.exec('yarn', {cwd: basePath}); } + overridePackage(basePath, packageName) { + const sourceFolder = path.resolve(basePath, packageName); + const destinationFolder = path.resolve(SHARED_NODE_MODULES_PATH, '@angular', packageName); + shelljs.rm('-rf', destinationFolder); + fs.ensureSymlinkSync(sourceFolder, destinationFolder); + } + getFoldersContaining(basePath, filename, ignore) { const pattern = path.resolve(basePath, '**', filename); const ignorePattern = path.resolve(basePath, '**', ignore, '**'); diff --git a/aio/tools/examples/example-boilerplate.spec.js b/aio/tools/examples/example-boilerplate.spec.js index dc44a71cf4..e5d075afd4 100644 --- a/aio/tools/examples/example-boilerplate.spec.js +++ b/aio/tools/examples/example-boilerplate.spec.js @@ -12,6 +12,7 @@ describe('example-boilerplate tool', () => { beforeEach(() => { spyOn(exampleBoilerPlate, 'installNodeModules'); + spyOn(exampleBoilerPlate, 'overridePackage'); spyOn(exampleBoilerPlate, 'getFoldersContaining').and.returnValue(exampleFolders); spyOn(fs, 'ensureSymlinkSync'); spyOn(exampleBoilerPlate, 'copyFile'); @@ -23,6 +24,16 @@ describe('example-boilerplate tool', () => { expect(exampleBoilerPlate.installNodeModules).toHaveBeenCalledWith(path.resolve(__dirname, 'shared')); }); + it('should override the Angular node_modules with the locally built Angular packages if `useLocal` is true', () => { + const numberOfAngularPackages = 12; + const numberOfAngularToolsPackages = 1; + exampleBoilerPlate.add(true); + expect(exampleBoilerPlate.overridePackage).toHaveBeenCalledTimes(numberOfAngularPackages + numberOfAngularToolsPackages); + // for example + expect(exampleBoilerPlate.overridePackage).toHaveBeenCalledWith(path.resolve(__dirname, '../../../dist/packages-dist'), 'core'); + expect(exampleBoilerPlate.overridePackage).toHaveBeenCalledWith(path.resolve(__dirname, '../../../dist/tools/@angular'), 'tsc-wrapped'); + }); + it('should process all the example folders', () => { exampleBoilerPlate.add(); expect(exampleBoilerPlate.getFoldersContaining).toHaveBeenCalledWith(path.resolve(__dirname, '../../content/examples'), 'example-config.json', 'node_modules'); @@ -76,6 +87,23 @@ describe('example-boilerplate tool', () => { }); }); + describe('overridePackage', () => { + beforeEach(() => { + spyOn(shelljs, 'rm'); + spyOn(fs, 'ensureSymlinkSync'); + }); + + it('should remove the original package from the shared node_modules folder', () => { + exampleBoilerPlate.overridePackage('base/path', 'somePackage'); + expect(shelljs.rm).toHaveBeenCalledWith('-rf', path.resolve(__dirname, 'shared/node_modules/@angular/somePackage')); + }); + + it('should symlink the source folder to the shared node_modules folder', () => { + exampleBoilerPlate.overridePackage('base/path', 'somePackage'); + expect(fs.ensureSymlinkSync).toHaveBeenCalledWith(path.resolve('base/path/somePackage'), path.resolve(__dirname, 'shared/node_modules/@angular/somePackage')); + }); + }); + describe('getFoldersContaining', () => { it('should use glob.sync', () => { spyOn(glob, 'sync').and.returnValue(['a/b/config.json', 'c/d/config.json']); @@ -112,4 +140,4 @@ describe('example-boilerplate tool', () => { expect(result).toEqual({}); }); }); -}); \ No newline at end of file +});