]>
Commit | Line | Data |
---|---|---|
727e2055 MT |
1 | # -*- coding: utf-8 -*- ex:set ts=4 sw=4 et: |
2 | ||
3 | # Copyright © 2008 - Steve Frécinaux | |
4 | # License: LGPL 2 | |
5 | ||
6 | import subprocess | |
7 | import select | |
8 | import exceptions | |
9 | import os | |
10 | ||
11 | class ExecutionError(exceptions.Exception): | |
12 | pass | |
13 | ||
14 | class GitBinary(object): | |
15 | binary = ['/usr/bin/env', 'git'] | |
16 | ||
17 | def __init__(self, repo_dir, bare=False): | |
18 | self.repo_args = [] | |
19 | if bare: | |
20 | self.repo_args.append('--bare') | |
21 | else: | |
22 | self.repo_args.append('--work-tree=%s' % repo_dir) | |
23 | repo_dir = os.path.join(repo_dir, '.git') | |
24 | self.repo_args.append('--git-dir=%s' % repo_dir) | |
25 | self.bare = bare | |
26 | self.git_dir = repo_dir | |
27 | ||
28 | def _command(self, *args): | |
29 | if args[0] == 'clone': | |
30 | return self.binary + list(args) | |
31 | else: | |
32 | return self.binary + self.repo_args + list(args) | |
33 | ||
34 | def gen(self, p): | |
35 | while True: | |
36 | rlist = select.select([p.stdout], [], [])[0] | |
37 | if p.stdout in rlist: | |
38 | line = p.stdout.readline() | |
39 | if line: | |
40 | yield line.rstrip("\n") | |
41 | else: | |
42 | break | |
43 | p.stdout.close() | |
44 | ||
45 | if p.wait() != 0: | |
46 | raise ExecutionError("Subprocess exited with non-zero returncode" | |
47 | " of %d" % p.returncode) | |
48 | ||
49 | def __call__(self, *args, **kwargs): | |
50 | cmd = self._command(args) | |
51 | ||
52 | # The input parameter allows to feed the process's stdin | |
53 | input = kwargs.get('input', None) | |
54 | has_input = input is not None | |
55 | ||
56 | # The wait parameter will make the function wait for the process to | |
57 | # have completed and return the full output at once. | |
58 | wait = bool(kwargs.get('wait', False)) | |
59 | ||
60 | # The output parameter will make the function watch for some output. | |
61 | has_output = bool(kwargs.get('output', True)) | |
62 | ||
63 | p = subprocess.Popen(self._command(*args), | |
64 | stdin = has_input and subprocess.PIPE or None, | |
65 | stdout = has_output and subprocess.PIPE or None, | |
66 | bufsize=1) | |
67 | if has_input: | |
68 | p.stdin.write(input) | |
69 | p.stdin.close() | |
70 | ||
71 | if has_output: | |
72 | gen = self.gen(p) | |
73 | return wait and '\n'.join(gen) or gen | |
74 | ||
75 | if p.wait() != 0: | |
76 | raise ExecutionError("Subprocess exited with non-zero returncode" | |
77 | " of %d" % p.returncode) |