MCPcopy
hub / github.com/ray-project/ray / replace_symlinks_with_junctions

Function replace_symlinks_with_junctions

python/setup.py:479–532  ·  view source on GitHub ↗

Per default Windows requires admin access to create symlinks, while junctions (which behave similarly) can be created by users. This function replaces symlinks (which might be broken when checked out without admin rights) with junctions so Ray can be built both with and without

()

Source from the content-addressed store, hash-verified

477
478
479def replace_symlinks_with_junctions():
480 """
481 Per default Windows requires admin access to create symlinks, while
482 junctions (which behave similarly) can be created by users.
483
484 This function replaces symlinks (which might be broken when checked
485 out without admin rights) with junctions so Ray can be built both
486 with and without admin access.
487 """
488 assert is_native_windows_or_msys()
489
490 # Update this list if new symlinks are introduced to the source tree
491 _LINKS = {
492 r"ray\rllib": "../../rllib",
493 }
494 root_dir = os.path.dirname(__file__)
495 for link, default in _LINKS.items():
496 path = os.path.join(root_dir, link)
497 try:
498 out = subprocess.check_output(
499 "DIR /A:LD /B", shell=True, cwd=os.path.dirname(path)
500 )
501 except subprocess.CalledProcessError:
502 out = b""
503 if os.path.basename(path) in out.decode("utf8").splitlines():
504 logger.info(f"'{link}' is already converted to junction point")
505 else:
506 logger.info(f"Converting '{link}' to junction point...")
507 if os.path.isfile(path):
508 with open(path) as inp:
509 target = inp.read()
510 os.unlink(path)
511 elif os.path.isdir(path):
512 target = default
513 try:
514 # unlink() works on links as well as on regular files,
515 # and links to directories are considered directories now
516 os.unlink(path)
517 except OSError as err:
518 # On Windows attempt to unlink a regular directory results
519 # in a PermissionError with errno set to errno.EACCES.
520 if err.errno != errno.EACCES:
521 raise
522 # For regular directories deletion is done with rmdir call.
523 os.rmdir(path)
524 else:
525 raise ValueError(f"Unexpected type of entry: '{path}'")
526 target = os.path.abspath(os.path.join(os.path.dirname(path), target))
527 logger.info("Setting {} -> {}".format(link, target))
528 subprocess.check_call(
529 f'MKLINK /J "{os.path.basename(link)}" "{target}"',
530 shell=True,
531 cwd=os.path.dirname(path),
532 )
533
534
535if is_conda_forge_build and is_native_windows_or_msys():

Callers 1

setup.pyFile · 0.85

Calls 10

openFunction · 0.85
check_outputMethod · 0.80
check_callMethod · 0.80
itemsMethod · 0.45
joinMethod · 0.45
decodeMethod · 0.45
infoMethod · 0.45
readMethod · 0.45
formatMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…