'Convert http_archive to repository_rule
I'm trying to convert a binary fetching from http_archive:
def purescript_toolchain():
http_archive(
name = "purs",
urls = ["https://github.com/purescript/purescript/releases/download/v0.14.7/linux64.tar.gz"],
sha256 = "cae16a0017c63fd83e029ca5a01cb9fc02cacdbd805b1d2b248f9bb3c3ea926d",
strip_prefix = strip_"purescript",
build_file_content = """exports_files(["purs"])""",
)
To a repository rule based approach:
def _purescript_toolchain_impl(repository_ctx):
repository_ctx.download_and_extract(
url = "https://github.com/purescript/purescript/releases/download/v0.14.7/linux64.tar.gz",
sha256 = "cae16a0017c63fd83e029ca5a01cb9fc02cacdbd805b1d2b248f9bb3c3ea926d",
stripPrefix = "purescript",
)
repository_ctx.file(
"BUILD.bazel",
content = """exports_files(["purs"])""",
)
_purescript_toolchain = repository_rule(
_purescript_toolchain_impl,
configure = True,
environ = ["PATH"],
)
def purescript_toolchain():
_purescript_toolchain(name = "purs")
It seems to work, but when I try to call other functions:
run_template = """
#!/usr/bin/env bash
set -o errexit
node -e "require('./{target_path}/{entry_module}/index.js').{entry_function}({entry_params})"
"""
def _purescript_compile(ctx):
srcs = ctx.files.srcs + ctx.files.deps
target = ctx.actions.declare_file(ctx.outputs.target.basename)
purs = ctx.executable.purs
flags = " ".join(ctx.attr.compiler_flags)
bazel_ps_deps = []
for d in ctx.attr.deps:
for f in d.files.to_list():
if f.basename == "target_srcs":
bazel_ps_deps = [f.path + "/**/*.purs"] + bazel_ps_deps
compileCmd = "\n".join(
[ "set -o errexit"
, """mkdir "$2" """
, """ "$1" compile """ + flags + """ --output "$2" "${@:3}" """
]
)
ctx.actions.run_shell(
tools = srcs + [purs],
outputs = [target],
command = compileCmd,
arguments = [purs.path, target.path] +
[src.path for src in srcs if src.extension == "purs"] +
bazel_ps_deps,
)
cpSrcsCmd = "\n".join(
[ "set -o errexit"
, """mkdir -p "$1" """
, """cp "${@:2}" "$1" """
]
)
target_srcs = ctx.actions.declare_file(ctx.outputs.target_srcs.basename)
ctx.actions.run_shell(
inputs = ctx.files.srcs,
outputs = [target_srcs],
command = cpSrcsCmd,
arguments = [target_srcs.path] + [src.path for src in ctx.files.srcs],
)
return target
def _purescript_tar(ctx):
target = _purescript_compile(ctx)
tar = ctx.actions.declare_file(ctx.outputs.tar.basename)
ctx.actions.run_shell(
inputs = [target],
outputs = [tar],
command = """
set -o errexit
tar --create --file "$1" --directory "$2" .
""",
arguments = [tar.path, target.path],
)
def _purescript_app(ctx):
target = _purescript_compile(ctx)
entry_params = ",".join([
'\\"{entry}\\"'.format(entry=e) for e in ctx.attr.entry_parameters
])
script = ctx.actions.declare_file(ctx.label.name)
script_content = run_template.format(
target_path = target.short_path,
entry_module = getattr(ctx.attr, "entry_module"),
entry_function = getattr(ctx.attr, "entry_function"),
entry_params = entry_params,
)
ctx.actions.write(script, script_content, is_executable = True)
runfiles = ctx.runfiles(files = [target])
return [DefaultInfo(executable = script, runfiles = runfiles)]
purescript_app = rule(
implementation = _purescript_app,
attrs = {
"srcs": attr.label_list(
allow_files = True,
),
"deps": attr.label_list(
default = [],
),
"purs": attr.label(
allow_single_file = True,
executable = True,
cfg = "host",
default = "@purs",
),
"compiler_flags": attr.string_list(
default = []
),
"entry_module": attr.string(
default = "Main",
),
"entry_function": attr.string(
default = "main",
),
"entry_parameters": attr.string_list(
default = [],
),
},
outputs = {
"target": "target",
"target_srcs": "target_srcs",
},
executable = True,
)
Called via:
purescript_app(
name = "ui",
visibility = ["//visibility:public"],
srcs = glob(["src/**/*.purs"]),
)
However, with this new version I get this error:
DEBUG: Repository io_bazel_rules_purescript instantiated at:
.../WORKSPACE:66:13: in <toplevel>
Repository rule http_archive defined at:
~/.cache/bazel/_bazel_black/b6b6a2b95964967dc5a9c8dec827e874/external/bazel_tools/tools/build_defs/repo/http.bzl:336:31: in <toplevel>
INFO: Analyzed target //webui:ui (0 packages loaded, 0 targets configured).
INFO: Found 1 target...
ERROR: .../webui/BUILD.bazel:16:15: Action webui/target failed: (Exit 127): bash failed: error executing command /nix/store/4nmqxajzaf60yjribkgvj5j54x9yvr1r-bash-5.1-p12/bin/bash -c 'set -o errexit
mkdir "$2"
"$1" compile --output "$2" "${@:3}" ' '' external/purs/purs bazel-out/k8-fastbuild/bin/webui/target ... (remaining 98 argument(s) skipped)
Use --sandbox_debug to see verbose messages from the sandbox
: line 3: external/purs/purs: No such file or directory
Target //webui:ui failed to build
Which is surprising since the file exist in the directory (external/purs/purs).
Is their anything to add in the new version?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
