Merge branch 'ps/fewer-perl'

Reduce requirement for Perl in our documentation build and a few
scripts.

* ps/fewer-perl:
  Documentation: stop depending on Perl to generate command list
  Documentation: stop depending on Perl to massage user manual
  request-pull: stop depending on Perl
  filter-branch: stop depending on Perl
This commit is contained in:
Junio C Hamano
2025-04-29 14:21:30 -07:00
10 changed files with 191 additions and 160 deletions

View File

@@ -317,8 +317,8 @@ cmds_txt = cmds-ancillaryinterrogators.adoc \
$(cmds_txt): cmd-list.made
cmd-list.made: cmd-list.perl ../command-list.txt $(MAN1_TXT)
$(QUIET_GEN)$(PERL_PATH) ./cmd-list.perl .. . $(cmds_txt) && \
cmd-list.made: cmd-list.sh ../command-list.txt $(MAN1_TXT)
$(QUIET_GEN)$(SHELL_PATH) ./cmd-list.sh .. . $(cmds_txt) && \
date >$@
mergetools-%.adoc: generate-mergetool-list.sh ../git-mergetool--lib.sh $(wildcard ../mergetools/*)
@@ -398,9 +398,9 @@ user-manual.html: user-manual.xml $(XSLT)
git.info: user-manual.texi
$(QUIET_MAKEINFO)$(MAKEINFO) --no-split -o $@ user-manual.texi
user-manual.texi: user-manual.xml
user-manual.texi: user-manual.xml fix-texi.sh
$(QUIET_DB2TEXI)$(DOCBOOK2X_TEXI) user-manual.xml --encoding=UTF-8 --to-stdout >$@+ && \
$(PERL_PATH) fix-texi.perl <$@+ >$@ && \
$(SHELL_PATH) fix-texi.sh <$@+ >$@ && \
$(RM) $@+
user-manual.pdf: user-manual.xml

View File

@@ -1,80 +0,0 @@
#!/usr/bin/perl -w
use File::Compare qw(compare);
sub format_one {
my ($source_dir, $out, $nameattr) = @_;
my ($name, $attr) = @$nameattr;
my ($path) = "$source_dir/Documentation/$name.adoc";
my ($state, $description);
my $mansection;
$state = 0;
open I, '<', "$path" or die "No such file $path.adoc";
while (<I>) {
if (/^(?:git|scalar)[a-z0-9-]*\(([0-9])\)$/) {
$mansection = $1;
next;
}
if (/^NAME$/) {
$state = 1;
next;
}
if ($state == 1 && /^----$/) {
$state = 2;
next;
}
next if ($state != 2);
chomp;
$description = $_;
last;
}
close I;
if (!defined $description) {
die "No description found in $path.adoc";
}
if (my ($verify_name, $text) = ($description =~ /^($name) - (.*)/)) {
print $out "linkgit:$name\[$mansection\]::\n\t";
if ($attr =~ / deprecated /) {
print $out "(deprecated) ";
}
print $out "$text.\n\n";
}
else {
die "Description does not match $name: $description";
}
}
my ($source_dir, $build_dir, @categories) = @ARGV;
open IN, "<$source_dir/command-list.txt";
while (<IN>) {
last if /^### command list/;
}
my %cmds = ();
for (sort <IN>) {
next if /^#/;
chomp;
my ($name, $cat, $attr) = /^(\S+)\s+(.*?)(?:\s+(.*))?$/;
$attr = '' unless defined $attr;
push @{$cmds{$cat}}, [$name, " $attr "];
}
close IN;
for my $out (@categories) {
my ($cat) = $out =~ /^cmds-(.*)\.adoc$/;
my ($path) = "$build_dir/$out";
open O, '>', "$path+" or die "Cannot open output file $out+";
for (@{$cmds{$cat}}) {
format_one($source_dir, \*O, $_);
}
close O;
if (-f "$path" && compare("$path", "$path+") == 0) {
unlink "$path+";
}
else {
rename "$path+", "$path";
}
}

104
Documentation/cmd-list.sh Executable file
View File

@@ -0,0 +1,104 @@
#!/bin/sh
set -e
format_one () {
source_dir="$1"
command="$2"
attributes="$3"
path="$source_dir/Documentation/$command.adoc"
if ! test -f "$path"
then
echo >&2 "No such file $path"
exit 1
fi
state=0
while read line
do
case "$state" in
0)
case "$line" in
git*\(*\)|scalar*\(*\))
mansection="${line##*\(}"
mansection="${mansection%\)}"
;;
NAME)
state=1;;
esac
;;
1)
if test "$line" = "----"
then
state=2
fi
;;
2)
description="$line"
break
;;
esac
done <"$path"
if test -z "$mansection"
then
echo "No man section found in $path" >&2
exit 1
fi
if test -z "$description"
then
echo >&2 "No description found in $path"
exit 1
fi
case "$description" in
"$command - "*)
text="${description#$command - }"
printf "linkgit:%s[%s]::\n\t" "$command" "$mansection"
case "$attributes" in
*" deprecated "*)
printf "(deprecated) "
;;
esac
printf "$text.\n\n"
;;
*)
echo >&2 "Description does not match $command: $description"
exit 1
;;
esac
}
source_dir="$1"
build_dir="$2"
shift 2
for out
do
category="${out#cmds-}"
category="${category%.adoc}"
path="$build_dir/$out"
while read command command_category attributes
do
case "$command" in
"#"*)
continue;;
esac
case "$command_category" in
"$category")
format_one "$source_dir" "$command" " $attributes ";;
esac
done <"$source_dir/command-list.txt" >"$build_dir/$out+"
if cmp "$build_dir/$out+" "$build_dir/$out" >/dev/null 2>&1
then
rm "$build_dir/$out+"
else
mv "$build_dir/$out+" "$build_dir/$out"
fi
done

View File

@@ -1,15 +0,0 @@
#!/usr/bin/perl -w
while (<>) {
if (/^\@setfilename/) {
$_ = "\@setfilename git.info\n";
} elsif (/^\@direntry/) {
print '@dircategory Development
@direntry
* Git: (git). A fast distributed revision control system
@end direntry
'; }
unless (/^\@direntry/../^\@end direntry/) {
print;
}
}

21
Documentation/fix-texi.sh Executable file
View File

@@ -0,0 +1,21 @@
#!/bin/sh
awk '
/^@setfilename/{
print "@setfilename git.info"
next
}
/^@direntry/{
direntry=1
print "@dircategory Development"
print "@direntry"
print "* Git: (git). A fast distributed revision control system"
print "@end direntry"
next
}
/^@end direntry/{
direntry=0
next
}
!direntry
'

View File

@@ -335,12 +335,12 @@ cmd_lists = [
documentation_deps += custom_target(
command: [
perl,
shell,
'@INPUT@',
meson.project_source_root(),
meson.current_build_dir(),
] + cmd_lists,
input: 'cmd-list.perl',
input: 'cmd-list.sh',
output: cmd_lists
)

View File

@@ -295,15 +295,18 @@ then
if test -n "$state_commit"
then
echo "Populating map from $state_branch ($state_commit)" 1>&2
perl -e'open(MAP, "-|", "git show $ARGV[0]:filter.map") or die;
while (<MAP>) {
m/(.*):(.*)/ or die;
open F, ">../map/$1" or die;
print F "$2" or die;
close(F) or die;
}
close(MAP) or die;' "$state_commit" \
|| die "Unable to load state from $state_branch:filter.map"
git show "$state_commit:filter.map" >"$tempdir"/filter-map ||
die "Unable to load state from $state_branch:filter.map"
while read line
do
case "$line" in
*:*)
echo "${line%:*}" >../map/"${line#*:}";;
*)
die "Unable to load state from $state_branch:filter.map";;
esac
done <"$tempdir"/filter-map
else
echo "Branch $state_branch does not exist. Will create" 1>&2
fi
@@ -633,15 +636,13 @@ if test -n "$state_branch"
then
echo "Saving rewrite state to $state_branch" 1>&2
state_blob=$(
perl -e'opendir D, "../map" or die;
open H, "|-", "git hash-object -w --stdin" or die;
foreach (sort readdir(D)) {
next if m/^\.\.?$/;
open F, "<../map/$_" or die;
chomp($f = <F>);
print H "$_:$f\n" or die;
}
close(H) or die;' || die "Unable to save state")
for file in ../map/*
do
from_commit=$(basename "$file")
to_commit=$(cat "$file")
echo "$from_commit:$to_commit"
done | git hash-object -w --stdin || die "Unable to save state"
)
state_tree=$(printf '100644 blob %s\tfilter.map\n' "$state_blob" | git mktree)
if test -n "$state_commit"
then

View File

@@ -78,41 +78,47 @@ fi
merge_base=$(git merge-base $baserev $headrev) ||
die "fatal: No commits in common between $base and $head"
# $head is the refname from the command line.
# Find a ref with the same name as $head that exists at the remote
find_matching_ref () {
while read sha1 ref
do
case "$ref" in
*"^"?*)
ref="${ref%"^"*}"
deref=true
;;
*)
deref=
;;
esac
if test "$sha1" = "${remote:-HEAD}"
then
echo "$sha1 $sha1"
break
fi
case "$ref" in
"${remote:-HEAD}"|*"/${remote:-HEAD}")
if test -z "$deref"
then
# Remember the matching unpeeled object on the
# remote side.
remote_sha1="$sha1"
fi
if test "$sha1" = "$headrev"
then
echo "${remote_sha1:-$headrev} $ref"
break
fi
;;
esac
done
}
# Find a ref with the same name as $remote that exists at the remote
# and points to the same commit as the local object.
find_matching_ref='
my ($head,$headrev) = (@ARGV);
my $pattern = qr{/\Q$head\E$};
my ($remote_sha1, $found);
while (<STDIN>) {
chomp;
my ($sha1, $ref, $deref) = /^(\S+)\s+([^^]+)(\S*)$/;
if ($sha1 eq $head) {
$found = $remote_sha1 = $sha1;
break;
}
if ($ref eq $head || $ref =~ $pattern) {
if ($deref eq "") {
# Remember the matching object on the remote side
$remote_sha1 = $sha1;
}
if ($sha1 eq $headrev) {
$found = $ref;
break;
}
}
}
if ($found) {
$remote_sha1 = $headrev if ! defined $remote_sha1;
print "$remote_sha1 $found\n";
}
'
set fnord $(git ls-remote "$url" | @PERL_PATH@ -e "$find_matching_ref" "${remote:-HEAD}" "$headrev")
set fnord $(git ls-remote "$url" | find_matching_ref)
remote_sha1=$2
ref=$3

View File

@@ -836,7 +836,7 @@ endif
# features. It is optional if you want to neither execute tests nor use any of
# these optional features.
perl_required = get_option('perl')
if get_option('gitweb').enabled() or 'netrc' in get_option('credential_helpers') or get_option('docs') != []
if get_option('gitweb').enabled() or 'netrc' in get_option('credential_helpers')
perl_required = true
endif

View File

@@ -7,12 +7,6 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. ./test-lib.sh
if ! test_have_prereq PERL
then
skip_all='skipping request-pull tests, perl not available'
test_done
fi
test_expect_success 'setup' '
git init --bare upstream.git &&