Skip to content

Commit

Permalink
Add support for repo mapping (#878)
Browse files Browse the repository at this point in the history
* Add support for repo mapping

Esp. when include_runfiles = True

Closes #769

Signed-off-by: Thomas Lam <thomaslam@canva.com>

* Update windows golden manifest

Signed-off-by: Thomas Lam <thomaslam@canva.com>

* Split repo_mapping manifest checking logic into its own function

Signed-off-by: Thomas Lam <thomaslam@canva.com>

* Comment

Signed-off-by: Thomas Lam <thomaslam@canva.com>

---------

Signed-off-by: Thomas Lam <thomaslam@canva.com>
  • Loading branch information
lamcw authored Aug 14, 2024
1 parent 6a44f01 commit 447fb8e
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 17 deletions.
8 changes: 8 additions & 0 deletions pkg/mappings.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ here.

load("@bazel_skylib//lib:paths.bzl", "paths")
load("//pkg:providers.bzl", "PackageDirsInfo", "PackageFilegroupInfo", "PackageFilesInfo", "PackageSymlinkInfo")
load("//pkg/private:util.bzl", "get_repo_mapping_manifest")

# TODO(#333): strip_prefix module functions should produce unique outputs. In
# particular, this one and `_sp_from_pkg` can overlap.
Expand Down Expand Up @@ -311,6 +312,13 @@ def _pkg_files_impl(ctx):
else:
src_dest_paths_map[rf] = dest_path

# if repo_mapping manifest exists (for e.g. with --enable_bzlmod),
# create _repo_mapping under runfiles directory
repo_mapping_manifest = get_repo_mapping_manifest(target)
if repo_mapping_manifest:
dest_path = paths.join(src_dest_paths_map[src] + ".runfiles", "_repo_mapping")
src_dest_paths_map[repo_mapping_manifest] = dest_path

# At this point, we have a fully valid src -> dest mapping in src_dest_paths_map.
#
# Construct the inverse of this mapping to pass to the output providers, and
Expand Down
66 changes: 51 additions & 15 deletions pkg/private/pkg_files.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ load(
"PackageFilesInfo",
"PackageSymlinkInfo",
)
load(
"//pkg/private:util.bzl",
"get_files_to_run_provider",
"get_repo_mapping_manifest",
)

ENTRY_IS_FILE = "file" # Entry is a file: take content from <src>
ENTRY_IS_LINK = "symlink" # Entry is a symlink: dest -> <src>
Expand Down Expand Up @@ -75,7 +80,6 @@ _MappingContext = provider(
"include_runfiles": "bool: include runfiles",
"workspace_name": "string: name of the main workspace",
"strip_prefix": "strip_prefix",

"path_mapper": "function to map destination paths",

# Defaults
Expand All @@ -95,8 +99,7 @@ def create_mapping_context_from_ctx(
strip_prefix = None,
include_runfiles = None,
default_mode = None,
path_mapper = None
):
path_mapper = None):
"""Construct a MappingContext.
Args: See the provider definition.
Expand Down Expand Up @@ -400,7 +403,8 @@ def add_from_default_info(
all_files = src[DefaultInfo].files.to_list()
for f in all_files:
d_path = mapping_context.path_mapper(
dest_path(f, data_path, data_path_without_prefix))
dest_path(f, data_path, data_path_without_prefix),
)
if f.is_directory:
add_tree_artifact(
mapping_context.content_map,
Expand All @@ -422,6 +426,7 @@ def add_from_default_info(
user = mapping_context.default_user,
group = mapping_context.default_group,
)

if include_runfiles:
runfiles = src[DefaultInfo].default_runfiles
if runfiles:
Expand Down Expand Up @@ -449,6 +454,43 @@ def add_from_default_info(
gid = mapping_context.default_gid,
)

# if repo_mapping manifest exists (for e.g. with --enable_bzlmod),
# create _repo_mapping under runfiles directory
repo_mapping_manifest = get_repo_mapping_manifest(src)
if repo_mapping_manifest:
mapping_context.file_deps.append(depset([repo_mapping_manifest]))

# TODO: This should really be a symlink into .runfiles/_repo_mapping
# that also respects remap_paths. For now this is duplicated with the
# repo_mapping file within the runfiles directory
d_path = mapping_context.path_mapper(dest_path(
repo_mapping_manifest,
data_path,
data_path_without_prefix,
))
add_single_file(
mapping_context,
dest_path = d_path,
src = repo_mapping_manifest,
origin = src.label,
mode = mapping_context.default_mode,
user = mapping_context.default_user,
group = mapping_context.default_group,
)

runfiles_repo_mapping_path = mapping_context.path_mapper(
base_file_path + ".runfiles/_repo_mapping",
)
add_single_file(
mapping_context,
dest_path = runfiles_repo_mapping_path,
src = repo_mapping_manifest,
origin = src.label,
mode = mapping_context.default_mode,
user = mapping_context.default_user,
group = mapping_context.default_group,
)

def get_my_executable(src):
"""If a target represents an executable, return its file handle.
Expand All @@ -461,21 +503,15 @@ def get_my_executable(src):
Returns:
File or None.
"""
if not DefaultInfo in src:
return None
di = src[DefaultInfo]
if not hasattr(di, "files_to_run"):
return None
ftr = di.files_to_run

files_to_run_provider = get_files_to_run_provider(src)

# The docs lead you to believe that you could look at
# files_to_run.executable, but that is filled out even for source
# files.
if not hasattr(ftr, "runfiles_manifest"):
return None
if ftr.runfiles_manifest:
# DEBUG print("Got an manifest executable", ftr.executable)
return ftr.executable
if getattr(files_to_run_provider, "runfiles_manifest"):
# DEBUG print("Got an manifest executable", files_to_run_provider.executable)
return files_to_run_provider.executable
return None

def add_single_file(mapping_context, dest_path, src, origin, mode = None, user = None, group = None, uid = None, gid = None):
Expand Down
35 changes: 34 additions & 1 deletion pkg/private/util.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,37 @@ def substitute_package_variables(ctx, attribute_value):
attribute_value = attribute_value.replace("$(", "{", 1)
attribute_value = attribute_value.replace(")", "}", 1)

return attribute_value.format(**vars)
return attribute_value.format(**vars)

def get_files_to_run_provider(src):
"""Safely retrieve FilesToRunProvider from a target.
Args:
src: target to get FilesToRunProvider from
Returns:
FilesToRunProvider or None: FilesToRunProvider if found in target
provider, otherwise None
"""
if not DefaultInfo in src:
return None
di = src[DefaultInfo]
if not hasattr(di, "files_to_run"):
return None
return di.files_to_run

def get_repo_mapping_manifest(src):
"""Safely retrieve repo_mapping_manifest from a target if it exists.
Args:
src: target to get repo_mapping_manifest from
Returns:
File or None: repo_mapping_manifest
"""
files_to_run_provider = get_files_to_run_provider(src)
if files_to_run_provider:
# repo_mapping_manifest may not exist in older Bazel versions (<7.0.0)
# https://github.com/bazelbuild/bazel/issues/19937
return getattr(files_to_run_provider, "repo_mapping_manifest")
return None
4 changes: 3 additions & 1 deletion tests/mappings/executable.manifest.golden
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
[
{"dest":"an_executable.runfiles/_main/tests/foo.cc","gid":null,"group":null,"mode":"","origin":"@//tests:an_executable","src":"tests/foo.cc","type":"file","uid":null,"user":null},
{"dest":"an_executable.runfiles/_main/tests/an_executable","gid":null,"group":null,"mode":"0755","origin":"@//tests:an_executable","src":"tests/an_executable","type":"file","uid":null,"user":null},
{"dest":"an_executable.runfiles/_main/tests/foo.cc","gid":null,"group":null,"mode":"","origin":"@//tests:an_executable","src":"tests/foo.cc","type":"file","uid":null,"user":null},
{"dest":"an_executable.runfiles/_main/tests/testdata/hello.txt","gid":null,"group":null,"mode":"","origin":"@//tests:an_executable","src":"tests/testdata/hello.txt","type":"file","uid":null,"user":null},
{"dest":"an_executable","gid":null,"group":null,"mode":"0755","origin":"@//tests:an_executable","src":"tests/an_executable","type":"file","uid":null,"user":null},
{"dest":"an_executable.repo_mapping","gid":null,"group":null,"mode":"","origin":"@//tests:an_executable","src":"tests/an_executable.repo_mapping","type":"file","uid":null,"user":null},
{"dest":"an_executable.runfiles/_repo_mapping","gid":null,"group":null,"mode":"","origin":"@//tests:an_executable","src":"tests/an_executable.repo_mapping","type":"file","uid":null,"user":null},
{"dest":"mappings_test.bzl","gid":null,"group":null,"mode":"","origin":"@//tests/mappings:mappings_test.bzl","src":"tests/mappings/mappings_test.bzl","type":"file","uid":null,"user":null}
]
2 changes: 2 additions & 0 deletions tests/mappings/executable.manifest.windows.golden
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
{"dest":"an_executable.exe.runfiles/_main/tests/an_executable.exe","gid":null,"group":null,"mode":"0755","origin":"@//tests:an_executable","src":"tests/an_executable.exe","type":"file","uid":null,"user":null},
{"dest":"an_executable.exe.runfiles/_main/tests/testdata/hello.txt","gid":null,"group":null,"mode":"","origin":"@//tests:an_executable","src":"tests/testdata/hello.txt","type":"file","uid":null,"user":null},
{"dest":"an_executable.exe","gid":null,"group":null,"mode":"0755","origin":"@//tests:an_executable","src":"tests/an_executable.exe","type":"file","uid":null,"user":null},
{"dest":"an_executable.exe.repo_mapping","gid":null,"group":null,"mode":"","origin":"@//tests:an_executable","src": "tests/an_executable.exe.repo_mapping","type": "file","uid":null,"user":null},
{"dest":"an_executable.exe.runfiles/_repo_mapping","gid":null,"group":null,"mode":"","origin":"@//tests:an_executable","src": "tests/an_executable.exe.repo_mapping","type": "file","uid":null,"user":null},
{"dest":"mappings_test.bzl","gid":null,"group":null,"mode":"","origin":"@//tests/mappings:mappings_test.bzl","src":"tests/mappings/mappings_test.bzl","type":"file","uid":null,"user":null}
]
2 changes: 2 additions & 0 deletions tests/mappings/mappings_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,13 @@ def _test_pkg_files_contents():
{
"@bazel_tools//src/conditions:windows": [
"an_executable.exe",
"an_executable.exe.runfiles/_repo_mapping",
"an_executable.exe.runfiles/_main/tests/foo.cc",
"an_executable.exe.runfiles/_main/tests/testdata/hello.txt",
],
"//conditions:default": [
"an_executable",
"an_executable.runfiles/_repo_mapping",
"an_executable.runfiles/_main/tests/foo.cc",
"an_executable.runfiles/_main/tests/testdata/hello.txt",
],
Expand Down

0 comments on commit 447fb8e

Please sign in to comment.