Skip to content

Commit d6895cb

Browse files
committed
start of bootstrap prototype
1 parent c8120d9 commit d6895cb

5 files changed

Lines changed: 199 additions & 0 deletions

File tree

‎internal/bootstrap/BUILD.bazel‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Marker file indicating this directory is a Bazel package

‎internal/bootstrap/README.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Bootstrap
2+
3+
The bootstrap workspace provides the nodejs, npm, and yarn binaries.
4+
Users have to put this in their WORKSPACE manually to get started.

‎internal/bootstrap/WORKSPACE‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
workspace(name = "build_bazel_rules_nodejs_bootstrap")
2+

‎internal/bootstrap/defs.bzl‎

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
# Copyright 2017 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Install NodeJS when the user runs node_repositories() from their WORKSPACE.
16+
17+
We fetch a specific version of Node, to ensure builds are hermetic.
18+
We then create a repository @nodejs which provides the
19+
node binary to other rules.
20+
"""
21+
22+
load(":node_labels.bzl", "get_node_label")
23+
24+
def _node_impl(repository_ctx):
25+
os_name = repository_ctx.os.name.lower()
26+
if os_name.startswith("mac os"):
27+
repository_ctx.download_and_extract(
28+
[
29+
"https://mirror.bazel.build/nodejs.org/dist/v8.9.1/node-v8.9.1-darwin-x64.tar.gz",
30+
"https://nodejs.org/dist/v8.9.1/node-v8.9.1-darwin-x64.tar.gz",
31+
],
32+
stripPrefix = "node-v8.9.1-darwin-x64",
33+
sha256 = "05c992a6621d28d564b92bf3051a5dc0adf83839237c0d4653a8cdb8a1c73b94"
34+
)
35+
elif os_name.find("windows") != -1:
36+
repository_ctx.download_and_extract(
37+
[
38+
"https://mirror.bazel.build/nodejs.org/dist/v8.9.1/node-v8.9.1-win-x64.zip",
39+
"http://nodejs.org/dist/v8.9.1/node-v8.9.1-win-x64.zip",
40+
],
41+
stripPrefix = "node-v8.9.1-win-x64",
42+
sha256 = "db89c6e041da359561fbe7da075bb4f9881a0f7d3e98c203e83732cfb283fa4a"
43+
)
44+
else:
45+
repository_ctx.download_and_extract(
46+
[
47+
"https://mirror.bazel.build/nodejs.org/dist/v8.9.1/node-v8.9.1-linux-x64.tar.xz",
48+
"http://nodejs.org/dist/v8.9.1/node-v8.9.1-linux-x64.tar.xz",
49+
],
50+
stripPrefix = "node-v8.9.1-linux-x64",
51+
sha256 = "8be82805f7c1ab3e64d4569fb9a90ded2de78dd27cadbb91bad1bf975dae1e2d"
52+
)
53+
if os_name.lower().find("windows") != -1:
54+
# The windows distribution of nodejs has the binaries in different paths
55+
node = "node.exe"
56+
npm = "node_modules/npm/bin/npm-cli.js"
57+
else:
58+
node = "bin/node"
59+
npm = "bin/npm"
60+
repository_ctx.file("BUILD.bazel", content="""#Generated by node_repositories.bzl
61+
package(default_visibility = ["//visibility:public"])
62+
exports_files(["{0}", "run_npm.sh.template"])
63+
alias(name = "node", actual = "{0}")
64+
sh_binary(
65+
name = "npm",
66+
srcs = ["npm.sh"],
67+
)
68+
""".format(node))
69+
70+
# `yarn publish` is not ready for use under Bazel, see https://github.com/yarnpkg/yarn/issues/610
71+
repository_ctx.file("run_npm.sh.template", content="""
72+
NODE="{}"
73+
NPM="{}"
74+
"$NODE" "$NPM" TMPL_args "$@"
75+
""".format(repository_ctx.path(node), repository_ctx.path(npm)))
76+
77+
repository_ctx.file("npm.sh", content="""#!/bin/bash
78+
#Generated by node_repositories.bzl
79+
""" + "".join(["""
80+
ROOT="{}"
81+
NODE="{}"
82+
SCRIPT="{}"
83+
(cd "$ROOT"; "$NODE" "$SCRIPT" "$@")
84+
""".format(
85+
repository_ctx.path(package_json).dirname,
86+
repository_ctx.path(node),
87+
repository_ctx.path(npm))
88+
for package_json in repository_ctx.attr.package_json]), executable = True)
89+
90+
_node_repo = repository_rule(
91+
_node_impl,
92+
attrs = { "package_json": attr.label_list() },
93+
)
94+
95+
# def _write_node_modules_impl(repository_ctx):
96+
# WORKAROUND for https://github.com/bazelbuild/bazel/issues/374#issuecomment-296217940
97+
# Bazel does not allow labels to start with `@`, so when installing eg. the `@types/node`
98+
# module from the @types scoped package, you'll get an error.
99+
# The workaround is to move the rule up one level, from /node_modules to the project root.
100+
# For now, users must instead write their own /BUILD file on setup.
101+
102+
# repository_ctx.symlink(project_dir.get_child("node_modules"), "node_modules")
103+
# add a BUILD file inside the user's node_modules project folder
104+
# repository_ctx.file("installed/BUILD", """
105+
# filegroup(name = "node_modules", srcs = glob(["node_modules/**/*"]), visibility = ["//visibility:public"])
106+
# """)
107+
108+
# _write_node_modules = repository_rule(
109+
# _write_node_modules_impl,
110+
# attrs = { "package_json": attr.label() },
111+
# )
112+
113+
def _yarn_impl(repository_ctx):
114+
# Yarn is a package manager that downloads dependencies. Yarn is an improvement over the `npm` tool in
115+
# speed and correctness. We download a specific version of Yarn to ensure a hermetic build.
116+
repository_ctx.file("BUILD.bazel", content="""#Generated by node_repositories.bzl
117+
package(default_visibility = ["//visibility:public"])
118+
exports_files(["bin/yarn.js"])
119+
sh_binary(
120+
name = "yarn",
121+
srcs = ["yarn.sh"],
122+
)
123+
""")
124+
node = get_node_label(repository_ctx)
125+
126+
repository_ctx.file("yarn.sh", content="""#!/bin/bash
127+
#Generated by node_repositories.bzl
128+
""" + "".join(["""
129+
NODE="{}"
130+
SCRIPT="{}"
131+
ROOT="{}"
132+
"$NODE" "$SCRIPT" --cwd "$ROOT" "$@"
133+
""".format(
134+
repository_ctx.path(node),
135+
repository_ctx.path("bin/yarn.js"),
136+
repository_ctx.path(package_json).dirname)
137+
for package_json in repository_ctx.attr.package_json]), executable = True)
138+
repository_ctx.download_and_extract(
139+
[
140+
"https://mirror.bazel.build/github.com/yarnpkg/yarn/releases/download/v1.3.2/yarn-v1.3.2.tar.gz",
141+
"https://github.com/yarnpkg/yarn/releases/download/v1.3.2/yarn-v1.3.2.tar.gz",
142+
],
143+
stripPrefix = "yarn-v1.3.2",
144+
sha256 = "6cfe82e530ef0837212f13e45c1565ba53f5199eec2527b85ecbcd88bf26821d"
145+
)
146+
147+
_yarn_repo = repository_rule(
148+
_yarn_impl,
149+
attrs = { "package_json": attr.label_list() },
150+
)
151+
152+
def node_repositories(package_json):
153+
"""To be run in user's WORKSPACE to install NodeJS and rules_nodejs npm dependencies.
154+
"""
155+
156+
_node_repo(name = "nodejs", package_json = package_json)
157+
158+
_yarn_repo(name = "yarn", package_json = package_json)

‎internal/bootstrap/node_labels.bzl‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Copyright 2017 The Bazel Authors. All rights reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""Helper functions to get node and npm labels in @nodejs repository.
16+
17+
Labels are different on windows and linux/OSX.
18+
"""
19+
20+
def get_node_label(repository_ctx):
21+
if repository_ctx.os.name.lower().find("windows") != -1:
22+
# The windows distribution of nodejs has the binaries in different paths
23+
node = Label("@nodejs//:node.exe")
24+
else:
25+
node = Label("@nodejs//:bin/node")
26+
return node
27+
28+
def get_npm_label(repository_ctx):
29+
if repository_ctx.os.name.lower().find("windows") != -1:
30+
# The windows distribution of nodejs has the binaries in different paths
31+
npm = Label("@nodejs//:node_modules/npm/bin/npm-cli.js")
32+
else:
33+
npm = Label("@nodejs//:bin/npm")
34+
return npm

0 commit comments

Comments
 (0)