Merge ~dannf/canonical-server-hwe-utils:pre-commit into canonical-server-hwe-utils:master

Proposed by dann frazier
Status: Merged
Approved by: Alexandre Erwin Ittner
Approved revision: fe32deedec72a723de836d21e49b32632e8c742a
Merged at revision: fe32deedec72a723de836d21e49b32632e8c742a
Proposed branch: ~dannf/canonical-server-hwe-utils:pre-commit
Merge into: canonical-server-hwe-utils:master
Diff against target: 2123 lines (+790/-499)
18 files modified
.pre-commit-config.yaml (+10/-0)
labkey (+95/-71)
lp-scripts/LaunchpadBugBucketer.py (+5/-5)
lp-scripts/bandera-bug-csv-summary.py (+8/-7)
lp-scripts/bugreport/bugreport.py (+143/-81)
lp-scripts/clone-project-milestones.py (+21/-18)
lp-scripts/dump-bug-subscribers.py (+26/-14)
lp-scripts/lp-bulk-action.py (+46/-41)
lp-scripts/pearl-biweekly-bug-report-csv4.py (+87/-47)
lp-scripts/pearl-biweekly-report-csv.py (+78/-40)
lp-scripts/pearl-biweekly-report.csv.py (+93/-53)
lp-scripts/pearl-bug-csv-summary.py (+8/-7)
lp-scripts/pearl-risky-patch-schedule.py (+12/-10)
lp-scripts/pearl2-biweekly-report.csv.py (+60/-44)
lp-scripts/pearl2-d06-18.04-patch-status.py (+18/-13)
lp-scripts/pearl2-tag-ubuntu-18.04.3-risky.py (+14/-10)
lp-scripts/project-bug-lint.py (+54/-26)
sysadmin-tools/gen_conserver_cf.py (+12/-12)
Reviewer Review Type Date Requested Status
Alexandre Erwin Ittner Approve
Review via email: mp+383616@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Alexandre Erwin Ittner (aittner) wrote :

The python-black + pre-commit that we already agreed upon and code reformatting. Clear approval!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
2new file mode 100644
3index 0000000..5f7fa9a
4--- /dev/null
5+++ b/.pre-commit-config.yaml
6@@ -0,0 +1,10 @@
7+repos:
8+ - repo: https://github.com/psf/black
9+ rev: stable
10+ hooks:
11+ - id: black
12+ language_version: python3.8
13+ - repo: https://gitlab.com/pycqa/flake8
14+ rev: master
15+ hooks:
16+ - id: flake8
17diff --git a/labkey b/labkey
18index fe3f4ae..47f996b 100755
19--- a/labkey
20+++ b/labkey
21@@ -9,8 +9,8 @@ import sys
22 import yaml
23
24 ProgName = "labkey"
25-Config = os.path.join(os.environ['HOME'], '.config', ProgName)
26-ScaleBotLocal = os.path.join(Config, 'scalebot-repo')
27+Config = os.path.join(os.environ["HOME"], ".config", ProgName)
28+ScaleBotLocal = os.path.join(Config, "scalebot-repo")
29
30
31 def update(lpid, force):
32@@ -22,34 +22,31 @@ def update(lpid, force):
33 shutil.rmtree(ScaleBotLocal)
34
35 ScaleBotRemote = "git+ssh://%sgit.launchpad.net/scalebot" % (user)
36- umaskSav = os.umask(int('077', 8))
37+ umaskSav = os.umask(int("077", 8))
38 if os.path.exists(ScaleBotLocal):
39 os.chdir(ScaleBotLocal)
40- subprocess.run(['git', 'pull'], check=True)
41+ subprocess.run(["git", "pull"], check=True)
42 else:
43- subprocess.run(['git', 'clone',
44- ScaleBotRemote, ScaleBotLocal],
45- check=True)
46+ subprocess.run(["git", "clone", ScaleBotRemote, ScaleBotLocal], check=True)
47 os.umask(umaskSav)
48
49
50 def loadLabs():
51 config = []
52- labroot = os.path.join(ScaleBotLocal, 'labs')
53+ labroot = os.path.join(ScaleBotLocal, "labs")
54 for labdir in os.scandir(labroot):
55 if not labdir.is_dir():
56 continue
57 lab = None
58 machines = None
59 for f in os.scandir(labdir):
60- if f.name == 'lab.yaml':
61- with open(f.path, 'r') as stream:
62+ if f.name == "lab.yaml":
63+ with open(f.path, "r") as stream:
64 lab = yaml.load(stream, Loader=yaml.SafeLoader)
65- elif f.name == 'machines.yaml':
66- with open(f.path, 'r') as stream:
67+ elif f.name == "machines.yaml":
68+ with open(f.path, "r") as stream:
69 machines = yaml.load(stream, Loader=yaml.SafeLoader)
70- config.append({'lab': lab,
71- 'machines': machines})
72+ config.append({"lab": lab, "machines": machines})
73 return config
74
75
76@@ -58,96 +55,123 @@ class Machine:
77 self.name = name
78 labs = loadLabs()
79 for lab in labs:
80- if lab['machines'] is None:
81+ if lab["machines"] is None:
82 continue
83- if name in lab['machines'].keys():
84- self.data = lab['machines'][name]
85- self.labdata = lab['lab']
86+ if name in lab["machines"].keys():
87+ self.data = lab["machines"][name]
88+ self.labdata = lab["lab"]
89 return
90- raise KeyError('Machine not found')
91+ raise KeyError("Machine not found")
92
93 def __repr__(self):
94 return yaml.dump(self.data, default_flow_style=False)
95
96 def _do_ipmitool(self, cmd):
97- bmc = self.data['bmc']
98- if bmc['type'] != "ipmi":
99- raise KeyError('Machine has unknown power type')
100- subprocess.run(['ipmitool', '-I', 'lanplus',
101- '-H', bmc['address'],
102- '-U', bmc['user'],
103- '-P', bmc['password']] + cmd, check=True)
104+ bmc = self.data["bmc"]
105+ if bmc["type"] != "ipmi":
106+ raise KeyError("Machine has unknown power type")
107+ subprocess.run(
108+ [
109+ "ipmitool",
110+ "-I",
111+ "lanplus",
112+ "-H",
113+ bmc["address"],
114+ "-U",
115+ bmc["user"],
116+ "-P",
117+ bmc["password"],
118+ ]
119+ + cmd,
120+ check=True,
121+ )
122
123 def mc_reset(self):
124- cmd = ['mc', 'reset', 'cold']
125+ cmd = ["mc", "reset", "cold"]
126 self._do_ipmitool(cmd)
127
128 def power(self, state):
129- cmd = ['chassis', 'power', state]
130+ cmd = ["chassis", "power", state]
131 self._do_ipmitool(cmd)
132
133 def open_console(self):
134- '''
135+ """
136 Open an interactive console session to the machine.
137 Currently only supports conserver.
138- '''
139+ """
140 if self.labdata is None:
141- raise KeyError('No lab.yaml associated with %s' % (self.name))
142- if 'conserver' not in self.labdata.keys():
143- raise KeyError('No conserver defined for lab %s' %
144- (self.labdata['name']))
145- concfg = self.labdata['conserver']
146- subprocess.run(['console', '-M%s' % (concfg['master']),
147- '-p%s' % (concfg['port']),
148- self.name],
149- stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr)
150- subprocess.run(['console', '-M%s' % (concfg['master']),
151- '-p%s' % (concfg['port']),
152- self.name],
153- capture_output=True)
154-
155-
156-if __name__ == '__main__':
157- power_cmds = ['on', 'off', 'cycle', 'mc-reset', 'reset', 'status']
158- machine_cmds = power_cmds + ['console', 'show']
159+ raise KeyError("No lab.yaml associated with %s" % (self.name))
160+ if "conserver" not in self.labdata.keys():
161+ raise KeyError("No conserver defined for lab %s" % (self.labdata["name"]))
162+ concfg = self.labdata["conserver"]
163+ subprocess.run(
164+ [
165+ "console",
166+ "-M%s" % (concfg["master"]),
167+ "-p%s" % (concfg["port"]),
168+ self.name,
169+ ],
170+ stdin=sys.stdin,
171+ stdout=sys.stdout,
172+ stderr=sys.stderr,
173+ )
174+ subprocess.run(
175+ [
176+ "console",
177+ "-M%s" % (concfg["master"]),
178+ "-p%s" % (concfg["port"]),
179+ self.name,
180+ ],
181+ capture_output=True,
182+ )
183+
184+
185+if __name__ == "__main__":
186+ power_cmds = ["on", "off", "cycle", "mc-reset", "reset", "status"]
187+ machine_cmds = power_cmds + ["console", "show"]
188 cmd_help = {
189- 'show': "Show machine configuration",
190- 'on': "Power machine on",
191- 'off': "Power machine off",
192- 'cycle': "Power cycle machine",
193- 'mc-reset': "Perform cold reset of BMC",
194- 'reset': "Hard reset machine",
195- 'console': "Open a console session",
196- 'status': "Show machine power status",
197- 'update': "Update cached machine information",
198+ "show": "Show machine configuration",
199+ "on": "Power machine on",
200+ "off": "Power machine off",
201+ "cycle": "Power cycle machine",
202+ "mc-reset": "Perform cold reset of BMC",
203+ "reset": "Hard reset machine",
204+ "console": "Open a console session",
205+ "status": "Show machine power status",
206+ "update": "Update cached machine information",
207 }
208
209- d = 'Do things with machines in ScaleBot labs'
210+ d = "Do things with machines in ScaleBot labs"
211 parser = argparse.ArgumentParser(prog=ProgName, description=d)
212- subparsers = parser.add_subparsers(help='sub-command help')
213- update_parser = subparsers.add_parser('update', help=cmd_help['update'])
214- update_parser.add_argument('-u', dest='lpid', metavar='LPID',
215- required=False, help="Launchpad ID")
216- update_parser.add_argument('-f', dest='force', action='store_true',
217- required=False,
218- help="Flush machine cache before update")
219- update_parser.set_defaults(cmd='update')
220+ subparsers = parser.add_subparsers(help="sub-command help")
221+ update_parser = subparsers.add_parser("update", help=cmd_help["update"])
222+ update_parser.add_argument(
223+ "-u", dest="lpid", metavar="LPID", required=False, help="Launchpad ID"
224+ )
225+ update_parser.add_argument(
226+ "-f",
227+ dest="force",
228+ action="store_true",
229+ required=False,
230+ help="Flush machine cache before update",
231+ )
232+ update_parser.set_defaults(cmd="update")
233 for a in machine_cmds:
234 action_parser = subparsers.add_parser(a, help=cmd_help[a])
235- action_parser.add_argument('machine', metavar='MACHINE')
236+ action_parser.add_argument("machine", metavar="MACHINE")
237 action_parser.set_defaults(cmd=a)
238 args = parser.parse_args()
239
240- if args.cmd == 'update':
241+ if args.cmd == "update":
242 update(lpid=args.lpid, force=args.force)
243 sys.exit(0)
244
245 m = Machine(args.machine)
246- if args.cmd == 'show':
247+ if args.cmd == "show":
248 print(m)
249- elif args.cmd == 'mc-reset':
250+ elif args.cmd == "mc-reset":
251 m.mc_reset()
252- elif args.cmd == 'console':
253+ elif args.cmd == "console":
254 m.open_console()
255 elif args.cmd in power_cmds:
256 m.power(args.cmd)
257diff --git a/lp-scripts/LaunchpadBugBucketer.py b/lp-scripts/LaunchpadBugBucketer.py
258index 7831132..81e9e99 100644
259--- a/lp-scripts/LaunchpadBugBucketer.py
260+++ b/lp-scripts/LaunchpadBugBucketer.py
261@@ -49,7 +49,7 @@ class LaunchpadBugBucketer(collections.UserDict):
262 requiredTags (:obj:`list` of :obj:`str`): Only bucket bugs that
263 have one or more tags from this list.
264 """
265- self.lp = Launchpad.login_with('lpbugs', 'production', version='devel')
266+ self.lp = Launchpad.login_with("lpbugs", "production", version="devel")
267 self.project = self.lp.projects[project]
268 self.series = series
269 self.requiredTags = requiredTags
270@@ -57,8 +57,8 @@ class LaunchpadBugBucketer(collections.UserDict):
271 collections.UserDict.__init__(self, self.buckets)
272
273 def taskToBug(self, task):
274- bugid = int(task.self_link.split('/')[-1])
275- return(self.lp.bugs[bugid])
276+ bugid = int(task.self_link.split("/")[-1])
277+ return self.lp.bugs[bugid]
278
279 def _doBucketing(self):
280 methods = inspect.getmembers(self, predicate=inspect.ismethod)
281@@ -72,10 +72,10 @@ class LaunchpadBugBucketer(collections.UserDict):
282 if not set(self.requiredTags) & set(bug.tags):
283 continue
284 for mName, mFunc in methods:
285- if not mName.startswith('is_'):
286+ if not mName.startswith("is_"):
287 continue
288 if mFunc(task):
289- b = mName[len('is_'):]
290+ b = mName[len("is_") :]
291 if b not in self.buckets.keys():
292 self.buckets[b] = []
293 self.buckets[b].append(task)
294diff --git a/lp-scripts/bandera-bug-csv-summary.py b/lp-scripts/bandera-bug-csv-summary.py
295index 1fae696..05f84aa 100755
296--- a/lp-scripts/bandera-bug-csv-summary.py
297+++ b/lp-scripts/bandera-bug-csv-summary.py
298@@ -7,18 +7,19 @@ from LaunchpadBugBucketer import LaunchpadBugBucketer
299
300 class BanderaBugBucketer(LaunchpadBugBucketer):
301 def __init__(self):
302- LaunchpadBugBucketer.__init__(self, 'bandera', 'ubuntu-16.04',
303- requiredTags=['patchset'])
304+ LaunchpadBugBucketer.__init__(
305+ self, "bandera", "ubuntu-16.04", requiredTags=["patchset"]
306+ )
307
308 def is_green(self, task):
309- if task.status in ['Fix Committed', 'Fix Released']:
310+ if task.status in ["Fix Committed", "Fix Released"]:
311 return True
312 return False
313
314 def is_amber(self, task):
315 if self.is_green(task):
316 return False
317- elif task.milestone and task.milestone.name == 'ubuntu-16.04.3':
318+ elif task.milestone and task.milestone.name == "ubuntu-16.04.3":
319 return True
320 return False
321
322@@ -28,16 +29,16 @@ class BanderaBugBucketer(LaunchpadBugBucketer):
323 return True
324
325
326-if __name__ == '__main__':
327+if __name__ == "__main__":
328 parser = argparse.ArgumentParser()
329 parser.add_argument("-o", "--outfile")
330 args = parser.parse_args()
331
332 s = BanderaBugBucketer()
333
334- with open(args.outfile, 'w') as csvfile:
335+ with open(args.outfile, "w") as csvfile:
336 c = csv.writer(csvfile)
337- c.writerow(['Title', 'Bug ID', 'Importance', 'Status', 'RAG Risk'])
338+ c.writerow(["Title", "Bug ID", "Importance", "Status", "RAG Risk"])
339 for bucket in s.keys():
340 for task in s[bucket]:
341 bug = s.taskToBug(task)
342diff --git a/lp-scripts/bugreport/bugreport.py b/lp-scripts/bugreport/bugreport.py
343index bc347b9..ca9b5b1 100755
344--- a/lp-scripts/bugreport/bugreport.py
345+++ b/lp-scripts/bugreport/bugreport.py
346@@ -3,7 +3,6 @@
347 # License: GPLv3
348 from launchpadlib.launchpad import Launchpad
349 from launchpadlib.uris import LPNET_SERVICE_ROOT
350-from launchpadlib.credentials import Credentials
351 from optparse import OptionParser
352 from re import compile
353 from datetime import datetime as dt
354@@ -16,7 +15,7 @@ import sys
355 def gen_bug_report(lp, lp_bugs, project, verbose):
356 bug_summary_info = coldict(dict)
357 bug_details_info = coldict(dict)
358- url = compile('https://api.launchpad.net/1.0/~|/')
359+ url = compile("https://api.launchpad.net/1.0/~|/")
360
361 for task in lp_bugs:
362 bug_info = {}
363@@ -27,13 +26,13 @@ def gen_bug_report(lp, lp_bugs, project, verbose):
364 else:
365 bug_summary_info[task.importance][task.status] = 1
366
367- if '#Bugs Processed' in bug_summary_info[task.importance]:
368- bug_summary_info[task.importance]['#Bugs Processed'] += 1
369+ if "#Bugs Processed" in bug_summary_info[task.importance]:
370+ bug_summary_info[task.importance]["#Bugs Processed"] += 1
371 else:
372- bug_summary_info[task.importance]['#Bugs Processed'] = 1
373+ bug_summary_info[task.importance]["#Bugs Processed"] = 1
374
375- if '#Bugs Closed' not in bug_summary_info[task.importance]:
376- bug_summary_info[task.importance]['#Bugs Closed'] = 0
377+ if "#Bugs Closed" not in bug_summary_info[task.importance]:
378+ bug_summary_info[task.importance]["#Bugs Closed"] = 0
379
380 # A bug could affect multiple projects, we care only whether
381 # the project we are tracking is complete.
382@@ -42,33 +41,40 @@ def gen_bug_report(lp, lp_bugs, project, verbose):
383 if bugtask.bug_target_name in project:
384 bug_is_complete = bugtask.is_complete
385 if verbose is True:
386- bug_subtask.append(
387- '%s: %s' % (bugtask.bug_target_name, bugtask.status))
388+ bug_subtask.append("%s: %s" % (bugtask.bug_target_name, bugtask.status))
389
390 if bug_is_complete is True:
391- if '#Bugs Closed' in bug_summary_info[task.importance]:
392- bug_summary_info[task.importance]['#Bugs Closed'] += 1
393+ if "#Bugs Closed" in bug_summary_info[task.importance]:
394+ bug_summary_info[task.importance]["#Bugs Closed"] += 1
395
396 if verbose is True:
397 inactive_days = 0
398 if bug_is_complete is not True:
399 inactive_days = np.busday_count(
400 task.bug.date_last_updated.strftime("%Y-%m-%d"),
401- dt.now().strftime("%Y-%m-%d"))
402+ dt.now().strftime("%Y-%m-%d"),
403+ )
404
405 active_days = np.busday_count(
406 task.bug.date_created.strftime("%Y-%m-%d"),
407- task.bug.date_last_updated.strftime("%Y-%m-%d"))
408+ task.bug.date_last_updated.strftime("%Y-%m-%d"),
409+ )
410
411- assignee = 'Unassigned' if task.assignee_link is None \
412- else url.sub('', task.assignee_link)
413+ assignee = (
414+ "Unassigned"
415+ if task.assignee_link is None
416+ else url.sub("", task.assignee_link)
417+ )
418
419 bug_info[task.bug.id] = [
420 task.bug.date_created.strftime("%Y-%m-%d"),
421- task.bug.date_last_updated.strftime("%Y-%m-%d"),
422- active_days,
423- inactive_days, task.bug.message_count, assignee,
424- "''<br>''".join(bug_subtask)]
425+ task.bug.date_last_updated.strftime("%Y-%m-%d"),
426+ active_days,
427+ inactive_days,
428+ task.bug.message_count,
429+ assignee,
430+ "''<br>''".join(bug_subtask),
431+ ]
432
433 bug_details_info[task.importance].update(bug_info)
434
435@@ -76,95 +82,151 @@ def gen_bug_report(lp, lp_bugs, project, verbose):
436
437
438 def main():
439- parser = OptionParser(usage='usage: %prog [options]', version='%prog 1.0')
440- parser.add_option('-d', '--date', dest='start_date', action='store',
441- default='2017-01-01',
442- type='string', help='start date for bug search')
443- parser.add_option('-p', '--project', dest='project', action='store',
444- default='ubuntu-power-systems',
445- type='string', help='name of the launchpad project')
446- parser.add_option('-s', '--status', dest='bug_status', action='store',
447- default=('New,Opinion,Invalid,Won\'t Fix,Expired,'
448- 'Confirmed,Triaged,In Progress,Fix Committed,'
449- 'Fix Released,Incomplete'),
450- type='string',
451- help='bug status (or quoted and comma seperated list)')
452- parser.add_option('-i', '--importance', dest='bug_importance',
453- default=(
454- 'Unknown,Undecided,Critical,High,Medium,Low,Wishlist'),
455- type='string',
456- help='bug importance (or comma seperated list, no spaces)')
457- parser.add_option('-t', '--tag', dest='bug_tag', default=None,
458- help='bug tag (or quoted and comma seperated list)')
459- parser.add_option('-m', '--modify', dest='bug_tag_modify', default='Any',
460- help='search any or all tags (valid args: any or all)')
461- parser.add_option('-v', '--verbose', dest='verbose', action='store_true',
462- help='verbose output with bug details')
463- parser.add_option('-a', '--author', dest='author',
464- default='Manoj Iyer manoj.iyer@canonical.com',
465- help='"Firstname Lastname first.last@canonical.com"')
466- parser.add_option('-o', '--outfile', dest='outfile',
467- help='filename to store output (default stdout)')
468+ parser = OptionParser(usage="usage: %prog [options]", version="%prog 1.0")
469+ parser.add_option(
470+ "-d",
471+ "--date",
472+ dest="start_date",
473+ action="store",
474+ default="2017-01-01",
475+ type="string",
476+ help="start date for bug search",
477+ )
478+ parser.add_option(
479+ "-p",
480+ "--project",
481+ dest="project",
482+ action="store",
483+ default="ubuntu-power-systems",
484+ type="string",
485+ help="name of the launchpad project",
486+ )
487+ parser.add_option(
488+ "-s",
489+ "--status",
490+ dest="bug_status",
491+ action="store",
492+ default=(
493+ "New,Opinion,Invalid,Won't Fix,Expired,"
494+ "Confirmed,Triaged,In Progress,Fix Committed,"
495+ "Fix Released,Incomplete"
496+ ),
497+ type="string",
498+ help="bug status (or quoted and comma seperated list)",
499+ )
500+ parser.add_option(
501+ "-i",
502+ "--importance",
503+ dest="bug_importance",
504+ default=("Unknown,Undecided,Critical,High,Medium,Low,Wishlist"),
505+ type="string",
506+ help="bug importance (or comma seperated list, no spaces)",
507+ )
508+ parser.add_option(
509+ "-t",
510+ "--tag",
511+ dest="bug_tag",
512+ default=None,
513+ help="bug tag (or quoted and comma seperated list)",
514+ )
515+ parser.add_option(
516+ "-m",
517+ "--modify",
518+ dest="bug_tag_modify",
519+ default="Any",
520+ help="search any or all tags (valid args: any or all)",
521+ )
522+ parser.add_option(
523+ "-v",
524+ "--verbose",
525+ dest="verbose",
526+ action="store_true",
527+ help="verbose output with bug details",
528+ )
529+ parser.add_option(
530+ "-a",
531+ "--author",
532+ dest="author",
533+ default="Manoj Iyer manoj.iyer@canonical.com",
534+ help='"Firstname Lastname first.last@canonical.com"',
535+ )
536+ parser.add_option(
537+ "-o",
538+ "--outfile",
539+ dest="outfile",
540+ help="filename to store output (default stdout)",
541+ )
542
543 (options, args) = parser.parse_args()
544
545 if len(args) is None:
546 parser.error("No arguments found!")
547
548- script_name = sys.argv[0].split("/")[-1].split('.')[0]
549- cachedir = os.path.expanduser('~/.launchpadlib/cache')
550+ script_name = sys.argv[0].split("/")[-1].split(".")[0]
551+ cachedir = os.path.expanduser("~/.launchpadlib/cache")
552
553 launchpad = Launchpad.login_with(script_name, LPNET_SERVICE_ROOT, cachedir)
554 lp_project = launchpad.projects[options.project]
555
556 lp_bugs = [
557- task for task in lp_project.searchTasks(
558- created_since=None if options.start_date is None else
559- dt.strptime(options.start_date,
560- '%Y-%m-%d').isoformat(),
561- status=options.bug_status.split(','),
562- importance=options.bug_importance.title().replace(
563- ' ', '').split(','),
564- tags=None if options.bug_tag is None else
565- options.bug_tag.split(','),
566- tags_combinator=options.bug_tag_modify.title())]
567-
568- with (open(options.outfile, 'w') if options.outfile else sys.stdout) as f:
569- f.write("Bug activity in %s project since %s\n\n\n" % (options.project,
570- options.start_date))
571- f.write(" || {:<35} | {:<20} |\n".format('Created By', 'Date'))
572+ task
573+ for task in lp_project.searchTasks(
574+ created_since=None
575+ if options.start_date is None
576+ else dt.strptime(options.start_date, "%Y-%m-%d").isoformat(),
577+ status=options.bug_status.split(","),
578+ importance=options.bug_importance.title().replace(" ", "").split(","),
579+ tags=None if options.bug_tag is None else options.bug_tag.split(","),
580+ tags_combinator=options.bug_tag_modify.title(),
581+ )
582+ ]
583+
584+ with (open(options.outfile, "w") if options.outfile else sys.stdout) as f:
585+ f.write(
586+ "Bug activity in %s project since %s\n\n\n"
587+ % (options.project, options.start_date)
588+ )
589+ f.write(" || {:<35} | {:<20} |\n".format("Created By", "Date"))
590 f.write(" | [%s]" % (options.author) + " | %%mtime(%A %B %d, %Y) |\n")
591
592 if f is not sys.stdout and options.verbose is True:
593- sys.stdout.write("Bug activity in %s project since %s\n" %
594- (options.project, options.start_date))
595- sys.stdout.write("Generating detailed report in %s \n" %
596- options.outfile)
597+ sys.stdout.write(
598+ "Bug activity in %s project since %s\n"
599+ % (options.project, options.start_date)
600+ )
601+ sys.stdout.write("Generating detailed report in %s \n" % options.outfile)
602 sys.stdout.write("Please wait...\n")
603 sys.stdout.flush()
604
605- summary_report, detailed_report = gen_bug_report(launchpad, lp_bugs,
606- options.project,
607- options.verbose)
608+ summary_report, detailed_report = gen_bug_report(
609+ launchpad, lp_bugs, options.project, options.verbose
610+ )
611
612 for k, v in sorted(summary_report.iteritems()):
613 f.write("\n= Summary of %s bugs =\n" % k)
614- f.write("|| {:<14} | {:<8} |\n".format('Status', 'Count'))
615+ f.write("|| {:<14} | {:<8} |\n".format("Status", "Count"))
616 for x, y in sorted(v.iteritems()):
617 f.write("| {:<15} | {:<8} |\n".format(x, y))
618 if options.verbose is True:
619 f.write("== Details on %s bugs ==\n" % k)
620- f.write("|| Bug# | Created | Last Updated | Active Period "
621- "| Dormant Period | #Comments | Assignee | Status |\n")
622-
623- for a, b in sorted(detailed_report[k].iteritems(),
624- key=lambda item: item[1][1], reverse=True):
625- f.write("| [%s https://launchpad.net/bugs/%s] | %s |\n" %
626- (a, a, ' | '.join(map(str, b))))
627+ f.write(
628+ "|| Bug# | Created | Last Updated | Active Period "
629+ "| Dormant Period | #Comments | Assignee | Status |\n"
630+ )
631+
632+ for a, b in sorted(
633+ detailed_report[k].iteritems(),
634+ key=lambda item: item[1][1],
635+ reverse=True,
636+ ):
637+ f.write(
638+ "| [%s https://launchpad.net/bugs/%s] | %s |\n"
639+ % (a, a, " | ".join(map(str, b)))
640+ )
641
642 if f is not sys.stdout:
643 f.close()
644
645
646-if __name__ == '__main__':
647+if __name__ == "__main__":
648 main()
649diff --git a/lp-scripts/clone-project-milestones.py b/lp-scripts/clone-project-milestones.py
650index b0783d2..39099ab 100755
651--- a/lp-scripts/clone-project-milestones.py
652+++ b/lp-scripts/clone-project-milestones.py
653@@ -10,11 +10,11 @@ from launchpadlib.launchpad import Launchpad
654
655
656 # These may contain proprietary content, skip them
657-IgnoredSeries = ['firmware', 'ppa-uose', 'silicon', 'trunk']
658+IgnoredSeries = ["firmware", "ppa-uose", "silicon", "trunk"]
659
660
661 def clone_project_milestones(src, dest, dry_run):
662- lp = Launchpad.login_with('lpbugs', 'production', version='devel')
663+ lp = Launchpad.login_with("lpbugs", "production", version="devel")
664 src_project = lp.projects[src]
665 dest_project = lp.projects[dest]
666 for src_series in src_project.series:
667@@ -22,46 +22,49 @@ def clone_project_milestones(src, dest, dry_run):
668 continue
669 dest_series = dest_project.getSeries(name=src_series.name)
670 if dest_series:
671- logger.warning("Series %s already exists, skipping\n" %
672- (dest_series))
673+ logger.warning("Series %s already exists, skipping\n" % (dest_series))
674 else:
675 logger.info("Creating series %s" % (src_series.name))
676 if not dry_run:
677 dest_series = dest_project.newSeries(
678- name=src_series.name,
679- summary=src_series.summary)
680+ name=src_series.name, summary=src_series.summary
681+ )
682 for src_milestone in src_series.all_milestones:
683 dest_milestone = dest_project.getMilestone(name=src_milestone.name)
684 if dest_milestone:
685 logger.warning(
686- "Project already has milestone %s, skipping\n" %
687- (dest_milestone.name))
688+ "Project already has milestone %s, skipping\n"
689+ % (dest_milestone.name)
690+ )
691 else:
692 logger.info("Creating milestone %s" % (src_milestone.name))
693 if not dry_run:
694 dest_milestone = dest_series.newMilestone(
695 name=src_milestone.name,
696- date_targeted=src_milestone.date_targeted)
697+ date_targeted=src_milestone.date_targeted,
698+ )
699 dest_milestone.is_active = src_milestone.is_active
700 dest_milestone.lp_save()
701 src_release = src_milestone.release
702 if src_release:
703- logger.info("Releasing milestone %s on %s " %
704- (src_milestone.name,
705- src_milestone.release.date_released))
706+ logger.info(
707+ "Releasing milestone %s on %s "
708+ % (src_milestone.name, src_milestone.release.date_released)
709+ )
710 if not dry_run:
711 dest_milestone.createProductRelease(
712- date_released=src_milestone.release.date_released)
713+ date_released=src_milestone.release.date_released
714+ )
715
716
717-if __name__ == '__main__':
718+if __name__ == "__main__":
719 parser = argparse.ArgumentParser()
720- parser.add_argument('-s', '--source', required=True)
721- parser.add_argument('-d', '--dest', required=True)
722- parser.add_argument('--dry-run', action='store_true')
723+ parser.add_argument("-s", "--source", required=True)
724+ parser.add_argument("-d", "--dest", required=True)
725+ parser.add_argument("--dry-run", action="store_true")
726 args = parser.parse_args()
727
728- logger = logging.getLogger('clone-project-milestones')
729+ logger = logging.getLogger("clone-project-milestones")
730 logger.setLevel(logging.INFO)
731 ch = logging.StreamHandler()
732 formatter = logging.Formatter("%(levelname)s - %(message)s")
733diff --git a/lp-scripts/dump-bug-subscribers.py b/lp-scripts/dump-bug-subscribers.py
734index 061c539..70f8c72 100755
735--- a/lp-scripts/dump-bug-subscribers.py
736+++ b/lp-scripts/dump-bug-subscribers.py
737@@ -8,42 +8,54 @@ import csv
738 from launchpadlib.launchpad import Launchpad
739
740
741-bugStatuses = ["New", "Opinion", "Invalid", "Won't Fix", "Expired",
742- "Confirmed", "Triaged", "In Progress", "Fix Committed",
743- "Fix Released", "Incomplete"]
744+bugStatuses = [
745+ "New",
746+ "Opinion",
747+ "Invalid",
748+ "Won't Fix",
749+ "Expired",
750+ "Confirmed",
751+ "Triaged",
752+ "In Progress",
753+ "Fix Committed",
754+ "Fix Released",
755+ "Incomplete",
756+]
757
758
759 def taskToBug(task):
760- bugid = int(task.self_link.split('/')[-1])
761- return(lp.bugs[bugid])
762+ bugid = int(task.self_link.split("/")[-1])
763+ return lp.bugs[bugid]
764
765
766 def getSubscriptionId(subscription_url):
767 lpString = str(subscription_url)
768- lpPath = lpString.rsplit('/', 1)
769+ lpPath = lpString.rsplit("/", 1)
770 return lpPath[-1]
771
772
773-if __name__ == '__main__':
774+if __name__ == "__main__":
775 parser = argparse.ArgumentParser()
776- parser.add_argument("project", help="Launchpad project from which \
777- subscribers will be dumped")
778+ parser.add_argument(
779+ "project",
780+ help="Launchpad project from which \
781+ subscribers will be dumped",
782+ )
783 parser.add_argument("-o", "--outfile", help="Output file", required=True)
784 args = parser.parse_args()
785
786- lp = Launchpad.login_with('lpbugs', 'production', version='devel')
787+ lp = Launchpad.login_with("lpbugs", "production", version="devel")
788 project = lp.projects[args.project]
789
790- with open(args.outfile, 'w') as csvfile:
791+ with open(args.outfile, "w") as csvfile:
792 c = csv.writer(csvfile)
793 c.writerow(["Bug", "Title", "Subscribers"])
794-# no way to list all open/closed bugs, so iterate through bug states
795+ # no way to list all open/closed bugs, so iterate through bug states
796 for bugStatus in bugStatuses:
797 for task in project.searchTasks(status=bugStatus):
798 output = []
799 bug = taskToBug(task)
800- output.append('=HYPERLINK("%s", "LP: #%d")' %
801- (task.web_link, bug.id))
802+ output.append('=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id))
803 output.append(bug.title)
804 for subscription in bug.subscriptions:
805 output.append(getSubscriptionId(subscription))
806diff --git a/lp-scripts/lp-bulk-action.py b/lp-scripts/lp-bulk-action.py
807index be1b047..acada01 100755
808--- a/lp-scripts/lp-bulk-action.py
809+++ b/lp-scripts/lp-bulk-action.py
810@@ -5,14 +5,14 @@ import sys
811 from launchpadlib.launchpad import Launchpad
812
813 Projects = [
814- 'bandera',
815- 'kunpeng920',
816- 'pearl',
817- 'pearl2',
818- 'ubuntu-power-systems',
819- 'ubuntu-z-systems',
820- 'yarmouth',
821- 'yarmouth2',
822+ "bandera",
823+ "kunpeng920",
824+ "pearl",
825+ "pearl2",
826+ "ubuntu-power-systems",
827+ "ubuntu-z-systems",
828+ "yarmouth",
829+ "yarmouth2",
830 ]
831
832
833@@ -20,13 +20,15 @@ def createMilestone(lp, project, series, milestone, date):
834 p = lp.projects[project]
835 s = p.getSeries(name=series)
836 if not s:
837- sys.stderr.write("Warning: Project %s has no series %s, skipping\n" %
838- (project, series))
839+ sys.stderr.write(
840+ "Warning: Project %s has no series %s, skipping\n" % (project, series)
841+ )
842 return
843 if p.getMilestone(name=milestone):
844 sys.stderr.write(
845- "Warning: Project %s already has milestone %s, skipping\n" %
846- (project, milestone))
847+ "Warning: Project %s already has milestone %s, skipping\n"
848+ % (project, milestone)
849+ )
850 return
851 s.newMilestone(name=milestone, date_targeted=date)
852
853@@ -36,13 +38,14 @@ def releaseMilestone(lp, project, milestone, date):
854 m = p.getMilestone(name=milestone)
855 if not m:
856 sys.stderr.write(
857- "Warning: Project %s has no milestone %s, skipping\n" %
858- (project, milestone))
859+ "Warning: Project %s has no milestone %s, skipping\n" % (project, milestone)
860+ )
861 return
862 if m.release:
863 sys.stderr.write(
864- "Warning: Milestone %s in project %s is already released\n" %
865- (milestone, project))
866+ "Warning: Milestone %s in project %s is already released\n"
867+ % (milestone, project)
868+ )
869 return
870 m.createProductRelease(date_released=date)
871
872@@ -52,8 +55,9 @@ def updateMilestone(lp, project, milestone, date):
873 m = p.getMilestone(name=milestone)
874 if not m:
875 sys.stderr.write(
876- "Warning: Project %s does not have milestone %s, skipping\n" %
877- (project, milestone))
878+ "Warning: Project %s does not have milestone %s, skipping\n"
879+ % (project, milestone)
880+ )
881 return
882 m.date_targeted = date
883 m.lp_save()
884@@ -63,51 +67,52 @@ def createSeries(lp, project, series, summary):
885 p = lp.projects[project]
886 if p.getSeries(name=series):
887 sys.stderr.write(
888- "Warning: Project %s already has series %s, skipping\n" %
889- (project, series))
890+ "Warning: Project %s already has series %s, skipping\n" % (project, series)
891+ )
892 return
893 p.newSeries(name=series, summary=summary)
894
895
896-if __name__ == '__main__':
897+if __name__ == "__main__":
898 parser = argparse.ArgumentParser()
899- subparsers = parser.add_subparsers(dest='cmd')
900+ subparsers = parser.add_subparsers(dest="cmd")
901 subparsers.required = True
902- createMilestoneParser = subparsers.add_parser('create-milestone',
903- help="Create Milestone")
904+ createMilestoneParser = subparsers.add_parser(
905+ "create-milestone", help="Create Milestone"
906+ )
907 createMilestoneParser.add_argument("-s", "--series", required=True)
908 createMilestoneParser.add_argument("-d", "--date", required=True)
909 createMilestoneParser.add_argument("milestone")
910- createMilestoneParser.set_defaults(cmd='create-milestone')
911+ createMilestoneParser.set_defaults(cmd="create-milestone")
912
913- releaseMilestoneParser = subparsers.add_parser('release-milestone',
914- help="Release Milestone")
915+ releaseMilestoneParser = subparsers.add_parser(
916+ "release-milestone", help="Release Milestone"
917+ )
918 releaseMilestoneParser.add_argument("-d", "--date", required=True)
919 releaseMilestoneParser.add_argument("milestone")
920- releaseMilestoneParser.set_defaults(cmd='release-milestone')
921+ releaseMilestoneParser.set_defaults(cmd="release-milestone")
922
923- releaseMilestoneParser = subparsers.add_parser('update-milestone',
924- help="Update Milestone")
925+ releaseMilestoneParser = subparsers.add_parser(
926+ "update-milestone", help="Update Milestone"
927+ )
928 releaseMilestoneParser.add_argument("-d", "--date", required=True)
929 releaseMilestoneParser.add_argument("milestone")
930- releaseMilestoneParser.set_defaults(cmd='update-milestone')
931+ releaseMilestoneParser.set_defaults(cmd="update-milestone")
932
933- createSeriesParser = subparsers.add_parser('create-series',
934- help="Create Series")
935+ createSeriesParser = subparsers.add_parser("create-series", help="Create Series")
936 createSeriesParser.add_argument("-s", "--summary", required=True)
937 createSeriesParser.add_argument("series")
938- createSeriesParser.set_defaults(cmd='create-series')
939+ createSeriesParser.set_defaults(cmd="create-series")
940 args = parser.parse_args()
941
942- lp = Launchpad.login_with('lpbugs', 'production', version='devel')
943+ lp = Launchpad.login_with("lpbugs", "production", version="devel")
944
945 for project in Projects:
946- if args.cmd == 'create-milestone':
947- createMilestone(lp, project, args.series,
948- args.milestone, args.date)
949- elif args.cmd == 'create-series':
950+ if args.cmd == "create-milestone":
951+ createMilestone(lp, project, args.series, args.milestone, args.date)
952+ elif args.cmd == "create-series":
953 createSeries(lp, project, args.series, args.summary)
954- elif args.cmd == 'release-milestone':
955+ elif args.cmd == "release-milestone":
956 releaseMilestone(lp, project, args.milestone, args.date)
957- elif args.cmd == 'update-milestone':
958+ elif args.cmd == "update-milestone":
959 updateMilestone(lp, project, args.milestone, args.date)
960diff --git a/lp-scripts/pearl-biweekly-bug-report-csv4.py b/lp-scripts/pearl-biweekly-bug-report-csv4.py
961index 6590ecf..1295c43 100755
962--- a/lp-scripts/pearl-biweekly-bug-report-csv4.py
963+++ b/lp-scripts/pearl-biweekly-bug-report-csv4.py
964@@ -1,74 +1,93 @@
965+#!/usr/bin/python3
966 # Change History
967 # Modify encode utf_8 to byte code in Rationale/Comment
968-# Add Date_created column for creating date for bug
969+# Add Date_created column for creating date for bug
970 # Add Scope column for showing impact for all arc or arch-arm64 or D05 Boad only
971
972-#!/usr/bin/python3
973-
974 import argparse
975 import csv
976 from launchpadlib.launchpad import Launchpad
977
978-rationaleSectionHeader="[16.04.3 Risk Comments]"
979-rationaleBoilerplate="Still under investigation, not yet root-caused."
980+rationaleSectionHeader = "[16.04.3 Risk Comments]"
981+rationaleBoilerplate = "Still under investigation, not yet root-caused."
982+
983
984 def taskToBug(task):
985- bugid = int(task.self_link.split('/')[-1])
986- return(lp.bugs[bugid])
987+ bugid = int(task.self_link.split("/")[-1])
988+ return lp.bugs[bugid]
989+
990
991 def ownerFromStatus(status):
992- if 'Incomplete' in status:
993- owner='Huawei'
994+ if "Incomplete" in status:
995+ owner = "Huawei"
996 else:
997- owner='Canonical'
998- return(owner)
999+ owner = "Canonical"
1000+ return owner
1001+
1002
1003 def rationaleFromDescription(des):
1004- export_rationale_flag=0 # Flag to detect the start of the "[16.04.3 Risk Comments]" section
1005- rationale=""
1006- for des_line in des.splitlines(): # Loop through the bug description line-by-line looking for sections to export
1007+ export_rationale_flag = (
1008+ 0 # Flag to detect the start of the "[16.04.3 Risk Comments]" section
1009+ )
1010+ rationale = ""
1011+ for (
1012+ des_line
1013+ ) in (
1014+ des.splitlines()
1015+ ): # Loop through the bug description line-by-line looking for sections to export
1016 if des_line == rationaleSectionHeader:
1017- export_rationale_flag=1
1018+ export_rationale_flag = 1
1019 else:
1020- if export_rationale_flag==1:
1021- if des_line=="":
1022- export_rationale_flag=0
1023+ if export_rationale_flag == 1:
1024+ if des_line == "":
1025+ export_rationale_flag = 0
1026 else:
1027- rationale+=des_line
1028- return(rationale)
1029+ rationale += des_line
1030+ return rationale
1031
1032
1033 def checkScopeTags(tags):
1034- scopeTags = ['scope-arch-all', 'scope-arch-arm64', 'scope-d05-only']
1035+ scopeTags = ["scope-arch-all", "scope-arch-arm64", "scope-d05-only"]
1036 scope = set(scopeTags).intersection(tags)
1037 for i in scope:
1038- return(i)
1039+ return i
1040
1041- return('Unknown')
1042+ return "Unknown"
1043
1044
1045-if __name__ == '__main__':
1046+if __name__ == "__main__":
1047 parser = argparse.ArgumentParser()
1048 parser.add_argument("-o", "--outfile", required=True)
1049 args = parser.parse_args()
1050
1051- lp = Launchpad.login_with('lpbugs', 'production', version='devel')
1052+ lp = Launchpad.login_with("lpbugs", "production", version="devel")
1053
1054- pearl = lp.projects['pearl']
1055+ pearl = lp.projects["pearl"]
1056
1057- with open(args.outfile, 'w') as csvfile:
1058+ with open(args.outfile, "w") as csvfile:
1059 c = csv.writer(csvfile)
1060- c.writerow(["Title", "Link", "Status", "Milestone", "Scope","Rationale/Comment", "Owner", "DateCreated"])
1061-# First pass: patchset bugs
1062+ c.writerow(
1063+ [
1064+ "Title",
1065+ "Link",
1066+ "Status",
1067+ "Milestone",
1068+ "Scope",
1069+ "Rationale/Comment",
1070+ "Owner",
1071+ "DateCreated",
1072+ ]
1073+ )
1074+ # First pass: patchset bugs
1075 for series in pearl.series:
1076- if series.name not in ['ubuntu-16.04']:
1077+ if series.name not in ["ubuntu-16.04"]:
1078 continue
1079-# First pass, phase one: search for the 'open' bugs
1080- for task in series.searchTasks():
1081+ # First pass, phase one: search for the 'open' bugs
1082+ for task in series.searchTasks():
1083 bug = taskToBug(task)
1084 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'
1085-# if 'upstream-risky' not in bug.tags:
1086-# continue
1087+ # if 'upstream-risky' not in bug.tags:
1088+ # continue
1089 if task.milestone is None:
1090 milestone = "TBD"
1091 else:
1092@@ -76,18 +95,29 @@ if __name__ == '__main__':
1093 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)
1094 rationale = rationaleFromDescription(bug.description)
1095 if (not rationale) and (task.milestone is None):
1096- rationale=rationaleBoilerplate
1097- scope = checkScopeTags(bug.tags)
1098- owner = ownerFromStatus(task.status)
1099- date_created = bug.date_created.strftime("%Y/%m/%d")
1100- c.writerow([bug.title, link, task.status, milestone, scope, rationale.encode('utf_8'), owner, date_created])
1101-
1102-# First pass, phase two: Fix Released bugs
1103+ rationale = rationaleBoilerplate
1104+ scope = checkScopeTags(bug.tags)
1105+ owner = ownerFromStatus(task.status)
1106+ date_created = bug.date_created.strftime("%Y/%m/%d")
1107+ c.writerow(
1108+ [
1109+ bug.title,
1110+ link,
1111+ task.status,
1112+ milestone,
1113+ scope,
1114+ rationale.encode("utf_8"),
1115+ owner,
1116+ date_created,
1117+ ]
1118+ )
1119+
1120+ # First pass, phase two: Fix Released bugs
1121 for task in series.searchTasks(status="Fix Released"):
1122 bug = taskToBug(task)
1123 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'
1124-# if not 'upstream-risky' not in bug.tags:
1125-# continue
1126+ # if not 'upstream-risky' not in bug.tags:
1127+ # continue
1128 if task.milestone is None:
1129 milestone = "TBD"
1130 else:
1131@@ -95,9 +125,19 @@ if __name__ == '__main__':
1132 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)
1133 rationale = rationaleFromDescription(bug.description)
1134 if (not rationale) and (task.milestone is None):
1135- rationale=rationaleBoilerplate
1136+ rationale = rationaleBoilerplate
1137 scope = checkScopeTags(bug.tags)
1138 owner = ownerFromStatus(task.status)
1139- date_created = bug.date_created.strftime("%Y/%m/%d")
1140- c.writerow([bug.title, link, task.status, milestone, scope, rationale.encode('utf_8'), owner, date_created])
1141-
1142+ date_created = bug.date_created.strftime("%Y/%m/%d")
1143+ c.writerow(
1144+ [
1145+ bug.title,
1146+ link,
1147+ task.status,
1148+ milestone,
1149+ scope,
1150+ rationale.encode("utf_8"),
1151+ owner,
1152+ date_created,
1153+ ]
1154+ )
1155diff --git a/lp-scripts/pearl-biweekly-report-csv.py b/lp-scripts/pearl-biweekly-report-csv.py
1156index 2006490..5da289d 100755
1157--- a/lp-scripts/pearl-biweekly-report-csv.py
1158+++ b/lp-scripts/pearl-biweekly-report-csv.py
1159@@ -4,57 +4,76 @@ import argparse
1160 import csv
1161 from launchpadlib.launchpad import Launchpad
1162
1163-rationaleSectionHeader="[16.04.3 Risk Comments]"
1164-rationaleBoilerplate="Still under investigation, not yet root-caused."
1165+rationaleSectionHeader = "[16.04.3 Risk Comments]"
1166+rationaleBoilerplate = "Still under investigation, not yet root-caused."
1167+
1168
1169 def taskToBug(task):
1170- bugid = int(task.self_link.split('/')[-1])
1171- return(lp.bugs[bugid])
1172+ bugid = int(task.self_link.split("/")[-1])
1173+ return lp.bugs[bugid]
1174+
1175
1176 def ownerFromStatus(status):
1177- if 'Incomplete' in status:
1178- owner='Huawei'
1179+ if "Incomplete" in status:
1180+ owner = "Huawei"
1181 else:
1182- owner='Canonical'
1183- return(owner)
1184+ owner = "Canonical"
1185+ return owner
1186+
1187
1188 def rationaleFromDescription(des):
1189- export_rationale_flag=0 # Flag to detect the start of the "[16.04.3 Risk Comments]" section
1190- rationale=""
1191- for des_line in des.splitlines(): # Loop through the bug description line-by-line looking for sections to export
1192+ export_rationale_flag = (
1193+ 0 # Flag to detect the start of the "[16.04.3 Risk Comments]" section
1194+ )
1195+ rationale = ""
1196+ for (
1197+ des_line
1198+ ) in (
1199+ des.splitlines()
1200+ ): # Loop through the bug description line-by-line looking for sections to export
1201 if des_line == rationaleSectionHeader:
1202- export_rationale_flag=1
1203+ export_rationale_flag = 1
1204 else:
1205- if export_rationale_flag==1:
1206- if des_line=="":
1207- export_rationale_flag=0
1208+ if export_rationale_flag == 1:
1209+ if des_line == "":
1210+ export_rationale_flag = 0
1211 else:
1212- rationale+=des_line
1213- return(rationale)
1214+ rationale += des_line
1215+ return rationale
1216
1217-
1218-if __name__ == '__main__':
1219+
1220+if __name__ == "__main__":
1221 parser = argparse.ArgumentParser()
1222 parser.add_argument("-o", "--outfile", required=True)
1223 args = parser.parse_args()
1224
1225- lp = Launchpad.login_with('lpbugs', 'production', version='devel')
1226+ lp = Launchpad.login_with("lpbugs", "production", version="devel")
1227
1228- pearl = lp.projects['pearl']
1229+ pearl = lp.projects["pearl"]
1230
1231- with open(args.outfile, 'w') as csvfile:
1232+ with open(args.outfile, "w") as csvfile:
1233 c = csv.writer(csvfile)
1234- c.writerow(["Title", "Link", "Status", "Milestone", "Rationale/Comment", "Owner", "DateCreated"])
1235-# First pass: patchset bugs
1236+ c.writerow(
1237+ [
1238+ "Title",
1239+ "Link",
1240+ "Status",
1241+ "Milestone",
1242+ "Rationale/Comment",
1243+ "Owner",
1244+ "DateCreated",
1245+ ]
1246+ )
1247+ # First pass: patchset bugs
1248 for series in pearl.series:
1249- if series.name not in ['ubuntu-16.04']:
1250+ if series.name not in ["ubuntu-16.04"]:
1251 continue
1252-# First pass, phase one: search for the 'open' bugs
1253- for task in series.searchTasks():
1254+ # First pass, phase one: search for the 'open' bugs
1255+ for task in series.searchTasks():
1256 bug = taskToBug(task)
1257 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'
1258-# if 'upstream-risky' not in bug.tags:
1259-# continue
1260+ # if 'upstream-risky' not in bug.tags:
1261+ # continue
1262 if task.milestone is None:
1263 milestone = "TBD"
1264 else:
1265@@ -62,17 +81,27 @@ if __name__ == '__main__':
1266 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)
1267 rationale = rationaleFromDescription(bug.description)
1268 if (not rationale) and (task.milestone is None):
1269- rationale=rationaleBoilerplate
1270+ rationale = rationaleBoilerplate
1271 owner = ownerFromStatus(task.status)
1272- date_created = bug.date_created.strftime("%Y/%m/%d")
1273- c.writerow([bug.title, link, task.status, milestone, rationale.encode('utf_8'), owner, date_created])
1274+ date_created = bug.date_created.strftime("%Y/%m/%d")
1275+ c.writerow(
1276+ [
1277+ bug.title,
1278+ link,
1279+ task.status,
1280+ milestone,
1281+ rationale.encode("utf_8"),
1282+ owner,
1283+ date_created,
1284+ ]
1285+ )
1286
1287-# First pass, phase two: Fix Released bugs
1288- for task in series.searchTasks(status="Fix Released"):
1289+ # First pass, phase two: Fix Released bugs
1290+ for task in series.searchTasks(status="Fix Released"):
1291 bug = taskToBug(task)
1292 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'
1293-# if not 'upstream-risky' not in bug.tags:
1294-# continue
1295+ # if not 'upstream-risky' not in bug.tags:
1296+ # continue
1297 if task.milestone is None:
1298 milestone = "TBD"
1299 else:
1300@@ -80,8 +109,17 @@ if __name__ == '__main__':
1301 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)
1302 rationale = rationaleFromDescription(bug.description)
1303 if (not rationale) and (task.milestone is None):
1304- rationale=rationaleBoilerplate
1305+ rationale = rationaleBoilerplate
1306 owner = ownerFromStatus(task.status)
1307- date_created = bug.date_created.strftime("%Y/%m/%d")
1308- c.writerow([bug.title, link, task.status, milestone, rationale.encode('utf_8'), owner, date_created])
1309-
1310+ date_created = bug.date_created.strftime("%Y/%m/%d")
1311+ c.writerow(
1312+ [
1313+ bug.title,
1314+ link,
1315+ task.status,
1316+ milestone,
1317+ rationale.encode("utf_8"),
1318+ owner,
1319+ date_created,
1320+ ]
1321+ )
1322diff --git a/lp-scripts/pearl-biweekly-report.csv.py b/lp-scripts/pearl-biweekly-report.csv.py
1323index 454c993..bfebacc 100644
1324--- a/lp-scripts/pearl-biweekly-report.csv.py
1325+++ b/lp-scripts/pearl-biweekly-report.csv.py
1326@@ -1,80 +1,99 @@
1327+#!/usr/bin/python3
1328 # Change History
1329 # Modify encode utf_8 to byte code in Rationale/Comment
1330-# Add Date_created column for creating date for bug
1331+# Add Date_created column for creating date for bug
1332 # Add Scope column for showing impact for all arc or arch-arm64 or D05 Boad only
1333
1334-#!/usr/bin/python3
1335-
1336 import argparse
1337 import csv
1338 from launchpadlib.launchpad import Launchpad
1339
1340-rationaleSectionHeader="[16.04.3 Risk Comments]"
1341-rationaleBoilerplate="Still under investigation, not yet root-caused."
1342+rationaleSectionHeader = "[16.04.3 Risk Comments]"
1343+rationaleBoilerplate = "Still under investigation, not yet root-caused."
1344+
1345
1346 def taskToBug(task):
1347- bugid = int(task.self_link.split('/')[-1])
1348- return(lp.bugs[bugid])
1349+ bugid = int(task.self_link.split("/")[-1])
1350+ return lp.bugs[bugid]
1351+
1352
1353 def ownerFromStatus(status):
1354- if 'Incomplete' in status:
1355- owner='Huawei'
1356+ if "Incomplete" in status:
1357+ owner = "Huawei"
1358 else:
1359- owner='Canonical'
1360- return(owner)
1361+ owner = "Canonical"
1362+ return owner
1363+
1364
1365 def rationaleFromDescription(des):
1366- export_rationale_flag=0 # Flag to detect the start of the "[16.04.3 Risk Comments]" section
1367- rationale=""
1368- for des_line in des.splitlines(): # Loop through the bug description line-by-line looking for sections to export
1369+ export_rationale_flag = (
1370+ 0 # Flag to detect the start of the "[16.04.3 Risk Comments]" section
1371+ )
1372+ rationale = ""
1373+ for (
1374+ des_line
1375+ ) in (
1376+ des.splitlines()
1377+ ): # Loop through the bug description line-by-line looking for sections to export
1378 if des_line == rationaleSectionHeader:
1379- export_rationale_flag=1
1380+ export_rationale_flag = 1
1381 else:
1382- if export_rationale_flag==1:
1383- if des_line=="":
1384- export_rationale_flag=0
1385+ if export_rationale_flag == 1:
1386+ if des_line == "":
1387+ export_rationale_flag = 0
1388 else:
1389- rationale+=des_line
1390- return(rationale)
1391+ rationale += des_line
1392+ return rationale
1393
1394
1395 def checkScopeTags(tags):
1396- scopeTags = ['scope-arch-all', 'scope-arch-arm64', 'scope-d05-only']
1397+ scopeTags = ["scope-arch-all", "scope-arch-arm64", "scope-d05-only"]
1398 scope = set(scopeTags).intersection(tags)
1399 for i in scope:
1400- if i == 'scope-arch-all':
1401- i = 'Generic'
1402- elif i == 'scope-arch-arm64':
1403- i = 'ARM64 generic'
1404- elif i == 'scope-d05-only':
1405- i = 'D05 only'
1406- return(i)
1407+ if i == "scope-arch-all":
1408+ i = "Generic"
1409+ elif i == "scope-arch-arm64":
1410+ i = "ARM64 generic"
1411+ elif i == "scope-d05-only":
1412+ i = "D05 only"
1413+ return i
1414
1415- return('Unknown')
1416+ return "Unknown"
1417
1418
1419-if __name__ == '__main__':
1420+if __name__ == "__main__":
1421 parser = argparse.ArgumentParser()
1422 parser.add_argument("-o", "--outfile", required=True)
1423 args = parser.parse_args()
1424
1425- lp = Launchpad.login_with('lpbugs', 'production', version='devel')
1426+ lp = Launchpad.login_with("lpbugs", "production", version="devel")
1427
1428- pearl = lp.projects['pearl']
1429+ pearl = lp.projects["pearl"]
1430
1431- with open(args.outfile, 'w') as csvfile:
1432+ with open(args.outfile, "w") as csvfile:
1433 c = csv.writer(csvfile)
1434- c.writerow(["Title", "Link", "Status", "Milestone", "Scope","Rationale/Comment", "Owner", "DateCreated"])
1435-# First pass: patchset bugs
1436+ c.writerow(
1437+ [
1438+ "Title",
1439+ "Link",
1440+ "Status",
1441+ "Milestone",
1442+ "Scope",
1443+ "Rationale/Comment",
1444+ "Owner",
1445+ "DateCreated",
1446+ ]
1447+ )
1448+ # First pass: patchset bugs
1449 for series in pearl.series:
1450- if series.name not in ['ubuntu-16.04']:
1451+ if series.name not in ["ubuntu-16.04"]:
1452 continue
1453-# First pass, phase one: search for the 'open' bugs
1454- for task in series.searchTasks():
1455+ # First pass, phase one: search for the 'open' bugs
1456+ for task in series.searchTasks():
1457 bug = taskToBug(task)
1458 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'
1459-# if 'upstream-risky' not in bug.tags:
1460-# continue
1461+ # if 'upstream-risky' not in bug.tags:
1462+ # continue
1463 if task.milestone is None:
1464 milestone = "TBD"
1465 else:
1466@@ -82,18 +101,29 @@ if __name__ == '__main__':
1467 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)
1468 rationale = rationaleFromDescription(bug.description)
1469 if (not rationale) and (task.milestone is None):
1470- rationale=rationaleBoilerplate
1471- scope = checkScopeTags(bug.tags)
1472- owner = ownerFromStatus(task.status)
1473- date_created = bug.date_created.strftime("%Y/%m/%d")
1474- c.writerow([bug.title, link, task.status, milestone, scope, rationale.encode('utf_8'), owner, date_created])
1475-
1476-# First pass, phase two: Fix Released bugs
1477+ rationale = rationaleBoilerplate
1478+ scope = checkScopeTags(bug.tags)
1479+ owner = ownerFromStatus(task.status)
1480+ date_created = bug.date_created.strftime("%Y/%m/%d")
1481+ c.writerow(
1482+ [
1483+ bug.title,
1484+ link,
1485+ task.status,
1486+ milestone,
1487+ scope,
1488+ rationale.encode("utf_8"),
1489+ owner,
1490+ date_created,
1491+ ]
1492+ )
1493+
1494+ # First pass, phase two: Fix Released bugs
1495 for task in series.searchTasks(status="Fix Released"):
1496 bug = taskToBug(task)
1497 # All kernel patchset bugs in the pearl project are tagged 'upstream-risky'
1498-# if not 'upstream-risky' not in bug.tags:
1499-# continue
1500+ # if not 'upstream-risky' not in bug.tags:
1501+ # continue
1502 if task.milestone is None:
1503 milestone = "TBD"
1504 else:
1505@@ -101,9 +131,19 @@ if __name__ == '__main__':
1506 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)
1507 rationale = rationaleFromDescription(bug.description)
1508 if (not rationale) and (task.milestone is None):
1509- rationale=rationaleBoilerplate
1510+ rationale = rationaleBoilerplate
1511 scope = checkScopeTags(bug.tags)
1512 owner = ownerFromStatus(task.status)
1513- date_created = bug.date_created.strftime("%Y/%m/%d")
1514- c.writerow([bug.title, link, task.status, milestone, scope, rationale.encode('utf_8'), owner, date_created])
1515-
1516+ date_created = bug.date_created.strftime("%Y/%m/%d")
1517+ c.writerow(
1518+ [
1519+ bug.title,
1520+ link,
1521+ task.status,
1522+ milestone,
1523+ scope,
1524+ rationale.encode("utf_8"),
1525+ owner,
1526+ date_created,
1527+ ]
1528+ )
1529diff --git a/lp-scripts/pearl-bug-csv-summary.py b/lp-scripts/pearl-bug-csv-summary.py
1530index a1a0b35..ad4a049 100755
1531--- a/lp-scripts/pearl-bug-csv-summary.py
1532+++ b/lp-scripts/pearl-bug-csv-summary.py
1533@@ -7,18 +7,19 @@ from LaunchpadBugBucketer import LaunchpadBugBucketer
1534
1535 class PearlBugBucketer(LaunchpadBugBucketer):
1536 def __init__(self):
1537- LaunchpadBugBucketer.__init__(self, 'pearl', 'ubuntu-16.04',
1538- requiredTags=['upstream-risky'])
1539+ LaunchpadBugBucketer.__init__(
1540+ self, "pearl", "ubuntu-16.04", requiredTags=["upstream-risky"]
1541+ )
1542
1543 def is_green(self, task):
1544- if task.status in ['Fix Committed', 'Fix Released']:
1545+ if task.status in ["Fix Committed", "Fix Released"]:
1546 return True
1547 return False
1548
1549 def is_amber(self, task):
1550 if self.is_green(task):
1551 return False
1552- elif task.milestone and task.milestone.name == 'ubuntu-16.04.3':
1553+ elif task.milestone and task.milestone.name == "ubuntu-16.04.3":
1554 return True
1555 return False
1556
1557@@ -28,16 +29,16 @@ class PearlBugBucketer(LaunchpadBugBucketer):
1558 return True
1559
1560
1561-if __name__ == '__main__':
1562+if __name__ == "__main__":
1563 parser = argparse.ArgumentParser()
1564 parser.add_argument("-o", "--outfile")
1565 args = parser.parse_args()
1566
1567 s = PearlBugBucketer()
1568
1569- with open(args.outfile, 'w') as csvfile:
1570+ with open(args.outfile, "w") as csvfile:
1571 c = csv.writer(csvfile)
1572- c.writerow(['Title', 'Bug ID', 'Importance', 'Status', 'RAG Risk'])
1573+ c.writerow(["Title", "Bug ID", "Importance", "Status", "RAG Risk"])
1574 for bucket in s.keys():
1575 for task in s[bucket]:
1576 bug = s.taskToBug(task)
1577diff --git a/lp-scripts/pearl-risky-patch-schedule.py b/lp-scripts/pearl-risky-patch-schedule.py
1578index a22f493..01d546e 100755
1579--- a/lp-scripts/pearl-risky-patch-schedule.py
1580+++ b/lp-scripts/pearl-risky-patch-schedule.py
1581@@ -4,29 +4,31 @@ import argparse
1582 import csv
1583 from launchpadlib.launchpad import Launchpad
1584
1585+
1586 def taskToBug(task):
1587- bugid = int(task.self_link.split('/')[-1])
1588- return(lp.bugs[bugid])
1589-
1590-if __name__ == '__main__':
1591+ bugid = int(task.self_link.split("/")[-1])
1592+ return lp.bugs[bugid]
1593+
1594+
1595+if __name__ == "__main__":
1596 parser = argparse.ArgumentParser()
1597 parser.add_argument("-o", "--outfile", required=True)
1598 args = parser.parse_args()
1599
1600- lp = Launchpad.login_with('lpbugs', 'production', version='devel')
1601+ lp = Launchpad.login_with("lpbugs", "production", version="devel")
1602
1603- pearl = lp.projects['pearl']
1604+ pearl = lp.projects["pearl"]
1605
1606- with open(args.outfile, 'w') as csvfile:
1607+ with open(args.outfile, "w") as csvfile:
1608 c = csv.writer(csvfile)
1609 for series in pearl.series:
1610- if series.name not in ['ubuntu-17.04']:
1611+ if series.name not in ["ubuntu-17.04"]:
1612 continue
1613- for task in series.searchTasks():
1614+ for task in series.searchTasks():
1615 bug = taskToBug(task)
1616 # All kernel patchset bugs in the pearl project are tagged
1617 # 'upstream-risky'
1618- if 'upstream-risky' not in bug.tags:
1619+ if "upstream-risky" not in bug.tags:
1620 continue
1621 if task.milestone is None:
1622 date = "TBD"
1623diff --git a/lp-scripts/pearl2-biweekly-report.csv.py b/lp-scripts/pearl2-biweekly-report.csv.py
1624index b005620..a5a75d9 100755
1625--- a/lp-scripts/pearl2-biweekly-report.csv.py
1626+++ b/lp-scripts/pearl2-biweekly-report.csv.py
1627@@ -10,94 +10,110 @@ import argparse
1628 import csv
1629 from launchpadlib.launchpad import Launchpad
1630
1631-rationaleSectionHeader="[18.04.1 Risk Comments]"
1632-rationaleBoilerplate="Still under investigation, not yet root-caused."
1633+rationaleSectionHeader = "[18.04.1 Risk Comments]"
1634+rationaleBoilerplate = "Still under investigation, not yet root-caused."
1635+
1636
1637 def taskToBug(task):
1638- bugid = int(task.self_link.split('/')[-1])
1639- return(lp.bugs[bugid])
1640+ bugid = int(task.self_link.split("/")[-1])
1641+ return lp.bugs[bugid]
1642+
1643
1644 def ownerFromStatus(status):
1645- if 'Incomplete' in status:
1646- owner='Huawei'
1647+ if "Incomplete" in status:
1648+ owner = "Huawei"
1649 else:
1650- owner='Canonical'
1651- return(owner)
1652+ owner = "Canonical"
1653+ return owner
1654+
1655
1656 def rationaleFromDescription(des):
1657- export_rationale_flag=0 # Flag to detect the start of the "[18.04.1 Risk Comments]" section
1658- rationale=""
1659- for des_line in des.splitlines(): # Loop through the bug description line-by-line looking for sections to export
1660+ export_rationale_flag = (
1661+ 0 # Flag to detect the start of the "[18.04.1 Risk Comments]" section
1662+ )
1663+ rationale = ""
1664+ for (
1665+ des_line
1666+ ) in (
1667+ des.splitlines()
1668+ ): # Loop through the bug description line-by-line looking for sections to export
1669 if des_line == rationaleSectionHeader:
1670- export_rationale_flag=1
1671+ export_rationale_flag = 1
1672 else:
1673- if export_rationale_flag==1:
1674- if des_line=="":
1675- export_rationale_flag=0
1676+ if export_rationale_flag == 1:
1677+ if des_line == "":
1678+ export_rationale_flag = 0
1679 else:
1680- rationale+=des_line
1681- return(rationale)
1682+ rationale += des_line
1683+ return rationale
1684
1685
1686 def checkScopeTags(tags):
1687- scopeTags = ['scope-arch-all', 'scope-arch-arm64', 'scope-d06-only']
1688+ scopeTags = ["scope-arch-all", "scope-arch-arm64", "scope-d06-only"]
1689 scope = set(scopeTags).intersection(tags)
1690 for i in scope:
1691- if i == 'scope-arch-all':
1692- i = 'Generic'
1693- elif i == 'scope-arch-arm64':
1694- i = 'ARM64 generic'
1695- elif i == 'scope-d06-only':
1696- i = 'D06 only'
1697- return(i)
1698+ if i == "scope-arch-all":
1699+ i = "Generic"
1700+ elif i == "scope-arch-arm64":
1701+ i = "ARM64 generic"
1702+ elif i == "scope-d06-only":
1703+ i = "D06 only"
1704+ return i
1705+
1706+ return "Unknown"
1707
1708- return('Unknown')
1709
1710 def getMilestones(series_array):
1711- milestones=[]
1712+ milestones = []
1713 for series in series_array:
1714- milestone_url=series['milestone_link']
1715+ milestone_url = series["milestone_link"]
1716 if milestone_url is not None:
1717- milestone_name=milestone_url.rsplit('/',1)
1718+ milestone_name = milestone_url.rsplit("/", 1)
1719 milestones.append(milestone_name[-1])
1720 return milestones
1721
1722+
1723 def getUoseMilestone(series_array):
1724- milestones=getMilestones(series_array)
1725- uose_milestone=""
1726+ milestones = getMilestones(series_array)
1727+ uose_milestone = ""
1728 for milestone in milestones:
1729 if "uose" in milestone:
1730- uose_milestone=milestone
1731+ uose_milestone = milestone
1732 return uose_milestone
1733
1734
1735-if __name__ == '__main__':
1736+if __name__ == "__main__":
1737 parser = argparse.ArgumentParser()
1738 parser.add_argument("-o", "--outfile", required=True)
1739 args = parser.parse_args()
1740
1741- lp = Launchpad.login_with('lpbugs', 'production', version='devel')
1742+ lp = Launchpad.login_with("lpbugs", "production", version="devel")
1743
1744- pearl = lp.projects['pearl2']
1745+ pearl = lp.projects["pearl2"]
1746
1747- with open(args.outfile, 'w') as csvfile:
1748+ with open(args.outfile, "w") as csvfile:
1749 c = csv.writer(csvfile)
1750- c.writerow(["Title", "Link", "Status", "Milestone", "Owner", "DateCreated","Comments"])
1751-# First pass: search for the 'open' bugs
1752+ c.writerow(
1753+ ["Title", "Link", "Status", "Milestone", "Owner", "DateCreated", "Comments"]
1754+ )
1755+ # First pass: search for the 'open' bugs
1756 for task in pearl.searchTasks():
1757- uose_milestone=getUoseMilestone(task.related_tasks.entries)
1758+ uose_milestone = getUoseMilestone(task.related_tasks.entries)
1759 bug = taskToBug(task)
1760 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)
1761 owner = ownerFromStatus(task.status)
1762 date_created = bug.date_created.strftime("%Y/%m/%d")
1763- c.writerow([bug.title, link, task.status, uose_milestone, owner, date_created])
1764+ c.writerow(
1765+ [bug.title, link, task.status, uose_milestone, owner, date_created]
1766+ )
1767
1768-# Second pass: search for the 'Fix Released' bugs
1769+ # Second pass: search for the 'Fix Released' bugs
1770 for task in pearl.searchTasks(status="Fix Released"):
1771 bug = taskToBug(task)
1772- uose_milestone=getUoseMilestone(task.related_tasks.entries)
1773+ uose_milestone = getUoseMilestone(task.related_tasks.entries)
1774 link = '=HYPERLINK("%s", "LP: #%d")' % (task.web_link, bug.id)
1775 owner = ownerFromStatus(task.status)
1776 date_created = bug.date_created.strftime("%Y/%m/%d")
1777- c.writerow([bug.title, link, task.status, uose_milestone, owner, date_created])
1778-
1779+ c.writerow(
1780+ [bug.title, link, task.status, uose_milestone, owner, date_created]
1781+ )
1782diff --git a/lp-scripts/pearl2-d06-18.04-patch-status.py b/lp-scripts/pearl2-d06-18.04-patch-status.py
1783index 2d56d05..79316bc 100755
1784--- a/lp-scripts/pearl2-d06-18.04-patch-status.py
1785+++ b/lp-scripts/pearl2-d06-18.04-patch-status.py
1786@@ -2,29 +2,34 @@
1787
1788 import argparse
1789 import csv
1790-import string
1791 from launchpadlib.launchpad import Launchpad
1792
1793+
1794 def taskToBug(task):
1795- bugid = int(task.self_link.split('/')[-1])
1796- return(lp.bugs[bugid])
1797+ bugid = int(task.self_link.split("/")[-1])
1798+ return lp.bugs[bugid]
1799
1800
1801-Pre18041Milestones = ['ubuntu-18.04-ga', 'ubuntu-18.04-sru-1',
1802- 'ubuntu-18.04-sru-2', 'ubuntu-18.04-sru-3',
1803- 'ubuntu-18.04-sru-4', 'ubuntu-18.04.1']
1804+Pre18041Milestones = [
1805+ "ubuntu-18.04-ga",
1806+ "ubuntu-18.04-sru-1",
1807+ "ubuntu-18.04-sru-2",
1808+ "ubuntu-18.04-sru-3",
1809+ "ubuntu-18.04-sru-4",
1810+ "ubuntu-18.04.1",
1811+]
1812
1813-if __name__ == '__main__':
1814+if __name__ == "__main__":
1815 parser = argparse.ArgumentParser()
1816 parser.add_argument("-o", "--outfile", required=True)
1817 args = parser.parse_args()
1818
1819- lp = Launchpad.login_with('lpbugs', 'production', version='devel')
1820+ lp = Launchpad.login_with("lpbugs", "production", version="devel")
1821
1822- pearl = lp.projects['pearl2']
1823- series = pearl.getSeries(name='ubuntu-18.04')
1824+ pearl = lp.projects["pearl2"]
1825+ series = pearl.getSeries(name="ubuntu-18.04")
1826
1827- with open(args.outfile, 'w') as csvfile:
1828+ with open(args.outfile, "w") as csvfile:
1829 c = csv.writer(csvfile)
1830 c.writerow(["Title", "Link", "Status", "Expected"])
1831 for task in series.searchTasks(status=[]):
1832@@ -34,8 +39,8 @@ if __name__ == '__main__':
1833 # patches will land in, or it should be tagged as risky.
1834 if task.status in ["Invalid", "Won't Fix"]:
1835 continue
1836- if task.status == 'Incomplete':
1837- if 'needs-sru-justification' in bug.tags:
1838+ if task.status == "Incomplete":
1839+ if "needs-sru-justification" in bug.tags:
1840 expected = "Needs SRU Justification"
1841 else:
1842 expected = "Need input from HiSilicon"
1843diff --git a/lp-scripts/pearl2-tag-ubuntu-18.04.3-risky.py b/lp-scripts/pearl2-tag-ubuntu-18.04.3-risky.py
1844index a29014e..01dc923 100755
1845--- a/lp-scripts/pearl2-tag-ubuntu-18.04.3-risky.py
1846+++ b/lp-scripts/pearl2-tag-ubuntu-18.04.3-risky.py
1847@@ -30,7 +30,7 @@ def get_risk(bug):
1848 for r in RiskyTagMap.keys():
1849 if RiskyTagMap[r] in bug.tags:
1850 # Only one tag should be found
1851- assert(found is None)
1852+ assert found is None
1853 found = r
1854 return found
1855
1856@@ -42,8 +42,7 @@ def set_risk(bug, risk):
1857 continue
1858 rmtag = RiskyTagMap[r]
1859 if rmtag in bug.tags:
1860- sys.stderr.write("Removing %s tag from %s\n" %
1861- (rmtag, bug.web_link))
1862+ sys.stderr.write("Removing %s tag from %s\n" % (rmtag, bug.web_link))
1863 newtags = list(bug.tags)
1864 newtags.remove(rmtag)
1865 bug.tags = newtags
1866@@ -55,10 +54,10 @@ def set_risk(bug, risk):
1867 bug.lp_save()
1868
1869
1870-if __name__ == '__main__':
1871- lp = Launchpad.login_with('lpbugs', 'production', version='devel')
1872+if __name__ == "__main__":
1873+ lp = Launchpad.login_with("lpbugs", "production", version="devel")
1874
1875- pearl2 = lp.projects['pearl2']
1876+ pearl2 = lp.projects["pearl2"]
1877 target_milestone = "ubuntu-18.04.3"
1878 target_date = None
1879 # Find the target date of our milestone. We can compare this with
1880@@ -68,9 +67,9 @@ if __name__ == '__main__':
1881 if m.name in [target_milestone]:
1882 target_date = m.date_targeted
1883 break
1884- assert(target_date is not None)
1885+ assert target_date is not None
1886
1887- series = pearl2.getSeries(name='ubuntu-18.04-hwe')
1888+ series = pearl2.getSeries(name="ubuntu-18.04-hwe")
1889 for task in series.searchTasks():
1890 if task.milestone is not None:
1891 tdelta = task.milestone.date_targeted - target_date
1892@@ -85,8 +84,13 @@ if __name__ == '__main__':
1893 continue
1894 # Now process the ones w/ no milestone set.
1895 # These by definition should all have milestones set.
1896- assert(task.status not in ["Opinion", "Invalid", "Won't Fix",
1897- "Fix Committed", "Fix Released"])
1898+ assert task.status not in [
1899+ "Opinion",
1900+ "Invalid",
1901+ "Won't Fix",
1902+ "Fix Committed",
1903+ "Fix Released",
1904+ ]
1905 if task.status == "Incomplete":
1906 set_risk(task.bug, Risky.HIGH)
1907 continue
1908diff --git a/lp-scripts/project-bug-lint.py b/lp-scripts/project-bug-lint.py
1909index 48f81db..5f62a01 100755
1910--- a/lp-scripts/project-bug-lint.py
1911+++ b/lp-scripts/project-bug-lint.py
1912@@ -8,33 +8,42 @@ import sys
1913 class BugProperty:
1914 def __init__(self, property):
1915 self.index = self.PropertyList.index(property)
1916-
1917+
1918 def __eq__(self, other):
1919- return(self.index == other.index)
1920+ return self.index == other.index
1921
1922 def __ne__(self, other):
1923- return(self.index != other.index)
1924+ return self.index != other.index
1925
1926 def __lt__(self, other):
1927- return(self.index < other.index)
1928+ return self.index < other.index
1929
1930 def __le__(self, other):
1931- return(self.index <= other.index)
1932+ return self.index <= other.index
1933
1934 def __gt__(self, other):
1935- return(self.index > other.index)
1936+ return self.index > other.index
1937
1938 def __ge__(self, other):
1939- return(self.index >= other.index)
1940+ return self.index >= other.index
1941
1942 def __repr__(self):
1943- return(self.PropertyList[self.index])
1944+ return self.PropertyList[self.index]
1945
1946
1947 class BugStatus(BugProperty):
1948- PropertyList = ['New', 'Incomplete', 'Opinion', 'Invalid',
1949- 'Won\'t Fix', 'Confirmed', 'Triaged', 'In Progress',
1950- 'Fix Committed', 'Fix Released']
1951+ PropertyList = [
1952+ "New",
1953+ "Incomplete",
1954+ "Opinion",
1955+ "Invalid",
1956+ "Won't Fix",
1957+ "Confirmed",
1958+ "Triaged",
1959+ "In Progress",
1960+ "Fix Committed",
1961+ "Fix Released",
1962+ ]
1963
1964 # min/max could ideally be in the baseclass, but I don't know
1965 # how to do that and stil refer to the correct PropertyList
1966@@ -45,12 +54,12 @@ class BugStatus(BugProperty):
1967 return BugStatus(BugStatus.PropertyList[-1])
1968
1969 def isTerminalState(self):
1970- terminalStates = ['Fix Released', 'Invalid', 'Won\'t Fix']
1971- return(self.PropertyList[self.index] in terminalStates)
1972+ terminalStates = ["Fix Released", "Invalid", "Won't Fix"]
1973+ return self.PropertyList[self.index] in terminalStates
1974+
1975
1976 class BugImportance(BugProperty):
1977- PropertyList = ['Undecided', 'Wishlist', 'Low',
1978- 'Medium', 'High', 'Critical']
1979+ PropertyList = ["Undecided", "Wishlist", "Low", "Medium", "High", "Critical"]
1980
1981 # min/max could ideally be in the baseclass, but I don't know
1982 # how to do that and stil refer to the correct PropertyList
1983@@ -60,11 +69,13 @@ class BugImportance(BugProperty):
1984 def max():
1985 return BugImportance(BugImportance.PropertyList[-1])
1986
1987+
1988 class BugTask:
1989 def __init__(self, lptask):
1990 self.status = BugStatus(lptask.status)
1991 self.importance = BugImportance(lptask.importance)
1992
1993+
1994 class Bug:
1995 def __init__(self):
1996 self.defaultTask = None
1997@@ -80,24 +91,29 @@ class Bug:
1998 self.targetedTasks[series] = BugTask(task)
1999
2000 def getTargetedTasks(self):
2001- return(self.targetedTasks)
2002+ return self.targetedTasks
2003+
2004
2005 def checkScopeTags(lpbug):
2006- scopeTags = ['scope-arch-all', 'scope-arch-arm64', 'scope-d05-only']
2007+ scopeTags = ["scope-arch-all", "scope-arch-arm64", "scope-d05-only"]
2008 common = set(scopeTags).intersection(lpbug.tags)
2009 if len(common) == 0:
2010 sys.stdout.write("http://launchpad.net/bugs/%d has no scope tag\n" % (bugid))
2011 if len(common) > 1:
2012- sys.stdout.write("http://launchpad.net/bugs/%d has multiple scope tags\n" % (bugid))
2013+ sys.stdout.write(
2014+ "http://launchpad.net/bugs/%d has multiple scope tags\n" % (bugid)
2015+ )
2016+
2017
2018 def taskToBugId(task):
2019- return(int(task.self_link.split('/')[-1]))
2020+ return int(task.self_link.split("/")[-1])
2021+
2022
2023-if __name__ == '__main__':
2024+if __name__ == "__main__":
2025 parser = argparse.ArgumentParser()
2026 parser.add_argument("-p", "--project", required=True)
2027 args = parser.parse_args()
2028- lp = Launchpad.login_with('lpbugs', 'production', version='devel')
2029+ lp = Launchpad.login_with("lpbugs", "production", version="devel")
2030 project = lp.projects[args.project]
2031
2032 bugs = {}
2033@@ -114,7 +130,10 @@ if __name__ == '__main__':
2034 if bugid in bugs.keys():
2035 bugs[bugid].addTargetedTask(series.name, task)
2036 else:
2037- sys.stderr.write("WARNING: http://launchpad.net/bugs/%d does not have a default task\n" % (bugid))
2038+ sys.stderr.write(
2039+ "WARNING: http://launchpad.net/bugs/%d does not have a default task\n"
2040+ % (bugid)
2041+ )
2042
2043 # Now process them.
2044 for bugid in bugs.keys():
2045@@ -123,7 +142,10 @@ if __name__ == '__main__':
2046 if len(targetedTasks) == 0:
2047 defaultStatus = bug.getDefaultTask().status
2048 if not defaultStatus.isTerminalState():
2049- sys.stderr.write("WARNING: http://launchpad.net/bugs/%d only has a default task\n" % (bugid))
2050+ sys.stderr.write(
2051+ "WARNING: http://launchpad.net/bugs/%d only has a default task\n"
2052+ % (bugid)
2053+ )
2054 continue
2055
2056 statusList = []
2057@@ -144,10 +166,16 @@ if __name__ == '__main__':
2058 currentStatus = defaultTask.status
2059 currentImportance = defaultTask.importance
2060 if targetStatus and targetStatus != currentStatus:
2061- sys.stdout.write("http://launchpad.net/bugs/%d status %s -> %s\n" % (bugid, currentStatus, targetStatus))
2062+ sys.stdout.write(
2063+ "http://launchpad.net/bugs/%d status %s -> %s\n"
2064+ % (bugid, currentStatus, targetStatus)
2065+ )
2066 if targetImportance != currentImportance:
2067- sys.stdout.write("http://launchpad.net/bugs/%d importance %s -> %s\n" % (bugid, currentImportance, targetImportance))
2068+ sys.stdout.write(
2069+ "http://launchpad.net/bugs/%d importance %s -> %s\n"
2070+ % (bugid, currentImportance, targetImportance)
2071+ )
2072
2073- if args.project == 'pearl':
2074+ if args.project == "pearl":
2075 if not defaultTask.status.isTerminalState():
2076 checkScopeTags(lp.bugs[bugid])
2077diff --git a/sysadmin-tools/gen_conserver_cf.py b/sysadmin-tools/gen_conserver_cf.py
2078index 065a30b..7153ed7 100755
2079--- a/sysadmin-tools/gen_conserver_cf.py
2080+++ b/sysadmin-tools/gen_conserver_cf.py
2081@@ -47,30 +47,30 @@ console {srv} {{
2082 exec ipmitool -I lanplus -H {addr} -U {user} -P {pwd} sol activate;
2083 }}"""
2084
2085-if __name__ == '__main__':
2086+if __name__ == "__main__":
2087 arg_parser = argparse.ArgumentParser()
2088 arg_parser.add_argument("machines_yaml", help="Lab's machines.yaml file")
2089- arg_parser.add_argument("-o", "--outfile", help="Output filename",
2090- required=True)
2091+ arg_parser.add_argument("-o", "--outfile", help="Output filename", required=True)
2092 args = arg_parser.parse_args()
2093
2094 with open(args.machines_yaml) as f:
2095 machines = yaml.safe_load(f)
2096
2097- with open(args.outfile, 'w') as outfile:
2098+ with open(args.outfile, "w") as outfile:
2099 outfile.write(header.format(progname=arg_parser.prog))
2100 for server in machines:
2101 # bmc is required for conserver to attach
2102- if ("bmc" not in machines[server]):
2103+ if "bmc" not in machines[server]:
2104 continue
2105 bmc_info = machines[server]["bmc"]
2106 # type is required so the conserver knows how to attach
2107- if ("type" not in bmc_info):
2108+ if "type" not in bmc_info:
2109 continue
2110- if (bmc_info["type"] == "ipmi"):
2111- addr = bmc_info["address"].replace('#', '\\#')
2112- user = bmc_info["user"].replace('#', '\\#')
2113- pwd = bmc_info["password"].replace('#', '\\#')
2114- outfile.write(ipmi_sol_entry.format(srv=server, addr=addr,
2115- user=user, pwd=pwd))
2116+ if bmc_info["type"] == "ipmi":
2117+ addr = bmc_info["address"].replace("#", "\\#")
2118+ user = bmc_info["user"].replace("#", "\\#")
2119+ pwd = bmc_info["password"].replace("#", "\\#")
2120+ outfile.write(
2121+ ipmi_sol_entry.format(srv=server, addr=addr, user=user, pwd=pwd)
2122+ )
2123 outfile.write(footer.format())

Subscribers

People subscribed via source and target branches

to all changes: