Update ffmpeg and ffmpeg-mt submodules
[mplayer-build.git] / script / helpers.py
blobc592cc84ebc121e8bf264cb835a3e48c21c481c4
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 --null --list')
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 foreach_submodule(self, func, recurse=True):
90 for module in self.get_submodules():
91 if path.exists(path.join(module, '.git')):
92 os.chdir(module)
93 func()
94 if recurse:
95 self.foreach_submodule(func)
96 os.chdir('..')
98 def foreach_module(self, func):
99 func()
100 self.foreach_submodule(func)
103 def parse_configfile(filename):
104 if not path.exists(filename):
105 return []
106 args = []
107 f = open(filename)
108 for line in f:
109 line = line.strip()
110 if not line or line.startswith('#'):
111 continue
112 args.append(line)
113 f.close()
114 return args