@@ -28,6 +28,21 @@ def _interpreter_flags(ctx):
2828
2929 return args
3030
31+ # Forked from bazel-lib to avoid keeping `ctx` alive to execution phase
32+ def _to_rlocation_path (workspace_name , file ):
33+ if file .short_path .startswith ("../" ):
34+ return file .short_path [3 :]
35+ else :
36+ return workspace_name + "/" + file .short_path
37+
38+
39+ def _interpreter_path (workspace_name , py_toolchain ):
40+ return (
41+ _to_rlocation_path (workspace_name , py_toolchain .python )
42+ if py_toolchain .runfiles_interpreter
43+ else py_toolchain .python .path
44+ )
45+
3146# FIXME: This is derived directly from the py_binary.bzl rule and should really
3247# be a layer on top of it if we can figure out flowing the data around. This is
3348# PoC quality.
@@ -96,57 +111,73 @@ def _py_venv_base_impl(ctx):
96111
97112 venv_name = ".{}" .format (ctx .attr .name )
98113 venv_dir = ctx .actions .declare_directory (venv_name )
114+ workspace_name = ctx .workspace_name
115+
116+ args = ctx .actions .args ()
117+ args .add_all ([venv_dir ], expand_directories = False , format_each = "--location=%s" )
118+ args .add (py_shim .bin .bin , format = "--venv-shim=%s" )
119+
120+ # Post-bzlmod we need to record the current repository in case the
121+ # user tries to consume a `py_venv_binary` across repo boundaries
122+ # which could cause repo mapping to become relevant.
123+ args .add (
124+ ctx .label .repo_name or workspace_name ,
125+ format = "--repo=%s" ,
126+ )
127+ args .add_all (
128+ [py_toolchain ],
129+ map_each = lambda py_toolchain : _interpreter_path (workspace_name , py_toolchain ),
130+ format_each = "--python=%s" ,
131+ allow_closure = True )
132+ args .add (site_packages_pth_file , format = "--pth-file=%s" )
133+ args .add (env_file , format = "--env-file=%s" )
134+ args .add (ctx .bin_dir .path , format = "--bin-dir=%s" )
135+ args .add (ctx .attr .package_collisions , format = "--collision-strategy=%s" )
136+ args .add (venv_name , format = "--venv-name=%s" )
137+ args .add (ctx .attr .mode , format = "--mode=%s" )
138+ args .add (
139+ "{}.{}" .format (
140+ py_toolchain .interpreter_version_info .major ,
141+ py_toolchain .interpreter_version_info .minor ,
142+ ),
143+ format = "--version=%s" ,
144+ )
145+ args .add (
146+ "true" if ctx .attr .include_system_site_packages else "false" ,
147+ format = "--include-system-site-packages=%s" ,
148+ )
149+ args .add (
150+ "true" if ctx .attr .include_system_site_packages else "false" ,
151+ format = "--include-user-site-packages=%s" ,
152+ )
153+
154+ if ctx .attr .debug :
155+ args .add ("--debug" )
99156
100157 ctx .actions .run (
101158 executable = venv_tool ,
102- arguments = [
103- "--location=" + venv_dir .path ,
104- "--venv-shim=" + py_shim .bin .bin .path ,
105- # Post-bzlmod we need to record the current repository in case the
106- # user tries to consume a `py_venv_binary` across repo boundaries
107- # which could cause repo mapping to become relevant.
108- "--repo=" + (ctx .label .repo_name or ctx .workspace_name ),
109- "--python=" + (to_rlocation_path (ctx , py_toolchain .python ) if py_toolchain .runfiles_interpreter else py_toolchain .python .path ),
110- "--pth-file=" + site_packages_pth_file .path ,
111- "--env-file=" + env_file .path ,
112- "--bin-dir=" + ctx .bin_dir .path ,
113- "--collision-strategy=" + ctx .attr .package_collisions ,
114- "--venv-name=" + venv_name ,
115- "--mode=" + ctx .attr .mode ,
116- "--version={}.{}" .format (
117- py_toolchain .interpreter_version_info .major ,
118- py_toolchain .interpreter_version_info .minor ,
119- ),
120- "--include-system-site-packages=" + ({
121- True : "true" ,
122- False : "false" ,
123- }[ctx .attr .include_system_site_packages ]),
124- "--include-user-site-packages=" + ({
125- True : "true" ,
126- False : "false" ,
127- }[ctx .attr .include_system_site_packages ]),
128- ] + (["--debug" ] if ctx .attr .debug else []),
159+ arguments = [args ],
129160 inputs = rfs .merge_all ([
130- ctx .runfiles (files = [
131- site_packages_pth_file ,
132- env_file ,
133- venv_tool ,
134- ] + py_toolchain .files .to_list ()),
161+ ctx .runfiles (files = [site_packages_pth_file , env_file , venv_tool ]),
135162 py_shim .default_info .default_runfiles ,
136163 ]).files ,
137164 outputs = [
138165 venv_dir ,
139166 ],
167+ execution_requirements = {
168+ "supports-path-mapping" : "1" ,
169+ },
140170 # TODO: Is this right? The venv toolchain isn't quite in the right
141171 # configuration (target not exec) so we have to use a different source
142172 # of the target, but it is (logically) the venv toolchain.
143173 toolchain = VENV_TOOLCHAIN ,
144174 )
145175
146176 return venv_dir , rfs .merge_all ([
147- ctx .runfiles (files = [
148- venv_dir ,
149- ] + py_toolchain .files .to_list ()),
177+ ctx .runfiles (
178+ files = [venv_dir ],
179+ transitive_files = py_toolchain .files ,
180+ ),
150181 ctx .attr ._runfiles_lib [DefaultInfo ].default_runfiles ,
151182 ])
152183
0 commit comments