build: replace setup angular snapshots script with python script

In order to be able to take advantage of Google's official
bazel docker images, we no longer can use a NodeJS script
for setting up the snapshot builds because NodeJS is not
installed in the image. Rather we need to convert the script
to a python script in order to be able to perform the package.json
modification.

Since this script is not intended to be executed locally, we
are free to use Python for this.
This commit is contained in:
Paul Gschwendtner
2019-06-19 11:42:51 +02:00
committed by Jeremy Elbourn
parent 2ce5ffd56b
commit 10cd71a0ed
3 changed files with 74 additions and 67 deletions
+4 -4
View File
@@ -364,9 +364,9 @@ jobs:
- *checkout_code
- *restore_cache
- *yarn_download
- *yarn_install
- run: node ./scripts/circleci/setup-angular-snapshots.js
- run: python ./scripts/circleci/setup-angular-snapshots.py --tag master
- *yarn_install
- run: ./scripts/circleci/run-local-browser-tests.sh
@@ -392,7 +392,7 @@ jobs:
# we use ngcc to apply the ivy switches because ngcc currently does not handle the
# UMD format which is used by Bazel when running tests. UMD processing is in
# progress and tracked with FW-85.
- run: bazel run @nodejs//:node -- ./scripts/circleci/setup-angular-snapshots.js --tag 8.1.0-next.1-ivy-aot+82e0b4a
- run: python ./scripts/circleci/setup-angular-snapshots.py --tag 8.1.0-next.1-ivy-aot+82e0b4a
# Disable type checking when building with Ivy. This is necessary because
# type checking is not complete yet and can incorrectly break compilation.
# Issue is tracked with FW-1004.
@@ -417,7 +417,7 @@ jobs:
- *setup_bazel_remote_execution
# Setup Angular ivy snapshots built with ngtsc.
- run: bazel run @nodejs//:node -- ./scripts/circleci/setup-angular-snapshots.js --tag master-ivy-aot
- run: python ./scripts/circleci/setup-angular-snapshots.py --tag master-ivy-aot
# Disable type checking when building with Ivy. This is necessary because
# type checking is not complete yet and can incorrectly break compilation.
# Issue is tracked with FW-1004.
@@ -1,63 +0,0 @@
/**
* Script that sets up the Angular snapshot github builds. We set up the snapshot builds by
* overwriting the versions in the "package.json" and taking advantage of Yarn's resolutions
* feature. Yarn resolutions will be used to flatten nested Angular packages because by default
* Yarn does not flatten any dependency. See:
*
* node_modules/compiler@snapshot
* node_modules/compiler-cli@snapshot
* node_modules/compiler@7.0.1
*
* Note that we cannot just use Yarn's `--flat` option because that would mean that it tries
* to flatten **all** dependencies and could cause unexpected results. We **only** want to
* explicitly flatten out all `@angular/*` dependencies. This can be achieved with resolutions.
* Read more here: https://yarnpkg.com/lang/en/docs/package-json/#toc-resolutions
*/
const {yellow, green} = require('chalk');
const {writeFileSync} = require('fs');
const {join} = require('path');
const {execSync} = require('child_process');
const {tag} = require('minimist')(process.argv.slice(2), {string: ['tag']});
const projectDir = join(__dirname, '../../');
const packageJsonPath = join(projectDir, 'package.json');
const packageJson = require(packageJsonPath);
// Initialize the "resolutions" property in case it is not present in the "package.json" yet.
// See: https://yarnpkg.com/lang/en/docs/package-json/#toc-resolutions for the API.
packageJson['resolutions'] = packageJson['resolutions'] || {};
// List that contains the names of all installed Angular packages (e.g. "@angular/core")
const angularPackages = Object.keys({...packageJson.dependencies, ...packageJson.devDependencies})
.filter(packageName => packageName.startsWith('@angular/'));
const packageSuffix = tag ? ` (${tag})` : '';
console.log(green('Setting up snapshot builds for:\n'));
console.log(yellow(` ${angularPackages.map(n => `${n}${packageSuffix}`).join('\n ')}\n`));
// Setup the snapshot version for each Angular package specified in the "package.json" file.
angularPackages.forEach(packageName => {
let buildsUrl = `github:angular/${packageName.split('/')[1]}-builds${tag ? `#${tag}` : ''}`;
// Add resolutions for each package in the format "**/{PACKAGE}" so that all
// nested versions of that specific Angular package will have the same version.
packageJson.resolutions[`**/${packageName}`] = buildsUrl;
// Since the resolutions only cover the version of all nested installs, we also need
// to explicitly set the version for the package listed in the project "package.json".
packageJson.dependencies[packageName] = buildsUrl;
// In case this dependency was previously a dev dependency, just remove it because we
// re-added it as a normal dependency for simplicity.
delete packageJson.devDependencies[packageName];
});
// Write changes to the "packageJson", so that we can install the new versions afterwards.
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
console.log(green('Successfully added the "resolutions" to the "package.json".'));
// Run "yarn" in the directory that contains the "package.json". Also pipe all output to the
// current process so that everything can be debugged within CircleCI.
execSync('yarn', {cwd: projectDir, stdio: 'inherit', shell: true});
@@ -0,0 +1,70 @@
"""
Script that sets up the Angular snapshot github builds. We set up the snapshot builds by
overwriting the versions in the "package.json" and taking advantage of Yarn's resolutions
feature. Yarn resolutions will be used to flatten nested Angular packages because by default
Yarn does not flatten any dependency. See:
node_modules/compiler@snapshot
node_modules/compiler-cli@snapshot
node_modules/compiler@7.0.1
Note that we cannot just use Yarn's `--flat` option because that would mean that it tries
to flatten **all** dependencies and could cause unexpected results. We **only** want to
explicitly flatten out all `@angular/*` dependencies. This can be achieved with resolutions.
Read more here: https://yarnpkg.com/lang/en/docs/package-json/#toc-resolutions
"""
import json
import os
import argparse
def collect_angular_deps(obj, result):
for item in obj:
if (item.startswith('@angular/')):
result.append(item)
project_dir = os.path.realpath(os.path.join(os.path.dirname(__file__), '../../'))
package_json_path = os.path.join(project_dir, 'package.json')
parser = argparse.ArgumentParser(description='Setup Angular snapshot packages')
parser.add_argument('--tag', required = True)
parsed_args = parser.parse_args()
with open(package_json_path, 'r') as package_json:
data = json.load(package_json)
angular_pkgs = []
collect_angular_deps(data['dependencies'], angular_pkgs)
collect_angular_deps(data['devDependencies'], angular_pkgs)
if not 'resolutions' in data:
data['resolutions'] = {}
print('Setting up snapshot builds for:')
for pkg in angular_pkgs:
new_url = "github:angular/%s-builds#%s" % (pkg.split('/')[1], parsed_args.tag)
print(" %s -> %s" % (pkg, new_url))
# Add resolutions for each package in the format "**/{PACKAGE}" so that all
# nested versions of that specific Angular package will have the same version.
data['resolutions']['**/%s' % pkg] = new_url
# Since the resolutions only cover the version of all nested installs, we also need
# to explicitly set the version for the package listed in the project "package.json".
data['dependencies'][pkg] = new_url
# In case this dependency was previously a dev dependency, just remove it because we
# re-added it as a normal dependency for simplicity.
if pkg in data['devDependencies']:
del data['devDependencies'][pkg]
new_package_json = json.dumps(data, indent = 2)
with open(package_json_path, 'w') as package_json_out:
package_json_out.write(new_package_json)
print('')
print('Successfully added the "resolutions" to the "package.json".')
print('Please run "yarn install" in the project to update the lock file.')