4 from subprocess
import Popen
, PIPE
, check_call
6 # Arch Linux thought it was a good idea to suddenly switch the "python"
7 # binary to point to python3...
9 This script is written for Python version 2, but for some reason
10 it's being run under incompatible version 3. If you didn't do anything
11 yourself to explicitly change the version then the reason is probably
12 that your system links plain "python" to "python3" instead of a
13 backwards-compatible version. Arch Linux reportedly did this.
14 You may be able to make things work by changing the first line of all
15 Python scripts from "#!/usr/bin/env python" to "#!/usr/bin/env python2".
16 Blame your distro for the inconvenience.
19 if sys
.version_info
> (3,):
20 raise Exception(version3error
)
22 def run_command(args
):
23 # interpret a string as a whitespace-separated list of executable+arguments
24 if isinstance(args
, types
.StringTypes
):
26 t
= Popen(args
, stdout
=PIPE
)
27 stdout
= t
.communicate()[0]
29 raise OSError("Call %s failed" % str(args
))
32 class GitWrapper(object):
35 self
.supports_nofetch
= True
36 v
= run_command('git --version')
37 prefix
= 'git version '
39 sys
.stderr
.write('Cannot parse "git --version" output, '
40 'assuming new version')
41 if not v
.startswith(prefix
):
46 v
= [int(n
) for n
in v
.split('.')[:3]]
51 self
.supports_nofetch
= False
53 def submodule_clone(self
, name
):
55 # Use a depth greater than 1 for shallow clones to reduce the
56 # chance that required submodule versions are not fetched when
57 # all branch heads in the corresponding repo have moved ahead.
58 shallow_args
= ['--depth', '100']
61 if self
.supports_nofetch
:
62 nofetch_args
= ['--no-fetch']
65 if path
.exists(path
.join(name
, '.git')):
66 # If the submodule already exists just try to update it
67 check_call('git submodule sync'.split()+[name
])
68 check_call('git submodule update'.split()+[name
])
70 # Do things manually instead of using "git submodule update --init",
71 # because git's sucky submodule support has no way of giving
72 # options to the "git clone" command that would be needed for
74 repo_addr
= run_command('git config --get submodule.%s.url' % name
)
75 # old git versions fail to clone over an empty directory
79 # Don't fail if it already doesn't exist - having other
80 # failure cases continue and fail later is OK.
82 check_call('git clone'.split() + shallow_args
+ [repo_addr
, name
])
83 check_call('git submodule update'.split() + nofetch_args
+ [name
])
86 output
= run_command('git config --null --list')
88 for line
in output
.split(chr(0)):
91 name
, value
= line
.split('\n', 1)
95 def get_submodules(self
):
96 output
= run_command('git ls-files --stage')
98 for line
in output
.splitlines():
99 mode
, sha
, stage
, path
= line
.split(None, 3)
105 def foreach_submodule(self
, func
, recurse
=True):
106 for module
in self
.get_submodules():
107 if path
.exists(path
.join(module
, '.git')):
111 self
.foreach_submodule(func
)
114 def foreach_module(self
, func
):
116 self
.foreach_submodule(func
)
119 def parse_configfile(filename
):
120 if not path
.exists(filename
):
126 if not line
or line
.startswith('#'):