source: rtems-tools/rtemstoolkit/git.py @ de1beea

4.105
Last change on this file since de1beea was de1beea, checked in by Chris Johns <chrisj@…>, on 02/19/16 at 00:26:51

Disable installing PYO and PYC. Fix install paths.

Installing PYO and PYC does not work so disable this. Move the
Python check to the top level and have a single place.

Fix the install paths a revert the 'from . import' changes. This
is resolved by installing into the correct paths.

  • Property mode set to 100644
File size: 7.4 KB
Line 
1#
2# RTEMS Tools Project (http://www.rtems.org/)
3# Copyright 2010-2015 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# 1. Redistributions of source code must retain the above copyright notice,
9# this list of conditions and the following disclaimer.
10#
11# 2. Redistributions in binary form must reproduce the above copyright notice,
12# this list of conditions and the following disclaimer in the documentation
13# and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25# POSSIBILITY OF SUCH DAMAGE.
26#
27
28#
29# Provide some basic access to the git command.
30#
31
32import os
33
34import error
35import execute
36import log
37import options
38import path
39
40class repo:
41    """An object to manage a git repo."""
42
43    def _git_exit_code(self, ec):
44        if ec:
45            raise error.general('git command failed (%s): %d' % (self.git, ec))
46
47    def _run(self, args, check = False):
48        e = execute.capture_execution()
49        if path.exists(self.path):
50            cwd = self.path
51        else:
52            cwd = None
53        cmd = [self.git] + args
54        log.trace('cmd: (%s) %s' % (str(cwd), ' '.join(cmd)))
55        exit_code, proc, output = e.spawn(cmd, cwd = path.host(cwd))
56        log.trace(output)
57        if check:
58            self._git_exit_code(exit_code)
59        return exit_code, output
60
61    def __init__(self, _path, opts = None, macros = None):
62        self.path = _path
63        self.opts = opts
64        if macros is None and opts is not None:
65            self.macros = opts.defaults
66        else:
67            self.macros = macros
68        if self.macros is None:
69            self.git = 'git'
70        else:
71            self.git = self.macros.expand('%{__git}')
72
73    def git_version(self):
74        ec, output = self._run(['--version'], True)
75        gvs = output.split()
76        if len(gvs) < 3:
77            raise error.general('invalid version string from git: %s' % (output))
78        vs = gvs[2].split('.')
79        if len(vs) != 4:
80            raise error.general('invalid version number from git: %s' % (gvs[2]))
81        return (int(vs[0]), int(vs[1]), int(vs[2]), int(vs[3]))
82
83    def clone(self, url, _path):
84        ec, output = self._run(['clone', url, path.host(_path)], check = True)
85
86    def fetch(self):
87        ec, output = self._run(['fetch'], check = True)
88
89    def merge(self):
90        ec, output = self._run(['merge'], check = True)
91
92    def pull(self):
93        ec, output = self._run(['pull'], check = True)
94
95    def reset(self, args):
96        if type(args) == str:
97            args = [args]
98        ec, output = self._run(['reset'] + args, check = True)
99
100    def branch(self):
101        ec, output = self._run(['branch'])
102        if ec == 0:
103            for b in output.split('\n'):
104                if b[0] == '*':
105                    return b[2:]
106        return None
107
108    def checkout(self, branch = 'master'):
109        ec, output = self._run(['checkout', branch], check = True)
110
111    def submodule(self, module):
112        ec, output = self._run(['submodule', 'update', '--init', module], check = True)
113
114    def clean(self, args = []):
115        if type(args) == str:
116            args = [args]
117        ec, output = self._run(['clean'] + args, check = True)
118
119    def status(self):
120        _status = {}
121        if path.exists(self.path):
122            ec, output = self._run(['status'])
123            if ec == 0:
124                state = 'none'
125                for l in output.split('\n'):
126                    if l.startswith('# '):
127                        l = l[2:]
128                    if l.startswith('On branch '):
129                        _status['branch'] = l[len('On branch '):]
130                    elif l.startswith('Changes to be committed:'):
131                        state = 'staged'
132                    elif l.startswith('Changes not staged for commit:'):
133                        state = 'unstaged'
134                    elif l.startswith('Untracked files:'):
135                        state = 'untracked'
136                    elif l.startswith('HEAD detached'):
137                        state = 'detached'
138                    elif state != 'none' and len(l.strip()) != 0:
139                        if l[0].isspace():
140                            l = l.strip()
141                            if l[0] != '(':
142                                if state not in _status:
143                                    _status[state] = []
144                                l = l[1:]
145                                if ':' in l:
146                                    l = l.split(':')[1]
147                                _status[state] += [l.strip()]
148        return _status
149
150    def dirty(self):
151        _status = self.status()
152        return not (len(_status) == 1 and 'branch' in _status)
153
154    def valid(self):
155        if path.exists(self.path):
156            ec, output = self._run(['status'])
157            return ec == 0
158        return False
159
160    def remotes(self):
161        _remotes = {}
162        ec, output = self._run(['config', '--list'])
163        if ec == 0:
164            for l in output.split('\n'):
165                if l.startswith('remote'):
166                    ls = l.split('=')
167                    if len(ls) >= 2:
168                        rs = ls[0].split('.')
169                        if len(rs) == 3:
170                            r_name = rs[1]
171                            r_type = rs[2]
172                            if r_name not in _remotes:
173                                _remotes[r_name] = {}
174                            if r_type not in _remotes[r_name]:
175                                _remotes[r_name][r_type] = []
176                            _remotes[r_name][r_type] = '='.join(ls[1:])
177        return _remotes
178
179    def email(self):
180        _email = None
181        _name = None
182        ec, output = self._run(['config', '--list'])
183        if ec == 0:
184            for l in output.split('\n'):
185                if l.startswith('user.email'):
186                    ls = l.split('=')
187                    if len(ls) >= 2:
188                        _email = ls[1]
189                elif l.startswith('user.name'):
190                    ls = l.split('=')
191                    if len(ls) >= 2:
192                        _name = ls[1]
193        if _email is not None:
194            if _name is not None:
195                _email = '%s <%s>' % (_name, _email)
196            return _email
197        return None
198
199    def head(self):
200        hash = ''
201        ec, output = self._run(['log', '-n', '1'])
202        if ec == 0:
203            l1 = output.split('\n')[0]
204            if l1.startswith('commit '):
205                hash = l1[len('commit '):]
206        return hash
207
208if __name__ == '__main__':
209    import sys
210    opts = options.load(sys.argv)
211    g = repo('.', opts)
212    print(g.git_version())
213    print(g.valid())
214    print(g.status())
215    print(g.clean())
216    print(g.remotes())
217    print(g.email())
218    print(g.head())
Note: See TracBrowser for help on using the repository browser.