1313# limitations under the License.
1414
1515import collections
16- import functools
1716import itertools
1817import json
1918import os
2221import sys
2322import textwrap
2423import venv
25- from typing import Dict , List , Optional , Union
24+ from typing import Dict , List , Optional
2625
2726import importlib_metadata
2827
@@ -45,25 +44,40 @@ def console_script(env_path: pathlib.Path, module: str, func: str) -> str:
4544 )
4645
4746
48- def get_site_packages_path (path : str , imports : List [str ]) -> Optional [str ]:
49- if not path .startswith ("../" ):
50- return path
47+ def path_starts_with (path : pathlib .Path , prefix : pathlib .Path ) -> bool :
48+ return path .parts [: len (prefix .parts )] == prefix .parts
49+
50+
51+ def get_site_packages_path (
52+ workspace : str , path : pathlib .Path , imports : List [pathlib .Path ]
53+ ) -> Optional [pathlib .Path ]:
54+ # Import prefixes start with the workspace name, which might be the local workspace.
55+ # We first normalize the given path so that it starts with its workspace name.
56+ if path .parts [0 ] == ".." :
57+ wspath = path .relative_to (".." )
58+ is_external = True
59+ else :
60+ wspath = pathlib .Path (workspace ) / path
61+ is_external = False
5162
5263 for imp in imports :
53- # Newer versions of rules_python use a site-packages/ prefix, so we also check for that.
54- prefixes = [f"../{ imp } /site-packages/" , f"../{ imp } /" ]
55- for prefix in prefixes :
56- if path .startswith (prefix ):
57- return path [len (prefix ) :]
64+ if path_starts_with (wspath , imp ):
65+ return wspath .relative_to (imp )
66+
67+ if not is_external :
68+ # If the input wasn't an external path and it didn't match any import prefixes,
69+ # just return it as given.
70+ return path
5871
5972 # External file that didn't match imports. Include but warn.
60- parts = path .split ("/" , maxsplit = 2 )
61- include_path = parts [2 ]
73+ # We include it as relative to its workspace directory, so strip the first component
74+ # off wspath.
75+ include_path = wspath .relative_to (wspath .parts [0 ])
6276 print (f"Warning: [{ path } ] didn't match any imports. Including as [{ include_path } ]" )
6377
6478
65- def is_external (file_ : str ) -> bool :
66- return file_ .startswith ( "../" )
79+ def is_external (file_ : pathlib . Path ) -> bool :
80+ return file_ .parts [ 0 ] == ".."
6781
6882
6983def find_site_packages (env_path : pathlib .Path ) -> pathlib .Path :
@@ -82,21 +96,32 @@ def find_site_packages(env_path: pathlib.Path) -> pathlib.Path:
8296def get_files (build_env_input : Dict ) -> List [EnvFile ]:
8397 files = []
8498
85- imports = build_env_input ["imports" ]
99+ imports = [pathlib .Path (imp ) for imp in build_env_input ["imports" ]]
100+ print (imports )
101+ workspace = build_env_input ["workspace" ]
86102 for depfile in build_env_input ["files" ]:
87103 # Bucket files into external and workspace groups.
88104 # Only generated workspace files are kept.
89105 type_ = depfile ["t" ]
90- path = depfile ["p" ]
106+ input_path = pathlib . Path ( depfile ["p" ])
91107
92- site_packages_path = get_site_packages_path ( path , imports )
93- if not site_packages_path :
108+ # Only add external and generated files
109+ if not ( is_external ( input_path ) or type_ == "G" ) :
94110 continue
95111
96- if is_external (path ):
97- files .append (EnvFile (pathlib .Path (path ), pathlib .Path (site_packages_path )))
98- elif type_ == "G" :
99- files .append (EnvFile (pathlib .Path (path ), pathlib .Path (site_packages_path )))
112+ # If this is a directory, expand to each recursive child.
113+ if input_path .is_dir ():
114+ paths = input_path .glob ("**/*" )
115+ paths = [p for p in paths if not p .is_dir ()]
116+ else :
117+ paths = [input_path ]
118+
119+ for path in paths :
120+ site_packages_path = get_site_packages_path (workspace , path , imports )
121+ if not site_packages_path :
122+ continue
123+
124+ files .append (EnvFile (path , site_packages_path ))
100125
101126 return files
102127
0 commit comments