Skip to content

Commit

Permalink
feat: add copy_to_bin rule
Browse files Browse the repository at this point in the history
  • Loading branch information
gregmagolan committed Apr 12, 2022
1 parent 6e653ca commit 3de67fa
Show file tree
Hide file tree
Showing 11 changed files with 218 additions and 0 deletions.
5 changes: 5 additions & 0 deletions docs/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ stardoc_with_diff_test(
bzl_library_target = "//lib:copy_to_directory",
)

stardoc_with_diff_test(
name = "copy_to_bin",
bzl_library_target = "//lib:copy_to_bin",
)

stardoc_with_diff_test(
name = "docs",
bzl_library_target = "//lib:docs",
Expand Down
38 changes: 38 additions & 0 deletions docs/copy_to_bin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!-- Generated with Stardoc: http://skydoc.bazel.build -->

AA rule that copies source files to the output tree.

This rule uses a Bash command (diff) on Linux/macOS/non-Windows, and a cmd.exe
command (fc.exe) on Windows (no Bash is required).


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

## copy_to_bin

<pre>
copy_to_bin(<a href="#copy_to_bin-name">name</a>, <a href="#copy_to_bin-srcs">srcs</a>, <a href="#copy_to_bin-kwargs">kwargs</a>)
</pre>

Copies a source file to output tree at the same workspace-relative path.

e.g. `<execroot>/path/to/file -> <execroot>/bazel-out/<platform>/bin/path/to/file`

This is useful to populate the output folder with all files needed at runtime, even
those which aren't outputs of a Bazel rule.

This way you can run a binary in the output folder (execroot or runfiles_root)
without that program needing to rely on a runfiles helper library or be aware that
files are divided between the source tree and the output tree.


**PARAMETERS**


| Name | Description | Default Value |
| :------------- | :------------- | :------------- |
| <a id="copy_to_bin-name"></a>name | Name of the rule. | none |
| <a id="copy_to_bin-srcs"></a>srcs | A list of labels. File(s) to copy. | none |
| <a id="copy_to_bin-kwargs"></a>kwargs | further keyword arguments, e.g. <code>visibility</code> | none |


7 changes: 7 additions & 0 deletions lib/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ bzl_library(
deps = ["//lib/private:copy_to_directory"],
)

bzl_library(
name = "copy_to_bin",
srcs = ["copy_to_bin.bzl"],
visibility = ["//visibility:public"],
deps = ["//lib/private:copy_to_bin"],
)

bzl_library(
name = "write_source_files",
srcs = ["write_source_files.bzl"],
Expand Down
12 changes: 12 additions & 0 deletions lib/copy_to_bin.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""AA rule that copies source files to the output tree.
This rule uses a Bash command (diff) on Linux/macOS/non-Windows, and a cmd.exe
command (fc.exe) on Windows (no Bash is required).
"""

load(
"//lib/private:copy_to_bin.bzl",
_copy_to_bin = "copy_to_bin",
)

copy_to_bin = _copy_to_bin
7 changes: 7 additions & 0 deletions lib/private/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ bzl_library(
],
)

bzl_library(
name = "copy_to_bin",
srcs = ["copy_to_bin.bzl"],
visibility = ["//lib:__subpackages__"],
deps = [":copy_file"],
)

bzl_library(
name = "params_file",
srcs = ["params_file.bzl"],
Expand Down
72 changes: 72 additions & 0 deletions lib/private/copy_to_bin.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Copyright 2019 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.

"""Implementation of copy_to_bin macro and underlying rules.
A rule that copies source files to the output tree.
This rule uses a Bash command (diff) on Linux/macOS/non-Windows, and a cmd.exe
command (fc.exe) on Windows (no Bash is required).
"""

load(":copy_file.bzl", "copy_file_action")

def _impl(ctx):
all_dst = []
for src in ctx.files.srcs:
if not src.is_source:
fail("A source file must be specified in copy_to_bin rule, %s is not a source file." % src.path)
dst = ctx.actions.declare_file(src.basename, sibling = src)
copy_file_action(ctx, src, dst, is_windows = ctx.attr.is_windows)
all_dst.append(dst)
return DefaultInfo(
files = depset(all_dst),
runfiles = ctx.runfiles(files = all_dst),
)

_copy_to_bin = rule(
implementation = _impl,
provides = [DefaultInfo],
attrs = {
"is_windows": attr.bool(mandatory = True),
"srcs": attr.label_list(mandatory = True, allow_files = True),
},
)

def copy_to_bin(name, srcs, **kwargs):
"""Copies a source file to output tree at the same workspace-relative path.
e.g. `<execroot>/path/to/file -> <execroot>/bazel-out/<platform>/bin/path/to/file`
This is useful to populate the output folder with all files needed at runtime, even
those which aren't outputs of a Bazel rule.
This way you can run a binary in the output folder (execroot or runfiles_root)
without that program needing to rely on a runfiles helper library or be aware that
files are divided between the source tree and the output tree.
Args:
name: Name of the rule.
srcs: A list of labels. File(s) to copy.
**kwargs: further keyword arguments, e.g. `visibility`
"""
_copy_to_bin(
name = name,
srcs = srcs,
is_windows = select({
"@bazel_tools//src/conditions:host_windows": True,
"//conditions:default": False,
}),
**kwargs
)
4 changes: 4 additions & 0 deletions lib/private/diff_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ def _diff_test_impl(ctx):
file2 = ctx.files.file2[0]
file2_path = _runfiles_path(file2)

if file1 == file2:
msg = "diff_test comparing the same file %s" % file1
fail(msg)

if ctx.attr.is_windows:
test_bin = ctx.actions.declare_file(ctx.label.name + "-test.bat")
ctx.actions.write(
Expand Down
52 changes: 52 additions & 0 deletions lib/tests/copy_to_bin/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"tests for copy_to_bin"

load("//lib:copy_to_bin.bzl", "copy_to_bin")
load("//lib:output_files.bzl", "output_files")

copy_to_bin(
name = "copy",
srcs = [
"file1",
"file2",
],
)

output_files(
name = "pull_out_file1",
paths = ["%s/file1" % package_name()],
target = ":copy",
)

output_files(
name = "pull_out_file2",
paths = ["%s/file2" % package_name()],
target = ":copy",
)

sh_test(
name = "file1_test",
srcs = ["test.sh"],
args = [
"lib/tests/copy_to_bin/file1",
"$(execpath file1)",
"$(execpath :pull_out_file1)",
],
data = [
"file1",
":pull_out_file1",
],
)

sh_test(
name = "file2_test",
srcs = ["test.sh"],
args = [
"lib/tests/copy_to_bin/file2",
"$(execpath file2)",
"$(execpath :pull_out_file2)",
],
data = [
"file2",
":pull_out_file2",
],
)
1 change: 1 addition & 0 deletions lib/tests/copy_to_bin/file1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
file1
1 change: 1 addition & 0 deletions lib/tests/copy_to_bin/file2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
file2
19 changes: 19 additions & 0 deletions lib/tests/copy_to_bin/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash

set -o errexit -o nounset

expected_file="$1"
source_file="$2"
bin_file="$3"
if [[ "$expected_file" != "$source_file" ]]; then
echo "ERROR: expected source_file to be $expected_file, but got $source_file"
exit 1
fi
if [[ "$bin_file" != "bazel-out/"* ]]; then
echo "ERROR: expected bin_file to be start with bazel-out/, but got $bin_file"
exit 1
fi
if [[ "$bin_file" != *"/bin/$expected_file" ]]; then
echo "ERROR: expected bin_file to be end with /bin/$expected_file, but got $bin_file"
exit 1
fi

0 comments on commit 3de67fa

Please sign in to comment.