source: rtems-source-builder/source-builder/sb/git.py @ 649a64c

4.104.114.95
Last change on this file since 649a64c was 649a64c, checked in by Chris Johns <chrisj@…>, on 04/16/13 at 04:25:34

Add download git support.

Add support to use a git cloned repo as the source. Move the download
code out of the build module and into a separate module. Add to this
module support for git.

Update the GCC common configuration to support using a symlinked
git repo.

Add checks for all languages.

  • Property mode set to 100644
File size: 5.8 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 options
29import path
30
31class repo:
32    """An object to manage a git repo."""
33
34    def _git_exit_code(self, ec):
35        if ec:
36            raise error.general('git command failed (%s): %d' % (self.git, ec))
37
38    def _run(self, args, check = False):
39        e = execute.capture_execution()
40        if path.exists(self.path):
41            cwd = self.path
42        else:
43            cwd = None
44        exit_code, proc, output = e.spawn([self.git] + args, cwd = cwd)
45        if check:
46            self._git_exit_code(exit_code)
47        return exit_code, output
48
49    def __init__(self, _path, opts, macros = None):
50        self.path = _path
51        self.opts = opts
52        if macros is None:
53            self.macros = opts.defaults
54        else:
55            self.macros = macros
56        self.git = self.macros.expand('%{__git}')
57
58    def git_version(self):
59        ec, output = self._run(['--version'], True)
60        gvs = output.split()
61        if len(gvs) < 3:
62            raise error.general('invalid version string from git: %s' % (output))
63        vs = gvs[2].split('.')
64        if len(vs) != 4:
65            raise error.general('invalid version number from git: %s' % (gvs[2]))
66        return (int(vs[0]), int(vs[1]), int(vs[2]), int(vs[3]))
67
68    def clone(self, url, path):
69        ec, output = self._run(['clone', url, path])
70        if ec != 0:
71            raise error.general('clone of %s failed: %s' % (url, output))
72
73    def fetch(self, url, path):
74        ec, output = self._run(['fetch', url])
75        if ec != 0:
76            raise error.general('fetch of %s failed: %s' % (url, output))
77
78    def pull(self):
79        ec, output = self._run(['pull'])
80        if ec != 0:
81            raise error.general('pull of %s failed: %s' % (url, output))
82
83    def reset(self, args):
84        if type(args) == str:
85            args = [args]
86        ec, output = self._run(['reset'] + args)
87        if ec != 0:
88            raise error.general('pull of %s failed: %s' % (url, output))
89
90    def branch(self):
91        ec, output = self._run(['branch'])
92        if ec == 0:
93            for b in output.split('\n'):
94                if b[0] == '*':
95                    return b[2:]
96        return None
97
98    def checkout(self, branch = 'master'):
99        ec, output = self._run(['checkout', branch])
100        return ec == 0
101
102    def status(self):
103        _status = {}
104        if path.exists(self.path):
105            ec, output = self._run(['status'])
106            if ec == 0:
107                state = 'none'
108                for l in output.split('\n'):
109                    if l.startswith('# On branch '):
110                        _status['branch'] = l[len('# On branch '):]
111                    elif l.startswith('# Changes to be committed:'):
112                        state = 'staged'
113                    elif l.startswith('# Changes not staged for commit:'):
114                        state = 'unstaged'
115                    elif l.startswith('# Untracked files:'):
116                        state = 'untracked'
117                    elif state != 'none' and l[0] == '#':
118                        if l.strip() != '#' and not l.startswith('#   ('):
119                            if state not in _status:
120                                _status[state] = []
121                            l = l[1:]
122                            if ':' in l:
123                                l = l.split(':')[1]
124                            _status[state] += [l.strip()]
125        return _status
126
127    def clean(self):
128        _status = self.status()
129        return len(_status) == 1 and 'branch' in _status
130
131    def valid(self):
132        if path.exists(self.path):
133            ec, output = self._run(['status'])
134            return ec == 0
135        return False
136
137    def remotes(self):
138        _remotes = {}
139        ec, output = self._run(['config', '--list'])
140        if ec == 0:
141            for l in output.split('\n'):
142                if l.startswith('remote'):
143                    ls = l.split('=')
144                    if len(ls) >= 2:
145                        rs = ls[0].split('.')
146                        if len(rs) == 3:
147                            r_name = rs[1]
148                            r_type = rs[2]
149                            if r_name not in _remotes:
150                                _remotes[r_name] = {}
151                            if r_type not in _remotes[r_name]:
152                                _remotes[r_name][r_type] = []
153                            _remotes[r_name][r_type] = '='.join(ls[1:])
154        return _remotes
155
156    def head(self):
157        hash = ''
158        ec, output = self._run(['log', '-n', '1'])
159        if ec == 0:
160            l1 = output.split('\n')[0]
161            if l1.startswith('commit '):
162                hash = l1[len('commit '):]
163        return hash
164
165if __name__ == '__main__':
166    import sys
167    opts = options.load(sys.argv)
168    g = repo('.', opts)
169    print g.git_version()
170    print g.valid()
171    print g.status()
172    print g.clean()
173    print g.remotes()
174    print g.head()
Note: See TracBrowser for help on using the repository browser.