Skip to content

Commit 7b6c814

Browse files
authored
Add copy_directory binary tool (bazel-contrib#324)
1 parent 4edb501 commit 7b6c814

File tree

24 files changed

+429
-19
lines changed

24 files changed

+429
-19
lines changed

docs/copy_directory.md

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/copy_file.md

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/copy_to_bin.md

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/copy_to_directory.md

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/private/copy_directory.bzl

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def _copy_cmd(ctx, src, dst):
2222
# NB: robocopy return non-zero exit codes on success so we must exit 0 after calling it
2323
cmd_tmpl = "@robocopy \"{src}\" \"{dst}\" /E >NUL & @exit 0"
2424
mnemonic = "CopyDirectory"
25-
progress_message = "Copying directory %s" % src.path
25+
progress_message = "Copying directory %{input}"
2626

2727
ctx.actions.write(
2828
output = bat,
@@ -49,7 +49,7 @@ def _copy_cmd(ctx, src, dst):
4949
def _copy_bash(ctx, src, dst):
5050
cmd = "rm -Rf \"$2\" && cp -fR \"$1/\" \"$2\""
5151
mnemonic = "CopyDirectory"
52-
progress_message = "Copying directory %s" % src.path
52+
progress_message = "Copying directory %{input}"
5353

5454
ctx.actions.run_shell(
5555
tools = [src],
@@ -63,7 +63,7 @@ def _copy_bash(ctx, src, dst):
6363
)
6464

6565
def copy_directory_action(ctx, src, dst, is_windows = None):
66-
"""Helper function that creates an action to copy a directory from src to dst.
66+
"""Factory function that creates an action to copy a directory from src to dst.
6767
6868
This helper is used by copy_directory. It is exposed as a public API so it can be used within
6969
other rule implementations.
@@ -90,6 +90,57 @@ def copy_directory_action(ctx, src, dst, is_windows = None):
9090
else:
9191
_copy_bash(ctx, src, dst)
9292

93+
def copy_directory_bin_action(
94+
ctx,
95+
src,
96+
dst,
97+
copy_directory_bin,
98+
hardlink = "auto",
99+
verbose = False):
100+
"""Factory function that creates an action to copy a directory from src to dst using a tool binary.
101+
102+
The tool binary will typically be the `@aspect_bazel_lib//tools/copy_directory` `go_binary`
103+
either built from source or provided by a toolchain.
104+
105+
This helper is used by the copy_directory rule. It is exposed as a public API so it can be used
106+
within other rule implementations.
107+
108+
Args:
109+
ctx: The rule context.
110+
111+
src: The source directory to copy.
112+
113+
dst: The directory to copy to. Must be a TreeArtifact.
114+
115+
copy_directory_bin: Copy to directory tool binary.
116+
117+
hardlink: Controls when to use hardlinks to files instead of making copies.
118+
See copy_directory rule documentation for more details.
119+
120+
verbose: If true, prints out verbose logs to stdout
121+
"""
122+
args = [
123+
src.path,
124+
dst.path,
125+
]
126+
if verbose:
127+
args.append("--verbose")
128+
129+
if hardlink == "on":
130+
args.append("--hardlink")
131+
elif hardlink == "auto" and not src.is_source:
132+
args.append("--hardlink")
133+
134+
ctx.actions.run(
135+
inputs = [src],
136+
outputs = [dst],
137+
executable = copy_directory_bin,
138+
arguments = args,
139+
mnemonic = "CopyDirectory",
140+
progress_message = "Copying directory %{input}",
141+
execution_requirements = _COPY_EXECUTION_REQUIREMENTS,
142+
)
143+
93144
def _copy_directory_impl(ctx):
94145
dst = ctx.actions.declare_directory(ctx.attr.out)
95146
copy_directory_action(ctx, ctx.file.src, dst)

lib/private/copy_file.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def _copy_bash(ctx, src, src_path, dst):
8585
)
8686

8787
def copy_file_action(ctx, src, dst, dir_path = None, is_windows = None):
88-
"""Helper function that creates an action to copy a file from src to dst.
88+
"""Factory function that creates an action to copy a file from src to dst.
8989
9090
If src is a TreeArtifact, dir_path must be specified as the path within
9191
the TreeArtifact to the file to copy.

lib/private/copy_to_bin.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ load("@bazel_skylib//lib:paths.bzl", "paths")
1818
load(":copy_file.bzl", "copy_file_action")
1919

2020
def copy_file_to_bin_action(ctx, file, is_windows = None):
21-
"""Helper function that creates an action to copy a file to the output tree.
21+
"""Factory function that creates an action to copy a file to the output tree.
2222
2323
File are copied to the same workspace-relative path. The resulting files is
2424
returned.
@@ -92,7 +92,7 @@ target to {file_package} using:
9292
)
9393

9494
def copy_files_to_bin_actions(ctx, files, is_windows = None):
95-
"""Helper function that creates actions to copy files to the output tree.
95+
"""Factory function that creates actions to copy files to the output tree.
9696
9797
Files are copied to the same workspace-relative path. The resulting list of
9898
files is returned.

lib/private/copy_to_directory.bzl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -632,7 +632,7 @@ def copy_to_directory_bin_action(
632632
replace_prefixes = {},
633633
allow_overwrites = False,
634634
verbose = False):
635-
"""Helper function to copy files to a directory using a tool binary.
635+
"""Factory function to copy files to a directory using a tool binary.
636636
637637
The tool binary will typically be the `@aspect_bazel_lib//tools/copy_to_directory` `go_binary`
638638
either built from source or provided by a toolchain.
@@ -824,7 +824,7 @@ def copy_to_directory_action(
824824
replace_prefixes = {},
825825
allow_overwrites = False,
826826
is_windows = None):
827-
"""Legacy helper function to copy files to a directory.
827+
"""Legacy factory function to copy files to a directory.
828828
829829
This helper calculates copy paths in Starlark during analysis and performs the copies in a
830830
bash/bat script. For improved analysis and runtime performance, it is recommended the switch
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
load("//lib:diff_test.bzl", "diff_test")
2+
load(":pkg.bzl", "pkg")
3+
4+
pkg(
5+
name = "pkg",
6+
src = "d",
7+
out = "d2",
8+
)
9+
10+
pkg(
11+
name = "pkg2",
12+
src = "pkg",
13+
out = "d3",
14+
)
15+
16+
diff_test(
17+
name = "copy_test",
18+
file1 = ":d",
19+
file2 = ":pkg",
20+
# Source directories are not support on remote execution.
21+
tags = ["no-remote-exec"],
22+
)
23+
24+
diff_test(
25+
name = "hardlink_test",
26+
file1 = ":d",
27+
file2 = ":pkg2",
28+
# Source directories are not support on remote execution.
29+
tags = ["no-remote-exec"],
30+
)
31+
32+
diff_test(
33+
name = "sanity_test",
34+
file1 = ":pkg",
35+
file2 = ":pkg2",
36+
)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
./1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
./2
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
d
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
./1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
./2
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""
2+
Test rule to create a pkg with DefaultInfo using copy_directory_bin_action
3+
"""
4+
5+
load("@aspect_bazel_lib//lib/private:copy_directory.bzl", "copy_directory_bin_action")
6+
7+
_attrs = {
8+
"src": attr.label(
9+
mandatory = True,
10+
allow_single_file = True,
11+
),
12+
"out": attr.string(mandatory = True),
13+
"_tool": attr.label(
14+
executable = True,
15+
cfg = "exec",
16+
default = "//tools/copy_directory",
17+
),
18+
}
19+
20+
def _pkg_impl(ctx):
21+
dst = ctx.actions.declare_directory(ctx.attr.out)
22+
23+
copy_directory_bin_action(
24+
ctx,
25+
src = ctx.file.src,
26+
dst = dst,
27+
copy_directory_bin = ctx.executable._tool,
28+
hardlink = "auto",
29+
verbose = True,
30+
)
31+
32+
return [
33+
DefaultInfo(files = depset([dst])),
34+
]
35+
36+
pkg = rule(
37+
implementation = _pkg_impl,
38+
attrs = _attrs,
39+
provides = [DefaultInfo],
40+
)

tools/BUILD.bazel

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,17 @@ multi_platform_go_binaries(
1010
tags = ["manual"],
1111
)
1212

13+
multi_platform_go_binaries(
14+
name = "copy_directory",
15+
embed = ["//tools/copy_directory:copy_directory_lib"],
16+
tags = ["manual"],
17+
)
18+
1319
release(
1420
name = "release",
1521
tags = ["manual"],
1622
targets = [
23+
":copy_directory",
1724
":copy_to_directory",
1825
],
1926
)

tools/copy_directory/BUILD.bazel

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
2+
3+
# Under --stamp, the Go linker will fill in these placeholders with VCS info
4+
# see https://github.com/bazelbuild/rules_go/blob/master/go/core.rst#stamping-with-the-workspace-status-script
5+
_GO_STAMP_X_DEFS = {
6+
"BuildTime": "{BUILD_TIMESTAMP}",
7+
"GitCommit": "{STABLE_BUILD_SCM_SHA}",
8+
"GitStatus": "{STABLE_BUILD_SCM_LOCAL_CHANGES}",
9+
"HostName": "{BUILD_HOST}",
10+
"Release": "{STABLE_BUILD_SCM_TAG}",
11+
}
12+
13+
go_library(
14+
name = "copy_directory_lib",
15+
srcs = [
16+
"main.go",
17+
"stamp.go",
18+
],
19+
importpath = "github.com/aspect-build/bazel-lib/tools/copy_directory",
20+
visibility = ["//visibility:public"],
21+
x_defs = _GO_STAMP_X_DEFS,
22+
)
23+
24+
go_binary(
25+
name = "copy_directory",
26+
embed = [":copy_directory_lib"],
27+
visibility = ["//visibility:public"],
28+
)

0 commit comments

Comments
 (0)