Convert some scripts to Python
[mplayer-build.git] / script / helpers.py
blob64e8f0aab04e9a3e15b13d75b2070705f14fc91f
1 import os
2 from os import path
3 import types
4 from subprocess import Popen, PIPE, check_call
6 def run_command(args):
7 # interpret a string as a whitespace-separated list of executable+arguments
8 if isinstance(args, types.StringTypes):
9 args = args.split()
10 t = Popen(args, stdout=PIPE)
11 stdout = t.communicate()[0]
12 if t.returncode != 0:
13 raise OSError("Call %s failed" % args)
14 return stdout
16 class GitWrapper(object):
17 def __init__(self):
18 self.shallow = False
19 self.supports_nofetch = True
20 v = run_command('git --version')
21 prefix = 'git version '
22 def error():
23 sys.stderr.write('Cannot parse "git --version" output, '
24 'assuming new version')
25 if not v.startswith(prefix):
26 error()
27 return
28 v = v[len(prefix):]
29 try:
30 v = [int(n) for n in v.split('.')[:3]]
31 except:
32 error()
33 return
34 if v < [1, 6, 2]:
35 self.supports_nofetch = False
37 def submodule_clone(self, name):
38 if self.shallow:
39 # Use a depth greater than 1 for shallow clones to reduce the
40 # chance that required submodule versions are not fetched when
41 # all branch heads in the corresponding repo have moved ahead.
42 shallow_args = ['--depth', '100']
43 else:
44 shallow_args = []
45 if self.supports_nofetch:
46 nofetch_args = ['--no-fetch']
47 else:
48 nofetch_args = []
49 if path.exists(path.join(name, '.git')):
50 # If the submodule already exists just try to update it
51 check_call('git submodule sync'.split()+[name])
52 check_call('git submodule update'.split()+[name])
53 else:
54 # Do things manually instead of using "git submodule update --init",
55 # because git's sucky submodule support has no way of giving
56 # options to the "git clone" command that would be needed for
57 # shallow clones.
58 repo_addr = run_command('git config --get submodule.%s.url' % name)
59 # old git versions fail to clone over an empty directory
60 try:
61 os.rmdir(name)
62 except:
63 # Don't fail if it already doesn't exist - having other
64 # failure cases continue and fail later is OK.
65 pass
66 check_call('git clone'.split() + shallow_args + [repo_addr, name])
67 check_call('git submodule update'.split() + nofetch_args + [name])
69 def get_config(self):
70 output = run_command('git config --list --null')
71 result = {}
72 for line in output.split(chr(0)):
73 if not line:
74 continue
75 name, value = line.split('\n', 1)
76 result[name] = value
77 return result
79 def get_submodules(self):
80 output = run_command('git ls-files --stage')
81 result = []
82 for line in output.splitlines():
83 mode, sha, stage, path = line.split(None, 3)
84 if mode != '160000':
85 continue
86 result.append(path)
87 return result
89 def run_foreach_submodule(command, *args):
90 env = os.environ.copy()
91 env['MPBUILD_COMMAND'] = command
92 executable = path.join(os.getcwd(), 'script', 'foreach_submodule')
93 check_call([executable] + list(args), env=env)
95 def parse_configfile(filename):
96 if not path.exists(filename):
97 return []
98 args = []
99 f = open(filename)
100 for line in f:
101 line = line.strip()
102 if not line or line.startswith('#'):
103 continue
104 args.append(line)
105 f.close()
106 return args