Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/cygwin-apps/calm.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'calm/reports.py')
-rw-r--r--calm/reports.py130
1 files changed, 130 insertions, 0 deletions
diff --git a/calm/reports.py b/calm/reports.py
new file mode 100644
index 0000000..2b7020f
--- /dev/null
+++ b/calm/reports.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python3
+#
+# Copyright (c) 2022 Jon Turney
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+import io
+import os
+import textwrap
+import types
+
+from . import maintainers
+from . import package
+from . import pkg2html
+from . import utils
+from .version import SetupVersion
+
+
+def template(title, body, f):
+ os.fchmod(f.fileno(), 0o755)
+
+ print(textwrap.dedent('''\
+ <!DOCTYPE html>
+ <html>
+ <head>
+ <link rel="stylesheet" type="text/css" href="/style.css"/>
+ <title>{0}</title>
+ </head>
+ <body>
+ <div id="main">
+ <h1>{0}</h1>''').format(title), file=f)
+
+ print(body, file=f)
+
+ print(textwrap.dedent('''\
+ </div>
+ </body>
+ </html>'''), file=f)
+
+
+def linkify(pn, po):
+ return '<a href="/packages/summary/{0}.html">{1}</a>'.format(pn, po.orig_name)
+
+
+#
+# produce a report of unmaintained packages
+#
+def unmaintained(args, packages, reportsdir):
+ mlist = maintainers.read(args, None)
+ pkg_maintainers = maintainers.invert(mlist)
+
+ um_list = []
+
+ arch = 'x86_64'
+ # XXX: look into how we can make this 'src', after x86 is dropped
+ for p in packages[arch]:
+ po = packages[arch][p]
+
+ if po.kind != package.Kind.source:
+ continue
+
+ if 'ORPHANED' not in pkg_maintainers[po.orig_name]:
+ continue
+
+ # the highest version we have
+ v = sorted(po.versions(), key=lambda v: SetupVersion(v), reverse=True)[0]
+
+ # determine the number of unique rdepends over all subpackages (and
+ # likewise build_rdepends)
+ #
+ # zero rdepends makes this package a candidate for removal, whereas lots
+ # means it's important to update it.
+ rdepends = set()
+ build_rdepends = set()
+ for subp in po.is_used_by:
+ rdepends.update(packages[arch][subp].rdepends)
+ build_rdepends.update(packages[arch][subp].build_rdepends)
+
+ up = types.SimpleNamespace()
+ up.pn = p
+ up.po = po
+ up.v = v
+ up.ts = po.tar(v).mtime
+ up.rdepends = len(rdepends)
+ up.build_rdepends = len(build_rdepends)
+
+ um_list.append(up)
+
+ body = io.StringIO()
+ print('<p>Packages without a maintainer.</p>', file=body)
+
+ print('<table class="grid">', file=body)
+ print('<tr><th>last updated</th><th>package</th><th>version</th><th>rdepends</th><th>build_rdepends</th></tr>', file=body)
+
+ for up in sorted(um_list, key=lambda i: (i.rdepends + i.build_rdepends, i.ts), reverse=True):
+ print('<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>' %
+ (pkg2html.tsformat(up.ts), linkify(up.pn, up.po), up.v, up.rdepends, up.build_rdepends), file=body)
+
+ print('</table>', file=body)
+
+ unmaintained = os.path.join(reportsdir, 'unmaintained.html')
+ with utils.open_amifc(unmaintained) as f:
+ template('Unmaintained packages', body.getvalue(), f)
+
+
+def do_reports(args, packages):
+ if args.dryrun:
+ return
+
+ reportsdir = os.path.join(args.htdocs, 'reports')
+ pkg2html.ensure_dir_exists(args, reportsdir)
+
+ unmaintained(args, packages, reportsdir)