public inbox for cygwin-apps-cvs@sourceware.org help / color / mirror / Atom feed
From: Jon Turney <jturney@sourceware.org> To: cygwin-apps-cvs@sourceware.org Subject: [calm - Cygwin server-side packaging maintenance script] branch master, updated. 20230209-111-gb586495 Date: Wed, 29 May 2024 15:12:43 +0000 (GMT) [thread overview] Message-ID: <20240529151243.C3AEE3858D20@sourceware.org> (raw) https://sourceware.org/git/gitweb.cgi?p=cygwin-apps/calm.git;h=b5864958558c98ed95f831a9276f3cd33eb8998f commit b5864958558c98ed95f831a9276f3cd33eb8998f Author: Jon Turney <jon.turney@dronecode.org.uk> Date: Mon May 27 15:19:00 2024 +0100 Produce a report to help identify long-inactive maintainers Diff: --- calm/maintainers.py | 9 ++++ calm/pkg2html.py | 5 ++- calm/reports.py | 70 +++++++++++++++++++++++++++++- test/testdata/process_arch/htdocs.expected | 7 ++- 4 files changed, 88 insertions(+), 3 deletions(-) diff --git a/calm/maintainers.py b/calm/maintainers.py index e2c60c7..2a02dc0 100644 --- a/calm/maintainers.py +++ b/calm/maintainers.py @@ -33,6 +33,7 @@ # - an email address (in HOME/!email (or !mail), as we don't want to publish # it, and want to allow the maintainer to change it) # - the timestamp when 'ignoring' warnings were last emitted +# - the timestamp of their last ssh connection # import logging @@ -84,6 +85,7 @@ class Maintainer(object): self.email = email self.pkgs = pkgs self.quiet = False + self.has_homedir = os.path.isdir(self.homedir()) # the mtime of this file records the timestamp reminder_file = os.path.join(self.homedir(), '!reminder-timestamp') @@ -94,6 +96,13 @@ class Maintainer(object): self.reminders_issued = False self.reminders_timestamp_checked = False + # the mtime of this file records the last ssh session + last_seen_file = os.path.join(self.homedir(), '.last-seen') + if os.path.isfile(last_seen_file): + self.last_seen = os.path.getmtime(last_seen_file) + else: + self.last_seen = 0 # meaning 'unknown' + def __repr__(self): return "maintainers.Maintainer('%s', %s, %s)" % (self.name, self.email, self.pkgs) diff --git a/calm/pkg2html.py b/calm/pkg2html.py index 979914b..ab7591a 100755 --- a/calm/pkg2html.py +++ b/calm/pkg2html.py @@ -136,7 +136,10 @@ def ensure_dir_exists(args, path): # format a unix epoch time (UTC) # def tsformat(ts): - return time.strftime('%Y-%m-%d %H:%M', time.gmtime(ts)) + if ts == 0: + return 'Unknown' + else: + return time.strftime('%Y-%m-%d %H:%M', time.gmtime(ts)) # diff --git a/calm/reports.py b/calm/reports.py index 02e9082..240b5d9 100644 --- a/calm/reports.py +++ b/calm/reports.py @@ -69,7 +69,7 @@ def write_report(args, title, body, fn, reportlist, not_empty=True): def linkify(pn, po): - return '<a href="/packages/summary/{0}.html">{1}</a>'.format(pn, po.orig_name) + return '<a href="/packages/summary/{0}.html">{1}</a>'.format(po.name, po.orig_name) # @@ -281,6 +281,72 @@ def unstable(args, packages, reportlist): write_report(args, 'Packages marked as unstable', body, 'unstable.html', reportlist) +# produce a report on maintainer (in)activity +# +def maintainer_activity(args, packages, reportlist): + activity_list = [] + + arch = 'x86_64' + # XXX: look into how we can make this 'src', after x86 is dropped + + ml = maintainers.maintainer_list(args) + for m in ml.values(): + if m.name == 'ORPHANED': + continue + + a = types.SimpleNamespace() + a.name = m.name + a.last_seen = m.last_seen + + count = 0 + mtime = 0 + pkgs = [] + for p in m.pkgs: + if not p.is_orphaned(): + count += 1 + + pn = p.data + '-src' + # do something reasonable for sourceless packages + if pn not in packages[arch]: + pn = p.data + + po = packages[arch].get(pn, None) + if po: + pkgs.append(pn) + + for v in po.versions(): + if po.tar(v).mtime > mtime: + mtime = po.tar(v).mtime + + # ignore if all their packages are orphaned + # (key should be already disabled in this case) + if count == 0: + continue + + a.count = count + a.pkgs = pkgs + a.last_package = mtime + + activity_list.append(a) + + body = io.StringIO() + print('<p>Maintainer activity.</p>', file=body) + + print('<table class="grid sortable">', file=body) + print('<tr><th>Maintainer</th><th># packages</th><th>Last ssh</th><th>Latest package</th></tr>', file=body) + + for a in sorted(activity_list, key=lambda i: (i.last_seen, i.last_package)): + def pkg_details(pkgs): + return '<details><summary>%d</summary>%s</details>' % (len(pkgs), ', '.join(linkify(p, packages[arch][p]) for p in pkgs)) + + print('<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>' % + (a.name, pkg_details(a.pkgs), pkg2html.tsformat(a.last_seen), pkg2html.tsformat(a.last_package)), file=body) + + print('</table>', file=body) + + write_report(args, 'Maintainer activity', body, 'maintainer_activity.html', reportlist, not_empty=False) + + # produce a report of packages which need rebuilding for the latest major # version version provides # @@ -463,6 +529,8 @@ def do_reports(args, packages): provides_rebuild(args, packages, 'ruby_rebuilds.html', 'ruby', reportlist) python_rebuild(args, packages, 'python_rebuilds.html', reportlist) + maintainer_activity(args, packages, reportlist) + fn = os.path.join(args.htdocs, 'reports_list.inc') with utils.open_amifc(fn) as f: print('<ul>', file=f) diff --git a/test/testdata/process_arch/htdocs.expected b/test/testdata/process_arch/htdocs.expected index 80e2fdf..cb93982 100644 --- a/test/testdata/process_arch/htdocs.expected +++ b/test/testdata/process_arch/htdocs.expected @@ -1,5 +1,10 @@ {'.': ['calm.db', 'packages.inc', 'reports_list.inc', 'src_packages.inc'], - 'reports': ['deprecated_so.html', 'perl_rebuilds.html', 'ruby_rebuilds.html', 'unmaintained.html', 'unstable.html'], + 'reports': ['deprecated_so.html', + 'maintainer_activity.html', + 'perl_rebuilds.html', + 'ruby_rebuilds.html', + 'unmaintained.html', + 'unstable.html'], 'summary': ['arc-src.html', 'arc.html', 'base-cygwin.html',
reply other threads:[~2024-05-29 15:12 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20240529151243.C3AEE3858D20@sourceware.org \ --to=jturney@sourceware.org \ --cc=cygwin-apps-cvs@sourceware.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).