Skip to content

Commit

Permalink
Add post_install argument to yarn_modules rule (#56)
Browse files Browse the repository at this point in the history
Fixes #55
  • Loading branch information
pcj authored Feb 12, 2018
1 parent e383505 commit 7674456
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ node_module(
| --- | --- | --- | --- |
| optional | `label` | `package_json` | A `package.json` file containing the dependencies that should be installed. |
| optional | `string_dict` | `deps` | A mapping of `name` --> `version` for the dependencies that should be installed. |
| 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). |

> Either `package_json` or `deps` must be present, but not both.
Expand Down
23 changes: 23 additions & 0 deletions node/internal/clean_node_modules.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict';

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

// Yes, could look for BUILD files also, but wait for that error to
// occur before fixing it.
visitSync('node_modules/', filename => {
if (filename.endsWith("BUILD.bazel")) {
fs.unlink(filename);
console.log("Removed", filename, "from the node_modules/ tree");
}
});

function visitSync(d, visitFn) {
if (fs.statSync(d).isDirectory()) {
fs.readdirSync(d).forEach(name => visitSync(path.join(d, name), visitFn));
} else {
visitFn(d);
}
}


30 changes: 30 additions & 0 deletions node/internal/yarn_modules.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def _yarn_modules_impl(ctx):
node = ctx.path(node_label)

parse_yarn_lock_js = ctx.path(ctx.attr._parse_yarn_lock_js)
clean_node_modules_js = ctx.path(ctx.attr._clean_node_modules_js)
yarn_js = ctx.path(ctx.attr._yarn_js)


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

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

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

# Sadly, pre-existing BUILD.bazel files located in npm modules can
# screw up package boudaries. Remove these.
execute(ctx, [node, "internal/clean_node_modules.js"], quiet = True)

# Run the script and save the stdout to our BUILD file(s)
parse_args = ["--resolve=%s:%s" % (k, v) for k, v in ctx.attr.resolutions.items()]
result = execute(ctx, [node, "internal/parse_yarn_lock.js"] + parse_args, quiet = True)

# If the user has specified a post_install step, build those args
# and execute it.
post_install_args = []
for arg in ctx.attr.post_install:
if arg == "{node}":
post_install_args.append(node)
else:
post_install_args.append(arg)
if len(post_install_args) > 0:
# Expose python, node, and basic tools by default. Might need
# to add a post_install_tools option in the future if this is
# not sufficient.
python = ctx.which("python")
mkdir = ctx.which("mkdir")
execute(ctx, post_install_args, environment = {
"PATH": ":".join([node.dirname, python.dirname, mkdir.dirname, "$PATH"])
})

ctx.file("BUILD.bazel", result.stdout)


Expand All @@ -96,6 +121,10 @@ yarn_modules = repository_rule(
default = Label("//node:internal/parse_yarn_lock.js"),
single_file = True,
),
"_clean_node_modules_js": attr.label(
default = Label("//node:internal/clean_node_modules.js"),
single_file = True,
),
"_yarn_js": attr.label(
default = Label("@yarn//:bin/yarn.js"),
single_file = True,
Expand All @@ -107,6 +136,7 @@ yarn_modules = repository_rule(
mandatory = False,
allow_files = FileType(["package.json"]),
),
"post_install": attr.string_list(),
"deps": attr.string_dict(mandatory = False),
"resolutions": attr.string_dict(mandatory = False),
}
Expand Down

0 comments on commit 7674456

Please sign in to comment.