From 27354d40a0314b9791d42dd128984ef63a01bfa8 Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Mon, 1 Mar 2021 13:04:42 -0700 Subject: [PATCH] projtool.pl: support new readme formats Make the behind-the-scenes adoption process grok the new readme formats and process the readme if necessary during the adoption process. Add a new optional `--format=` option to the `setreadme` command to select the desired type and make it possible to change the type without changing the readme data itself (reinterprets the old data as the new type). Signed-off-by: Kyle J. McKay --- toolbox/projtool.pl | 134 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 88 insertions(+), 46 deletions(-) diff --git a/toolbox/projtool.pl b/toolbox/projtool.pl index 06c720a..9eba59d 100755 --- a/toolbox/projtool.pl +++ b/toolbox/projtool.pl @@ -145,9 +145,11 @@ Usage: %s [...] set project description to without "set" and only 1 arg, just show current project desc - [set]readme [--force] + [set]readme [--force] [--format=] [] set project readme to + is markdown|plain|html (default is no change) is automatic|suppressed|-|[@]filename + with "set" and/or is required without "set" and only 2 args, just show current readme setting [set]head @@ -775,6 +777,10 @@ sub cmd_adopt { } } my $readme = ""; + my $origreadme = ""; + my $readmedata = ""; + my $origreadmedata = ""; + my $readmetype = Girocco::Project::_normalize_rmtype($config{"girocco.readmetype"},1); if (-e "$projdir/README.html") { open my $fd, '<', "$projdir/README.html" or die "Cannot open \"$projdir/README.html\": $!\n"; { @@ -788,32 +794,48 @@ sub cmd_adopt { $readme =~ s/^\s+//s; $readme =~ s/\s+$//s; $readme eq "" or $readme .= "\n"; - if (length($readme) > 8192) { + $origreadme = $readme; + if (-e "$projdir/README.dat") { + open my $fd2, '<', "$projdir/README.dat" or die "Cannot open \"$projdir/README.dat\": $!\n"; + { + local $/; + $readmedata = <$fd2>; + } + close $fd2; + defined $readmedata or $readmedata = ""; + $readmedata = to_utf8($readmedata, 1); + $readmedata =~ s/\r\n?/\n/gs; + $readmedata =~ s/^\s+//s; + $readmedata =~ s/\s+$//s; + $readmedata eq "" or $readmedata .= "\n"; + $origreadmedata = $readmedata; + } + !$readmetype && length($readme) && !length($readmedata) and do { + # the old HTML format + $readmetype = 'HTML'; + $readmedata = $readme; + }; + if (length($readmedata) > 8192) { die "readme greater than 8192 chars is too long (use --force to override)\n" unless $force; warn "using readme greater than 8192 chars with --force\n" unless $quiet; } - my $rd = get_readme_desc($readme); - if ($rd ne "automatic" && $rd ne "suppressed") { - my $xmllint = qx(sh -c 'command -v xmllint'); chomp $xmllint; - if (-f $xmllint && -x $xmllint) { - my $dummy = {README => $readme}; - my ($cnt, $err) = Girocco::Project::_lint_readme($dummy, 0); - if ($cnt) { - my $msg = "xmllint: $cnt error"; - $msg .= "s" unless $cnt == 1; - print STDERR "$msg\n", "-" x length($msg), "\n", $err - unless $force && $quiet; - exit(255) unless $force; - warn "$projname: using invalid raw HTML with --force\n" unless $quiet; - } + { + my $dummy = {READMEDATA => $readmedata, rmtype => $readmetype, name => $projname}; + my ($cnt, $err) = Girocco::Project::_lint_readme($dummy, 0); + if ($cnt) { + my $msg = "README: $cnt error"; + $msg .= "s" unless $cnt == 1; + print STDERR "$msg\n", "-" x length($msg), "\n", $err + unless $force && $quiet; + exit(255) unless $force && $readmetype eq 'HTML'; + warn "$projname: using invalid raw HTML with --force\n" unless $quiet; } else { - die "xmllint not available, refusing to use raw HTML without --force\n" - unless $force; - warn "xmllint not available using unchecked raw HTML with --force\n" unless $quiet; + $readme = $dummy->{README}; } } } + $readmetype or $readmetype = Girocco::Project::_normalize_rmtype(""); # use default type # Inspect any remotes now # Yes, Virginia, remote urls can be multi-valued my %remotes = (); @@ -982,6 +1004,8 @@ sub cmd_adopt { defined($newproj) or die "Girocco::Project::ghost failed: $@\n"; $newproj->{desc} = $desc; $newproj->{README} = $readme; + $newproj->{READMEDATA} = $readmedata; + $newproj->{rmtype} = $readmetype; $newproj->{url} = $baseurl if $makemirror || exists($config{"gitweb.baseurl"}); $newproj->{email} = $owner if defined($owner); $newproj->{users} = $users; @@ -1017,6 +1041,21 @@ sub cmd_adopt { } } + # Write out any README.dat/README.html changes before the actual Adoption + # Otherwise they will get stepped on. The Girocco::Project::adopt function + # does not know how to validate README.html during adoption like the above code does. + if ($readmedata ne $origreadmedata) { + open my $fd, '>', "$projdir/README.dat" or die "Cannot write \"$projdir/README.dat\": $!\n"; + print $fd $readmedata or die "Error writing \"$projdir/README.dat\": $!\n"; + close $fd or die "Error closing \"$projdir/README.dat\": $!\n"; + } + if ($readme ne $origreadme || ! -e "$projdir/README.html") { + open my $fd, '>', "$projdir/README.html" or die "Cannot write \"$projdir/README.html\": $!\n"; + print $fd $readme or die "Error writing \"$projdir/README.html\": $!\n"; + close $fd or die "Error closing \"$projdir/README.html\": $!\n"; + } + git_config($projdir, "girocco.rmtype", $readmetype); + # Perform the actual adoption $newproj->adopt or die "Girocco::Project::adopt failed\n"; @@ -1419,19 +1458,27 @@ sub cmd_setdesc { } sub cmd_setreadme { - my $force = 0; - shift(@ARGV), $force=1 if @ARGV && $ARGV[0] eq '--force'; - @ARGV == 2 || (@ARGV == 1 && !$force && !$setopt) or die_usage; + my ($force, $readmetype) = (0, undef); + parse_options(force => \$force, ":type" => \$readmetype, ":format" => \$readmetype); + @ARGV == 1 && defined($readmetype) and push(@ARGV, undef); + @ARGV == 2 || (@ARGV == 1 && !$force && !defined($readmetype) && !$setopt) or die_usage; + defined($readmetype) and $readmetype = Girocco::Project::_normalize_rmtype($readmetype,1); + defined($readmetype) && !$readmetype and die_usage; my $project = get_project($ARGV[0]); - my $old = $project->{README}; + my $old = $project->{READMEDATA}; if (@ARGV == 1) { chomp $old if defined($old); print "$old\n" if defined($old) && $old ne ""; return 0; } + $readmetype or $readmetype = $project->{rmtype}; my ($new, $raw, $newname); $newname = ''; - if ($ARGV[1] eq "-") { + if (!defined($ARGV[1])) { + $new = $old; + $newname = "original README data"; + $readmetype ne $project->{rmtype} && $new ne "" and $raw = 1; + } elsif ($ARGV[1] eq "-") { local $/; $new = ; $raw = 1; @@ -1453,39 +1500,34 @@ sub cmd_setreadme { $newname = "contents of \"$fn\""; } defined($new) or $new = ''; - $project->{README} = to_utf8($new, 1); + my $origrmtype = $project->{rmtype}; + $project->{rmtype} = $readmetype; + $project->{READMEDATA} = to_utf8($new, 1); $project->_cleanup_readme; - if (length($project->{README}) > 8192) { + if (length($project->{READMEDATA}) > 8192) { die "readme greater than 8192 chars is too long (use --force to override)\n" unless $force; warn "using readme greater than 8192 chars with --force\n" unless $quiet; } if ($raw) { - my $rd = get_readme_desc($project->{README}); - if ($rd ne "automatic" && $rd ne "suppressed") { - my $xmllint = qx(command -v xmllint); chomp $xmllint; - if (-f $xmllint && -x $xmllint) { - my ($cnt, $err) = $project->_lint_readme(0); - if ($cnt) { - my $msg = "xmllint: $cnt error"; - $msg .= "s" unless $cnt == 1; - print STDERR "$msg\n", "-" x length($msg), "\n", $err - unless $force && $quiet; - exit(255) unless $force; - warn $project->{name} . ": using invalid raw HTML with --force\n" unless $quiet; - } - } else { - die "xmllint not available, refusing to use raw HTML without --force\n" - unless $force; - warn "xmllint not available using unchecked raw HTML with --force\n" unless $quiet; - } + my ($cnt, $err) = $project->_lint_readme(0); + if ($cnt) { + my $msg = "README: $cnt error"; + $msg .= "s" unless $cnt == 1; + print STDERR "$msg\n", "-" x length($msg), "\n", $err + unless $force && $quiet; + exit(255) unless $force && $project->{rmtype} eq 'HTML'; + warn $project->{name} . ": using invalid raw HTML with --force\n" unless $quiet; + $project->{README} = $project->{READMEDATA}; } } - if (defined($old) && $old eq $project->{README}) { + if (defined($old) && $old eq $project->{READMEDATA} && $readmetype eq $origrmtype && !$force) { warn $project->{name}, ": skipping update of README to same value\n" unless $quiet; } else { # Avoid touching anything other than README.html file + $project->_property_fput("READMEDATA", $project->{READMEDATA}, 1); $project->_property_fput("README", $project->{README}); + $project->_property_fput("rmtype", $readmetype) if $readmetype ne $origrmtype; $project->_set_changed; my $desc = get_readme_desc($project->{README}); if ($newname) { @@ -1493,7 +1535,7 @@ sub cmd_setreadme { } else { $newname = $desc; } - warn $project->{name}, ": README updated to $newname\n" unless $quiet; + warn $project->{name}, ": README $readmetype format updated to $newname\n" unless $quiet; } return 0; } -- 2.11.4.GIT