Skip to content

Commit

Permalink
Clean packages from yarn cache in process_package_json step of yarn_i…
Browse files Browse the repository at this point in the history
…nstall that have file:// URIs
  • Loading branch information
gregmagolan committed Apr 2, 2019
1 parent b366e0e commit 57c1371
Show file tree
Hide file tree
Showing 11 changed files with 156 additions and 41 deletions.
19 changes: 15 additions & 4 deletions e2e/define_var/WORKSPACE
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
workspace(name = "examples_define_var")
# Copyright 2017 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

workspace(name = "e2e_define_var")

# In your code, you'd fetch this repository with an `http_archive` call.
# We do this local repository only because this example lives in the same
# repository with the rules_nodejs code and we want to test them together.
local_repository(
name = "build_bazel_rules_nodejs",
path = "../../dist/build_bazel_rules_nodejs/release",
Expand Down
23 changes: 15 additions & 8 deletions e2e/tsconfig_extends/WORKSPACE
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
workspace(name = "examples_tsconfig_extends")
# Copyright 2017 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

workspace(name = "e2e_tsconfig_extends")

# In your code, you'd fetch this repository with an `http_archive` call.
# We do this local repository only because this example lives in the same
# repository with the rules_nodejs code and we want to test them together.
local_repository(
name = "build_bazel_rules_nodejs",
path = "../../dist/build_bazel_rules_nodejs/release",
)

load("@build_bazel_rules_nodejs//:defs.bzl", "yarn_install")

# This runs yarn install, then our generate_build_file.js to create BUILD files
# inside the resulting node_modules directory.
# The name "npm" here means the resulting modules are referenced like
# @npm//jasmine
yarn_install(
name = "npm",
package_json = "//:package.json",
Expand Down
10 changes: 8 additions & 2 deletions internal/npm_install/npm_install.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,10 @@ cd "{root}" && "{npm}" {npm_args}
_add_data_dependencies(repository_ctx)
_add_scripts(repository_ctx)

result = repository_ctx.execute([node, "process_package_json.js", ",".join(repository_ctx.attr.exclude_packages)])
result = repository_ctx.execute(
[node, "process_package_json.js", "npm", ",".join(repository_ctx.attr.exclude_packages)],
quiet = repository_ctx.attr.quiet,
)
if result.return_code:
fail("node failed: \nSTDOUT:\n%s\nSTDERR:\n%s" % (result.stdout, result.stderr))

Expand Down Expand Up @@ -249,7 +252,10 @@ def _yarn_install_impl(repository_ctx):
_add_data_dependencies(repository_ctx)
_add_scripts(repository_ctx)

result = repository_ctx.execute([node, "process_package_json.js", ",".join(repository_ctx.attr.exclude_packages)])
result = repository_ctx.execute(
[node, "process_package_json.js", "yarn", ",".join(repository_ctx.attr.exclude_packages)],
quiet = repository_ctx.attr.quiet,
)
if result.return_code:
fail("node failed: \nSTDOUT:\n%s\nSTDERR:\n%s" % (result.stdout, result.stderr))

Expand Down
65 changes: 61 additions & 4 deletions internal/npm_install/process_package_json.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@
'use strict';

const fs = require('fs');
const path = require('path');
const child_process = require('child_process');

const DEBUG = false;

const args = process.argv.slice(2);
const removePackages = args[0] ? args[0].split(',') : [];
const packageManager = args[0];
const excludePackages = args[1] ? args[1].split(',') : [];

if (require.main === module) {
main();
Expand All @@ -36,9 +39,26 @@ if (require.main === module) {
* Main entrypoint.
*/
function main() {
const isYarn = (packageManager === 'yarn');

const pkg = JSON.parse(fs.readFileSync('_package.json', {encoding: 'utf8'}));

removePackages.forEach(p => {
if (DEBUG) console.error(`Pre-processing package.json`);

removeExcludedPackages(pkg);

if (isYarn) {
// Work-around for https://github.com/yarnpkg/yarn/issues/2165
// Note: there is no equivalent npm functionality to clean out individual packages
// from the npm cache.
clearYarnFilePathCaches(pkg);
}

fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2));
}

function removeExcludedPackages(pkg) {
excludePackages.forEach(p => {
if (pkg.dependencies) {
delete pkg.dependencies[p];
}
Expand All @@ -52,8 +72,45 @@ function main() {
delete pkg.optionalDependencies[p];
}
});
}

fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2));
/**
* Runs `yarn cache clean` for all packages that have `file://` URIs.
* Work-around for https://github.com/yarnpkg/yarn/issues/2165.
*/
function clearYarnFilePathCaches(pkg) {
const fileRegex = /^file\:\/\//i;
const clearPackages = [];

if (pkg.dependencies) {
Object.keys(pkg.dependencies).forEach(p => {
if (pkg.dependencies[p].match(fileRegex)) {
clearPackages.push(p);
}
});
}
if (pkg.devDependencies) {
Object.keys(pkg.devDependencies).forEach(p => {
if (pkg.devDependencies[p].match(fileRegex)) {
clearPackages.push(p);
}
});
}
if (pkg.optionalDependencies) {
Object.keys(pkg.optionalDependencies).forEach(p => {
if (pkg.optionalDependencies[p].match(fileRegex)) {
clearPackages.push(p);
}
});
}

if (clearPackages.length) {
if (DEBUG) console.error(`Cleaning packages from yarn cache: ${clearPackages.join(' ')}`);

child_process.execFileSync(
'yarn', ['cache', 'clean'].concat(clearPackages),
{stdio: [process.stdin, process.stdout, process.stderr]});
}
}

module.exports = {main};
11 changes: 11 additions & 0 deletions scripts/build_all.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash

set -eu -o pipefail
# -e: exits if a command fails
# -u: errors if an variable is referenced before being set
# -o pipefail: causes a pipeline to produce a failure return code if any command errors

readonly RULES_NODEJS_DIR=$(cd $(dirname "$0")/..; pwd)

${RULES_NODEJS_DIR}/scripts/build_release.sh
${RULES_NODEJS_DIR}/scripts/build_packages_all.sh
2 changes: 0 additions & 2 deletions scripts/build_packages_all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,5 @@ set -eu -o pipefail
readonly RULES_NODEJS_DIR=$(cd $(dirname "$0")/..; pwd)
source "${RULES_NODEJS_DIR}/scripts/packages.sh"

echo_and_run() { echo "+ $@" ; "$@" ; }

${RULES_NODEJS_DIR}/scripts/build_packages.sh ${PACKAGES[@]}

34 changes: 18 additions & 16 deletions scripts/clean_all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,21 @@ echo_and_run rm -rf ./internal/npm_install/test/package/node_modules

echo_and_run bazel clean --expunge

for rootDir in examples e2e internal/e2e packages ; do
(
cd ${rootDir}
for subDir in $(ls) ; do
[[ -d "${subDir}" ]] || continue
(
cd ${subDir}
if [[ -e 'WORKSPACE' ]] ; then
printf "\n\nCleaning /${rootDir}/${subDir}\n"
echo_and_run bazel clean --expunge
echo_and_run rm -rf node_modules
fi
)
done
)
done
${RULES_NODEJS_DIR}/scripts/clean_e2e_all.sh
${RULES_NODEJS_DIR}/scripts/clean_examples_all.sh
${RULES_NODEJS_DIR}/scripts/clean_packages_all.sh

(
cd internal/e2e
for subDir in $(ls) ; do
[[ -d "${subDir}" ]] || continue
(
cd ${subDir}
if [[ -e 'WORKSPACE' ]] ; then
printf "\n\nCleaning /internal/e2e/${subDir}\n"
echo_and_run bazel clean --expunge
echo_and_run rm -rf node_modules
fi
)
done
)
2 changes: 1 addition & 1 deletion scripts/clean_e2e_all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ set -eu -o pipefail
readonly RULES_NODEJS_DIR=$(cd $(dirname "$0")/..; pwd)
readonly E2E_DIR="${RULES_NODEJS_DIR}/e2e"

readonly E2E=$(ls ${E2E_DIR})
readonly E2E=$(ls -l ${E2E_DIR} | grep "^d" | awk -F" " '{print $9}')

${RULES_NODEJS_DIR}/scripts/clean_e2e.sh ${E2E[@]}
2 changes: 1 addition & 1 deletion scripts/clean_examples_all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ set -eu -o pipefail
readonly RULES_NODEJS_DIR=$(cd $(dirname "$0")/..; pwd)
readonly EXAMPLES_DIR="${RULES_NODEJS_DIR}/examples"

readonly EXAMPLES=$(ls ${EXAMPLES_DIR})
readonly EXAMPLES=$(ls -l ${EXAMPLES_DIR} | grep "^d" | awk -F" " '{print $9}')

${RULES_NODEJS_DIR}/scripts/clean_examples.sh ${EXAMPLES[@]}
5 changes: 2 additions & 3 deletions scripts/clean_packages_all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ set -eu -o pipefail
# -o pipefail: causes a pipeline to produce a failure return code if any command errors

readonly RULES_NODEJS_DIR=$(cd $(dirname "$0")/..; pwd)
readonly PACKAGES_DIR="${RULES_NODEJS_DIR}/package"
source "${RULES_NODEJS_DIR}/scripts/packages.sh"

readonly PACKAGES=$(ls ${PACKAGES_DIR})
${RULES_NODEJS_DIR}/scripts/clean_packages.sh ${PACKAGES[@]}

${RULES_NODEJS_DIR}/scripts/clean_package.sh ${PACKAGES[@]}
24 changes: 24 additions & 0 deletions scripts/clean_yarn_cache_selectively.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash

set -eu -o pipefail
# -e: exits if a command fails
# -u: errors if an variable is referenced before being set
# -o pipefail: causes a pipeline to produce a failure return code if any command errors

readonly YARN_CACHE_ROOT=$(dirname $(yarn cache dir))
readonly RULES_NODEJS_DIR=$(cd $(dirname "$0")/..; pwd)
source "${RULES_NODEJS_DIR}/scripts/packages.sh"

echo_and_run() { echo "+ $@" ; "$@" ; }

echo "yarn cache root: ${YARN_CACHE_ROOT}"

for package in ${PACKAGES[@]} ; do
echo_and_run yarn cache clean @bazel/${package}
done

# Also clean cache for different versions of yarn since the locally installed
# yarn may have a different cache version from yarn version used by Bazel
for package in ${PACKAGES[@]} ; do
echo_and_run rm -rf ${YARN_CACHE_ROOT}/*/npm-@bazel-${package}-*
done

0 comments on commit 57c1371

Please sign in to comment.