@@ -67,8 +67,6 @@ load(":transition_labels.bzl", "TRANSITION_LABELS")
6767load (":venv_runfiles.bzl" , "create_venv_app_files" )
6868
6969_py_builtins = py_internal
70- _EXTERNAL_PATH_PREFIX = "external"
71- _ZIP_RUNFILES_DIRECTORY_NAME = "runfiles"
7270
7371# Non-Google-specific attributes for executables
7472# These attributes are for rules that accept Python sources.
@@ -236,7 +234,7 @@ accepting arbitrary Python versions.
236234 "_zipper" : lambda : attrb .Label (
237235 cfg = "exec" ,
238236 executable = True ,
239- default = "@bazel_tools//tools/zip:zipper " ,
237+ default = ":py_executable_zip_gen " ,
240238 ),
241239 },
242240)
@@ -380,9 +378,8 @@ def _create_executable(
380378 _create_zip_file (
381379 ctx ,
382380 output = zip_file ,
383- original_nonzip_executable = executable ,
384381 zip_main = zip_main ,
385- runfiles = runfiles_details .default_runfiles .merge (extra_runfiles ),
382+ runfiles = runfiles_details .runfiles_without_exe .merge (extra_runfiles ),
386383 )
387384
388385 extra_files_to_build = []
@@ -803,35 +800,16 @@ def _create_windows_exe_launcher(
803800 use_default_shell_env = True ,
804801 )
805802
806- def _create_zip_file (ctx , * , output , original_nonzip_executable , zip_main , runfiles ):
803+ def _create_zip_file (ctx , * , output , zip_main , runfiles ):
807804 """Create a Python zipapp (zip with __main__.py entry point)."""
808- workspace_name = ctx .workspace_name
809805 legacy_external_runfiles = _py_builtins .get_legacy_external_runfiles (ctx )
810806
811- manifest = ctx .actions .args ()
812- manifest .use_param_file ("@%s" , use_always = True )
813- manifest .set_param_file_format ("multiline" )
814-
815- manifest .add ("__main__.py={}" .format (zip_main .path ))
816- manifest .add ("__init__.py=" )
817- manifest .add (
818- "{}=" .format (
819- _get_zip_runfiles_path ("__init__.py" , workspace_name , legacy_external_runfiles ),
820- ),
821- )
822- for path in runfiles .empty_filenames .to_list ():
823- manifest .add ("{}=" .format (_get_zip_runfiles_path (path , workspace_name , legacy_external_runfiles )))
824-
825- def map_zip_runfiles (file ):
826- if file != original_nonzip_executable and file != output :
827- return "{}={}" .format (
828- _get_zip_runfiles_path (file .short_path , workspace_name , legacy_external_runfiles ),
829- file .path ,
830- )
831- else :
832- return None
833-
834- manifest .add_all (runfiles .files , map_each = map_zip_runfiles , allow_closure = True )
807+ args = ctx .actions .args ()
808+ args .add ("--output" , output )
809+ args .add ("--workspace-name" , ctx .workspace_name )
810+ args .add ("--main-file" , zip_main )
811+ if legacy_external_runfiles :
812+ args .add ("--legacy-external-runfiles" )
835813
836814 inputs = [zip_main ]
837815 if _py_builtins .is_bzlmod_enabled (ctx ):
@@ -844,43 +822,30 @@ def _create_zip_file(ctx, *, output, original_nonzip_executable, zip_main, runfi
844822 runfiles = runfiles ,
845823 output = zip_repo_mapping_manifest ,
846824 )
847- manifest .add ("{}/_repo_mapping={}" .format (
848- _ZIP_RUNFILES_DIRECTORY_NAME ,
849- zip_repo_mapping_manifest .path ,
850- ))
825+ args .add ("--repo-mapping-manifest" , zip_repo_mapping_manifest )
851826 inputs .append (zip_repo_mapping_manifest )
852827
853- for artifact in runfiles .files .to_list ():
854- # Don't include the original executable because it isn't used by the
855- # zip file, so no need to build it for the action.
856- # Don't include the zipfile itself because it's an output.
857- if artifact != original_nonzip_executable and artifact != output :
858- inputs .append (artifact )
859-
860- zip_cli_args = ctx .actions .args ()
861- zip_cli_args .add ("cC" )
862- zip_cli_args .add (output )
828+ manifest = ctx .actions .args ()
829+ manifest .use_param_file ("%s" , use_always = True )
830+ manifest .set_param_file_format ("multiline" )
831+ manifest .add_all (runfiles .empty_filenames , map_each = _get_zip_empty_path_arg )
832+ manifest .add_all (runfiles .files , map_each = _get_zip_path_arg )
863833
864834 ctx .actions .run (
865835 executable = ctx .executable ._zipper ,
866- arguments = [zip_cli_args , manifest ],
867- inputs = depset (inputs ),
836+ arguments = [args , manifest ],
837+ inputs = depset (inputs , transitive = [ runfiles . files ] ),
868838 outputs = [output ],
869839 use_default_shell_env = True ,
870840 mnemonic = "PythonZipper" ,
871841 progress_message = "Building Python zip: %{label}" ,
872842 )
873843
874- def _get_zip_runfiles_path (path , workspace_name , legacy_external_runfiles ):
875- if legacy_external_runfiles and path .startswith (_EXTERNAL_PATH_PREFIX ):
876- zip_runfiles_path = paths .relativize (path , _EXTERNAL_PATH_PREFIX )
877- else :
878- # NOTE: External runfiles (artifacts in other repos) will have a leading
879- # path component of "../" so that they refer outside the main workspace
880- # directory and into the runfiles root. By normalizing, we simplify e.g.
881- # "workspace/../foo/bar" to simply "foo/bar".
882- zip_runfiles_path = paths .normalize ("{}/{}" .format (workspace_name , path ))
883- return "{}/{}" .format (_ZIP_RUNFILES_DIRECTORY_NAME , zip_runfiles_path )
844+ def _get_zip_empty_path_arg (file ):
845+ return "{}=" .format (file )
846+
847+ def _get_zip_path_arg (file ):
848+ return "{}={}" .format (file .short_path , file .path )
884849
885850def _create_executable_zip_file (
886851 ctx ,
0 commit comments