# 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. """Install NodeJS when the user runs node_repositories() from their WORKSPACE. We fetch a specific version of Node, to ensure builds are hermetic. We then create a repository @nodejs which provides the node binary to other rules. """ def get_executables(repository_ctx): if repository_ctx.os.name.lower().find("windows") != -1: # The windows distribution of nodejs has the binaries in different paths return {"node": "node.exe", "npm": "npm.cmd"} else: return {"node": "bin/node", "npm": "bin/npm"} def _node_impl(repository_ctx): os_name = repository_ctx.os.name.lower() if os_name.startswith("mac os"): repository_ctx.download_and_extract( [ "https://mirror.bazel.build/nodejs.org/dist/v8.9.1/node-v8.9.1-darwin-x64.tar.gz", "https://nodejs.org/dist/v8.9.1/node-v8.9.1-darwin-x64.tar.gz", ], stripPrefix = "node-v8.9.1-darwin-x64", sha256 = "05c992a6621d28d564b92bf3051a5dc0adf83839237c0d4653a8cdb8a1c73b94" ) elif os_name.find("windows") != -1: repository_ctx.download_and_extract( [ "https://mirror.bazel.build/nodejs.org/dist/v8.9.1/node-v8.9.1-win-x64.zip", "http://nodejs.org/dist/v8.9.1/node-v8.9.1-win-x64.zip", ], stripPrefix = "node-v8.9.1-win-x64", sha256 = "db89c6e041da359561fbe7da075bb4f9881a0f7d3e98c203e83732cfb283fa4a" ) else: repository_ctx.download_and_extract( [ "https://mirror.bazel.build/nodejs.org/dist/v8.9.1/node-v8.9.1-linux-x64.tar.xz", "http://nodejs.org/dist/v8.9.1/node-v8.9.1-linux-x64.tar.xz", ], stripPrefix = "node-v8.9.1-linux-x64", sha256 = "8be82805f7c1ab3e64d4569fb9a90ded2de78dd27cadbb91bad1bf975dae1e2d" ) executables = get_executables(repository_ctx) repository_ctx.file("BUILD.bazel", content="""#Generated by node_install.bzl package(default_visibility = ["//visibility:public"]) exports_files([ "{0}", "{1}", ]) alias(name = "node", actual = "{0}") alias(name = "npm", actual = "{1}") """.format(executables["node"], executables["npm"])) _node_repo = repository_rule(_node_impl, attrs = {}) # def _write_node_modules_impl(ctx): # WORKAROUND for https://github.com/bazelbuild/bazel/issues/374#issuecomment-296217940 # Bazel does not allow labels to start with `@`, so when installing eg. the `@types/node` # module from the @types scoped package, you'll get an error. # The workaround is to move the rule up one level, from /node_modules to the project root. # For now, users must instead write their own /BUILD file on setup. # ctx.symlink(project_dir.get_child("node_modules"), "node_modules") # add a BUILD file inside the user's node_modules project folder # ctx.file("installed/BUILD", """ # filegroup(name = "node_modules", srcs = glob(["node_modules/**/*"]), visibility = ["//visibility:public"]) # """) # _write_node_modules = repository_rule( # _write_node_modules_impl, # attrs = { "package_json": attr.label() }, # ) def _yarn_impl(ctx): # Yarn is a package manager that downloads dependencies. Yarn is an improvement over the `npm` tool in # speed and correctness. We download a specific version of Yarn to ensure a hermetic build. ctx.file("BUILD.bazel", """ package(default_visibility = ["//visibility:public"]) sh_binary( name = "yarn", srcs = ["yarn.sh"], ) """) if ctx.os.name.lower().find("windows") != -1: node = Label("@nodejs//:node.exe") else: node = Label("@nodejs//:bin/node") ctx.file("yarn.sh", "#!/bin/bash" + "".join([""" ROOT="{}" NODE="{}" SCRIPT="{}" (cd "$ROOT"; "$NODE" "$SCRIPT" "$@") """.format( ctx.path(package_json).dirname, ctx.path(node), ctx.path("bin/yarn.js")) for package_json in ctx.attr.package_json]), executable = True) ctx.download_and_extract( [ "https://mirror.bazel.build/github.com/yarnpkg/yarn/releases/download/v1.3.2/yarn-v1.3.2.tar.gz", "https://github.com/yarnpkg/yarn/releases/download/v1.3.2/yarn-v1.3.2.tar.gz", ], stripPrefix = "yarn-v1.3.2", sha256 = "6cfe82e530ef0837212f13e45c1565ba53f5199eec2527b85ecbcd88bf26821d" ) _yarn_repo = repository_rule( _yarn_impl, attrs = { "package_json": attr.label_list() }, ) load(":check_bazel_version.bzl", "check_bazel_version") load(":npm_install.bzl", "npm_install") def node_repositories(package_json): # Windows users need sh_binary wrapped as an .exe check_bazel_version("0.5.4") _node_repo(name = "nodejs") _yarn_repo(name = "yarn", package_json = package_json) npm_install( name = "build_bazel_rules_nodejs_rollup_deps", package_json = "@build_bazel_rules_nodejs//internal/rollup:package.json", )