Fixing a utility script.
[jarrpa/prequel.git] / scripts / git_utils.py
1 # ============================================================================ #
2 #                            $Name: git_utils.py$
3 #
4 # Copyright (C) 2012 Jose A. Rivera <jarrpa@redhat.com>
5 #
6 # $Date: 2013-01-22 22:49:58 -0600$
7 #
8 # ---------------------------------------------------------------------------- #
9 #
10 # Description: Mostly-git-related utility functions.
11 #
12 # ---------------------------------------------------------------------------- #
13 #
14 # License:
15 #
16 #   This program is free software: you can redistribute it and/or modify
17 #   it under the terms of the GNU General Public License as published by
18 #   the Free Software Foundation, either version 3 of the License, or
19 #   (at your option) any later version.
20 #
21 #   This program is distributed in the hope that it will be useful,
22 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
23 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 #   GNU General Public License for more details.
25 #
26 #   You should have received a copy of the GNU General Public License
27 #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
28 #
29 # ---------------------------------------------------------------------------- #
30 #
31 # Notes:
32 #
33 # ============================================================================ #
34
35 import sys
36 import re
37 import os
38 import subprocess
39 import time as _time
40 from datetime import datetime, timedelta, tzinfo
41
42
43 def git(args, interactive=False, input=None, cwd=None ):
44   if type(args) == str:
45     tmp = args.split('"')
46     tmp2 = []
47     for i in range(len(tmp)):
48       if i%2:
49         tmp2.append(tmp[i])
50       else:
51         tmp2 += tmp[i].split()
52     args = tmp2
53   args  = ['git'] + args
54   out   = None if interactive else subprocess.PIPE
55   inp   = None if interactive else subprocess.PIPE
56   git   = subprocess.Popen( args, 
57                             stdout=out, stdin=inp, stderr=subprocess.STDOUT,
58                             cwd=cwd )
59
60   if not interactive:
61     details = git.communicate(input)[0]
62     details = details.strip()
63   else:
64     git.wait()
65     details = None
66   return details
67
68 def git_config(key):
69   details = git(['config', '%s' % (key)])
70   if len(details) > 0:
71     return details
72   else:
73     return None
74
75 def git_repo_name():
76   if git(['rev-parse', '--is-bare-repository']) == 'true':
77     return os.path.basename(os.getcwd())
78   else:
79     return os.path.basename(os.path.dirname(os.getcwd()))
80
81 def git_parse_date( datestr, fmt=False ):
82   '''Parse a given date string into a Python datetime object. Formats allowed 
83   for the date string are the same as those outlined in 'git help commit' under
84   DATE FORMATS.
85   
86   datestr - A properly formatted date string.
87   fmt     - A boolean to indicate if the discovered format of the string should
88             also be returned. See the Output section.
89   
90   Output: If fmt is False, return a Python datetime object. If fmt is True, 
91           return a tuple (<date>, <format>) where <date> is a datetime object 
92           and <format> is a format string indicating the discovered format of 
93           datestr. If datestr can not me parsed, return either None (if 
94           fmt=False) or a tuple of (None,'') (if fmt=True). 
95   '''
96   # Define acceptable formats.
97   fmtstrs = { 'gittime'  : '%s %z', # NOTE: %s may not be cross-platform.
98               'rfc2822'  : '%a, %d %b %Y %H:%M:%S %z',
99               'isodate1' : '%Y-%m-%d',
100               'isodate2' : '%Y.%m.%d',
101               'isodate3' : '%m/%d/%Y',
102               'isodate4' : '%d.%m.%Y',
103               'isosep1'  : 'T',
104               'isosep2'  : ' ',
105               'isotime'  : '%H:%M:%S',
106             }
107   
108   dtm    = None
109   fmtstr = ''
110   
111   # Done. Return results.
112   if fmt == False:
113     results = dtm
114   else:
115     results = ( dtm, fmtstr )
116
117   return results
118
119 # A class capturing the platform's idea of local time.
120 # Taken from http://docs.python.org/library/datetime.html#tzinfo-objects
121 # on 2012-05-24.
122
123 ZERO = timedelta(0)
124
125 STDOFFSET = timedelta(seconds = -_time.timezone)
126 if _time.daylight:
127     DSTOFFSET = timedelta(seconds = -_time.altzone)
128 else:
129     DSTOFFSET = STDOFFSET
130
131 DSTDIFF = DSTOFFSET - STDOFFSET
132
133 class LocalTimezone(tzinfo):
134
135     def utcoffset(self, dt):
136         if self._isdst(dt):
137             return DSTOFFSET
138         else:
139             return STDOFFSET
140
141     def dst(self, dt):
142         if self._isdst(dt):
143             return DSTDIFF
144         else:
145             return ZERO
146
147     def tzname(self, dt):
148         return _time.tzname[self._isdst(dt)]
149
150     def _isdst(self, dt):
151         tt = (dt.year, dt.month, dt.day,
152               dt.hour, dt.minute, dt.second,
153               dt.weekday(), 0, 0)
154         stamp = _time.mktime(tt)
155         tt = _time.localtime(stamp)
156         return tt.tm_isdst > 0
157
158 LocalTZ = LocalTimezone()
159
160 # ============================================================================ #