Skip to content

Commit

Permalink
feat: node-patches\filesystem patcher. (#1332)
Browse files Browse the repository at this point in the history
  • Loading branch information
soldair authored Nov 22, 2019
1 parent 9802e88 commit 0b2f675
Show file tree
Hide file tree
Showing 26 changed files with 4,399 additions and 1 deletion.
11 changes: 10 additions & 1 deletion WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@

workspace(
name = "build_bazel_rules_nodejs",
managed_directories = {"@npm": ["node_modules"]},
managed_directories = {
"@npm": ["node_modules"],
"@npm_node_patches": ["packages/node-patches/node_modules"],
},
)

load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
Expand Down Expand Up @@ -85,6 +88,12 @@ filegroup(
yarn_lock = "//:yarn.lock",
)

npm_install(
name = "npm_node_patches",
package_json = "//packages/node-patches:package.json",
package_lock_json = "//packages/node-patches:package-lock.json",
)

# Install all Bazel dependencies needed for npm packages that supply Bazel rules
load("@npm//:install_bazel_dependencies.bzl", "install_bazel_dependencies")

Expand Down
3 changes: 3 additions & 0 deletions common.bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
#
# The full list of Bazel options: https://docs.bazel.build/versions/master/command-line-reference.html

# Cache action outputs on disk so they persist across output_base and bazel shutdown (eg. changing branches)
build --disk_cache=~/.cache/bazel-disk-cache

# Bazel will create symlinks from the workspace directory to output artifacts.
# Build results will be placed in a directory called "dist/bin"
# Other directories will be created like "dist/testlogs"
Expand Down
5 changes: 5 additions & 0 deletions internal/node/bazel_require_script.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
// Adapt node programs to run under Bazel
// Meant to be run in a --require hook

if(global.BAZEL_NODE_PATCHES) {
return;
}
global.BAZEL_NODE_PATCHES = true;

const fs = require('fs');
const path = require('path');
const orig = {};
Expand Down
10 changes: 10 additions & 0 deletions packages/node-patches/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
coverage
node_modules
build
.nyc_output
src/*.js
src/*.d.ts
test/**/*.js
test/**/*.d.ts
register.js
register.d.ts
1 change: 1 addition & 0 deletions packages/node-patches/.nycrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"include":["build/src/**","src/**"]}
81 changes: 81 additions & 0 deletions packages/node-patches/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# 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.

load("@build_bazel_rules_nodejs//:tools/defaults.bzl", "npm_package")
load("@npm_node_patches//mocha:index.bzl", "mocha_test")
load("@npm_node_patches//typescript:index.bzl", "tsc")

package(default_visibility = ["//visibility:public"])

filegroup(
name = "node-patches",
srcs = [
"package.json",
":compile",
],
)

npm_package(
name = "npm_package",
srcs = [
"README.md",
],
deps = [
":node-patches",
],
)

sources = glob(
[
"src/*.ts",
],
exclude = ["src/*.d.ts"],
) + ["register.ts"]

tests = glob(
["test/**/*.ts"],
exclude = ["test/**/*.d.ts"],
)

tsc(
name = "compile",
# TODO: we ought to compile tests separately?
outs = [s.replace(".ts", ext) for ext in [
".js",
".d.ts",
] for s in sources + tests],
args = [
"-p",
"$(location tsconfig-bazel.json)",
"--outDir",
"$@",
],
data = sources + tests + [
"tsconfig-bazel.json",
"@npm_node_patches//:node_modules",
],
)

test_js = [s.replace(".ts", ".js") for s in tests]

mocha_test(
name = "unit_test",
args = ["$(location %s)" % s for s in test_js],
data = test_js + [s.replace(".ts", ".js") for s in sources] + [
"@npm_node_patches//:node_modules",
],
tags = [
"fix-windows",
],
)
52 changes: 52 additions & 0 deletions packages/node-patches/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# @bazel/node-patches

Runtime modifications to nodejs internals to help node/npm distributed programs run in bazel

## fs

patch any `fs` like object such that symlinks that point outside a specified directory seem to be their targets instead of links

### example

```js
const fs = require('fs')
const path = require('path')
const patcher = require('@bazel/node-patches')

patcher.fs(fs,'/my/files')

fs.symlinkSync(path.resolve('./node_modules'),'/my/files/node_modules')

// now try to stat.

const stat = fs.lstatSync('/my/files/node_modules')

console.log(stat.isSymbolicLink() === false)// true

console.log(stat.isDirectory() === true) //true

```

this should not change the behavior of any paths that are outside of the root.

### loader

you can use the register script to include it in a -r flag to preload the patch before user code.
This depends on setting the environment variable BAZEL_PATCH_ROOT

```sh
BAZEL_PATCH_ROOT=~/.cache/bazel node -r @bazel/node-patches/register <your app js>
```

### api

`{fs} = require('@bazel/node-patches')`
- fs(fsLikeObject: require('fs'), root:string)

## bazel

to use this package as a dependency in bazel depend on it's exposed file group rule.

`:node_patches`

this filegroup will always expose one or more files needed to run this package and will not depend on npm install etc.
Loading

0 comments on commit 0b2f675

Please sign in to comment.