source: rtems-source-builder/source-builder/sb/git.py @ 97a685f

4.104.114.95
Last change on this file since 97a685f was 97a685f, checked in by Chris Johns <chrisj@…>, on 04/30/13 at 01:20:54

Add mail support to mail reports.

  • Property mode set to 100644
File size: 6.3 KB
Line 
1#
2# RTEMS Tools Project (http://www.rtems.org/)
3# Copyright 2010-2013 Chris Johns (chrisj@rtems.org)
4# All rights reserved.
5#
6# This file is part of the RTEMS Tools package in 'rtems-tools'.
7#
8# Permission to use, copy, modify, and/or distribute this software for any
9# purpose with or without fee is hereby granted, provided that the above
10# copyright notice and this permission notice appear in all copies.
11#
12# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
20#
21# Provide some basic access to the git command.
22#
23
24import os
25
26import error
27import execute
28import log
29import options
30import path
31
32class repo:
33    """An object to manage a git repo."""
34
35    def _git_exit_code(self, ec):
36        if ec:
37            raise error.general('git command failed (%s): %d' % (self.git, ec))
38
39    def _run(self, args, check = False):
40        e = execute.capture_execution()
41        if path.exists(self.path):
42            cwd = self.path
43        else:
44            cwd = None
45        cmd = [self.git] + args
46        log.trace('cmd: (%s) %s' % (str(cwd), ' '.join(cmd)))
47        exit_code, proc, output = e.spawn(cmd, cwd = cwd)
48        log.trace(output)
49        if check:
50            self._git_exit_code(exit_code)
51        return exit_code, output
52
53    def __init__(self, _path, opts, macros = None):
54        self.path = _path
55        self.opts = opts
56        if macros is None:
57            self.macros = opts.defaults
58        else:
59            self.macros = macros
60        self.git = self.macros.expand('%{__git}')
61
62    def git_version(self):
63        ec, output = self._run(['--version'], True)
64        gvs = output.split()
65        if len(gvs) < 3:
66            raise error.general('invalid version string from git: %s' % (output))
67        vs = gvs[2].split('.')
68        if len(vs) != 4:
69            raise error.general('invalid version number from git: %s' % (gvs[2]))
70        return (int(vs[0]), int(vs[1]), int(vs[2]), int(vs[3]))
71
72    def clone(self, url, path):
73        ec, output = self._run(['clone', url, path], check = True)
74
75    def fetch(self):
76        ec, output = self._run(['fetch'], check = True)
77
78    def pull(self):
79        ec, output = self._run(['pull'], check = True)
80
81    def reset(self, args):
82        if type(args) == str:
83            args = [args]
84        ec, output = self._run(['reset'] + args, check = True)
85
86    def branch(self):
87        ec, output = self._run(['branch'])
88        if ec == 0:
89            for b in output.split('\n'):
90                if b[0] == '*':
91                    return b[2:]
92        return None
93
94    def checkout(self, branch = 'master'):
95        ec, output = self._run(['checkout', branch], check = True)
96
97    def status(self):
98        _status = {}
99        if path.exists(self.path):
100            ec, output = self._run(['status'])
101            if ec == 0:
102                state = 'none'
103                for l in output.split('\n'):
104                    if l.startswith('# On branch '):
105                        _status['branch'] = l[len('# On branch '):]
106                    elif l.startswith('# Changes to be committed:'):
107                        state = 'staged'
108                    elif l.startswith('# Changes not staged for commit:'):
109                        state = 'unstaged'
110                    elif l.startswith('# Untracked files:'):
111                        state = 'untracked'
112                    elif state != 'none' and l[0] == '#':
113                        if l.strip() != '#' and not l.startswith('#   ('):
114                            if state not in _status:
115                                _status[state] = []
116                            l = l[1:]
117                            if ':' in l:
118                                l = l.split(':')[1]
119                            _status[state] += [l.strip()]
120        return _status
121
122    def clean(self):
123        _status = self.status()
124        return len(_status) == 1 and 'branch' in _status
125
126    def valid(self):
127        if path.exists(self.path):
128            ec, output = self._run(['status'])
129            return ec == 0
130        return False
131
132    def remotes(self):
133        _remotes = {}
134        ec, output = self._run(['config', '--list'])
135        if ec == 0:
136            for l in output.split('\n'):
137                if l.startswith('remote'):
138                    ls = l.split('=')
139                    if len(ls) >= 2:
140                        rs = ls[0].split('.')
141                        if len(rs) == 3:
142                            r_name = rs[1]
143                            r_type = rs[2]
144                            if r_name not in _remotes:
145                                _remotes[r_name] = {}
146                            if r_type not in _remotes[r_name]:
147                                _remotes[r_name][r_type] = []
148                            _remotes[r_name][r_type] = '='.join(ls[1:])
149        return _remotes
150
151    def email(self):
152        _email = None
153        _name = None
154        ec, output = self._run(['config', '--list'])
155        if ec == 0:
156            for l in output.split('\n'):
157                if l.startswith('user.email'):
158                    ls = l.split('=')
159                    if len(ls) >= 2:
160                        _email = ls[1]
161                elif l.startswith('user.name'):
162                    ls = l.split('=')
163                    if len(ls) >= 2:
164                        _name = ls[1]
165        if _email is not None:
166            if _name is not None:
167                _email = '%s <%s>' % (_name, _email)
168            return _email
169        return None
170
171    def head(self):
172        hash = ''
173        ec, output = self._run(['log', '-n', '1'])
174        if ec == 0:
175            l1 = output.split('\n')[0]
176            if l1.startswith('commit '):
177                hash = l1[len('commit '):]
178        return hash
179
180if __name__ == '__main__':
181    import sys
182    opts = options.load(sys.argv)
183    g = repo('.', opts)
184    print g.git_version()
185    print g.valid()
186    print g.status()
187    print g.clean()
188    print g.remotes()
189    print g.email()
190    print g.head()
Note: See TracBrowser for help on using the repository browser.