5 from subprocess
import Popen
, PIPE
, check_call
8 # interpret a string as a whitespace-separated list of executable+arguments
9 if isinstance(args
, (str, bytes
)):
11 t
= Popen(args
, stdout
=PIPE
)
12 stdout
= t
.communicate()[0]
14 raise OSError("Call %s failed" % str(args
))
17 class GitWrapper(object):
20 self
.supports_nofetch
= True
21 v
= run_command('git --version')
22 prefix
= b
'git version '
24 sys
.stderr
.write('Cannot parse "git --version" output, '
25 'assuming new version\n')
26 if not v
.startswith(prefix
):
31 v
= [int(n
) for n
in v
.split(b
'.')[:3]]
36 self
.supports_nofetch
= False
38 def submodule_clone(self
, name
):
40 # Use a depth greater than 1 for shallow clones to reduce the
41 # chance that required submodule versions are not fetched when
42 # all branch heads in the corresponding repo have moved ahead.
43 shallow_args
= ['--depth', '100']
46 if self
.supports_nofetch
:
47 nofetch_args
= ['--no-fetch']
50 if path
.exists(path
.join(name
, '.git')):
51 # If the submodule already exists just try to update it
52 check_call('git submodule sync'.split()+[name
])
53 check_call('git submodule update'.split()+[name
])
55 # Do things manually instead of using "git submodule update --init",
56 # because git's sucky submodule support has no way of giving
57 # options to the "git clone" command that would be needed for
59 repo_addr
= run_command('git config --get submodule.%s.url'
61 # old git versions fail to clone over an empty directory
65 # Don't fail if it already doesn't exist - having other
66 # failure cases continue and fail later is OK.
68 check_call('git clone'.split() + shallow_args
+ [repo_addr
, name
])
69 check_call('git submodule update'.split() + nofetch_args
+ [name
])
72 output
= run_command('git config --null --list')
74 for line
in output
.split(bytes([0])):
77 name
, value
= line
.split(b
'\n', 1)
81 def get_submodules(self
):
82 output
= run_command('git ls-files --stage')
84 for line
in output
.splitlines():
85 mode
, sha
, stage
, path
= line
.split(None, 3)
91 def foreach_submodule(self
, func
, recurse
=True):
92 for module
in self
.get_submodules():
93 if path
.exists(path
.join(module
, b
'.git')):
97 self
.foreach_submodule(func
)
100 def foreach_module(self
, func
):
102 self
.foreach_submodule(func
)
105 def parse_configfile(filename
):
106 if not path
.exists(filename
):
109 f
= open(filename
, 'rb')
112 if not line
or line
.startswith(b
'#'):