Skip to content

Commit 7674456

Browse files
authored
Add post_install argument to yarn_modules rule (#56)
Fixes #55
1 parent e383505 commit 7674456

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ node_module(
114114
| --- | --- | --- | --- |
115115
| optional | `label` | `package_json` | A `package.json` file containing the dependencies that should be installed. |
116116
| optional | `string_dict` | `deps` | A mapping of `name` --> `version` for the dependencies that should be installed. |
117+
| optional | `string_list` | `post_install` | A list of command-line arguments that should be invoked after the `yarn install` step. See [#55](https://github.com/pubref/rules_node/issues/55). |
117118

118119
> Either `package_json` or `deps` must be present, but not both.
119120
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
'use strict';
2+
3+
const fs = require('fs');
4+
const path = require('path')
5+
6+
// Yes, could look for BUILD files also, but wait for that error to
7+
// occur before fixing it.
8+
visitSync('node_modules/', filename => {
9+
if (filename.endsWith("BUILD.bazel")) {
10+
fs.unlink(filename);
11+
console.log("Removed", filename, "from the node_modules/ tree");
12+
}
13+
});
14+
15+
function visitSync(d, visitFn) {
16+
if (fs.statSync(d).isDirectory()) {
17+
fs.readdirSync(d).forEach(name => visitSync(path.join(d, name), visitFn));
18+
} else {
19+
visitFn(d);
20+
}
21+
}
22+
23+

node/internal/yarn_modules.bzl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def _yarn_modules_impl(ctx):
3232
node = ctx.path(node_label)
3333

3434
parse_yarn_lock_js = ctx.path(ctx.attr._parse_yarn_lock_js)
35+
clean_node_modules_js = ctx.path(ctx.attr._clean_node_modules_js)
3536
yarn_js = ctx.path(ctx.attr._yarn_js)
3637

3738

@@ -53,6 +54,7 @@ def _yarn_modules_impl(ctx):
5354

5455
# Copy the parse_yarn_lock script and yarn.js over here.
5556
execute(ctx, ["cp", parse_yarn_lock_js, "internal/parse_yarn_lock.js"])
57+
execute(ctx, ["cp", clean_node_modules_js, "internal/clean_node_modules.js"])
5658
execute(ctx, ["cp", yarn_js, "yarn.js"])
5759

5860
install_path = [node.dirname]
@@ -68,9 +70,32 @@ def _yarn_modules_impl(ctx):
6870
"PATH": ":".join(install_path),
6971
})
7072

73+
# Sadly, pre-existing BUILD.bazel files located in npm modules can
74+
# screw up package boudaries. Remove these.
75+
execute(ctx, [node, "internal/clean_node_modules.js"], quiet = True)
76+
7177
# Run the script and save the stdout to our BUILD file(s)
7278
parse_args = ["--resolve=%s:%s" % (k, v) for k, v in ctx.attr.resolutions.items()]
7379
result = execute(ctx, [node, "internal/parse_yarn_lock.js"] + parse_args, quiet = True)
80+
81+
# If the user has specified a post_install step, build those args
82+
# and execute it.
83+
post_install_args = []
84+
for arg in ctx.attr.post_install:
85+
if arg == "{node}":
86+
post_install_args.append(node)
87+
else:
88+
post_install_args.append(arg)
89+
if len(post_install_args) > 0:
90+
# Expose python, node, and basic tools by default. Might need
91+
# to add a post_install_tools option in the future if this is
92+
# not sufficient.
93+
python = ctx.which("python")
94+
mkdir = ctx.which("mkdir")
95+
execute(ctx, post_install_args, environment = {
96+
"PATH": ":".join([node.dirname, python.dirname, mkdir.dirname, "$PATH"])
97+
})
98+
7499
ctx.file("BUILD.bazel", result.stdout)
75100

76101

@@ -96,6 +121,10 @@ yarn_modules = repository_rule(
96121
default = Label("//node:internal/parse_yarn_lock.js"),
97122
single_file = True,
98123
),
124+
"_clean_node_modules_js": attr.label(
125+
default = Label("//node:internal/clean_node_modules.js"),
126+
single_file = True,
127+
),
99128
"_yarn_js": attr.label(
100129
default = Label("@yarn//:bin/yarn.js"),
101130
single_file = True,
@@ -107,6 +136,7 @@ yarn_modules = repository_rule(
107136
mandatory = False,
108137
allow_files = FileType(["package.json"]),
109138
),
139+
"post_install": attr.string_list(),
110140
"deps": attr.string_dict(mandatory = False),
111141
"resolutions": attr.string_dict(mandatory = False),
112142
}

0 commit comments

Comments
 (0)