Merge lp:~rbalint/ubuntu-archive-scripts/bzr-by-team-report into lp:ubuntu-archive-scripts

Proposed by Balint Reczey
Status: Merged
Approved by: Łukasz Zemczak
Approved revision: 236
Merged at revision: 306
Proposed branch: lp:~rbalint/ubuntu-archive-scripts/bzr-by-team-report
Merge into: lp:ubuntu-archive-scripts
Diff against target: 179 lines (+170/-0)
2 files modified
generate-team-bzr (+132/-0)
templates/team-report-bzr.html (+38/-0)
To merge this branch: bzr merge lp:~rbalint/ubuntu-archive-scripts/bzr-by-team-report
Reviewer Review Type Date Requested Status
Łukasz Zemczak Approve
Review via email: mp+359222@code.launchpad.net
To post a comment you must log in.
236. By Balint Reczey

add link to UbuntuDevelopment/MigratingFromBzrToGit

Revision history for this message
Balint Reczey (rbalint) wrote :

I'd also like to add the new report to the reports generated from archive-reports but I'm wondering if there is an easy way of testing that or someone with a setup for testing could add it for me.

Revision history for this message
Dimitri John Ledkov (xnox) wrote :

PING PING PING PING

Revision history for this message
Łukasz Zemczak (sil2100) wrote :

Ok, I guess it should be fine to have such a 'short lived' report for the bazaar migration. Once the bzr migration is complete, it might be good to get rid of this. Code looks okay - at least it follows the same style and design as the generate-team-p-m script. I'll fix some whitespaces and get this merged.

review: Approve
Revision history for this message
Łukasz Zemczak (sil2100) wrote :

Oh, I missed a small typo in the template, but now fixed.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'generate-team-bzr'
2--- generate-team-bzr 1970-01-01 00:00:00 +0000
3+++ generate-team-bzr 2018-11-23 17:03:38 +0000
4@@ -0,0 +1,132 @@
5+#!/usr/bin/env python3
6+# -*- coding: utf-8 -*-
7+
8+# Copyright (C) 2018 Canonical Ltd
9+
10+# This program is free software; you can redistribute it and/or
11+# modify it under the terms of the GNU General Public License
12+# as published by the Free Software Foundation; either version 2
13+# of the License, or (at your option) any later version.
14+#
15+# This program is distributed in the hope that it will be useful,
16+# but WITHOUT ANY WARRANTY; without even the implied warranty of
17+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+# GNU General Public License for more details.
19+#
20+# A copy of the GNU General Public License version 2 is in LICENSE.
21+
22+import apt_pkg
23+import argparse
24+import atexit
25+from collections import defaultdict
26+from datetime import datetime
27+import gzip
28+import json
29+import os
30+import re
31+import shutil
32+import tempfile
33+from textwrap import dedent
34+from urllib.request import urlopen
35+
36+import attr
37+from jinja2 import Environment, FileSystemLoader
38+import yaml
39+
40+env = Environment(
41+ loader=FileSystemLoader(os.path.dirname(os.path.abspath(__file__)) + '/templates'),
42+ autoescape=True,
43+ extensions=['jinja2.ext.i18n'],
44+)
45+env.install_null_translations(True)
46+
47+tempdir = None
48+
49+# copied from component-mismatches
50+def ensure_tempdir():
51+ global tempdir
52+ if not tempdir:
53+ tempdir = tempfile.mkdtemp(prefix='component-mismatches')
54+ atexit.register(shutil.rmtree, tempdir)
55+
56+
57+# copied from component-mismatches
58+def decompress_open(tagfile):
59+ ensure_tempdir()
60+ decompressed = tempfile.mktemp(dir=tempdir)
61+ fin = gzip.GzipFile(filename=tagfile)
62+ with open(decompressed, 'wb') as fout:
63+ fout.write(fin.read())
64+ return open(decompressed, 'r')
65+
66+
67+# copied from generate-team-p-m
68+def get_subscribers_json(packages, subscribers_json):
69+ if subscribers_json is None:
70+ j = urlopen("http://people.canonical.com/~ubuntu-archive/package-team-mapping.json")
71+ else:
72+ j = open(subscribers_json, 'rb')
73+ with j:
74+ team_to_packages = json.loads(j.read().decode('utf-8'))
75+ package_to_teams = {}
76+ for team, team_packages in team_to_packages.items():
77+ for package in team_packages:
78+ if package in packages:
79+ package_to_teams.setdefault(package, []).append(team)
80+ return package_to_teams
81+
82+def packages_with_bzr_repos(options):
83+ pkgs = {}
84+ for component in options.components.split(','):
85+ sources_path = "%s/dists/%s/%s/source/Sources.gz" % (
86+ options.archive_dir, options.suite, component)
87+ for section in apt_pkg.TagFile(decompress_open(sources_path)):
88+ if 'Package' in section and 'Vcs-Bzr' in section:
89+ pkgs[section['Package']] = section['Vcs-Bzr']
90+ return pkgs
91+
92+
93+def repo_url(repo):
94+ return re.sub('^lp:','https://code.launchpad.net/',repo)
95+
96+def main():
97+ parser = argparse.ArgumentParser()
98+ parser.add_argument('--archive-dir', action='store', default=os.path.expanduser("~/mirror/ubuntu"))
99+ parser.add_argument('--components', action='store', default="main,restricted,universe,multiverse")
100+ parser.add_argument('--suite', action='store')
101+ parser.add_argument('--subscribers-json', action='store')
102+ parser.add_argument('output')
103+ args = parser.parse_args()
104+
105+ pkgs = packages_with_bzr_repos(args)
106+
107+ print("getting subscribers")
108+ subscribers = get_subscribers_json(set(pkgs.keys()), args.subscribers_json)
109+ for p in set(pkgs.keys()):
110+ if p not in subscribers:
111+ subscribers[p] = ['unknown']
112+
113+ all_teams = set()
114+ team_to_pkgs = defaultdict(list)
115+ for package, teams in subscribers.items():
116+ all_teams |= set(teams)
117+ for team in teams:
118+ team_to_pkgs[team].append(package)
119+
120+ team_to_attn_count = {}
121+ for team, packages in team_to_pkgs.items():
122+ team_to_attn_count[team] = len(packages)
123+ team_to_pkgs[team] = [(package, repo_url(pkgs[package])) for package in sorted(packages)]
124+
125+ print("rendering")
126+ t = env.get_template('team-report-bzr.html')
127+ now = datetime.utcnow()
128+ with open(args.output, 'w', encoding='utf-8') as fp:
129+ fp.write(t.render(
130+ all_teams=all_teams,
131+ now="%s.%s.%s %d:%s:%s UTC" % (now.year, now.month, now.day, now.hour, now.minute, now.second),
132+ team_to_pkgs=team_to_pkgs,
133+ team_to_attn_count=team_to_attn_count))
134+
135+if __name__ == '__main__':
136+ main()
137
138=== added file 'templates/team-report-bzr.html'
139--- templates/team-report-bzr.html 1970-01-01 00:00:00 +0000
140+++ templates/team-report-bzr.html 2018-11-23 17:03:38 +0000
141@@ -0,0 +1,38 @@
142+<!DOCTYPE HTML>
143+<html>
144+ <head>
145+ <meta charset="utf-8">
146+ <title>Bazaar packaging repositories by team</title>
147+ <style>
148+ body { font-family: ubuntu }
149+ .not-late { color: grey; }
150+ .not-late a { color: #77f; }
151+ </style>
152+ </head>
153+ <body lang="en">
154+ <h1>Bazaar packaging repositories by team</h1>
155+ <p>Git migration tools and schedule: <a href="https://wiki.ubuntu.com/UbuntuDevelopment/MigratingFromBzrToGit">https://wiki.ubuntu.com/UbuntuDevelopment/MigratingFromBzrToGit</a></p
156+ <p>
157+ Generated: {{ now }}
158+ <ul>
159+ {% for team in all_teams|sort %}
160+ <li><a href="#{{ team }}">{{ team }}</a> ({{ ngettext("%(num)d packaging repository", "%(num)d packaging repositories", team_to_attn_count[team]) }})</li>
161+ {% endfor %}
162+ </ul>
163+ {% for team in all_teams|sort %}
164+ <h1 id="{{ team }}">{{ team }}</h1>
165+ <p>
166+ {{ ngettext("%(num)d packaging repositories", "%(num)d packaging repositories", team_to_attn_count[team]) }}
167+ </p>
168+ <ul>
169+ {% for pkg in team_to_pkgs[team] %}
170+ {% set p = pkg[0] %}
171+ {% set url = pkg[1] %}
172+ <li>
173+ <b><a href="https://launchpad.net/ubuntu/+source/{{ p }}/">{{ p }}</a>:</b> <a href="{{ url }}">{{ url }}</a>
174+ </li>
175+ {% endfor %}
176+ </ul>
177+ {% endfor %}
178+ </body>
179+</html>

Subscribers

People subscribed via source and target branches