build(aio): add support for using the locally built Angular packages for aio
This commit allows building angular.io against the locally built Angular packages. It adds two new npm scripts: - `setup-local`: Same as `setup`, but overwrites the Angular packages for both angular.io and the examples boilerplate with the locally built ones. - `build-local`: Same as `build`, but uses `setup-local` instead of `setup` under the hood, thus overwriting installed Angular packages with locally built ones. Fixes #18611
This commit is contained in:
parent
bb1665cbd8
commit
7a965dc58f
|
@ -13,7 +13,11 @@ You should run all these tasks from the `angular/aio` folder.
|
||||||
Here are the most important tasks you might need to use:
|
Here are the most important tasks you might need to use:
|
||||||
|
|
||||||
* `yarn` - install all the dependencies.
|
* `yarn` - install all the dependencies.
|
||||||
* `yarn setup` - Install all the dependencies, boilerplate, plunkers, zips and runs dgeni on the docs.
|
* `yarn setup` - install all the dependencies, boilerplate, plunkers, zips and run dgeni on the docs.
|
||||||
|
* `yarn setup-local` - same as `setup`, but use the locally built Angular packages for aio and docs examples boilerplate.
|
||||||
|
|
||||||
|
* `yarn build` - create a production build of the application (after installing dependencies, boilerplate, etc).
|
||||||
|
* `yarn build-local` - same as `build`, but use `setup-local` instead of `setup`.
|
||||||
|
|
||||||
* `yarn start` - run a development web server that watches the files; then builds the doc-viewer and reloads the page, as necessary.
|
* `yarn start` - run a development web server that watches the files; then builds the doc-viewer and reloads the page, as necessary.
|
||||||
* `yarn serve-and-sync` - run both the `docs-watch` and `start` in the same console.
|
* `yarn serve-and-sync` - run both the `docs-watch` and `start` in the same console.
|
||||||
|
|
|
@ -8,31 +8,38 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"ng": "yarn check-env && ng",
|
"ng": "yarn check-env && ng",
|
||||||
"start": "yarn check-env && ng serve",
|
"start": "yarn check-env && ng serve",
|
||||||
"prebuild": "yarn check-env && yarn setup",
|
"prebuild": "yarn setup",
|
||||||
"build": "ng build --target=production --environment=stable -sm --build-optimizer",
|
"build": "yarn ~~build",
|
||||||
"postbuild": "yarn sw-manifest && yarn sw-copy",
|
"prebuild-local": "yarn setup-local",
|
||||||
|
"build-local": "yarn ~~build",
|
||||||
"lint": "yarn check-env && yarn docs-lint && ng lint && yarn example-lint",
|
"lint": "yarn check-env && yarn docs-lint && ng lint && yarn example-lint",
|
||||||
"test": "yarn check-env && ng test",
|
"test": "yarn check-env && ng test",
|
||||||
"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",
|
||||||
"setup": "yarn && yarn build-ie-polyfills && yarn boilerplate:remove && yarn boilerplate:add && yarn generate-plunkers && yarn generate-zips && yarn docs",
|
"presetup": "yarn ~~check-env && yarn install && yarn boilerplate:remove",
|
||||||
"pretest-pwa-score-local": "yarn build",
|
"setup": "node tools/ng-packages-installer restore . && yarn boilerplate:add",
|
||||||
"test-pwa-score-local": "concurrently --kill-others --success first \"http-server dist -p 4200 --silent\" \"yarn test-pwa-score -- http://localhost:4200 90\"",
|
"postsetup": "yarn build-ie-polyfills && yarn generate-plunkers && yarn generate-zips && yarn docs",
|
||||||
|
"presetup-local": "yarn presetup",
|
||||||
|
"setup-local": "node tools/ng-packages-installer overwrite . && yarn boilerplate:add -- --local",
|
||||||
|
"postsetup-local": "yarn postsetup",
|
||||||
|
"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": "node scripts/test-pwa-score",
|
"test-pwa-score": "node scripts/test-pwa-score",
|
||||||
"example-e2e": "node ./tools/examples/run-example-e2e",
|
"example-e2e": "yarn check-ng-packages -- tools/examples/shared && node ./tools/examples/run-example-e2e",
|
||||||
"example-lint": "tslint -c \"content/examples/tslint.json\" \"content/examples/**/*.ts\" -e \"content/examples/styleguide/**/*.avoid.ts\"",
|
"example-lint": "tslint -c \"content/examples/tslint.json\" \"content/examples/**/*.ts\" -e \"content/examples/styleguide/**/*.avoid.ts\"",
|
||||||
"deploy-preview": "scripts/deploy-preview.sh",
|
"deploy-preview": "scripts/deploy-preview.sh",
|
||||||
"deploy-production": "scripts/deploy-to-firebase.sh",
|
"deploy-production": "scripts/deploy-to-firebase.sh",
|
||||||
"check-env": "node scripts/check-environment",
|
"check-ng-packages": "node tools/ng-packages-installer check",
|
||||||
|
"check-env": "yarn ~~check-env",
|
||||||
|
"postcheck-env": "yarn check-ng-packages -- .",
|
||||||
"payload-size": "scripts/payload.sh",
|
"payload-size": "scripts/payload.sh",
|
||||||
"predocs": "rimraf src/generated/{docs,*.json}",
|
"predocs": "rimraf src/generated/{docs,*.json}",
|
||||||
"docs": "dgeni ./tools/transforms/angular.io-package",
|
"docs": "dgeni ./tools/transforms/angular.io-package",
|
||||||
"docs-watch": "node tools/transforms/authors-package/watchr.js",
|
"docs-watch": "node tools/transforms/authors-package/watchr.js",
|
||||||
"docs-lint": "eslint --ignore-path=\"tools/transforms/.eslintignore\" tools/transforms",
|
"docs-lint": "eslint --ignore-path=\"tools/transforms/.eslintignore\" tools/transforms",
|
||||||
"docs-test": "node tools/transforms/test.js",
|
"docs-test": "node tools/transforms/test.js",
|
||||||
"tools-test": "./scripts/deploy-to-firebase.test.sh && yarn docs-test",
|
"tools-test": "./scripts/deploy-to-firebase.test.sh && yarn docs-test && yarn boilerplate:test && jasmine tools/ng-packages-installer.spec.js",
|
||||||
"serve-and-sync": "concurrently --kill-others \"yarn docs-watch\" \"yarn start\"",
|
"serve-and-sync": "concurrently --kill-others \"yarn docs-watch\" \"yarn start\"",
|
||||||
"~~update-webdriver": "webdriver-manager update --standalone false --gecko false",
|
|
||||||
"boilerplate:add": "node ./tools/examples/example-boilerplate add",
|
"boilerplate:add": "node ./tools/examples/example-boilerplate add",
|
||||||
"boilerplate:remove": "node ./tools/examples/example-boilerplate remove",
|
"boilerplate:remove": "node ./tools/examples/example-boilerplate remove",
|
||||||
"boilerplate:test": "node tools/examples/test.js",
|
"boilerplate:test": "node tools/examples/test.js",
|
||||||
|
@ -41,7 +48,10 @@
|
||||||
"sw-manifest": "ngu-sw-manifest --dist dist --in ngsw-manifest.json --out dist/ngsw-manifest.json",
|
"sw-manifest": "ngu-sw-manifest --dist dist --in ngsw-manifest.json --out dist/ngsw-manifest.json",
|
||||||
"sw-copy": "cp node_modules/@angular/service-worker/bundles/worker-basic.min.js dist/",
|
"sw-copy": "cp node_modules/@angular/service-worker/bundles/worker-basic.min.js dist/",
|
||||||
"postinstall": "uglifyjs node_modules/lunr/lunr.js -c -m -o src/assets/js/lunr.min.js --source-map",
|
"postinstall": "uglifyjs node_modules/lunr/lunr.js -c -m -o src/assets/js/lunr.min.js --source-map",
|
||||||
"build-ie-polyfills": "node node_modules/webpack/bin/webpack.js -p src/ie-polyfills.js src/generated/ie-polyfills.min.js"
|
"build-ie-polyfills": "node node_modules/webpack/bin/webpack.js -p src/ie-polyfills.js src/generated/ie-polyfills.min.js",
|
||||||
|
"~~check-env": "node scripts/check-environment",
|
||||||
|
"~~build": "ng build --target=production --environment=stable -sm --build-optimizer && yarn sw-manifest && yarn sw-copy",
|
||||||
|
"~~update-webdriver": "webdriver-manager update --standalone false --gecko false"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.5 <7.0.0",
|
"node": ">=6.9.5 <7.0.0",
|
||||||
|
@ -78,6 +88,7 @@
|
||||||
"@types/node": "~6.0.60",
|
"@types/node": "~6.0.60",
|
||||||
"archiver": "^1.3.0",
|
"archiver": "^1.3.0",
|
||||||
"canonical-path": "^0.0.2",
|
"canonical-path": "^0.0.2",
|
||||||
|
"chalk": "^2.1.0",
|
||||||
"codelyzer": "~2.0.0",
|
"codelyzer": "~2.0.0",
|
||||||
"concurrently": "^3.4.0",
|
"concurrently": "^3.4.0",
|
||||||
"cross-spawn": "^5.1.0",
|
"cross-spawn": "^5.1.0",
|
||||||
|
|
|
@ -4,6 +4,8 @@ const path = require('canonical-path');
|
||||||
const shelljs = require('shelljs');
|
const shelljs = require('shelljs');
|
||||||
const yargs = require('yargs');
|
const yargs = require('yargs');
|
||||||
|
|
||||||
|
const ngPackagesInstaller = require('../ng-packages-installer');
|
||||||
|
|
||||||
const SHARED_PATH = path.resolve(__dirname, 'shared');
|
const SHARED_PATH = path.resolve(__dirname, 'shared');
|
||||||
const SHARED_NODE_MODULES_PATH = path.resolve(SHARED_PATH, 'node_modules');
|
const SHARED_NODE_MODULES_PATH = path.resolve(SHARED_PATH, 'node_modules');
|
||||||
const BOILERPLATE_BASE_PATH = path.resolve(SHARED_PATH, 'boilerplate');
|
const BOILERPLATE_BASE_PATH = path.resolve(SHARED_PATH, 'boilerplate');
|
||||||
|
@ -46,23 +48,6 @@ const BOILERPLATE_PATHS = {
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
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 EXAMPLE_CONFIG_FILENAME = 'example-config.json';
|
const EXAMPLE_CONFIG_FILENAME = 'example-config.json';
|
||||||
|
|
||||||
class ExampleBoilerPlate {
|
class ExampleBoilerPlate {
|
||||||
|
@ -72,13 +57,8 @@ class ExampleBoilerPlate {
|
||||||
* @param useLocal if true then overwrite the Angular library files with locally built ones
|
* @param useLocal if true then overwrite the Angular library files with locally built ones
|
||||||
*/
|
*/
|
||||||
add(useLocal) {
|
add(useLocal) {
|
||||||
// first install the shared node_modules
|
// Install the shared `node_modules/` (if necessary overwrite Angular packages from npm with local ones).
|
||||||
this.installNodeModules(SHARED_PATH);
|
this.installNodeModules(SHARED_PATH, useLocal);
|
||||||
|
|
||||||
// Replace the Angular packages with those from the dist folder, if necessary
|
|
||||||
if (useLocal) {
|
|
||||||
ANGULAR_PACKAGES.forEach(packageName => this.overridePackage(ANGULAR_PACKAGES_PATH, packageName));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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');
|
||||||
|
@ -118,15 +98,14 @@ class ExampleBoilerPlate {
|
||||||
.argv;
|
.argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
installNodeModules(basePath) {
|
installNodeModules(basePath, useLocal) {
|
||||||
shelljs.exec('yarn', {cwd: basePath});
|
shelljs.exec('yarn', {cwd: basePath});
|
||||||
}
|
|
||||||
|
|
||||||
overridePackage(basePath, packageName) {
|
if (useLocal) {
|
||||||
const sourceFolder = path.resolve(basePath, packageName);
|
ngPackagesInstaller.overwritePackages(basePath);
|
||||||
const destinationFolder = path.resolve(SHARED_NODE_MODULES_PATH, '@angular', packageName);
|
} else {
|
||||||
shelljs.rm('-rf', destinationFolder);
|
ngPackagesInstaller.restorePackages(basePath);
|
||||||
fs.copySync(sourceFolder, destinationFolder);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getFoldersContaining(basePath, filename, ignore) {
|
getFoldersContaining(basePath, filename, ignore) {
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
const exampleBoilerPlate = require('./example-boilerplate');
|
const path = require('canonical-path');
|
||||||
const shelljs = require('shelljs');
|
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const glob = require('glob');
|
const glob = require('glob');
|
||||||
const path = require('canonical-path');
|
const shelljs = require('shelljs');
|
||||||
|
|
||||||
|
const ngPackagesInstaller = require('../ng-packages-installer');
|
||||||
|
const exampleBoilerPlate = require('./example-boilerplate');
|
||||||
|
|
||||||
describe('example-boilerplate tool', () => {
|
describe('example-boilerplate tool', () => {
|
||||||
describe('add', () => {
|
describe('add', () => {
|
||||||
|
const sharedDir = path.resolve(__dirname, 'shared');
|
||||||
|
const sharedNodeModulesDir = path.resolve(sharedDir, 'node_modules');
|
||||||
const BPFiles = {
|
const BPFiles = {
|
||||||
cli: 18,
|
cli: 18,
|
||||||
systemjs: 7,
|
systemjs: 7,
|
||||||
|
@ -14,41 +18,44 @@ describe('example-boilerplate tool', () => {
|
||||||
const exampleFolders = ['a/b', 'c/d'];
|
const exampleFolders = ['a/b', 'c/d'];
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
spyOn(exampleBoilerPlate, 'installNodeModules');
|
|
||||||
spyOn(exampleBoilerPlate, 'overridePackage');
|
|
||||||
spyOn(exampleBoilerPlate, 'getFoldersContaining').and.returnValue(exampleFolders);
|
|
||||||
spyOn(fs, 'ensureSymlinkSync');
|
spyOn(fs, 'ensureSymlinkSync');
|
||||||
spyOn(exampleBoilerPlate, 'copyFile');
|
spyOn(exampleBoilerPlate, 'copyFile');
|
||||||
|
spyOn(exampleBoilerPlate, 'getFoldersContaining').and.returnValue(exampleFolders);
|
||||||
|
spyOn(exampleBoilerPlate, 'installNodeModules');
|
||||||
spyOn(exampleBoilerPlate, 'loadJsonFile').and.returnValue({});
|
spyOn(exampleBoilerPlate, 'loadJsonFile').and.returnValue({});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should install the node modules', () => {
|
it('should install the npm dependencies into `sharedDir` (and pass the `useLocal` argument through)', () => {
|
||||||
exampleBoilerPlate.add();
|
exampleBoilerPlate.add();
|
||||||
expect(exampleBoilerPlate.installNodeModules).toHaveBeenCalledWith(path.resolve(__dirname, 'shared'));
|
expect(exampleBoilerPlate.installNodeModules).toHaveBeenCalledWith(sharedDir, undefined);
|
||||||
});
|
|
||||||
|
exampleBoilerPlate.installNodeModules.calls.reset();
|
||||||
|
|
||||||
it('should override the Angular node_modules with the locally built Angular packages if `useLocal` is true', () => {
|
|
||||||
const numberOfAngularPackages = 12;
|
|
||||||
exampleBoilerPlate.add(true);
|
exampleBoilerPlate.add(true);
|
||||||
expect(exampleBoilerPlate.overridePackage).toHaveBeenCalledTimes(numberOfAngularPackages);
|
expect(exampleBoilerPlate.installNodeModules).toHaveBeenCalledWith(sharedDir, true);
|
||||||
// for example
|
|
||||||
expect(exampleBoilerPlate.overridePackage).toHaveBeenCalledWith(path.resolve(__dirname, '../../../dist/packages-dist'), 'common');
|
exampleBoilerPlate.installNodeModules.calls.reset();
|
||||||
expect(exampleBoilerPlate.overridePackage).toHaveBeenCalledWith(path.resolve(__dirname, '../../../dist/packages-dist'), 'core');
|
|
||||||
|
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');
|
||||||
exampleBoilerPlate.add();
|
exampleBoilerPlate.add();
|
||||||
expect(exampleBoilerPlate.getFoldersContaining).toHaveBeenCalledWith(path.resolve(__dirname, '../../content/examples'), 'example-config.json', 'node_modules');
|
expect(exampleBoilerPlate.getFoldersContaining)
|
||||||
|
.toHaveBeenCalledWith(examplesDir, 'example-config.json', 'node_modules');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should symlink the node_modules', () => {
|
it('should symlink the node_modules', () => {
|
||||||
exampleBoilerPlate.add();
|
exampleBoilerPlate.add();
|
||||||
expect(fs.ensureSymlinkSync).toHaveBeenCalledTimes(exampleFolders.length);
|
expect(fs.ensureSymlinkSync).toHaveBeenCalledTimes(exampleFolders.length);
|
||||||
expect(fs.ensureSymlinkSync).toHaveBeenCalledWith(path.resolve(__dirname, 'shared/node_modules'), path.resolve('a/b/node_modules'));
|
expect(fs.ensureSymlinkSync).toHaveBeenCalledWith(sharedNodeModulesDir, path.resolve('a/b/node_modules'));
|
||||||
expect(fs.ensureSymlinkSync).toHaveBeenCalledWith(path.resolve(__dirname, 'shared/node_modules'), path.resolve('c/d/node_modules'));
|
expect(fs.ensureSymlinkSync).toHaveBeenCalledWith(sharedNodeModulesDir, path.resolve('c/d/node_modules'));
|
||||||
});
|
});
|
||||||
|
|
||||||
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');
|
||||||
exampleBoilerPlate.loadJsonFile.and.callFake(filePath => filePath.indexOf('a/b') !== -1 ? { projectType: 'systemjs' } : {})
|
exampleBoilerPlate.loadJsonFile.and.callFake(filePath => filePath.indexOf('a/b') !== -1 ? { projectType: 'systemjs' } : {})
|
||||||
exampleBoilerPlate.add();
|
exampleBoilerPlate.add();
|
||||||
expect(exampleBoilerPlate.copyFile).toHaveBeenCalledTimes(
|
expect(exampleBoilerPlate.copyFile).toHaveBeenCalledTimes(
|
||||||
|
@ -57,19 +64,20 @@ describe('example-boilerplate tool', () => {
|
||||||
(BPFiles.common * exampleFolders.length)
|
(BPFiles.common * exampleFolders.length)
|
||||||
);
|
);
|
||||||
// for example
|
// for example
|
||||||
expect(exampleBoilerPlate.copyFile).toHaveBeenCalledWith(path.resolve(__dirname, 'shared/boilerplate/systemjs'), 'a/b', 'package.json');
|
expect(exampleBoilerPlate.copyFile).toHaveBeenCalledWith(`${boilerplateDir}/systemjs`, 'a/b', 'package.json');
|
||||||
expect(exampleBoilerPlate.copyFile).toHaveBeenCalledWith(path.resolve(__dirname, 'shared/boilerplate/common'), 'a/b', 'src/styles.css');
|
expect(exampleBoilerPlate.copyFile).toHaveBeenCalledWith(`${boilerplateDir}/common`, 'a/b', 'src/styles.css');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should copy all the source boilerplate files for cli', () => {
|
it('should copy all the source boilerplate files for cli', () => {
|
||||||
|
const boilerplateDir = path.resolve(sharedDir, 'boilerplate');
|
||||||
exampleBoilerPlate.add();
|
exampleBoilerPlate.add();
|
||||||
expect(exampleBoilerPlate.copyFile).toHaveBeenCalledTimes(
|
expect(exampleBoilerPlate.copyFile).toHaveBeenCalledTimes(
|
||||||
(BPFiles.cli * exampleFolders.length) +
|
(BPFiles.cli * exampleFolders.length) +
|
||||||
(BPFiles.common * exampleFolders.length)
|
(BPFiles.common * exampleFolders.length)
|
||||||
);
|
);
|
||||||
// for example
|
// for example
|
||||||
expect(exampleBoilerPlate.copyFile).toHaveBeenCalledWith(path.resolve(__dirname, 'shared/boilerplate/cli'), 'a/b', 'package.json');
|
expect(exampleBoilerPlate.copyFile).toHaveBeenCalledWith(`${boilerplateDir}/cli`, 'a/b', 'package.json');
|
||||||
expect(exampleBoilerPlate.copyFile).toHaveBeenCalledWith(path.resolve(__dirname, 'shared/boilerplate/common'), 'c/d', 'src/styles.css');
|
expect(exampleBoilerPlate.copyFile).toHaveBeenCalledWith(`${boilerplateDir}/common`, 'c/d', 'src/styles.css');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should try to load the example config file', () => {
|
it('should try to load the example config file', () => {
|
||||||
|
@ -89,27 +97,33 @@ describe('example-boilerplate tool', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('installNodeModules', () => {
|
describe('installNodeModules', () => {
|
||||||
it('should run `yarn` in the base path', () => {
|
beforeEach(() => {
|
||||||
spyOn(shelljs, 'exec');
|
spyOn(shelljs, 'exec');
|
||||||
|
spyOn(ngPackagesInstaller, 'overwritePackages');
|
||||||
|
spyOn(ngPackagesInstaller, 'restorePackages');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should run `yarn` in the base path', () => {
|
||||||
exampleBoilerPlate.installNodeModules('some/base/path');
|
exampleBoilerPlate.installNodeModules('some/base/path');
|
||||||
expect(shelljs.exec).toHaveBeenCalledWith('yarn', { cwd: 'some/base/path' });
|
expect(shelljs.exec).toHaveBeenCalledWith('yarn', { cwd: 'some/base/path' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should overwrite the Angular packages if `useLocal` is true', () => {
|
||||||
|
ngPackagesInstaller.overwritePackages.and.callFake(() => expect(shelljs.exec).toHaveBeenCalled());
|
||||||
|
|
||||||
|
exampleBoilerPlate.installNodeModules('some/base/path', true);
|
||||||
|
expect(ngPackagesInstaller.overwritePackages).toHaveBeenCalledWith('some/base/path');
|
||||||
|
expect(ngPackagesInstaller.restorePackages).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('overridePackage', () => {
|
it('should restore the Angular packages if `useLocal` is not true', () => {
|
||||||
beforeEach(() => {
|
exampleBoilerPlate.installNodeModules('some/base/path1');
|
||||||
spyOn(shelljs, 'rm');
|
expect(ngPackagesInstaller.restorePackages).toHaveBeenCalledWith('some/base/path1');
|
||||||
spyOn(fs, 'copySync');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove the original package from the shared node_modules folder', () => {
|
exampleBoilerPlate.installNodeModules('some/base/path2', false);
|
||||||
exampleBoilerPlate.overridePackage('base/path', 'somePackage');
|
expect(ngPackagesInstaller.restorePackages).toHaveBeenCalledWith('some/base/path2');
|
||||||
expect(shelljs.rm).toHaveBeenCalledWith('-rf', path.resolve(__dirname, 'shared/node_modules/@angular/somePackage'));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should copy the source folder to the shared node_modules folder', () => {
|
expect(ngPackagesInstaller.overwritePackages).not.toHaveBeenCalled();
|
||||||
exampleBoilerPlate.overridePackage('base/path', 'somePackage');
|
|
||||||
expect(fs.copySync).toHaveBeenCalledWith(path.resolve('base/path/somePackage'), path.resolve(__dirname, 'shared/node_modules/@angular/somePackage'));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,235 @@
|
||||||
|
#!/bin/env node
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// Imports
|
||||||
|
const chalk = require('chalk');
|
||||||
|
const fs = require('fs-extra');
|
||||||
|
const path = require('canonical-path');
|
||||||
|
const shelljs = require('shelljs');
|
||||||
|
const yargs = require('yargs');
|
||||||
|
|
||||||
|
// Config
|
||||||
|
shelljs.set('-e');
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
const ROOT_DIR = path.resolve(__dirname, '../..');
|
||||||
|
const PACKAGES_DIR = path.join(ROOT_DIR, 'packages');
|
||||||
|
const PACKAGES_DIST_DIR = path.join(ROOT_DIR, 'dist/packages-dist');
|
||||||
|
const NG_LOCAL_FILENAME = '.ng-local';
|
||||||
|
|
||||||
|
// Classes
|
||||||
|
class NgPackagesInstaller {
|
||||||
|
constructor() {
|
||||||
|
// Properties - Protected
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A sorted list of Angular package names.
|
||||||
|
* (Detected as directories in '/packages/' that contain a top-level 'package.json' file.)
|
||||||
|
*/
|
||||||
|
this.ngPackages = shelljs.
|
||||||
|
find(PACKAGES_DIR).
|
||||||
|
map(path => path.slice(PACKAGES_DIR.length + 1)).
|
||||||
|
filter(path => /^[^/]+\/package.json$/.test(path)).
|
||||||
|
map(path => path.slice(0, -13)).
|
||||||
|
sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods - Public
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the Angular packages installed in the specified `rootDir`'s 'node_modules/' come from npm and print a
|
||||||
|
* warning if not.
|
||||||
|
* @param {string} rootDir - The root directory whose npm dependencies will be checked.
|
||||||
|
*/
|
||||||
|
checkPackages(rootDir) {
|
||||||
|
rootDir = path.resolve(rootDir);
|
||||||
|
const localPackages = this._findLocalPackages(rootDir);
|
||||||
|
|
||||||
|
if (localPackages.length) {
|
||||||
|
const relativeScriptPath = path.relative('.', __filename.replace(/\.js$/, ''));
|
||||||
|
const relativeRootDir = path.relative('.', rootDir) || '.';
|
||||||
|
const restoreCmd = `node ${relativeScriptPath} restore ${relativeRootDir}`;
|
||||||
|
|
||||||
|
// Log a warning.
|
||||||
|
console.warn(chalk.yellow([
|
||||||
|
'',
|
||||||
|
'!'.repeat(110),
|
||||||
|
'!!!',
|
||||||
|
'!!! WARNING',
|
||||||
|
'!!!',
|
||||||
|
`!!! The following packages have been overwritten in '${rootDir}/node_modules/' with the locally built ones:`,
|
||||||
|
'!!!',
|
||||||
|
...localPackages.map(pkg => `!!! - @angular/${pkg}`),
|
||||||
|
'!!!',
|
||||||
|
'!!! To restore the packages run:',
|
||||||
|
'!!!',
|
||||||
|
`!!! ${restoreCmd}`,
|
||||||
|
'!!!',
|
||||||
|
'!'.repeat(110),
|
||||||
|
'',
|
||||||
|
].join('\n')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overwrite the Angular packages installed in the specified `rootDir`'s 'node_modules/' with the locally built ones.
|
||||||
|
* @param {string} rootDir - The root directory whose npm dependencies will be overwritten.
|
||||||
|
*/
|
||||||
|
overwritePackages(rootDir) {
|
||||||
|
rootDir = path.resolve(rootDir);
|
||||||
|
const nodeModulesDir = path.join(rootDir, 'node_modules');
|
||||||
|
|
||||||
|
this.ngPackages.forEach(packageName => this._overwritePackage(packageName, nodeModulesDir));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that the Angular packages installed in the specified `rootDir`'s 'node_modules/' come from npm.
|
||||||
|
* (If necessary, re-install the Angular packages using `yarn`.)
|
||||||
|
* @param {string} rootDir - The root directory whose npm dependencies will be restored.
|
||||||
|
*/
|
||||||
|
restorePackages(rootDir) {
|
||||||
|
rootDir = path.resolve(rootDir);
|
||||||
|
const localPackages = this._findLocalPackages(rootDir);
|
||||||
|
|
||||||
|
if (localPackages.length) {
|
||||||
|
this._reinstallOverwrittenNodeModules(rootDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods - Protected
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find and return all Angular packages installed in the specified `rootDir`'s 'node_modules/' that have been
|
||||||
|
* overwritten with the locally built ones.
|
||||||
|
* @param {string} rootDir - The root directory whose npm dependencies will be checked.
|
||||||
|
* @return {string[]} - A list of overwritten package names.
|
||||||
|
*/
|
||||||
|
_findLocalPackages(rootDir) {
|
||||||
|
const nodeModulesDir = path.join(rootDir, 'node_modules');
|
||||||
|
const localPackages = this.ngPackages.filter(packageName => this._isLocalPackage(packageName, nodeModulesDir));
|
||||||
|
|
||||||
|
this._log(`Local packages found: ${localPackages.join(', ') || '-'}`);
|
||||||
|
|
||||||
|
return localPackages;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether an installed Angular package from `nodeModulesDir` has been overwritten with a
|
||||||
|
* locally built package.
|
||||||
|
* @param {string} packageName - The name of the package to check.
|
||||||
|
* @param {string} nodeModulesDir - The target `node_modules/` directory.
|
||||||
|
* @return {boolean} - True if the package has been overwritten or false otherwise.
|
||||||
|
*/
|
||||||
|
_isLocalPackage(packageName, nodeModulesDir) {
|
||||||
|
const targetPackageDir = path.join(nodeModulesDir, '@angular', packageName);
|
||||||
|
const localFlagFile = path.join(targetPackageDir, NG_LOCAL_FILENAME);
|
||||||
|
const isLocal = fs.existsSync(localFlagFile);
|
||||||
|
|
||||||
|
this._log(`Checking package '${packageName}' (${targetPackageDir})... local: ${isLocal}`);
|
||||||
|
|
||||||
|
return isLocal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a message if the `debug` property is set to true.
|
||||||
|
* @param {string} message - The message to be logged.
|
||||||
|
*/
|
||||||
|
_log(message) {
|
||||||
|
if (this.debug) {
|
||||||
|
const indent = ' ';
|
||||||
|
console.info(`${indent}[${NgPackagesInstaller.name}]: ${message.split('\n').join(`\n${indent}`)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse and validate the input and invoke the appropriate command.
|
||||||
|
*/
|
||||||
|
_main() {
|
||||||
|
const preCommand = argv => {
|
||||||
|
this.debug = argv.debug;
|
||||||
|
|
||||||
|
const availablePackages = this.ngPackages.map(pkg => `\n - @angular/${pkg}`).join('') || '-';
|
||||||
|
this._log(`Available Angular packages: ${availablePackages}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
yargs.
|
||||||
|
usage('$0 <cmd> <args>').
|
||||||
|
command(
|
||||||
|
'check <projectDir> [--debug]',
|
||||||
|
'Check whether the Angular packages installed as dependencies of `projectDir` come from npm and print a ' +
|
||||||
|
'warning if not.',
|
||||||
|
{
|
||||||
|
debug: {describe: 'Print debug information.'}
|
||||||
|
},
|
||||||
|
argv => {
|
||||||
|
preCommand(argv);
|
||||||
|
this.checkPackages(argv.projectDir);
|
||||||
|
}).
|
||||||
|
command(
|
||||||
|
'overwrite <projectDir> [--debug]',
|
||||||
|
'Overwrite the Angular packages installed as dependencies of `projectDir` with the locally built ones.',
|
||||||
|
{
|
||||||
|
debug: {describe: 'Print debug information.'}
|
||||||
|
},
|
||||||
|
argv => {
|
||||||
|
preCommand(argv);
|
||||||
|
this.overwritePackages(argv.projectDir);
|
||||||
|
}).
|
||||||
|
command(
|
||||||
|
'restore <projectDir> [--debug]',
|
||||||
|
'Ensure that the Angular packages installed as dependencies of `projectDir` come from npm.',
|
||||||
|
{
|
||||||
|
debug: {describe: 'Print debug information.'}
|
||||||
|
},
|
||||||
|
argv => {
|
||||||
|
preCommand(argv);
|
||||||
|
this.restorePackages(argv.projectDir);
|
||||||
|
}).
|
||||||
|
demandCommand(1, 'Please supply a command from the list above.').
|
||||||
|
strict().
|
||||||
|
argv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove an installed Angular package from `nodeModulesDir` and replace it with the locally built
|
||||||
|
* one. Mark the package by adding an `.ng-local` file in the target directory.
|
||||||
|
* @param {string} packageName - The name of the package to overwrite.
|
||||||
|
* @param {string} nodeModulesDir - The target `node_modules/` directory.
|
||||||
|
*/
|
||||||
|
_overwritePackage(packageName, nodeModulesDir) {
|
||||||
|
const sourcePackageDir = path.join(PACKAGES_DIST_DIR, packageName);
|
||||||
|
const targetPackageDir = path.join(nodeModulesDir, '@angular', packageName);
|
||||||
|
const localFlagFile = path.join(targetPackageDir, NG_LOCAL_FILENAME);
|
||||||
|
|
||||||
|
this._log(`Overwriting package '${packageName}' (${sourcePackageDir} --> ${targetPackageDir})...`);
|
||||||
|
|
||||||
|
if (fs.existsSync(targetPackageDir)) {
|
||||||
|
shelljs.rm('-rf', targetPackageDir);
|
||||||
|
fs.copySync(sourcePackageDir, targetPackageDir);
|
||||||
|
fs.writeFileSync(localFlagFile, '');
|
||||||
|
} else {
|
||||||
|
this._log(' Nothing to overwrite - the package is not installed...');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-install overwritten npm dependencies using `yarn`. Removes the `.yarn-integrity` file to ensure `yarn` detects
|
||||||
|
* the overwritten packages.
|
||||||
|
* @param {string} rootDir - The root directory whose npm dependencies will be re-installed.
|
||||||
|
*/
|
||||||
|
_reinstallOverwrittenNodeModules(rootDir) {
|
||||||
|
const installCmd = 'yarn install --check-files';
|
||||||
|
|
||||||
|
this._log(`Running '${installCmd}' in '${rootDir}'...`);
|
||||||
|
shelljs.exec(installCmd, {cwd: rootDir});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exports
|
||||||
|
module.exports = new NgPackagesInstaller();
|
||||||
|
|
||||||
|
// Run
|
||||||
|
if (require.main === module) {
|
||||||
|
// This file was run directly; run the main function.
|
||||||
|
module.exports._main();
|
||||||
|
}
|
|
@ -0,0 +1,286 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const fs = require('fs-extra');
|
||||||
|
const path = require('canonical-path');
|
||||||
|
const shelljs = require('shelljs');
|
||||||
|
|
||||||
|
const installer = require('./ng-packages-installer');
|
||||||
|
|
||||||
|
describe('NgPackagesInstaller', () => {
|
||||||
|
const ngPackages = installer.ngPackages;
|
||||||
|
const rootDir = 'root/dir';
|
||||||
|
const absoluteRootDir = path.resolve(rootDir);
|
||||||
|
const nodeModulesDir = `${absoluteRootDir}/node_modules`;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(fs, 'copySync');
|
||||||
|
spyOn(fs, 'existsSync');
|
||||||
|
spyOn(fs, 'writeFileSync');
|
||||||
|
spyOn(shelljs, 'exec');
|
||||||
|
spyOn(shelljs, 'rm');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
|
||||||
|
describe('.ngPackages', () => {
|
||||||
|
it('should include all package names', () => {
|
||||||
|
// For example...
|
||||||
|
expect(installer.ngPackages).toContain('common');
|
||||||
|
expect(installer.ngPackages).toContain('core');
|
||||||
|
expect(installer.ngPackages).toContain('router');
|
||||||
|
expect(installer.ngPackages).toContain('upgrade');
|
||||||
|
|
||||||
|
expect(installer.ngPackages).not.toContain('static');
|
||||||
|
expect(installer.ngPackages).not.toContain('upgrade/static');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should correspond to package directories with top-level \'package.json\' files', () => {
|
||||||
|
fs.existsSync.and.callThrough();
|
||||||
|
|
||||||
|
const packagesDir = path.resolve(__dirname, '../../packages');
|
||||||
|
|
||||||
|
installer.ngPackages.forEach(packageName => {
|
||||||
|
const packageJson = `${packagesDir}/${packageName}/package.json`;
|
||||||
|
expect(fs.existsSync(packageJson)).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
|
||||||
|
describe('checkPackages()', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(console, 'warn');
|
||||||
|
spyOn(installer, '_findLocalPackages');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should check whether there are any local Angular packages in the target directory', () => {
|
||||||
|
installer._findLocalPackages.and.returnValue([]);
|
||||||
|
|
||||||
|
installer.checkPackages(rootDir);
|
||||||
|
expect(installer._findLocalPackages).toHaveBeenCalledWith(absoluteRootDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not print a warning if all Angular packages come from npm', () => {
|
||||||
|
installer._findLocalPackages.and.returnValue([]);
|
||||||
|
|
||||||
|
installer.checkPackages(rootDir);
|
||||||
|
expect(console.warn).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when there are local Angular packages', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
installer._findLocalPackages.and.returnValue(['common', 'router']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should print a warning', () => {
|
||||||
|
installer.checkPackages(rootDir);
|
||||||
|
|
||||||
|
expect(console.warn).toHaveBeenCalled();
|
||||||
|
expect(console.warn.calls.mostRecent().args[0]).toContain('WARNING');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should list the local (i.e. overwritten) packages', () => {
|
||||||
|
installer.checkPackages(rootDir);
|
||||||
|
|
||||||
|
const warning = console.warn.calls.mostRecent().args[0];
|
||||||
|
expect(warning).toContain('@angular/common');
|
||||||
|
expect(warning).toContain('@angular/router');
|
||||||
|
expect(warning).not.toContain('@angular/core');
|
||||||
|
expect(warning).not.toContain('@angular/upgrade');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should mention the command to restore the Angular packages', () => {
|
||||||
|
// When run for the current working directory...
|
||||||
|
const dir1 = '.';
|
||||||
|
const restoreCmdRe1 = RegExp('\\bnode .*?ng-packages-installer restore \\.');
|
||||||
|
|
||||||
|
installer.checkPackages(dir1);
|
||||||
|
|
||||||
|
expect(console.warn.calls.argsFor(0)[0]).toMatch(restoreCmdRe1);
|
||||||
|
|
||||||
|
// When run for a different directory...
|
||||||
|
const dir2 = rootDir;
|
||||||
|
const restoreCmdRe2 = RegExp(`\\bnode .*?ng-packages-installer restore .*?${path.normalize(rootDir)}\\b`);
|
||||||
|
|
||||||
|
installer.checkPackages(dir2);
|
||||||
|
|
||||||
|
expect(console.warn.calls.argsFor(1)[0]).toMatch(restoreCmdRe2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('overwritePackages()', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(installer, '_overwritePackage');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should override the Angular packages in the target directory with the locally built ones', () => {
|
||||||
|
installer.overwritePackages(rootDir);
|
||||||
|
expect(installer._overwritePackage).toHaveBeenCalledTimes(ngPackages.length);
|
||||||
|
|
||||||
|
ngPackages.forEach(packageName =>
|
||||||
|
expect(installer._overwritePackage).toHaveBeenCalledWith(packageName, nodeModulesDir));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('restorePackages()', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(installer, '_findLocalPackages');
|
||||||
|
spyOn(installer, '_reinstallOverwrittenNodeModules');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should check whether there are any local Angular packages in the target directory first', () => {
|
||||||
|
installer._findLocalPackages.and.callFake(() => {
|
||||||
|
expect(installer._reinstallOverwrittenNodeModules).not.toHaveBeenCalled();
|
||||||
|
return [];
|
||||||
|
});
|
||||||
|
|
||||||
|
installer.restorePackages(rootDir);
|
||||||
|
expect(installer._findLocalPackages).toHaveBeenCalledWith(absoluteRootDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should re-install dependencies from npm afterwards (if necessary)', () => {
|
||||||
|
// No local packages.
|
||||||
|
installer._findLocalPackages.and.returnValue([]);
|
||||||
|
|
||||||
|
installer.restorePackages(rootDir);
|
||||||
|
expect(installer._reinstallOverwrittenNodeModules).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
// All local packages.
|
||||||
|
installer._reinstallOverwrittenNodeModules.calls.reset();
|
||||||
|
installer._findLocalPackages.and.returnValue(ngPackages);
|
||||||
|
|
||||||
|
installer.restorePackages(rootDir);
|
||||||
|
expect(installer._reinstallOverwrittenNodeModules).toHaveBeenCalledWith(absoluteRootDir);
|
||||||
|
|
||||||
|
// Some local packages.
|
||||||
|
installer._reinstallOverwrittenNodeModules.calls.reset();
|
||||||
|
installer._findLocalPackages.and.returnValue(['common', 'core', 'router', 'upgrade']);
|
||||||
|
|
||||||
|
installer.restorePackages(rootDir);
|
||||||
|
expect(installer._reinstallOverwrittenNodeModules).toHaveBeenCalledWith(absoluteRootDir);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('_findLocalPackages()', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(installer, '_isLocalPackage');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should check all Angular packages', () => {
|
||||||
|
installer._findLocalPackages(absoluteRootDir);
|
||||||
|
|
||||||
|
ngPackages.forEach(packageName =>
|
||||||
|
expect(installer._isLocalPackage).toHaveBeenCalledWith(packageName, nodeModulesDir));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return an empty list if all Angular packages come from npm', () => {
|
||||||
|
installer._isLocalPackage.and.returnValue(false);
|
||||||
|
expect(installer._findLocalPackages(rootDir)).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a list of all local (i.e. overwritten) Angular packages', () => {
|
||||||
|
const localPackages = ['common', 'core', 'router', 'upgrade'];
|
||||||
|
|
||||||
|
installer._isLocalPackage.and.callFake(packageName => localPackages.includes(packageName));
|
||||||
|
|
||||||
|
expect(installer._findLocalPackages(rootDir)).toEqual(localPackages);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('_isLocalPackage()', () => {
|
||||||
|
it('should check whether the specified package is local/overwritten', () => {
|
||||||
|
const targetPackageDir = `${rootDir}/@angular/somePackage`;
|
||||||
|
const localFlagFile = `${targetPackageDir}/.ng-local`;
|
||||||
|
|
||||||
|
installer._isLocalPackage('somePackage', rootDir);
|
||||||
|
expect(fs.existsSync).toHaveBeenCalledWith(localFlagFile);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return whether the specified package was local', () => {
|
||||||
|
fs.existsSync.and.returnValues(true, false);
|
||||||
|
|
||||||
|
expect(installer._isLocalPackage('somePackage', rootDir)).toBe(true);
|
||||||
|
expect(installer._isLocalPackage('somePackage', rootDir)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('_log()', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(console, 'info');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
installer.debug = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should log a message to the console if the `debug` property is true', () => {
|
||||||
|
installer._log('foo');
|
||||||
|
expect(console.info).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
installer.debug = true;
|
||||||
|
installer._log('bar');
|
||||||
|
expect(console.info).toHaveBeenCalledWith(' [NgPackagesInstaller]: bar');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('_overwritePackage()', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
fs.existsSync.and.returnValue(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should check whether the Angular package is installed', () => {
|
||||||
|
const targetPackageDir = `${rootDir}/@angular/somePackage`;
|
||||||
|
|
||||||
|
installer._overwritePackage('somePackage', rootDir);
|
||||||
|
expect(fs.existsSync).toHaveBeenCalledWith(targetPackageDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove the original package from the target directory', () => {
|
||||||
|
const targetPackageDir = `${rootDir}/@angular/somePackage`;
|
||||||
|
|
||||||
|
shelljs.rm.and.callFake(() => expect(fs.existsSync).toHaveBeenCalled());
|
||||||
|
|
||||||
|
installer._overwritePackage('somePackage', rootDir);
|
||||||
|
expect(shelljs.rm).toHaveBeenCalledWith('-rf', targetPackageDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should copy the source package directory to the target directory', () => {
|
||||||
|
const sourcePackageDir = path.resolve(__dirname, '../../dist/packages-dist/somePackage');
|
||||||
|
const targetPackageDir = `${rootDir}/@angular/somePackage`;
|
||||||
|
|
||||||
|
fs.copySync.and.callFake(() => expect(shelljs.rm).toHaveBeenCalled());
|
||||||
|
|
||||||
|
installer._overwritePackage('somePackage', rootDir);
|
||||||
|
expect(fs.copySync).toHaveBeenCalledWith(sourcePackageDir, targetPackageDir);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add an empty `.ng-local` file to the target directory', () => {
|
||||||
|
const targetPackageDir = `${rootDir}/@angular/somePackage`;
|
||||||
|
const localFlagFile = `${targetPackageDir}/.ng-local`;
|
||||||
|
|
||||||
|
fs.writeFileSync.and.callFake(() => expect(fs.copySync).toHaveBeenCalled());
|
||||||
|
|
||||||
|
installer._overwritePackage('somePackage', rootDir);
|
||||||
|
expect(fs.writeFileSync).toHaveBeenCalledWith(localFlagFile, '');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should do nothing if the Angular package is not installed', () => {
|
||||||
|
fs.existsSync.and.returnValue(false);
|
||||||
|
|
||||||
|
installer._overwritePackage('somePackage', rootDir);
|
||||||
|
|
||||||
|
expect(shelljs.rm).not.toHaveBeenCalled();
|
||||||
|
expect(fs.copySync).not.toHaveBeenCalled();
|
||||||
|
expect(fs.writeFileSync).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('_reinstallOverwrittenNodeModules()', () => {
|
||||||
|
it('should run `yarn install --check-files` in the specified directory', () => {
|
||||||
|
installer._reinstallOverwrittenNodeModules(rootDir);
|
||||||
|
expect(shelljs.exec).toHaveBeenCalledWith('yarn install --check-files', {cwd: rootDir});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1085,7 +1085,7 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
|
||||||
strip-ansi "^3.0.0"
|
strip-ansi "^3.0.0"
|
||||||
supports-color "^2.0.0"
|
supports-color "^2.0.0"
|
||||||
|
|
||||||
chalk@^2.0.0, chalk@^2.0.1:
|
chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e"
|
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
|
@ -18,12 +18,6 @@ source ${thisDir}/_travis-fold.sh
|
||||||
travisFoldEnd "test.aio.lint"
|
travisFoldEnd "test.aio.lint"
|
||||||
|
|
||||||
|
|
||||||
# Run unit tests for boilerplate tools
|
|
||||||
travisFoldStart "test.aio.boilerplate.unit"
|
|
||||||
yarn boilerplate:test
|
|
||||||
travisFoldEnd "test.aio.boilerplate.unit"
|
|
||||||
|
|
||||||
|
|
||||||
# Run unit tests
|
# Run unit tests
|
||||||
travisFoldStart "test.aio.unit"
|
travisFoldStart "test.aio.unit"
|
||||||
yarn test -- --single-run
|
yarn test -- --single-run
|
||||||
|
@ -38,7 +32,7 @@ source ${thisDir}/_travis-fold.sh
|
||||||
|
|
||||||
# Run PWA-score tests
|
# Run PWA-score tests
|
||||||
travisFoldStart "test.aio.pwaScore"
|
travisFoldStart "test.aio.pwaScore"
|
||||||
yarn test-pwa-score-local
|
yarn test-pwa-score-localhost
|
||||||
travisFoldEnd "test.aio.pwaScore"
|
travisFoldEnd "test.aio.pwaScore"
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue