Update libav submodule
[mplayer-build.git] / script / helpers.py
blob3304da2da6bffbcd75ef21eac7e4ee19fed53118
1 import sys
2 import os
3 from os import path
4 import types
5 from subprocess import Popen, PIPE, check_call
7 def run_command(args):
8 # interpret a string as a whitespace-separated list of executable+arguments
9 if isinstance(args, (str, bytes)):
10 args = args.split()
11 t = Popen(args, stdout=PIPE)
12 stdout = t.communicate()[0]
13 if t.returncode != 0:
14 raise OSError("Call %s failed" % str(args))
15 return stdout
17 class GitWrapper(object):
18 def __init__(self):
19 self.shallow = False
20 self.supports_nofetch = True
21 v = run_command('git --version')
22 prefix = b'git version '
23 def error():
24 sys.stderr.write('Cannot parse "git --version" output, '
25 'assuming new version\n')
26 if not v.startswith(prefix):
27 error()
28 return
29 v = v[len(prefix):]
30 try:
31 v = [int(n) for n in v.split(b'.')[:3]]
32 except:
33 error()
34 return
35 if v < [1, 6, 2]:
36 self.supports_nofetch = False
38 def submodule_clone(self, name):
39 if self.shallow:
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']
44 else:
45 shallow_args = []
46 if self.supports_nofetch:
47 nofetch_args = ['--no-fetch']
48 else:
49 nofetch_args = []
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])
54 else:
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
58 # shallow clones.
59 repo_addr = run_command('git config --get submodule.%s.url'
60 % name).strip()
61 # old git versions fail to clone over an empty directory
62 try:
63 os.rmdir(name)
64 except:
65 # Don't fail if it already doesn't exist - having other
66 # failure cases continue and fail later is OK.
67 pass
68 check_call('git clone'.split() + shallow_args + [repo_addr, name])
69 check_call('git submodule update'.split() + nofetch_args + [name])
71 def get_config(self):
72 output = run_command('git config --null --list')
73 result = {}
74 for line in output.split(bytes([0])):
75 if not line:
76 continue
77 name, value = line.split(b'\n', 1)
78 result[name] = value
79 return result
81 def get_submodules(self):
82 output = run_command('git ls-files --stage')
83 result = []
84 for line in output.splitlines():
85 mode, sha, stage, path = line.split(None, 3)
86 if mode != b'160000':
87 continue
88 result.append(path)
89 return result
91 def foreach_submodule(self, func, recurse=True):
92 for module in self.get_submodules():
93 if path.exists(path.join(module, b'.git')):
94 os.chdir(module)
95 func()
96 if recurse:
97 self.foreach_submodule(func)
98 os.chdir('..')
100 def foreach_module(self, func):
101 func()
102 self.foreach_submodule(func)
105 def parse_configfile(filename):
106 if not path.exists(filename):
107 return []
108 args = []
109 f = open(filename, 'rb')
110 for line in f:
111 line = line.strip()
112 if not line or line.startswith(b'#'):
113 continue
114 args.append(line)
115 f.close()
116 return args