Merge lp:~racb/ubuntu-archive-tools/handle-packageset-deletions into lp:ubuntu-archive-tools

Proposed by Robie Basak
Status: Needs review
Proposed branch: lp:~racb/ubuntu-archive-tools/handle-packageset-deletions
Merge into: lp:ubuntu-archive-tools
Diff against target: 161 lines (+80/-53)
1 file modified
packageset-report (+80/-53)
To merge this branch: bzr merge lp:~racb/ubuntu-archive-tools/handle-packageset-deletions
Reviewer Review Type Date Requested Status
Ubuntu Package Archive Administrators Pending
Review via email: mp+400678@code.launchpad.net

Description of the change

If a packageset is deleted, the corresponding file doesn't disappear from https://people.canonical.com/~ubuntu-archive/packagesets/. I can think of two approaches to fix this:

1) Adjust packageset-report to delete files not generated by its output. This is what this branch does. However, hypothetical users might find a tool that deletes things surprising, in which case you don't want this branch.

2) Adjust the cron job that calls packageset-report to delete or rename away the output directory first. But I don't have permission to make this adjustment myself, so if you don't like the former option, please could you fix this issue in the cronjob?

To post a comment you must log in.

Unmerged revisions

1458. By Robie Basak

Delete output from packagesets that are deleted

If a packageset is deleted, a subsequent run by this tool will retain
the output prior to that deletion in the target directory. This is
confusing, since the report output then implies that the packageset
still exists, when it doesn't.

Instead, explicitly delete output from inside that is not part of the
current report output.

1457. By Robie Basak

Factor out create_report()

Move this code into its own function to make future manipulation easier.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'packageset-report'
2--- packageset-report 2020-11-02 18:25:35 +0000
3+++ packageset-report 2021-04-07 03:56:33 +0000
4@@ -18,13 +18,74 @@
5
6 import argparse
7 import os
8+import stat
9 import time
10
11 from launchpadlib.launchpad import Launchpad
12 from codecs import open
13
14+
15+def create_report(ubuntu, pkgset, _teams={}):
16+ """Create a report for the given packageset
17+
18+ :param ubuntu: launchpadlib distribution object for Ubuntu
19+ :param pkgset: launchpadlib packageset object
20+ :param dict _teams: team cache (used internally)
21+ :rtype: str
22+ :returns: the packageset report as a string
23+ """
24+ report = ""
25+ report += "Name: %s\n" % pkgset.name
26+ report += "Description: %s\n" % pkgset.description
27+ report += "Owner: %s\n" % pkgset.owner.display_name
28+ report += "Creation date: %s\n" % pkgset.date_created
29+
30+ # List all the source packages
31+ report += "\nPackages:\n"
32+ for pkg in sorted(list(pkgset.getSourcesIncluded())):
33+ report += " - %s\n" % str(pkg)
34+
35+ # List all the sub-package sets
36+ report += "\nSub-package sets:\n"
37+ for child in sorted(list(pkgset.setsIncluded(direct_inclusion=True))):
38+ report += " - %s\n" % child.name
39+
40+ # List all the uploaders, when it's a team, show the members count
41+ report += "\nUploaders:\n"
42+ for archive in ubuntu.archives:
43+ for uploader in sorted(list(archive.getUploadersForPackageset(
44+ packageset=pkgset)),
45+ key=lambda uploader: uploader.person.display_name):
46+
47+ if uploader.person.is_team:
48+ if not uploader.person.name in _teams:
49+ team = uploader.person
50+ _teams[uploader.person.name] = team
51+ else:
52+ team = _teams[uploader.person.name]
53+
54+ report += " - %s (%s) (%s) (%s) (%s members)\n" % \
55+ (team.display_name,
56+ team.name,
57+ uploader.permission,
58+ archive.displayname,
59+ len(team.members))
60+ for member in sorted(list(team.members),
61+ key=lambda person: person.name):
62+ report += " - %s (%s)\n" % (member.display_name,
63+ member.name)
64+ else:
65+ report += " - %s (%s) (%s)\n" % \
66+ (uploader.person.name,
67+ uploader.person.display_name,
68+ uploader.permission)
69+
70+ report += "\nGenerated at: %s\n" % time.asctime()
71+ return report
72+
73+
74 parser = argparse.ArgumentParser(
75- description="Generate list of packages and uploaders for all packagesets.")
76+ description="Update list of packages and uploaders for all packagesets.")
77 parser.add_argument("target", metavar="TARGET",
78 help="Target directory")
79 parser.add_argument("-a", "--all", action="store_true",
80@@ -44,63 +105,29 @@
81 else:
82 ubuntu_series = [series for series in ubuntu.series if series.active]
83
84-# cache
85-teams = {}
86-
87 for series in ubuntu_series:
88 series_name = str(series.name)
89
90 if not os.path.exists(os.path.join(args.target, series_name)):
91 os.makedirs(os.path.join(args.target, series_name))
92
93- for pkgset in lp.packagesets.getBySeries(distroseries=series):
94- report = ""
95- report += "Name: %s\n" % pkgset.name
96- report += "Description: %s\n" % pkgset.description
97- report += "Owner: %s\n" % pkgset.owner.display_name
98- report += "Creation date: %s\n" % pkgset.date_created
99-
100- # List all the source packages
101- report += "\nPackages:\n"
102- for pkg in sorted(list(pkgset.getSourcesIncluded())):
103- report += " - %s\n" % str(pkg)
104-
105- # List all the sub-package sets
106- report += "\nSub-package sets:\n"
107- for child in sorted(list(pkgset.setsIncluded(direct_inclusion=True))):
108- report += " - %s\n" % child.name
109-
110- # List all the uploaders, when it's a team, show the members count
111- report += "\nUploaders:\n"
112- for archive in ubuntu.archives:
113- for uploader in sorted(list(archive.getUploadersForPackageset(
114- packageset=pkgset)),
115- key=lambda uploader: uploader.person.display_name):
116-
117- if uploader.person.is_team:
118- if not uploader.person.name in teams:
119- team = uploader.person
120- teams[uploader.person.name] = team
121- else:
122- team = teams[uploader.person.name]
123-
124- report += " - %s (%s) (%s) (%s) (%s members)\n" % \
125- (team.display_name,
126- team.name,
127- uploader.permission,
128- archive.displayname,
129- len(team.members))
130- for member in sorted(list(team.members),
131- key=lambda person: person.name):
132- report += " - %s (%s)\n" % (member.display_name,
133- member.name)
134- else:
135- report += " - %s (%s) (%s)\n" % \
136- (uploader.person.name,
137- uploader.person.display_name,
138- uploader.permission)
139-
140- report += "\nGenerated at: %s\n" % time.asctime()
141- with open(os.path.join(args.target, series_name, pkgset.name),
142+ reports = {
143+ pkgset.name: create_report(ubuntu, pkgset)
144+ for pkgset in lp.packagesets.getBySeries(distroseries=series)
145+ }
146+
147+ # Delete files in output directory that didn't result in a report
148+ existing_files = set(os.listdir(os.path.join(args.target, series_name)))
149+ extraneous_files = existing_files - set(reports.keys())
150+ for extraneous_file in extraneous_files:
151+ path = os.path.join(args.target, series_name, extraneous_file)
152+ # Sanity check: only remove if it's a regular file
153+ stat_result = os.lstat(path)
154+ if stat.S_ISREG(stat_result.st_mode):
155+ os.unlink(path)
156+
157+ # Write reports to disk
158+ for pkgset_name, report in reports.items():
159+ with open(os.path.join(args.target, series_name, pkgset_name),
160 "w+", encoding="utf-8") as fd:
161 fd.write(report)

Subscribers

People subscribed via source and target branches