Skip to content

Commit 795a40e

Browse files
author
Release Manager
committed
sagemathgh-36977: `sage --package metrics`: New tool to assist discussions of the Sage distribution <!-- ^^^^^ Please provide a concise, informative and self-explanatory title. Don't put issue numbers in there, do this in the PR body below. For example, instead of "Fixes sagemath#1234" use "Introduce new method to calculate 1+1" --> <!-- Describe your changes here in detail --> Discussions of the complexity of the Sage distribution pop up unexpectedly, as seen in sagemath#36982 (comment), sagemath#36982 (comment), sagemath#36982 (comment), sagemath#36982 (comment), sagemath#36982 (comment), sagemath#36982 (comment), sagemath#36982 (comment) sagemath#36726 (comment), sagemath#36726 (comment), sagemath#36726 (comment), sagemath#36726 (comment), sagemath#36726 (comment), sagemath#36726 (comment), sagemath#36726 (comment), sagemath#36726 (comment), sagemath#36726 (comment), sagemath#36726 (comment), sagemath#36726 (comment), sagemath#36726 (comment), sagemath#36726 (comment), sagemath#36726 (comment), sagemath#36726 (comment), sagemath#36726 (comment), sagemath#36726 (comment) sagemath#36777 (comment), sagemath#36777 (comment), sagemath#36777 (comment), sagemath#36777 (comment), sagemath#36777 (comment), sagemath#36777 (comment) To help put such discussions on a solid factual basis, we introduce the command `sage --package metrics`. ``` $ ./sage -package metrics :standard: has_file_distros_arch_txt=131 has_file_distros_conda_txt=216 has_file_distros_debian_txt=125 has_file_distros_fedora_txt=138 has_file_distros_gentoo_txt=181 has_file_distros_homebrew_txt=61 has_file_distros_macports_txt=129 has_file_distros_nix_txt=51 has_file_distros_opensuse_txt=146 has_file_distros_slackware_txt=25 has_file_distros_void_txt=184 has_file_patches=35 has_file_spkg_check=59 has_file_spkg_configure_m4=222 has_file_spkg_install=198 has_tarball_upstream_url=231 line_count_file_patches=22561 line_count_file_spkg_check=402 line_count_file_spkg_configure_m4=2792 line_count_file_spkg_install=2960 packages=272 type_standard=272 ``` Use `PATH=build/bin:$PATH SAGE_ROOT=some-other-worktree build/bin/sage- package metrics :standard:` to obtain the metrics of another version of Sage in some other worktree. We add computation and before/after comparison of the metrics to the CI Linux Incremental workflow. As an illustration, we change one Python package from "normal" to "wheel", removing an `spkg-install.in` file in the process. See https:// github.com/sagemath/sage/actions/runs/7342841283/job/19992606617?pr=3697 7#step:6:12 More metrics can be added after - sagemath#36740 <!-- Why is this change required? What problem does it solve? --> <!-- If this PR resolves an open issue, please link to it here. For example "Fixes sagemath#12345". --> <!-- If your change requires a documentation PR, please link it appropriately. --> ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> <!-- If your change requires a documentation PR, please link it appropriately --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> <!-- Feel free to remove irrelevant items. --> - [x] The title is concise, informative, and self-explanatory. - [x] The description explains in detail what this PR is about. - [ ] I have linked a relevant issue or discussion. - [ ] I have created tests covering the changes. - [ ] I have updated the documentation accordingly. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on - sagemath#12345: short description why this is a dependency - sagemath#34567: ... --> <!-- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> URL: sagemath#36977 Reported by: Matthias Köppe Reviewer(s): Kwankyu Lee, Matthias Köppe
2 parents eee1416 + 6731a1c commit 795a40e

File tree

8 files changed

+342
-114
lines changed

8 files changed

+342
-114
lines changed

.github/workflows/ci-linux-incremental.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,21 @@ jobs:
6363
echo "uninstall_targets=$(echo $(for a in '' ${{ steps.changed-packages.outputs.configures_all_changed_files }}; do echo $a | sed -E 's,build/pkgs/([a-z0-9][_.a-z0-9]*)/spkg-configure[.]m4 *,\1-uninstall,'; done | sort -u))" >> $GITHUB_OUTPUT
6464
echo "build_targets=$(echo $(for a in '' ${{ steps.changed-packages.outputs.pkgs_all_changed_files }}; do SPKG=$(echo $a | sed -E 's,-,_,g;s,(build/)?pkgs/([a-z0-9][-_.a-z0-9]*)/[^ ]* *,\2,;'); if [ -f "build/pkgs/$SPKG/checksums.ini" -o -f "build/pkgs/$SPKG/requirements.txt" -o -f "build/pkgs/$SPKG/spkg-install" ]; then echo "$SPKG-ensure"; fi; done | sort -u))" >> $GITHUB_OUTPUT
6565
cat $GITHUB_OUTPUT
66+
- uses: actions/checkout@v4
67+
with:
68+
ref: ${{ github.base_ref }}
69+
path: worktree-base
70+
if: github.base_ref
71+
- name: Compute metrics
72+
run: |
73+
export PATH=build/bin:$PATH
74+
if [ -d worktree-base ]; then
75+
(echo "# $GITHUB_BASE_REF"; SAGE_ROOT=worktree-base sage-package metrics :all:) > base-metrics.txt
76+
(echo "# $GITHUB_REF"; sage-package metrics :all:) > metrics.txt
77+
diff --color=always --width=100 --side-by-side --left-column base-metrics.txt metrics.txt || true
78+
else
79+
sage-package metrics :all:
80+
fi
6681
6782
test:
6883
needs: [changed_files]

build/pkgs/tzdata/checksums.ini

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
tarball=tzdata-VERSION.tar.gz
2-
sha1=e244bf1bde63515d3f8a452d3bbe9f97738e1e70
3-
md5=2ad4652fecc6ef4f6794726d3f367363
4-
cksum=2894139369
5-
upstream_url=https://pypi.io/packages/source/t/tzdata/tzdata-VERSION.tar.gz
1+
tarball=tzdata-VERSION-py2.py3-none-any.whl
2+
sha1=4686c7c91a01d5af9075903937c343afa05c141b
3+
md5=5e534124c0c916ab617421247649b193
4+
cksum=2929397850
5+
upstream_url=https://pypi.io/packages/py2.py3/t/tzdata/tzdata-VERSION-py2.py3-none-any.whl

build/pkgs/tzdata/package-version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2022.6
1+
2023.3

build/pkgs/tzdata/spkg-install.in

Lines changed: 0 additions & 2 deletions
This file was deleted.

build/sage_bootstrap/app.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import logging
2525
log = logging.getLogger()
2626

27+
from collections import defaultdict
28+
2729
from sage_bootstrap.package import Package
2830
from sage_bootstrap.tarball import Tarball, FileNotMirroredError
2931
from sage_bootstrap.updater import ChecksumUpdater, PackageUpdater
@@ -366,3 +368,63 @@ def clean(self):
366368
os.remove(filepath)
367369
count += 1
368370
print('{} files were removed from the {} directory'.format(count, SAGE_DISTFILES))
371+
372+
def metrics_cls(self, *package_classes):
373+
"""
374+
Show the metrics of given packages
375+
376+
$ sage --package metrics :standard:
377+
has_file_distros_arch_txt=131
378+
has_file_distros_conda_txt=216
379+
has_file_distros_debian_txt=125
380+
has_file_distros_fedora_txt=138
381+
has_file_distros_gentoo_txt=181
382+
has_file_distros_homebrew_txt=61
383+
has_file_distros_macports_txt=129
384+
has_file_distros_nix_txt=51
385+
has_file_distros_opensuse_txt=146
386+
has_file_distros_slackware_txt=25
387+
has_file_distros_void_txt=184
388+
has_file_patches=35
389+
has_file_spkg_check=59
390+
has_file_spkg_configure_m4=222
391+
has_file_spkg_install=198
392+
has_tarball_upstream_url=231
393+
line_count_file_patches=22561
394+
line_count_file_spkg_check=402
395+
line_count_file_spkg_configure_m4=2792
396+
line_count_file_spkg_install=2960
397+
packages=272
398+
type_standard=272
399+
"""
400+
log.debug('Computing metrics')
401+
metrics = defaultdict(int)
402+
pc = PackageClass(*package_classes)
403+
for package_name in pc.names:
404+
package = Package(package_name)
405+
metrics['packages'] += 1
406+
metrics['type_' + package.type] += 1
407+
for filenames in [['spkg-configure.m4'],
408+
['spkg-install', 'spkg-install.in'],
409+
['spkg-check', 'spkg-check.in'],
410+
['distros/arch.txt'],
411+
['distros/conda.txt'],
412+
['distros/debian.txt'],
413+
['distros/fedora.txt'],
414+
['distros/gentoo.txt'],
415+
['distros/homebrew.txt'],
416+
['distros/macports.txt'],
417+
['distros/nix.txt'],
418+
['distros/opensuse.txt'],
419+
['distros/slackware.txt'],
420+
['distros/void.txt'],
421+
['patches']]:
422+
key = filenames[0].replace('.', '_').replace('-', '_').replace('/', '_')
423+
metrics['has_file_' + key] += int(any(package.has_file(filename)
424+
for filename in filenames))
425+
if not key.startswith('distros_'):
426+
metrics['line_count_file_' + key] += sum(package.line_count_file(filename)
427+
for filename in filenames)
428+
metrics['has_tarball_upstream_url'] += int(bool(package.tarball_upstream_url))
429+
for key, value in sorted(metrics.items()):
430+
print('{0}={1}'.format(key, value))

build/sage_bootstrap/cmdline.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,27 @@
189189
42 files were removed from the .../upstream directory
190190
"""
191191

192+
epilog_metrics = \
193+
"""
194+
Print metrics of given package.
195+
196+
EXAMPLE:
197+
198+
$ sage --package metrics :standard:
199+
has_file_distros_arch_txt=131
200+
...
201+
has_file_distros_void_txt=184
202+
has_file_patches=35
203+
has_file_spkg_check=59
204+
has_file_spkg_configure_m4=222
205+
has_file_spkg_install=198
206+
has_tarball_upstream_url=231
207+
line_count_file_patches=22561
208+
...
209+
packages=272
210+
type_standard=272
211+
"""
212+
192213

193214
def make_parser():
194215
"""
@@ -346,6 +367,16 @@ def make_parser():
346367
formatter_class=argparse.RawDescriptionHelpFormatter,
347368
help='Remove outdated source tarballs from the upstream/ directory')
348369

370+
parser_metrics = subparsers.add_parser(
371+
'metrics', epilog=epilog_metrics,
372+
formatter_class=argparse.RawDescriptionHelpFormatter,
373+
help='Print metrics of given packages')
374+
parser_metrics.add_argument(
375+
'package_class', metavar='[package_name|:package_type:]',
376+
type=str, nargs='*', default=[':all:'],
377+
help=('package name or designator for all packages of a given type '
378+
'(one of :all:, :standard:, :optional:, and :experimental:; default: :all:)'))
379+
349380
return parser
350381

351382

@@ -403,6 +434,8 @@ def run():
403434
app.fix_checksum_cls(*args.package_class)
404435
elif args.subcommand == 'clean':
405436
app.clean()
437+
elif args.subcommand == 'metrics':
438+
app.metrics_cls(*args.package_class)
406439
else:
407440
raise RuntimeError('unknown subcommand: {0}'.format(args))
408441

build/sage_bootstrap/package.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,28 @@ def has_file(self, filename):
370370
"""
371371
return os.path.exists(os.path.join(self.path, filename))
372372

373+
def line_count_file(self, filename):
374+
"""
375+
Return the number of lines of the file
376+
377+
Directories are traversed recursively.
378+
379+
OUTPUT:
380+
381+
integer; 0 if the file cannot be read, 1 if it is a symlink
382+
"""
383+
path = os.path.join(self.path, filename)
384+
if os.path.islink(path):
385+
return 1
386+
if os.path.isdir(path):
387+
return sum(self.line_count_file(os.path.join(filename, entry))
388+
for entry in os.listdir(path))
389+
try:
390+
with open(path, "rb") as f:
391+
return len(list(f))
392+
except OSError:
393+
return 0
394+
373395
def _init_checksum(self):
374396
"""
375397
Load the checksums from the appropriate ``checksums.ini`` file

0 commit comments

Comments
 (0)