Is there a way to convert a tar target (created using rules_pkg) and turn it into a zip target in Bazel?
pkg_tar(
name = "bundle-tar",
srcs = [
":aws-lambda",
],
include_runfiles = True,
package_dir = "/",
)
pkg_zip(
name = "bundle-zip",
srcs = [
":bundle-tar", # ???
],
)
I imagine this could be accomplished using #bazel_tools//tools/zip:zipper?
This kind of works, but it is not deterministic:
genrule(
name = "bundle-zip",
srcs = [ ':bundle-tar' ],
outs = [ "bundle.zip" ],
cmd = " && ".join([
"tar xf $(location :bundle-tar)",
"zip $# $$(tar tf $(location :bundle-tar))",
]),
)
load("#bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "rules_pkg",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/rules_pkg/releases/download/0.7.0/rules_pkg-0.7.0.tar.gz",
"https://github.com/bazelbuild/rules_pkg/releases/download/0.7.0/rules_pkg-0.7.0.tar.gz",
],
sha256 = "8a298e832762eda1830597d64fe7db58178aa84cd5926d76d5b744d6558941c2",
)
load("#rules_pkg//:deps.bzl", "rules_pkg_dependencies")
rules_pkg_dependencies()
Please refer to this issue for a detailed explanation on how to convert tar to zip files. Thank you.
Related
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?
I am using bazel 3.7.2.
I am getting this error
error loading package '#maven//': Unable to find package for #io_bazel_stardoc//stardoc:stardoc.bzl: The repository '#io_bazel_stardoc' could not be resolved.
This is my workspace
load("#bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "bazel_skylib",
urls = [
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.0.3/bazel-skylib-1.0.3.tar.gz",
],
sha256 = "1c531376ac7e5a180e0237938a2536de0c54d93f5c278634818e0efc952dd56c",
)
load("#bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
bazel_skylib_workspace()
RULES_JVM_EXTERNAL_TAG = "4.0"
RULES_JVM_EXTERNAL_SHA = "31701ad93dbfe544d597dbe62c9a1fdd76d81d8a9150c2bf1ecf928ecdf97169"
http_archive(
name = "maven",
strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
sha256 = RULES_JVM_EXTERNAL_SHA,
url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
)
load("#maven//:defs.bzl", "maven_install")
maven_install(
artifacts = [
"com.fasterxml.jackson.core:jackson-databind:2.12.1",
"org.apache.commons:commons-lang3:3.11"
],
repositories = [
"https://repo1.maven.org/maven2",
"https://jcenter.bintray.com/"
],
);
I found the solution
git_repository(
name = "io_bazel_stardoc",
remote = "https://github.com/bazelbuild/stardoc.git",
tag = "0.4.0",
)
load("#io_bazel_stardoc//:setup.bzl", "stardoc_repositories")
stardoc_repositories()
essentially all I want is cp -r src/ dist/, but for some reason I simply cannot get this to work.
Currently I am trying:
filegroup(
name = "src_files",
srcs = glob([
"src/**",
]),
)
filegroup(
name = "dist_files",
srcs = glob([
"dist/**"
]),
)
genrule(
name = "copy",
srcs = ["//packages/variables:src_files"],
outs = ["//packages/variables:dist_files"],
cmd = "cp -R $(locations //packages/variables:src_files) $(locations //packages/variables:dist_files)"
)
I've gone through at least 4 pages of google and the docs, but it seems unless I create a genrule and manually specify all 100 files in the rule it won't work?
#JamesSharpe had what I was missing, updated the BUILD file to:
filegroup(
name = "src_files",
srcs = glob([
"src/**",
]),
)
pkg_tar(
name = "pack_srcs",
extension = "tar.gz",
srcs = [":src_files"],
)
genrule(
name = "unpack_to_dist",
srcs = [":pack_srcs"],
outs = ["dist"],
cmd = "mkdir $(RULEDIR)/dist && tar -C $(RULEDIR)/dist -zxvf $(SRCS)"
)
And was able to successfully pass this on to the downstream rule.
I'm trying to create a macro in Bazel to wrap java_test to run testng, however I'm running into trouble passing TestNG the filename
So far I have
load("#bazel_skylib//:lib.bzl", "paths")
def java_testng(file, deps=[], **kwargs):
native.java_test(
name = paths.split_extension(file)[0],
srcs = [file],
use_testrunner=False,
main_class='org.testng.TestNG',
deps = [
"//third_party:org_testng_testng"
] + deps,
args=[file],
**kwargs
)
However args seems to be a non-existent runfile.
Help appreciated on the correct value for args
Here is a sample usage I would like
java_testng(
file = "SomeFakeTest.java",
deps = [
"//:resources",
"//third_party:com_fasterxml_jackson_core_jackson_databind",
"//third_party:org_assertj_assertj_core",
],
)
Here is the solution I came up with
load("#bazel_skylib//:lib.bzl", "paths")
def java_testng(file, deps=[], size="small", **kwargs):
native.java_library(
name = paths.split_extension(file)[0] + "-lib",
deps = [
"//third_party:org_testng_testng"
] + deps,
srcs = [file]
)
native.java_test(
name = paths.split_extension(file)[0],
use_testrunner=False,
main_class='org.testng.TestNG',
runtime_deps = [
"//third_party:org_testng_testng",
paths.split_extension(file)[0] + "-lib"
],
data = [file],
size = size,
args=["-testclass $(location " + file + ")"],
**kwargs
)
I dont know why you used a macro, I manage to call testng without.
See my solution below:
I create my program jar (using some Annotation Processor)
I create my test jar (using some Annotation Processor)
I call testng via java_test().
The alone thing I didn't figure out: how to not hardcode the "libmy-model-test-lib.jar"
java_library(
name = "my-model",
srcs = glob(["src/main/java/**/*.java"]),
resources = glob(["src/main/resources/**"]),
deps = [
"#commons_logging_jar//jar",
":lombok",
":mysema_query",
...
],
)
java_library(
name = "my-model-test-lib",
srcs = glob(["src/test/java/**/*.java"]),
deps = [
"#org_hamcrest_core_jar//jar",
"#commons_logging_jar//jar",
":lombok",
":mysema_query",
...
"#assertj_jar//jar",
"#mockito_jar//jar",
"#testng_jar//jar",
],
)
java_test(
name = "AllTests",
size = "small",
runtime_deps = [
":my-model-test-lib",
":my-model",
"#org_jboss_logging_jar//jar",
"#org_objenesis_jar//jar",
"#com_beust_jcommander//jar",
],
use_testrunner=False,
main_class='org.testng.TestNG',
args=['-testjar','libmy-model-test-lib.jar','-verbose','2'],
)
java_plugin(
name = "lombok_plugin",
processor_class = "lombok.launch.AnnotationProcessorHider$AnnotationProcessor",
deps = ["#lombok_jar//jar"],
)
java_library(
name = "lombok",
exports = ["#lombok_jar//jar"],
exported_plugins = [":lombok_plugin"],
)
java_plugin(
name = "mysema_query_plugin",
processor_class = "com.mysema.query.apt.jpa.JPAAnnotationProcessor",
deps = [
"#querydsl_apt_jar//jar",
"#mysema_codegen_jar//jar",
"#javax_persistence_jar//jar",
"#querydsl_codegen_jar//jar",
"#guava_jar//jar",
"#querydsl_core_jar//jar",
"#javax_inject_jar//jar",
],
)
java_library(
name = "mysema_query",
exports = ["#querydsl_apt_jar//jar"],
exported_plugins = [":mysema_query_plugin"],
)
java_plugin(
name = "mockito_plugin",
processor_class = "",
deps = ["#mockito_jar//jar"],
)
java_library(
name = "mockito",
exports = ["#mockito_jar//jar"],
exported_plugins = [":mockito_plugin"],
)
I have many BUILD files that require Jetty or other common Java libraries (SLF4J, Lucene, Guava, etc.). Each of these has a set of other JARs that it references. I would like to know the best practice for organizing these declarations and their dependencies in a large project.
For example, using generate_workspace via bazel run //src/tools/generate_workspace -- --artifact=org.eclipse.jetty:jetty-server:9.3.8.v20160314 I get the following BUILD
# The following dependencies were calculated from:
# org.eclipse.jetty:jetty-server:9.3.8.v20160314
java_library(
name = "org_eclipse_jetty_jetty_http",
visibility = ["//visibility:public"],
exports = [
"#org_eclipse_jetty_jetty_http//jar",
"#org_eclipse_jetty_jetty_util//jar",
],
)
java_library(
name = "org_eclipse_jetty_jetty_util",
visibility = ["//visibility:public"],
exports = [
"#org_eclipse_jetty_jetty_util//jar",
],
)
java_library(
name = "javax_servlet_javax_servlet_api",
visibility = ["//visibility:public"],
exports = [
"#javax_servlet_javax_servlet_api//jar",
],
)
java_library(
name = "org_eclipse_jetty_jetty_server",
visibility = ["//visibility:public"],
exports = [
"#org_eclipse_jetty_jetty_server//jar",
"#javax_servlet_javax_servlet_api//jar",
"#org_eclipse_jetty_jetty_http//jar",
"#org_eclipse_jetty_jetty_io//jar",
"#org_eclipse_jetty_jetty_util//jar",
],
)
java_library(
name = "org_eclipse_jetty_jetty_io",
visibility = ["//visibility:public"],
exports = [
"#org_eclipse_jetty_jetty_io//jar",
"#org_eclipse_jetty_jetty_util//jar",
],
)
and WORKSPACE
# The following dependencies were calculated from:
# org.eclipse.jetty:jetty-server:9.3.8.v20160314
# org.eclipse.jetty:jetty-server:jar:9.3.8.v20160314
maven_jar(
name = "org_eclipse_jetty_jetty_http",
artifact = "org.eclipse.jetty:jetty-http:9.3.8.v20160314",
)
# org.eclipse.jetty:jetty-http:jar:9.3.8.v20160314
# org.eclipse.jetty:jetty-io:jar:9.3.8.v20160314
maven_jar(
name = "org_eclipse_jetty_jetty_util",
artifact = "org.eclipse.jetty:jetty-util:9.3.8.v20160314",
)
# org.eclipse.jetty:jetty-server:jar:9.3.8.v20160314
maven_jar(
name = "javax_servlet_javax_servlet_api",
artifact = "javax.servlet:javax.servlet-api:3.1.0",
)
maven_jar(
name = "org_eclipse_jetty_jetty_server",
artifact = "org.eclipse.jetty:jetty-server:9.3.8.v20160314",
)
# org.eclipse.jetty:jetty-server:jar:9.3.8.v20160314
maven_jar(
name = "org_eclipse_jetty_jetty_io",
artifact = "org.eclipse.jetty:jetty-io:9.3.8.v20160314",
)
files.
I have a dependency on jetty-server and jetty-util in many projects. Is there a better practice than repeating this information in each BUILD file?
Generally you'd put the generate_workspace-generated BUILD file in the root of your workspace (next to your WORKSPACE file) and then, in other BUILD files, you'd reference whatever target they needed to depend on. For example, in src/main/java/com/your-project/subcomponent/BUILD, you might say:
java_library(
name = "my-servlet",
srcs = glob(["*.java"]),
deps = [
"//:javax_servlet_javax_servlet_api",
# other deps...
],
)