From e2a9f17f6010ec90e2cbcc4c06c511ffcaeecdbf Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Tue, 2 Mar 2021 01:43:29 -0700 Subject: [PATCH] toolbox/lint-all-readme.pl: new utility to check readme data When run without --dry-run, attempt to update any README.html files that do not match the result of processing README.dat based on the rmtype value. Also report any projects that fail the _lint_readme call entirely. With --dry-run report but do not update. Signed-off-by: Kyle J. McKay --- toolbox/lint-all-readme.pl | 188 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100755 toolbox/lint-all-readme.pl diff --git a/toolbox/lint-all-readme.pl b/toolbox/lint-all-readme.pl new file mode 100755 index 0000000..d22558d --- /dev/null +++ b/toolbox/lint-all-readme.pl @@ -0,0 +1,188 @@ +#!/usr/bin/perl + +# lint-all-readme.pl - lint all projects' explicit README files +# Copyright (C) 2021 Kyle J. McKay. +# All rights reserved. +# License GPLv2+: GNU GPL version 2 or later. +# www.gnu.org/licenses/gpl-2.0.html +# This is free software: you are free to change and redistribute it. +# There is NO WARRANTY, to the extent permitted by law. + +use strict; +use warnings; +use vars qw($VERSION); +BEGIN {*VERSION = \'1.0.0'} +use File::Basename qw(basename); +use lib "__BASEDIR__"; +use Girocco::Config; +use Girocco::Util; +use Girocco::CLIUtil; +use Girocco::Project; +my $bn; BEGIN {$bn = basename(__FILE__)} + +{package Progress; + +use Time::HiRes qw(gettimeofday); + +sub fractime() { return scalar(gettimeofday) } + +sub new { + my $class = shift || __PACKAGE__; + my $max = shift; + defined($max) or $max = 100; + my $title = shift; + defined($title) or $title = "Progress"; + return bless { + title => $title, + max => $max, + cur => 0, + len => 0, + lastupd => fractime + 2 + }, $class; +} + +sub update { + my $self = shift; + !$self->{max} and return; + my $newcur = shift; + defined($newcur) or $newcur = $self->{cur} + 1; + $newcur > $self->{max} and $newcur = $self->{max}; + $newcur >= $self->{cur} or $newcur = $self->{cur}; + my $now = fractime; + if ($self->{lastupd} + 1 <= $now) { + $self->{lastupd} = $now; + if (!$self->{len} || $self->{cur} != $newcur) { + $self->{cur} = $newcur; + $self->show; + } + } +} + +sub show { + my $self = shift; + delete $self->{wasvis}; + !$self->{max} and return; + my $p = int((100 * $self->{cur} / $self->{max}) + 0.5); + $p > 100 and $p = 100; + $p == 100 && $self->{cur} < $self->{max} and $p = 99; + my $status = sprintf("%s: %3d%% (%d/%d)", $self->{title}, + $p, $self->{cur}, $self->{max}); + my $newlen = length($status); + $self->{len} > $newlen and $status .= " " x ($self->{len} - $newlen); + $status .= "\r"; + print STDERR $status; + $self->{len} = $newlen; +} + +sub clear { + my $self = shift; + if ($self->{len}) { + print STDERR " " x $self->{len}, "\r"; + $self->{len} = 0; + $self->{wasvis} = 1; + } +} + +sub restore { + my $self = shift; + $self->{wasvis} and $self->show; +} + +sub DESTROY { + my $self = shift; + $self->clear; +} + +}# END package Progress + +exit(&main(@ARGV)||0); + +our $help; +BEGIN {$help = <<'HELP'} +Usage: %s [--help] [--dry-run] + --help show this help + --dry-run show projects that need updating but don't update them + -P/--progress show progress on STDERR (default if STDERR is a tty) + + Exit status will always be non-zero if any readme files fail to lint. +HELP + +sub lint_project_readmes { + my ($dryrun, $show_progress) = @_; + my %allprojs = map({$_ => 1} Girocco::Project::get_full_list()); + my @allprojs = sort({lc($a) cmp lc($b)} keys(%allprojs)); + my @outdated = (); + my @badlint = (); + my $bd = $Girocco::Config::reporoot . '/'; + my $progress = Progress->new($show_progress ? scalar(@allprojs) : 0, + "Checking project readme files"); + my $cnt = 0; + foreach (@allprojs) { + ++$cnt; + $progress->update($cnt); + $progress->restore; + my $pd = $bd . $_ . '.git'; + -d $pd or next; # just ignore any phantoms + my $proj = undef; + eval { $proj = Girocco::Project->load($_); 1; } && $proj or + next; # just ignore unloadable projects + my $readme = $proj->{README}; + defined($readme) or $readme = ""; + chomp($readme); + my ($cnt, $err) = $proj->_lint_readme(0); + if ($cnt) { + push(@badlint, $_); + $progress->clear; + chomp($err); + print "$_: error: $err\n"; + next; + } + my $newreadme = $proj->{README}; + defined($newreadme) or $newreadme = ""; + chomp($newreadme); + $readme eq $newreadme and next; + $progress->clear; + if ($dryrun) { + push(@outdated, $_); + print "$_: needs update\n"; + } else { + push(@outdated, $_); + $proj->_property_fput("READMEDATA", $proj->{READMEDATA}, 1); + $proj->_property_fput("README", $proj->{README}, -e "$pd/README.html"); + $proj->_property_fput("rmtype", $proj->{rmtype}, 1); + $proj->_set_changed; + print "$_: updated\n"; + } + } + return {count => scalar(@allprojs), outdated => \@outdated, + badlint => \@badlint}; +} + +sub dohelp { + my $fd = shift; + my $ec = shift; + printf $fd "%s version %s\n", $bn, $VERSION; + printf $fd $help, $bn; + exit $ec; +} + +sub main { + local *ARGV = \@_; + my ($dryrun, $help); + my $progress = -t STDERR; + { + shift, $dryrun=1, redo if @ARGV && $ARGV[0] =~ /^(?:-n|--dry-run)$/i; + shift, $help=1, redo if @ARGV && $ARGV[0] =~ /^(?:-h|--help)$/i; + shift, $progress=1, redo if @ARGV && $ARGV[0] =~ /^(?:-P|--progress)$/i; + shift, $progress=0, redo if @ARGV && $ARGV[0] =~ /^(?:--no-progress)$/i; + } + !@ARGV && !$help or dohelp($help ? \*STDOUT : \*STDERR, !$help); + select((select(STDERR),$|=1)[0]); + select((select(STDOUT),$|=1)[0]); + my $results = lint_project_readmes(!!$dryrun, $progress); + printf "Total: %d %s: %d Lintfail: %d\n", + $results->{count}, + $dryrun ? "Outdated" : "Updated", scalar(@{$results->{outdated}}), + scalar(@{$results->{badlint}}); + exit @{$results->{badlint}} ? 1 : 0; +} -- 2.11.4.GIT