Skip to content

Commit 9fd88c9

Browse files
authored
chore: use new parallel build feature of jsii (#4367)
Improve build times by using the new "build-all-at-once" feature of jsii-pacmak (for the Java build). Goes together with aws/jsii#849. Also parallelize the "does this package exist on NPM" checks.
1 parent af56996 commit 9fd88c9

File tree

4 files changed

+108
-33
lines changed

4 files changed

+108
-33
lines changed

pack.sh

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,43 @@
22
# Runs "npm package" in all modules. This will produce a "dist/" directory in each module.
33
# Then, calls pack-collect.sh to merge all outputs into a root ./pack directory, which is
44
# later read by bundle-beta.sh.
5-
set -e
5+
set -eu
66
export PATH=$PWD/node_modules/.bin:$PATH
77
export NODE_OPTIONS="--max-old-space-size=4096 ${NODE_OPTIONS:-}"
88
root=$PWD
99

10+
TMPDIR=${TMPDIR:-$(dirname $(mktemp -u))}
1011
distdir="$PWD/dist"
1112
rm -fr ${distdir}
1213
mkdir -p ${distdir}
1314

14-
scopes=$(lerna ls 2>/dev/null | grep -v "(private)" | cut -d" " -f1 | xargs -n1 -I{} echo "--scope {}" | tr "\n" " ")
15+
# Split out jsii and non-jsii packages. Jsii packages will be built all at once.
16+
# Non-jsii packages will be run individually.
17+
echo "Collecting package list..." >&2
18+
scripts/list-packages $TMPDIR/jsii.txt $TMPDIR/nonjsii.txt
1519

16-
# Run the "cdk-package" script in all modules. For jsii modules, this invokes jsii-pacmak which generates and builds multi-language
17-
# outputs. For non-jsii module, it will just run "npm pack" and place the output in dist/npm
18-
# (which is similar to how pacmak outputs it).
19-
lerna run ${scopes} --sort --concurrency=1 --stream package
20+
# Return lerna scopes from a package list
21+
function lerna_scopes() {
22+
while [[ "${1:-}" != "" ]]; do
23+
echo "--scope $1 "
24+
shift
25+
done
26+
}
27+
28+
echo "Packaging jsii modules" >&2
29+
30+
# Jsii packaging (all at once using jsii-pacmak)
31+
jsii-pacmak \
32+
--verbose \
33+
--outdir $distdir/ \
34+
$(cat $TMPDIR/jsii.txt)
35+
36+
# Non-jsii packaging, which means running 'package' in every individual
37+
# module and rsync'ing the result to the shared dist directory.
38+
echo "Packaging non-jsii modules" >&2
39+
lerna run $(lerna_scopes $(cat $TMPDIR/nonjsii.txt)) --sort --concurrency=1 --stream package
2040

21-
# Collect dist/ from all modules into the root dist/
22-
for dir in $(find packages -name dist | grep -v node_modules); do
41+
for dir in $(find packages -name dist | grep -v node_modules | grep -v run-wrappers); do
2342
echo "Merging ${dir} into ${distdir}"
2443
rsync -av $dir/ ${distdir}/
2544
done

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"fs-extra": "^8.1.0",
1818
"jest": "^24.9.0",
1919
"jsii-diff": "^0.20.0",
20+
"jsii-pacmak": "^0.20.0",
2021
"lerna": "^3.18.3",
2122
"nodeunit": "^0.11.3",
2223
"nyc": "^14.1.1",

scripts/check-api-compatibility.sh

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,38 +9,56 @@ package_name() {
99
node -pe "require('$1/package.json').name"
1010
}
1111

12+
# Determine whether an NPM package exists on NPM
13+
#
14+
# Doesn't use 'npm view' as that is slow. Direct curl'ing npmjs is better
15+
package_exists_on_npm() {
16+
curl -I 2>/dev/null https://registry.npmjs.org/$1 | head -n 1 | grep 200 >/dev/null
17+
}
18+
19+
1220
#----------------------------------------------------------------------
1321

14-
echo "Listing packages..." >&2
15-
package_dirs=()
16-
package_names=()
17-
for dir in $(npx lerna ls -p); do
18-
if [[ -f $dir/.jsii ]]; then
19-
package_dirs+=("$dir")
20-
package_names+=("$(package_name $dir)")
21-
fi
22-
done
22+
list_jsii_packages() {
23+
echo "Listing jsii packages..." >&2
24+
for dir in $(npx lerna ls -p); do
25+
if [[ -f $dir/.jsii ]]; then
26+
echo "$dir"
27+
fi
28+
done
29+
}
30+
jsii_package_dirs=$(list_jsii_packages)
2331

2432
#----------------------------------------------------------------------
2533

34+
# Input a directory, output the package name IF it exists on GitHub
35+
dirs_to_existing_names() {
36+
local dir="$1"
37+
local name=$(package_name "$dir")
38+
if package_exists_on_npm $name; then
39+
echo "$name"
40+
echo -n "." >&2
41+
else
42+
echo -n "x" >&2
43+
fi
44+
}
45+
46+
export -f package_name
47+
export -f package_exists_on_npm
48+
export -f dirs_to_existing_names
49+
50+
2651
if ! ${SKIP_DOWNLOAD:-false}; then
2752
echo "Filtering on existing packages on NPM..." >&2
28-
for i in ${!package_dirs[@]}; do
29-
echo -n "${package_names[$i]}... "
30-
if npm view --loglevel silent ${package_names[$i]} > /dev/null; then
31-
echo "Exists."
32-
else
33-
echo "NEW."
34-
unset 'package_names[i]'
35-
unset 'package_dirs[i]'
36-
fi
37-
done
53+
# In parallel
54+
existing_names=$(echo "$jsii_package_dirs" | xargs -n1 -P4 -I {} bash -c 'dirs_to_existing_names "$@"' _ {})
55+
echo " Done." >&2
3856

3957
rm -rf $tmpdir
4058
mkdir -p $tmpdir
4159

4260
echo "Installing from NPM..." >&2
43-
(cd $tmpdir && npm install --prefix $tmpdir ${package_names[@]})
61+
(cd $tmpdir && npm install --prefix $tmpdir $existing_names)
4462
fi
4563

4664
#----------------------------------------------------------------------
@@ -50,14 +68,15 @@ current_version=$(npx lerna ls -pl | head -n 1 | cut -d ':' -f 3)
5068

5169
echo "Checking compatibility..." >&2
5270
success=true
53-
for i in ${!package_dirs[*]}; do
54-
if [[ ! -d $tmpdir/node_modules/${package_names[$i]} ]]; then continue; fi
55-
echo -n "${package_names[$i]}... "
71+
for dir in $jsii_package_dirs; do
72+
name=$(package_name "$dir")
73+
if [[ ! -d $tmpdir/node_modules/$name ]]; then continue; fi
74+
echo -n "$name... "
5675
if npx jsii-diff \
5776
--keys \
5877
--ignore-file ${repo_root}/allowed-breaking-changes.txt \
59-
$tmpdir/node_modules/${package_names[$i]} \
60-
${package_dirs[$i]} \
78+
$tmpdir/node_modules/$name \
79+
$dir \
6180
2>$tmpdir/output.txt; then
6281
echo "OK."
6382
else

scripts/list-packages

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/usr/bin/env node
2+
/**
3+
* Collects all packages in the repository in a way that makes it
4+
* easy to process for packaging.
5+
*/
6+
const child_process = require('child_process');
7+
const fs = require('fs-extra');
8+
const path = require('path');
9+
10+
if (process.argv.length < 4) {
11+
process.stderr.write('Usage: list-packages <jsii file> <nonjsii file>\n');
12+
process.exit(1);
13+
}
14+
15+
child_process.exec('lerna ls --json', { shell: true }, (error, stdout) => {
16+
if (error) {
17+
console.error('Error: ', error);
18+
process.exit(-1);
19+
}
20+
const modules = JSON.parse(stdout.toString('utf8'));
21+
22+
const jsiiDirectories = [];
23+
const nonJsiiNames = [];
24+
25+
for (const module of modules) {
26+
const pkgJson = require(path.join(module.location, 'package.json'));
27+
if (pkgJson.jsii) {
28+
jsiiDirectories.push(module.location);
29+
} else {
30+
nonJsiiNames.push(pkgJson.name);
31+
}
32+
}
33+
34+
fs.writeFileSync(process.argv[2], jsiiDirectories.join('\n'));
35+
fs.writeFileSync(process.argv[3], nonJsiiNames.join('\n'));
36+
});

0 commit comments

Comments
 (0)