mirror of
https://github.com/kristoferssolo/School.git
synced 2025-10-21 20:10:38 +00:00
71 lines
2.5 KiB
Python
71 lines
2.5 KiB
Python
import os
|
|
|
|
from .utils import trace
|
|
|
|
|
|
def scm_find_files(path, scm_files, scm_dirs):
|
|
""" setuptools compatible file finder that follows symlinks
|
|
|
|
- path: the root directory from which to search
|
|
- scm_files: set of scm controlled files and symlinks
|
|
(including symlinks to directories)
|
|
- scm_dirs: set of scm controlled directories
|
|
(including directories containing no scm controlled files)
|
|
|
|
scm_files and scm_dirs must be absolute with symlinks resolved (realpath),
|
|
with normalized case (normcase)
|
|
|
|
Spec here: http://setuptools.readthedocs.io/en/latest/setuptools.html#\
|
|
adding-support-for-revision-control-systems
|
|
"""
|
|
realpath = os.path.normcase(os.path.realpath(path))
|
|
seen = set()
|
|
res = []
|
|
for dirpath, dirnames, filenames in os.walk(realpath, followlinks=True):
|
|
# dirpath with symlinks resolved
|
|
realdirpath = os.path.normcase(os.path.realpath(dirpath))
|
|
|
|
def _link_not_in_scm(n):
|
|
fn = os.path.join(realdirpath, os.path.normcase(n))
|
|
return os.path.islink(fn) and fn not in scm_files
|
|
|
|
if realdirpath not in scm_dirs:
|
|
# directory not in scm, don't walk it's content
|
|
dirnames[:] = []
|
|
continue
|
|
if os.path.islink(dirpath) and not os.path.relpath(
|
|
realdirpath, realpath
|
|
).startswith(os.pardir):
|
|
# a symlink to a directory not outside path:
|
|
# we keep it in the result and don't walk its content
|
|
res.append(os.path.join(path, os.path.relpath(dirpath, path)))
|
|
dirnames[:] = []
|
|
continue
|
|
if realdirpath in seen:
|
|
# symlink loop protection
|
|
dirnames[:] = []
|
|
continue
|
|
dirnames[:] = [dn for dn in dirnames if not _link_not_in_scm(dn)]
|
|
for filename in filenames:
|
|
if _link_not_in_scm(filename):
|
|
continue
|
|
# dirpath + filename with symlinks preserved
|
|
fullfilename = os.path.join(dirpath, filename)
|
|
if os.path.normcase(os.path.realpath(fullfilename)) in scm_files:
|
|
res.append(os.path.join(path, os.path.relpath(fullfilename, realpath)))
|
|
seen.add(realdirpath)
|
|
return res
|
|
|
|
|
|
def is_toplevel_acceptable(toplevel):
|
|
""" """
|
|
if toplevel is None:
|
|
return False
|
|
|
|
ignored = os.environ.get("SETUPTOOLS_SCM_IGNORE_VCS_ROOTS", "").split(os.pathsep)
|
|
ignored = [os.path.normcase(p) for p in ignored]
|
|
|
|
trace(toplevel, ignored)
|
|
|
|
return toplevel not in ignored
|