@@ -236,7 +236,7 @@ accepting arbitrary Python versions.
236236        "_zipper" : lambda : attrb .Label (
237237            cfg  =  "exec" ,
238238            executable  =  True ,
239-             default  =  "@bazel_tools//tools/zip:zipper " ,
239+             default  =  ":py_executable_zip_gen " ,
240240        ),
241241    },
242242)
@@ -380,9 +380,8 @@ def _create_executable(
380380    _create_zip_file (
381381        ctx ,
382382        output  =  zip_file ,
383-         original_nonzip_executable  =  executable ,
384383        zip_main  =  zip_main ,
385-         runfiles  =  runfiles_details .default_runfiles .merge (extra_runfiles ),
384+         runfiles  =  runfiles_details .runfiles_without_exe .merge (extra_runfiles ),
386385    )
387386
388387    extra_files_to_build  =  []
@@ -803,35 +802,16 @@ def _create_windows_exe_launcher(
803802        use_default_shell_env  =  True ,
804803    )
805804
806- def  _create_zip_file (ctx , * , output , original_nonzip_executable ,  zip_main , runfiles ):
805+ def  _create_zip_file (ctx , * , output , zip_main , runfiles ):
807806    """Create a Python zipapp (zip with __main__.py entry point).""" 
808-     workspace_name  =  ctx .workspace_name 
809807    legacy_external_runfiles  =  _py_builtins .get_legacy_external_runfiles (ctx )
810808
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 )
809+     args  =  ctx .actions .args ()
810+     args .add ("--output" , output .path )
811+     args .add ("--workspace-name" , ctx .workspace_name )
812+     args .add ("--main-file" , zip_main .path )
813+     if  legacy_external_runfiles :
814+         args .add ("--legacy-external-runfiles" )
835815
836816    inputs  =  [zip_main ]
837817    if  _py_builtins .is_bzlmod_enabled (ctx ):
@@ -844,43 +824,30 @@ def _create_zip_file(ctx, *, output, original_nonzip_executable, zip_main, runfi
844824            runfiles  =  runfiles ,
845825            output  =  zip_repo_mapping_manifest ,
846826        )
847-         manifest .add ("{}/_repo_mapping={}" .format (
848-             _ZIP_RUNFILES_DIRECTORY_NAME ,
849-             zip_repo_mapping_manifest .path ,
850-         ))
827+         args .add ("--repo-mapping-manifest" , zip_repo_mapping_manifest .path )
851828        inputs .append (zip_repo_mapping_manifest )
852829
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 )
830+     manifest  =  ctx .actions .args ()
831+     manifest .use_param_file ("%s" , use_always  =  True )
832+     manifest .set_param_file_format ("multiline" )
833+     manifest .add_all (runfiles .empty_filenames , map_each  =  _get_zip_empty_path_arg )
834+     manifest .add_all (runfiles .files , map_each  =  _get_zip_path_arg )
863835
864836    ctx .actions .run (
865837        executable  =  ctx .executable ._zipper ,
866-         arguments  =  [zip_cli_args , manifest ],
867-         inputs  =  depset (inputs ),
838+         arguments  =  [args , manifest ],
839+         inputs  =  depset (inputs ,  transitive   =  [ runfiles . files ] ),
868840        outputs  =  [output ],
869841        use_default_shell_env  =  True ,
870842        mnemonic  =  "PythonZipper" ,
871843        progress_message  =  "Building Python zip: %{label}" ,
872844    )
873845
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 )
846+ def  _get_zip_empty_path_arg (file ):
847+     return  "{}=" .format (file )
848+ 
849+ def  _get_zip_path_arg (file ):
850+     return  "{}={}" .format (file .short_path , file .path )
884851
885852def  _create_executable_zip_file (
886853        ctx ,
0 commit comments