|  | # Internal helpers for building the Python protobuf runtime. | 
|  |  | 
|  | def _internal_copy_files_impl(ctx): | 
|  | strip_prefix = ctx.attr.strip_prefix | 
|  | if strip_prefix[-1] != "/": | 
|  | strip_prefix += "/" | 
|  |  | 
|  | src_dests = [] | 
|  | for src in ctx.files.srcs: | 
|  | if src.short_path[:len(strip_prefix)] != strip_prefix: | 
|  | fail("Source does not start with %s: %s" % | 
|  | (strip_prefix, src.short_path)) | 
|  | dest = ctx.actions.declare_file(src.short_path[len(strip_prefix):]) | 
|  | src_dests.append([src, dest]) | 
|  |  | 
|  | if ctx.attr.is_windows: | 
|  | bat_file = ctx.actions.declare_file(ctx.label.name + "_copy.bat") | 
|  | ctx.actions.write( | 
|  | output = bat_file, | 
|  | content = "\r\n".join([ | 
|  | '@copy /Y "{}" "{}" >NUL'.format( | 
|  | src.path.replace("/", "\\"), | 
|  | dest.path.replace("/", "\\"), | 
|  | ) | 
|  | for src, dest in src_dests | 
|  | ]) + "\r\n", | 
|  | ) | 
|  | ctx.actions.run( | 
|  | inputs = ctx.files.srcs, | 
|  | tools = [bat_file], | 
|  | outputs = [dest for src, dest in src_dests], | 
|  | executable = "cmd.exe", | 
|  | arguments = ["/C", bat_file.path.replace("/", "\\")], | 
|  | mnemonic = "InternalCopyFile", | 
|  | progress_message = "Copying files", | 
|  | use_default_shell_env = True, | 
|  | ) | 
|  |  | 
|  | else: | 
|  | sh_file = ctx.actions.declare_file(ctx.label.name + "_copy.sh") | 
|  | ctx.actions.write( | 
|  | output = sh_file, | 
|  | content = "\n".join([ | 
|  | 'cp -f "{}" "{}"'.format(src.path, dest.path) | 
|  | for src, dest in src_dests | 
|  | ]), | 
|  | ) | 
|  | ctx.actions.run( | 
|  | inputs = ctx.files.srcs, | 
|  | tools = [sh_file], | 
|  | outputs = [dest for src, dest in src_dests], | 
|  | executable = "bash", | 
|  | arguments = [sh_file.path], | 
|  | mnemonic = "InternalCopyFile", | 
|  | progress_message = "Copying files", | 
|  | use_default_shell_env = True, | 
|  | ) | 
|  |  | 
|  | return [ | 
|  | DefaultInfo(files = depset([dest for src, dest in src_dests])), | 
|  | ] | 
|  |  | 
|  | internal_copy_files_impl = rule( | 
|  | doc = """ | 
|  | Implementation for internal_copy_files macro. | 
|  |  | 
|  | This rule implements file copying, including a compatibility mode for Windows. | 
|  | """, | 
|  | implementation = _internal_copy_files_impl, | 
|  | attrs = { | 
|  | "srcs": attr.label_list(allow_files = True, providers = [DefaultInfo]), | 
|  | "strip_prefix": attr.string(), | 
|  | "is_windows": attr.bool(), | 
|  | }, | 
|  | ) | 
|  |  | 
|  | def internal_copy_files(name, srcs, strip_prefix, **kwargs): | 
|  | """Copies common proto files to the python tree. | 
|  |  | 
|  | In order for Python imports to work, generated proto interfaces under | 
|  | the google.protobuf package need to be in the same directory as other | 
|  | source files. This rule copies the .proto files themselves, e.g. with | 
|  | strip_prefix = 'src', 'src/google/protobuf/blah.proto' could be copied | 
|  | to '<package>/google/protobuf/blah.proto'. | 
|  |  | 
|  | (An alternative might be to implement a separate rule to generate | 
|  | Python code in a different location for the sources. However, this | 
|  | would be strange behavior that doesn't match any other language's proto | 
|  | library generation.) | 
|  |  | 
|  | Args: | 
|  | name: the name for the rule. | 
|  | srcs: the sources. | 
|  | strip_prefix: the prefix to remove from each of the paths in 'srcs'. The | 
|  | remainder will be used to construct the output path. | 
|  | **kwargs: common rule arguments. | 
|  |  | 
|  | """ | 
|  | internal_copy_files_impl( | 
|  | name = name, | 
|  | srcs = srcs, | 
|  | strip_prefix = strip_prefix, | 
|  | is_windows = select({ | 
|  | "@bazel_tools//src/conditions:host_windows": True, | 
|  | "//conditions:default": False, | 
|  | }), | 
|  | **kwargs | 
|  | ) | 
|  |  | 
|  | def internal_py_test(deps = [], **kwargs): | 
|  | """Internal wrapper for shared test configuration | 
|  |  | 
|  | Args: | 
|  | deps: any additional dependencies of the test. | 
|  | **kwargs: arguments forwarded to py_test. | 
|  | """ | 
|  | native.py_test( | 
|  | imports = ["."], | 
|  | deps = deps + [":python_test_lib"], | 
|  | target_compatible_with = select({ | 
|  | "@system_python//:supported": [], | 
|  | "//conditions:default": ["@platforms//:incompatible"], | 
|  | }), | 
|  | **kwargs | 
|  | ) |