Skip to content
Browse files

Follow symlinks to git-managed files

This is very useful for situations where you have symlinks in your
source pointing to files outside the package source, but still managed
in the same git repository. A common use case is sharing CSS and
javascript files between a prototype and a website implementation.
  • Loading branch information...
1 parent 16bf92c commit 8528d58975c595b64eea9e7e67298517117a7744 @wichert wichert committed
Showing with 27 additions and 7 deletions.
  1. +27 −7 setuptools_git.py
View
34 setuptools_git.py
@@ -4,8 +4,10 @@
A hook into setuptools for Git.
"""
+import os
from subprocess import CalledProcessError
from subprocess import PIPE
+from distutils.log import warn
try:
from subprocess import check_output
@@ -14,7 +16,8 @@
def check_output(*popenargs, **kwargs):
from subprocess import Popen
if 'stdout' in kwargs:
- raise ValueError('stdout argument not allowed, it will be overridden.')
+ raise ValueError(
+ 'stdout argument not allowed, it will be overridden.')
process = Popen(stdout=PIPE, *popenargs, **kwargs)
output, unused_err = process.communicate()
retcode = process.poll()
@@ -26,16 +29,33 @@ def check_output(*popenargs, **kwargs):
return output
-def gitlsfiles(dirname=""):
+def gitlsfiles(dirname=''):
try:
- output = check_output(['git', 'ls-files', dirname], stderr=PIPE)
- except CalledProcessError:
+ if dirname:
+ cwd = dirname
+ else:
+ cwd = None
+ dirname = '.'
+ dirname = os.path.realpath(dirname)
+ git_top = check_output(['git', 'rev-parse', '--show-toplevel'],
+ stderr=PIPE, cwd=cwd).strip()
+ git_files = check_output(['git', 'ls-files'], cwd=git_top, stderr=PIPE)
+ git_files = set([os.path.join(git_top, fn)
+ for fn in git_files.splitlines()])
+ except (CalledProcessError, OSError):
# Something went terribly wrong but the setuptools doc says we
# must be strong in the face of danger. We shall not run away
# in panic.
- return []
+ warn('Error running git')
+ raise StopIteration
- return output.splitlines()
+ prefix_length = len(dirname) + 1
+ for (root, dirs, files) in os.walk(dirname, followlinks=True):
+ for file in files:
+ filename = os.path.join(root, file)
+ realname = os.path.realpath(filename)
+ if realname in git_files:
+ yield filename[prefix_length:]
if __name__ == "__main__":
@@ -46,4 +66,4 @@ def gitlsfiles(dirname=""):
print("USAGE: %s DIRNAME" % sys.argv[0])
sys.exit(1)
- pprint(gitlsfiles(sys.argv[1]))
+ pprint(list(gitlsfiles(sys.argv[1])))

0 comments on commit 8528d58

Please sign in to comment.
Something went wrong with that request. Please try again.