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'
76 # old git versions fail to clone over an empty directory
80 # Don't fail if it already doesn't exist - having other
81 # failure cases continue and fail later is OK.
83 check_call('git clone'.split() + shallow_args
+ [repo_addr
, name
])
84 check_call('git submodule update'.split() + nofetch_args
+ [name
])
87 output
= run_command('git config --null --list')
89 for line
in output
.split(chr(0)):
92 name
, value
= line
.split('\n', 1)
96 def get_submodules(self
):
97 output
= run_command('git ls-files --stage')
99 for line
in output
.splitlines():
100 mode
, sha
, stage
, path
= line
.split(None, 3)
106 def foreach_submodule(self
, func
, recurse
=True):
107 for module
in self
.get_submodules():
108 if path
.exists(path
.join(module
, '.git')):
112 self
.foreach_submodule(func
)
115 def foreach_module(self
, func
):
117 self
.foreach_submodule(func
)
120 def parse_configfile(filename
):
121 if not path
.exists(filename
):
127 if not line
or line
.startswith('#'):