|
15 | 15 | """Helper functions to expand paths into runfiles |
16 | 16 | """ |
17 | 17 |
|
18 | | -def expand_location_into_runfiles(ctx, path): |
19 | | - """Expand a path into runfiles if it contains a $(location). |
20 | | -
|
21 | | - If the path has a location expansion, expand it. Otherwise return as-is. |
| 18 | +# Expand $(location) and $(locations) to runfiles manifest path |
| 19 | +def _expand_mlocations(ctx, input, targets): |
| 20 | + paths = ctx.expand_location(input, targets) |
| 21 | + return " ".join([_short_path_to_runfiles_manifest_path(ctx, p, targets) for p in paths.split(" ")]) |
| 22 | + |
| 23 | +# Convert a short_path in the execroot to the runfiles manifest path |
| 24 | +def _short_path_to_runfiles_manifest_path(ctx, path, targets): |
| 25 | + if path.startswith("../"): |
| 26 | + return path[len("../"):] |
| 27 | + if path.startswith("./"): |
| 28 | + path = path[len("./"):] |
| 29 | + elif path.startswith(ctx.bin_dir.path): |
| 30 | + path = path[len(ctx.bin_dir.path + "/"):] |
| 31 | + elif path.startswith(ctx.genfiles_dir.path): |
| 32 | + path = path[len(ctx.genfiles_dir.path + "/"):] |
| 33 | + return ctx.workspace_name + "/" + path |
| 34 | + |
| 35 | +# Expand $(location) and $(locations) to runfiles short path |
| 36 | +def _expand_locations(ctx, input, targets): |
| 37 | + paths = ctx.expand_location(input, targets) |
| 38 | + return " ".join([_short_path_to_runfiles_short_path(ctx, p, targets) for p in paths.split(" ")]) |
| 39 | + |
| 40 | +# Convert a short_path in the execroot to the runfiles short path |
| 41 | +def _short_path_to_runfiles_short_path(ctx, path, targets): |
| 42 | + path = path.replace(ctx.bin_dir.path + "/external/", "../", 1) |
| 43 | + path = path.replace(ctx.bin_dir.path + "/", "", 1) |
| 44 | + path = path.replace(ctx.genfiles_dir.path + "/external/", "../", 1) |
| 45 | + path = path.replace(ctx.genfiles_dir.path + "/", "", 1) |
| 46 | + return path |
| 47 | + |
| 48 | +def expand_location_into_runfiles(ctx, input, targets = []): |
| 49 | + """Expands all $(location ...) templates in the given string by replacing $(location //x) with the path |
| 50 | + in runfiles of the output file of target //x. Expansion only works for labels that point to direct dependencies |
| 51 | + of this rule or that are explicitly listed in the optional argument targets. |
| 52 | +
|
| 53 | + Path is returned in runfiles manifest path format such as `repo/path/to/file`. This differs from how $(location) |
| 54 | + and $(locations) expansion behaves in expansion the `args` attribute of a *_binary or *_test which returns |
| 55 | + the runfiles short path of the format `./path/to/file` for user repo and `../external_repo/path/to/file` for external |
| 56 | + repositories. We may change this behavior in the future with $(mlocation) and $(mlocations) used to expand |
| 57 | + to the runfiles manifest path. |
| 58 | + See https://docs.bazel.build/versions/master/be/common-definitions.html#common-attributes-binaries. |
22 | 59 |
|
23 | 60 | Args: |
24 | 61 | ctx: context |
25 | | - path: the path to expand |
| 62 | + input: String to be expanded |
| 63 | + targets: List of targets for additional lookup information. |
26 | 64 |
|
27 | 65 | Returns: |
28 | 66 | The expanded path or the original path |
29 | 67 | """ |
30 | | - if path.find("$(location") < 0: |
31 | | - return path |
32 | | - return expand_path_into_runfiles(ctx, path) |
33 | | - |
34 | | -# TODO(gregmagolan): rename to _expand_path_into_runfiles after angular/angular protractor rule |
35 | | -# is removed and no longer references this function |
36 | | -def expand_path_into_runfiles(ctx, path): |
37 | | - """Expand paths into runfiles. |
38 | | -
|
39 | | - Given a file path that might contain a $(location) or $(locations) label expansion, |
40 | | - provide the paths to the file in runfiles. |
41 | | -
|
42 | | - See https://docs.bazel.build/versions/master/skylark/lib/ctx.html#expand_location |
43 | | -
|
44 | | - Args: |
45 | | - ctx: context |
46 | | - path: the paths to expand |
47 | | -
|
48 | | - Returns: |
49 | | - The expanded paths |
50 | | - """ |
51 | | - targets = ctx.attr.data if hasattr(ctx.attr, "data") else [] |
52 | | - expanded = ctx.expand_location(path, targets) |
53 | | - |
54 | | - expansion = [_resolve_expanded_path(ctx, exp) for exp in expanded.strip().split(" ")] |
55 | | - |
56 | | - return " ".join(expansion) |
57 | | - |
58 | | -def _resolve_expanded_path(ctx, expanded): |
59 | | - """Resolves an expanded path |
60 | | -
|
61 | | - Given a file path that has been expaned with $(location), resolve the path to include the workspace name, |
62 | | - handling when that path is within bin_dir or gen_fir |
63 | | -
|
64 | | - Args: |
65 | | - ctx: context |
66 | | - expanded: the expanded path to resolve |
67 | | -
|
68 | | - Returns: |
69 | | - The resolved path |
70 | | - """ |
71 | | - if expanded.startswith("../"): |
72 | | - return expanded[len("../"):] |
73 | | - if expanded.startswith(ctx.bin_dir.path): |
74 | | - expanded = expanded[len(ctx.bin_dir.path + "/"):] |
75 | | - if expanded.startswith(ctx.genfiles_dir.path): |
76 | | - expanded = expanded[len(ctx.genfiles_dir.path + "/"):] |
77 | | - return ctx.workspace_name + "/" + expanded |
| 68 | + target = "@%s//%s:%s" % (ctx.workspace_name, "/".join(ctx.build_file_path.split("/")[:-1]), ctx.attr.name) |
| 69 | + |
| 70 | + # Loop through input an expand all $(location) and $(locations) using _expand_to_mlocation() |
| 71 | + path = "" |
| 72 | + length = len(input) |
| 73 | + last = 0 |
| 74 | + for i in range(length): |
| 75 | + if (input[i:i + 12] == "$(mlocation ") or (input[i:i + 13] == "$(mlocations "): |
| 76 | + j = input.find(")", i) + 1 |
| 77 | + if (j == 0): |
| 78 | + fail("invalid $(mlocation) expansion in string \"%s\" part of target %s" % (input, target)) |
| 79 | + path += input[last:i] |
| 80 | + path += _expand_mlocations(ctx, "$(" + input[i + 3:j], targets) |
| 81 | + last = j |
| 82 | + i = j |
| 83 | + if (input[i:i + 11] == "$(location ") or (input[i:i + 12] == "$(locations "): |
| 84 | + j = input.find(")", i) + 1 |
| 85 | + if (j == 0): |
| 86 | + fail("invalid $(location) expansion in string \"%s\" part of target %s" % (input, target)) |
| 87 | + path += input[last:i] |
| 88 | + |
| 89 | + # TODO(gmagolan): flip to _expand_locations in the future so $(location) expands to runfiles short |
| 90 | + # path which is more Bazel idiomatic and $(mlocation) can be used for runfiles manifest path |
| 91 | + path += _expand_mlocations(ctx, input[i:j], targets) |
| 92 | + last = j |
| 93 | + i = j |
| 94 | + path += input[last:] |
| 95 | + |
| 96 | + return path |
0 commit comments