Skip to content

Commit

Permalink
feat: add runfiles helpers needed for rules_js (#3)
Browse files Browse the repository at this point in the history
* feat: add runfiles helpers needed for rules_js

* chore: code review feedback
  • Loading branch information
alexeagle authored Nov 10, 2021
1 parent cb8c2ba commit da6fb88
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 3 deletions.
27 changes: 27 additions & 0 deletions docs/paths.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,30 @@ Resolves a relative path between two files, "to_file" and "frm_file", they must
The relative path from frm_file to to_file, including the file name


<a id="#to_manifest_path"></a>

## to_manifest_path

<pre>
to_manifest_path(<a href="#to_manifest_path-ctx">ctx</a>, <a href="#to_manifest_path-file">file</a>)
</pre>

The runfiles manifest entry for a file

We must avoid using non-normalized paths (workspace/../other_workspace/path)
in order to locate entries by their key.


**PARAMETERS**


| Name | Description | Default Value |
| :------------- | :------------- | :------------- |
| <a id="to_manifest_path-ctx"></a>ctx | starlark rule execution context | none |
| <a id="to_manifest_path-file"></a>file | a File object | none |

**RETURNS**

a key that can lookup the path from the runfiles manifest


7 changes: 6 additions & 1 deletion lib/expand_make_vars.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,9 @@ load(

expand_locations = _expand_locations
expand_variables = _expand_variables
expand_template = _expand_template

expand_template = rule(
doc = _expand_template.doc,
implementation = _expand_template.implementation,
attrs = _expand_template.attrs,
)
17 changes: 17 additions & 0 deletions lib/paths.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,20 @@
load("//lib/private:paths.bzl", "paths")

relative_file = paths.relative_file
to_manifest_path = paths.to_manifest_path

# Bash helper function for looking up runfiles.
# See windows_utils.bzl for the cmd.exe equivalent.
# Vendored from
# https://github.com/bazelbuild/bazel/blob/master/tools/bash/runfiles/runfiles.bash
BASH_RLOCATION_FUNCTION = r"""
# --- begin runfiles.bash initialization v2 ---
set -uo pipefail; f=bazel_tools/tools/bash/runfiles/runfiles.bash
source "${RUNFILES_DIR:-/dev/null}/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "${RUNFILES_MANIFEST_FILE:-/dev/null}" | cut -f2- -d' ')" 2>/dev/null || \
source "$0.runfiles/$f" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
source "$(grep -sm1 "^$f " "$0.exe.runfiles_manifest" | cut -f2- -d' ')" 2>/dev/null || \
{ echo>&2 "ERROR: cannot find $f"; exit 1; }; f=; set -e
# --- end runfiles.bash initialization v2 ---
"""
2 changes: 1 addition & 1 deletion lib/private/expand_make_vars.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def _expand_template_impl(ctx):
is_executable = ctx.attr.is_executable,
)

expand_template = rule(
expand_template = struct(
doc = """Template expansion
This performs a simple search over the template file for the keys in substitutions,
Expand Down
20 changes: 20 additions & 0 deletions lib/private/paths.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,26 @@ def _relative_file(to_file, frm_file):
)
)

def _to_manifest_path(ctx, file):
"""The runfiles manifest entry for a file
We must avoid using non-normalized paths (workspace/../other_workspace/path)
in order to locate entries by their key.
Args:
ctx: starlark rule execution context
file: a File object
Returns:
a key that can lookup the path from the runfiles manifest
"""

if file.short_path.startswith("../"):
return file.short_path[3:]
else:
return ctx.workspace_name + "/" + file.short_path

paths = struct(
relative_file = _relative_file,
to_manifest_path = _to_manifest_path,
)
16 changes: 15 additions & 1 deletion lib/tests/paths_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,21 @@ def _relative_file_test_impl(ctx):

return unittest.end(env)

def _runfiles_manifest_test_impl(ctx):
env = unittest.begin(ctx)
asserts.equals(env, "bazel_skylib/LICENSE", paths.to_manifest_path(ctx, ctx.file.f1))
asserts.equals(env, "aspect_bazel_lib/lib/paths.bzl", paths.to_manifest_path(ctx, ctx.file.f2))
return unittest.end(env)

relative_file_test = unittest.make(_relative_file_test_impl)
runfiles_manifest_test = unittest.make(_runfiles_manifest_test_impl,
attrs = {
"f1": attr.label(allow_single_file = True, default = "@bazel_skylib//:LICENSE"),
"f2": attr.label(allow_single_file = True, default = "//lib:paths.bzl"),
})

def paths_test_suite():
unittest.suite("relative_file_tests", relative_file_test)
unittest.suite(
"paths_tests",
relative_file_test,
runfiles_manifest_test)
52 changes: 52 additions & 0 deletions lib/windows_utils.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"Helpers for rules running on windows"

# cmd.exe function for looking up runfiles.
# Equivalent of the BASH_RLOCATION_FUNCTION in paths.bzl.
# Use this to write actions that don't require bash.
# Originally by @meteorcloudy in
# https://github.com/bazelbuild/rules_nodejs/commit/f06553a
BATCH_RLOCATION_FUNCTION = r"""
rem Usage of rlocation function:
rem call :rlocation <runfile_path> <abs_path>
rem The rlocation function maps the given <runfile_path> to its absolute
rem path and stores the result in a variable named <abs_path>.
rem This function fails if the <runfile_path> doesn't exist in mainifest
rem file.
:: Start of rlocation
goto :rlocation_end
:rlocation
if "%~2" equ "" (
echo>&2 ERROR: Expected two arguments for rlocation function.
exit 1
)
if "%RUNFILES_MANIFEST_ONLY%" neq "1" (
set %~2=%~1
exit /b 0
)
if exist "%RUNFILES_DIR%" (
set RUNFILES_MANIFEST_FILE=%RUNFILES_DIR%_manifest
)
if "%RUNFILES_MANIFEST_FILE%" equ "" (
set RUNFILES_MANIFEST_FILE=%~f0.runfiles\MANIFEST
)
if not exist "%RUNFILES_MANIFEST_FILE%" (
set RUNFILES_MANIFEST_FILE=%~f0.runfiles_manifest
)
set MF=%RUNFILES_MANIFEST_FILE:/=\%
if not exist "%MF%" (
echo>&2 ERROR: Manifest file %MF% does not exist.
exit 1
)
set runfile_path=%~1
for /F "tokens=2* usebackq" %%i in (`%SYSTEMROOT%\system32\findstr.exe /l /c:"!runfile_path! " "%MF%"`) do (
set abs_path=%%i
)
if "!abs_path!" equ "" (
echo>&2 ERROR: !runfile_path! not found in runfiles manifest
exit 1
)
set %~2=!abs_path!
exit /b 0
:rlocation_end
:: End of rlocation
"""

0 comments on commit da6fb88

Please sign in to comment.