From d7083ac01239af66d545fcecf4145eeaaf0e6143 Mon Sep 17 00:00:00 2001 From: Greg Magolan Date: Wed, 22 Jan 2020 15:42:34 -0800 Subject: [PATCH] fix(builtin): set cwd before running yarn for yarn_install (#1569) Also fix the same for @nodejs//:yarn & @nodejs//:yarn_node_repositories targets. This allows yarn to pickup the `yarn-path` attribute of `.yarnrc` which is only checked inside `${process.cwd()}/.yarnrc` when yarn runs. Previously we running yarn with `--cwd` which works for all other `.yarnrc` options except `yarn-path`. --- internal/node/node_repositories.bzl | 13 +++--- internal/npm_install/npm_install.bzl | 63 +++++++++++++++++++--------- 2 files changed, 50 insertions(+), 26 deletions(-) diff --git a/internal/node/node_repositories.bzl b/internal/node/node_repositories.bzl index 087c9ada7d..f68210a507 100644 --- a/internal/node/node_repositories.bzl +++ b/internal/node/node_repositories.bzl @@ -505,12 +505,12 @@ SET SCRIPT_DIR=%~dp0 # Npm entry point for node_repositories repository_ctx.file("bin/npm_node_repositories.cmd", content = """@echo off +SET SCRIPT_DIR=%~dp0 """ + "".join([ """ -SET SCRIPT_DIR=%~dp0 echo Running npm %* in {root} cd "{root}" -call "%SCRIPT_DIR%\\{node}" "%SCRIPT_DIR%\\{script}" --scripts-prepend-node-path=false %* +CALL "%SCRIPT_DIR%\\{node}" "%SCRIPT_DIR%\\{script}" --scripts-prepend-node-path=false %* if %errorlevel% neq 0 exit /b %errorlevel% """.format( root = repository_ctx.path(package_json).dirname, @@ -557,8 +557,8 @@ set -e # Executes the given yarn command over each of the package.json folders provided in node_repositories. """ + GET_SCRIPT_DIR + "".join([ """ -echo Running yarn --cwd "{root}" "$@" -"$SCRIPT_DIR/{node}" "$SCRIPT_DIR/{script}" --cwd "{root}" "$@" +echo Running yarn "$@" in {root} +(cd "{root}"; "$SCRIPT_DIR/{node}" "$SCRIPT_DIR/{script}" "$@") """.format( root = repository_ctx.path(package_json).dirname, node = paths.relativize(node_entry, "bin"), @@ -585,8 +585,9 @@ SET SCRIPT_DIR=%~dp0 SET SCRIPT_DIR=%~dp0 """ + "".join([ """ -echo Running yarn --cwd "{root}" %* -CALL "%SCRIPT_DIR%\\{node}" "%SCRIPT_DIR%\\{script}" --cwd "{root}" %* +echo Running yarn %* in {root} +cd "{root}" +CALL "%SCRIPT_DIR%\\{node}" "%SCRIPT_DIR%\\{script}" %* if %errorlevel% neq 0 exit /b %errorlevel% """.format( root = repository_ctx.path(package_json).dirname, diff --git a/internal/npm_install/npm_install.bzl b/internal/npm_install/npm_install.bzl index a06d3f8d9a..6442bf8a27 100644 --- a/internal/npm_install/npm_install.bzl +++ b/internal/npm_install/npm_install.bzl @@ -311,9 +311,23 @@ def _yarn_install_impl(repository_ctx): _check_min_bazel_version("yarn_install", repository_ctx) + is_windows_host = is_windows_os(repository_ctx) node = repository_ctx.path(get_node_label(repository_ctx)) yarn = get_yarn_label(repository_ctx) + yarn_args = [] + if not repository_ctx.attr.use_global_yarn_cache: + yarn_args.extend(["--cache-folder", repository_ctx.path("_yarn_cache")]) + else: + # Multiple yarn rules cannot run simultaneously using a shared cache. + # See https://github.com/yarnpkg/yarn/issues/683 + # The --mutex option ensures only one yarn runs at a time, see + # https://yarnpkg.com/en/docs/cli#toc-concurrency-and-mutex + # The shared cache is not necessarily hermetic, but we need to cache downloaded + # artifacts somewhere, so we rely on yarn to be correct. + yarn_args.extend(["--mutex", "network"]) + yarn_args.extend(repository_ctx.attr.args) + # If symlink_node_modules is true then run the package manager # in the package.json folder; otherwise, run it in the root of # the external repository @@ -322,6 +336,34 @@ def _yarn_install_impl(repository_ctx): else: root = repository_ctx.path("") + # The entry points for npm install for osx/linux and windows + if not is_windows_host: + repository_ctx.file( + "yarn", + content = """#!/usr/bin/env bash +# Immediately exit if any command fails. +set -e +(cd "{root}"; "{yarn}" {yarn_args}) +""".format( + root = root, + yarn = repository_ctx.path(yarn), + yarn_args = " ".join(yarn_args), + ), + executable = True, + ) + else: + repository_ctx.file( + "yarn.cmd", + content = """@echo off +cd "{root}" && "{yarn}" {yarn_args} +""".format( + root = root, + yarn = repository_ctx.path(yarn), + yarn_args = " ".join(yarn_args), + ), + executable = True, + ) + if not repository_ctx.attr.symlink_node_modules: repository_ctx.symlink( repository_ctx.attr.yarn_lock, @@ -339,28 +381,9 @@ def _yarn_install_impl(repository_ctx): if result.return_code: fail("pre_process_package_json.js failed: \nSTDOUT:\n%s\nSTDERR:\n%s" % (result.stdout, result.stderr)) - args = [ - repository_ctx.path(yarn), - "--cwd", - root, - ] - - if not repository_ctx.attr.use_global_yarn_cache: - args.extend(["--cache-folder", repository_ctx.path("_yarn_cache")]) - else: - # Multiple yarn rules cannot run simultaneously using a shared cache. - # See https://github.com/yarnpkg/yarn/issues/683 - # The --mutex option ensures only one yarn runs at a time, see - # https://yarnpkg.com/en/docs/cli#toc-concurrency-and-mutex - # The shared cache is not necessarily hermetic, but we need to cache downloaded - # artifacts somewhere, so we rely on yarn to be correct. - args.extend(["--mutex", "network"]) - - args.extend(repository_ctx.attr.args) - repository_ctx.report_progress("Running yarn install on %s" % repository_ctx.attr.package_json) result = repository_ctx.execute( - args, + [repository_ctx.path("yarn.cmd" if is_windows_host else "yarn")], timeout = repository_ctx.attr.timeout, quiet = repository_ctx.attr.quiet, )