Update packaking for newner ubuntu builds and remove python2 build and use libusb...
[iguanair.git] / mkChangelog
blobd431d1e487e09a1b3bb9fbbee5b7abe7fc3db734
1 #!/usr/bin/python -tt
2 from __future__ import with_statement
3 import datetime
4 import argparse
5 import sys
6 import os
8 #output "constants"
9 LOG_FATAL = 0
10 LOG_ERROR = 1
11 LOG_WARN = 2
12 LOG_ALWAYS = 2.5
13 LOG_NORMAL = 3
14 LOG_INFO = 4
15 LOG_DEBUG = 5
17 msgPrefixes = [
18 "FATAL: ",
19 "ERROR: ",
20 "WARNING: ",
21 "",
22 "INFO: ",
23 "DEBUG: "
26 #local variables
27 null = open(os.devnull, 'r+')
28 parser = argparse.ArgumentParser(description = 'Basis of my python scripts.')
29 arguments = None
31 def dieCleanly(level = None):
32 """Exit the application with proper cleanup."""
34 #TODO: perform application cleanup
36 if level == None:
37 level = LOG_ERROR
39 #exit with appropriate value
40 if level == LOG_FATAL:
41 sys.exit(1)
42 sys.exit(0)
45 def message(level, msg):
46 global arguments
47 """Print a message to a certain debug level"""
48 retval = None
50 if level <= arguments.logLevel or level == LOG_ALWAYS:
51 out = sys.stdout
53 # if logfile is open print to it instead
54 if arguments.logFile == "-":
55 out = sys.log
56 elif level <= LOG_WARN:
57 out = sys.stderr
59 retval = msgPrefixes[int(level + 0.5)] + msg
60 out.write(retval)
61 retval = len(retval)
63 if level <= LOG_FATAL:
64 dieCleanly(level)
66 return retval
68 def printUsage(msg = None):
69 global parser
70 if msg != None:
71 message(LOG_FATAL, msg + parser.get_usage())
72 message(LOG_ALWAYS, usage)
73 dieCleanly(LOG_ALWAYS)
75 def parseArguments():
76 global parser, arguments
77 parser.add_argument('-l', '--log-file',
78 metavar = 'FILE', dest = 'logFile',
79 help = 'Specify a log to receive all messages.')
80 parser.add_argument('-q', '--quiet',
81 action = 'count',
82 help = 'Decrease verbosity.')
83 parser.add_argument('-v', '--verbose',
84 action = 'count',
85 help = 'Increase verbosity.')
86 parser.add_argument('-a', '--append-to-spec',
87 metavar = 'SPECFILE',
88 help = 'Replace the changlog in the specified spec file with our content.')
89 parser.add_argument('-d', '--debian-release',
90 metavar = 'DEBREL',
91 help = 'Output a debian changelog with this version used in the first entry.')
92 parser.add_argument('-b', '--build',
93 metavar = 'BLDNUM',
94 help = 'Specify a build number to override the most recent entry.')
95 parser.add_argument('--arg-file',
96 metavar = 'ARGFILE',
97 help = 'Specify a file that lists arguments to parse one set per line.')
98 parser.add_argument('-o', '--output',
99 metavar = 'OUTPUT',
100 help = 'Where to put the output.')
101 arguments = parser.parse_args()
102 arguments.logLevel = LOG_NORMAL;
103 if arguments.verbose:
104 arguments.logLevel += arguments.verbose
105 if arguments.quiet:
106 arguments.logLevel -= arguments.quiet
107 if arguments.logLevel <= LOG_FATAL:
108 arguments.logLevel = LOG_FATAL
109 if arguments.logFile == '-':
110 arguments.logFile = None
112 parseArguments()
113 # open the log file if specified
114 if arguments.logFile != None:
115 sys.log = open(arguments.logFile, "a", 1)
116 arguments.logFile = "-"
118 entries = []
119 def readChangeLog():
120 global entries
122 with open(os.path.join(sys.path[0], 'ChangeLog')) as input:
123 entry = {}
124 inMessage = False
125 for line in input:
126 if not line:
127 continue
129 if 'message' in entry:
130 if line == 'END\n':
131 entries.append(entry)
132 entry = {}
133 else:
134 entry['message'] += line
135 else:
136 line = line.strip()
137 if line:
138 parts = list(map(lambda a : a.strip(), line.split(':', 1)))
139 if len(parts) == 2:
140 if parts[0].lower() == 'version':
141 entry['version'] = parts[1].strip()
142 elif parts[0].lower() == 'author':
143 entry['author'] = parts[1].strip()
144 elif parts[0].lower() == 'when':
145 #Tue Mar 07 2006
146 #Tue, 21 Aug 2012 20:01:44 -0600
148 entry['whenIsShort'] = False
149 try:
150 entry['when'] = datetime.datetime.strptime(parts[1], '%a %b %d %Y')
151 entry['whenIsShort'] = True
152 except:
153 try:
154 entry['when'] = datetime.datetime.strptime(parts[1].rsplit(None, 1)[0],
155 '%a, %d %b %Y %H:%M:%S')
156 except:
157 raise Exception('Failed to parse date string: %s' % parts[1])
158 entry['whenText'] = parts[1]
159 elif parts[0].lower() == 'debian':
160 debs = list(map(lambda a : a.strip(), parts[1].split(',')))
161 if len(debs) != 2:
162 raise Exception('Debian entry should look like: rel, bld: %s' % parts[1])
163 entry['debianRel'] = debs[0]
164 entry['debianBld'] = debs[1]
165 elif parts[0].lower() == 'fedora':
166 entry['fedoraBld'] = parts[1]
167 elif parts[0].lower() == 'message':
168 entry['message'] = ''
169 else:
170 raise Exception('Unknown field: %s' % parts[0])
171 elif line.startswith('END'):
172 break
173 else:
174 raise Exception('Unparsed line: %s' % line)
176 def execute(args):
177 output = sys.stdout
178 if args.output:
179 output = open(args.output, 'w')
181 if args.append_to_spec and args.debian_release:
182 message(LOG_FATAL, 'Either write a spec file or a debian changelog.\n')
183 elif args.append_to_spec:
184 # pass the spec through until we reach the changlog
185 with open(args.append_to_spec) as input:
186 for line in input:
187 output.write(line)
188 if line.strip().lower() == '%changelog':
189 break
191 # fedora format
192 first = True
193 for entry in entries:
194 if first:
195 if args.build:
196 entry = dict(entry)
197 entry['fedoraBld'] = args.build
198 first = False
200 entry['whenShort'] = entry['when'].strftime('%a %b %d %Y')
201 lines = []
202 for line in entry['message'].splitlines():
203 if not line.startswith(' * '):
204 raise Exception('Unrecognized message format: %s' % line)
205 else:
206 lines.append(line.strip()[2:])
207 text = ('- ' + ', '.join(lines)).replace('\t', ' ')
209 # wrap the text
210 wrapped = []
211 wrapAt = 72
212 while text:
213 if wrapAt >= len(text):
214 wrapped.append(text.strip())
215 text = ''
216 else:
217 at = wrapAt
218 while text[at] != ' ':
219 at -= 1
220 if at == 10:
221 raise Exception('Cannot wrap text: %s' % text)
222 wrapped.append(text[:at].strip())
223 text = ' ' + text[at:]
224 entry['oneWrapped'] = '\n '.join(wrapped)
226 output.write("""* %(whenShort)s %(author)s %(version)s-%(fedoraBld)s
227 %(oneWrapped)s
229 """ % entry)
230 elif args.debian_release:
231 # debian format
232 first = True
233 for entry in entries:
234 if first:
235 # override some fields of the first entry
236 if args.debian_release:
237 entry = dict(entry)
238 entry['debianRel'] = args.debian_release
239 if args.build:
240 entry = dict(entry)
241 entry['debianBld'] = args.build
242 first = False
244 if entry['whenIsShort']:
245 entry['longWhen'] = entry['when'].strftime('%a, %d %b %Y %H:%M:%S -0500')
246 else:
247 entry['longWhen'] = entry['whenText']
248 output.write("""iguanair (%(version)s-%(debianRel)s) %(debianRel)s; urgency=low
250 %(message)s
251 -- %(author)s %(longWhen)s
253 """ % entry)
254 else:
255 message(LOG_FATAL, 'Either write a spec file or a debian changelog: %s\n' % arguments)
257 if output != sys.stdout:
258 output.close()
260 readChangeLog()
261 if arguments.arg_file:
262 with open(arguments.arg_file) as input:
263 for line in map(lambda a : a.strip(), input):
264 execute(parser.parse_args(line.split()))
265 sys.exit()
266 else:
267 execute(arguments)