@@ -334,7 +334,7 @@ def _mkdir(mrctx, path):
334334 repo_root = str (mrctx .path ("." ))
335335 path_str = str (path )
336336
337- if not path_str . startswith ( repo_root ):
337+ if not _is_relative_to ( mrctx , path_str , repo_root ):
338338 mkdir_bin = mrctx .which ("mkdir" )
339339 if not mkdir_bin :
340340 return None
@@ -348,6 +348,28 @@ def _mkdir(mrctx, path):
348348 mrctx .delete (placeholder )
349349 return path
350350
351+ def _norm_path (mrctx , p ):
352+ p = str (p )
353+
354+ # Windows is case-insensitive
355+ if _get_platforms_os_name (mrctx ) == "windows" :
356+ return p .lower ()
357+ return p
358+
359+ def _relative_to (mrctx , path , parent , fail = fail ):
360+ path_d = _norm_path (mrctx , path ) + "/"
361+ parent_d = _norm_path (mrctx , parent ) + "/"
362+ if path_d .startswith (parent_d ):
363+ return path_d .removeprefix (parent_d )
364+ else :
365+ fail ("{} is not relative to {}" .format (path , parent ))
366+
367+ def _is_relative_to (mrctx , path , parent ):
368+ """Tell if `path` is equal to or beneath `parent`."""
369+ path = _norm_path (mrctx , path )
370+ parent = _norm_path (mrctx , parent )
371+ return (parent + "/" ).startswith (path + "/" )
372+
351373def _repo_root_relative_path (mrctx , path ):
352374 """Takes a path object and returns a repo-relative path string.
353375
@@ -360,14 +382,7 @@ def _repo_root_relative_path(mrctx, path):
360382 """
361383 repo_root = str (mrctx .path ("." ))
362384 path_str = str (path )
363- relative_path = path_str [len (repo_root ):]
364- if relative_path [0 ] != "/" :
365- fail ("{path} not under {repo_root}" .format (
366- path = path ,
367- repo_root = repo_root ,
368- ))
369- relative_path = relative_path [1 :]
370- return relative_path
385+ return _relative_to (mrctx , path_str , repo_root )
371386
372387def _args_to_str (arguments ):
373388 return " " .join ([_arg_repr (a ) for a in arguments ])
@@ -516,6 +531,8 @@ repo_utils = struct(
516531 is_repo_debug_enabled = _is_repo_debug_enabled ,
517532 logger = _logger ,
518533 mkdir = _mkdir ,
534+ norm_path = _norm_path ,
535+ relative_to = _relative_to ,
519536 repo_root_relative_path = _repo_root_relative_path ,
520537 which_checked = _which_checked ,
521538 which_unchecked = _which_unchecked ,
0 commit comments