@@ -181,60 +181,43 @@ def get_interpreter(archive):
181181
182182def _normalize_patterns (values : Iterable [str ] | None ) -> list [str ]:
183183 """
184- Split comma-separated items, strip whitespace, drop empties.
185- If a token has no glob metacharacters, treat it as a directory prefix:
186- expand 'foo' into ['foo', 'foo/**'] (after normalizing slashes).
184+ Return patterns exactly as provided by the CLI (no comma splitting).
185+ Each item is stripped of surrounding whitespace; empty items are dropped.
187186 """
188187 if not values :
189188 return []
190-
191- def has_glob (s : str ) -> bool :
192- return any (ch in s for ch in "*?[]" )
193-
194189 out : list [str ] = []
195190 for v in values :
196- for raw in (p .strip () for p in v .split (',' )):
197- if not raw :
198- continue
199- # normalize user input to POSIX-like form (match against rel.as_posix())
200- tok = raw .replace ('\\ ' , '/' ).lstrip ('./' ).rstrip ('/' )
201- if not tok :
202- continue
203- if has_glob (tok ):
204- out .append (tok )
205- else :
206- # directory name implies subtree
207- out .append (tok )
208- out .append (f"{ tok } /**" )
191+ v = v .strip ()
192+ if v :
193+ out .append (v )
209194 return out
210195
211196def _make_glob_filter (
212197 includes : Iterable [str ] | None ,
213- excludes : Iterable [str ] | None
198+ excludes : Iterable [str ] | None ,
214199) -> Callable [[pathlib .Path ], bool ]:
215200 """
216- Build a filter(relative_path: Path) -> bool applying include first, then exclude.
217- - Path argument is relative to source_root
218- - Patterns are matched against POSIX-style relative paths
219- - If includes is empty, defaults to ["**"] (include all)
201+ Build a filter(relative_path: Path) -> bool applying includes first, then excludes.
202+
203+ Semantics:
204+ - Patterns are standard glob patterns as implemented by PurePath.match.
205+ - If 'includes' is empty, all files/dirs are initially eligible.
206+ - If any exclude pattern matches, the path is rejected.
207+ - Matching respects the current platform's path flavor (separators, case).
220208 """
221- inc = _normalize_patterns (includes )
222- exc = _normalize_patterns (excludes )
223- if not inc :
224- inc = ["**" ]
209+ inc = _normalize_patterns (values = includes )
210+ exc = _normalize_patterns (values = excludes )
225211
226- def matches_any (patterns : list [str ], rel : pathlib .Path ) -> bool :
227- posix = rel .as_posix ()
228- # pathlib.Path.match uses glob semantics with ** (recursive)
229- return any (rel .match (pat ) or pathlib .PurePosixPath (posix ).match (pat )
230- for pat in patterns )
212+ if not inc and not exc :
213+ return None
231214
232215 def _filter (rel : pathlib .Path ) -> bool :
233- # Always work on files and directories; we'll add both. If a directory
234- # is excluded, its children still get visited by rglob('*') but will fail here.
235- if not matches_any (inc , rel ):
216+ # If includes were provided, at least one must match.
217+ if inc and not any (rel .match (pat ) for pat in inc ):
236218 return False
237- if exc and matches_any (exc , rel ):
219+ # Any exclude match removes the path.
220+ if exc and any (rel .match (pat ) for pat in exc ):
238221 return False
239222 return True
240223
@@ -268,10 +251,13 @@ def main(args=None):
268251 help = "Source directory (or existing archive)." )
269252 parser .add_argument ('--include' , action = 'extend' , nargs = '+' , default = None ,
270253 help = ("Glob pattern(s) of files/dirs to include (relative to SOURCE). "
271- "Repeat or use commas. Defaults to '**' (everything)." ))
254+ "Repeat the flag for multiple patterns. "
255+ "To include a directory and its contents, use 'foo/**'." ))
272256 parser .add_argument ('--exclude' , action = 'extend' , nargs = '+' , default = None ,
273257 help = ("Glob pattern(s) of files/dirs to exclude (relative to SOURCE). "
274- "Repeat or use commas. Applied after --include." ))
258+ "Repeat the flag for multiple patterns. "
259+ "To exclude a directory and its contents, use 'foo/**'. "
260+ "Applied after --include." ))
275261
276262 args = parser .parse_args (args )
277263
@@ -293,8 +279,11 @@ def main(args=None):
293279 # build a filter from include and exclude flags
294280 filter_fn = None
295281 src_path = pathlib .Path (args .source )
296- if src_path .exists () and src_path .is_dir ():
297- filter_fn = _make_glob_filter (args .include , args .exclude )
282+ if src_path .exists () and src_path .is_dir () and (args .include or args .exclude ):
283+ filter_fn = _make_glob_filter (
284+ includes = args .include ,
285+ excludes = args .exclude
286+ )
298287
299288 create_archive (args .source , args .output ,
300289 interpreter = args .python , main = args .main ,
0 commit comments