Merge branch 'ab/doc-lint'

Dev support.

* ab/doc-lint:
  docs: fix linting issues due to incorrect relative section order
  doc lint: lint relative section order
  doc lint: lint and fix missing "GIT" end sections
  doc lint: fix bugs in, simplify and improve lint script
  doc lint: Perl "strict" and "warnings" in lint-gitlink.perl
  Documentation/Makefile: make doc.dep dependencies a variable again
  Documentation/Makefile: make $(wildcard howto/*.txt) a var
This commit is contained in:
Junio C Hamano 2021-05-07 12:47:40 +09:00
commit 5a357fa477
12 changed files with 289 additions and 139 deletions

View file

@ -2,6 +2,8 @@
MAN1_TXT =
MAN5_TXT =
MAN7_TXT =
HOWTO_TXT =
DOC_DEP_TXT =
TECH_DOCS =
ARTICLES =
SP_ARTICLES =
@ -42,6 +44,11 @@ MAN7_TXT += gittutorial-2.txt
MAN7_TXT += gittutorial.txt
MAN7_TXT += gitworkflows.txt
HOWTO_TXT += $(wildcard howto/*.txt)
DOC_DEP_TXT += $(wildcard *.txt)
DOC_DEP_TXT += $(wildcard config/*.txt)
ifdef MAN_FILTER
MAN_TXT = $(filter $(MAN_FILTER),$(MAN1_TXT) $(MAN5_TXT) $(MAN7_TXT))
else
@ -286,7 +293,7 @@ docdep_prereqs = \
mergetools-list.made $(mergetools_txt) \
cmd-list.made $(cmds_txt)
doc.dep : $(docdep_prereqs) $(wildcard *.txt) $(wildcard config/*.txt) build-docdep.perl
doc.dep : $(docdep_prereqs) $(DOC_DEP_TXT) build-docdep.perl
$(QUIET_GEN)$(RM) $@+ $@ && \
$(PERL_PATH) ./build-docdep.perl >$@+ $(QUIET_STDERR) && \
mv $@+ $@
@ -429,9 +436,9 @@ $(patsubst %.txt,%.texi,$(MAN_TXT)): %.texi : %.xml
$(DOCBOOK2X_TEXI) --to-stdout $*.xml >$@+ && \
mv $@+ $@
howto-index.txt: howto-index.sh $(wildcard howto/*.txt)
howto-index.txt: howto-index.sh $(HOWTO_TXT)
$(QUIET_GEN)$(RM) $@+ $@ && \
'$(SHELL_PATH_SQ)' ./howto-index.sh $(sort $(wildcard howto/*.txt)) >$@+ && \
'$(SHELL_PATH_SQ)' ./howto-index.sh $(sort $(HOWTO_TXT)) >$@+ && \
mv $@+ $@
$(patsubst %,%.html,$(ARTICLES)) : %.html : %.txt
@ -440,7 +447,7 @@ $(patsubst %,%.html,$(ARTICLES)) : %.html : %.txt
WEBDOC_DEST = /pub/software/scm/git/docs
howto/%.html: ASCIIDOC_EXTRA += -a git-relative-html-prefix=../
$(patsubst %.txt,%.html,$(wildcard howto/*.txt)): %.html : %.txt GIT-ASCIIDOCFLAGS
$(patsubst %.txt,%.html,$(HOWTO_TXT)): %.html : %.txt GIT-ASCIIDOCFLAGS
$(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
sed -e '1,/^$$/d' $< | \
$(TXT_TO_HTML) - >$@+ && \
@ -472,7 +479,13 @@ print-man1:
@for i in $(MAN1_TXT); do echo $$i; done
lint-docs::
$(QUIET_LINT)$(PERL_PATH) lint-gitlink.perl
$(QUIET_LINT)$(PERL_PATH) lint-gitlink.perl \
$(HOWTO_TXT) $(DOC_DEP_TXT) \
--section=1 $(MAN1_TXT) \
--section=5 $(MAN5_TXT) \
--section=7 $(MAN7_TXT); \
$(PERL_PATH) lint-man-end-blurb.perl $(MAN_TXT); \
$(PERL_PATH) lint-man-section-order.perl $(MAN_TXT);
ifeq ($(wildcard po/Makefile),po/Makefile)
doc-l10n install-l10n::

View file

@ -159,3 +159,7 @@ empty string.
+
Components which are missing from the URL (e.g., there is no
username in the example above) will be left unset.
GIT
---
Part of the linkgit:git[1] suite

View file

@ -24,6 +24,18 @@ Usage:
[verse]
'git-cvsserver' [<options>] [pserver|server] [<directory> ...]
DESCRIPTION
-----------
This application is a CVS emulation layer for Git.
It is highly functional. However, not all methods are implemented,
and for those methods that are implemented,
not all switches are implemented.
Testing has been done using both the CLI CVS client, and the Eclipse CVS
plugin. Most functionality works fine with both of these clients.
OPTIONS
-------
@ -57,18 +69,6 @@ access still needs to be enabled by the `gitcvs.enabled` config option
unless `--export-all` was given, too.
DESCRIPTION
-----------
This application is a CVS emulation layer for Git.
It is highly functional. However, not all methods are implemented,
and for those methods that are implemented,
not all switches are implemented.
Testing has been done using both the CLI CVS client, and the Eclipse CVS
plugin. Most functionality works fine with both of these clients.
LIMITATIONS
-----------

View file

@ -38,38 +38,6 @@ are lists of one or more search expressions separated by newline
characters. An empty string as search expression matches all lines.
CONFIGURATION
-------------
grep.lineNumber::
If set to true, enable `-n` option by default.
grep.column::
If set to true, enable the `--column` option by default.
grep.patternType::
Set the default matching behavior. Using a value of 'basic', 'extended',
'fixed', or 'perl' will enable the `--basic-regexp`, `--extended-regexp`,
`--fixed-strings`, or `--perl-regexp` option accordingly, while the
value 'default' will return to the default matching behavior.
grep.extendedRegexp::
If set to true, enable `--extended-regexp` option by default. This
option is ignored when the `grep.patternType` option is set to a value
other than 'default'.
grep.threads::
Number of grep worker threads to use. If unset (or set to 0), Git will
use as many threads as the number of logical cores available.
grep.fullName::
If set to true, enable `--full-name` option by default.
grep.fallbackToNoIndex::
If set to true, fall back to git grep --no-index if git grep
is executed outside of a git repository. Defaults to false.
OPTIONS
-------
--cached::
@ -363,6 +331,38 @@ with multiple threads might perform slower than single threaded if `--textconv`
is given and there're too many text conversions. So if you experience low
performance in this case, it might be desirable to use `--threads=1`.
CONFIGURATION
-------------
grep.lineNumber::
If set to true, enable `-n` option by default.
grep.column::
If set to true, enable the `--column` option by default.
grep.patternType::
Set the default matching behavior. Using a value of 'basic', 'extended',
'fixed', or 'perl' will enable the `--basic-regexp`, `--extended-regexp`,
`--fixed-strings`, or `--perl-regexp` option accordingly, while the
value 'default' will return to the default matching behavior.
grep.extendedRegexp::
If set to true, enable `--extended-regexp` option by default. This
option is ignored when the `grep.patternType` option is set to a value
other than 'default'.
grep.threads::
Number of grep worker threads to use. If unset (or set to 0), Git will
use as many threads as the number of logical cores available.
grep.fullName::
If set to true, enable `--full-name` option by default.
grep.fallbackToNoIndex::
If set to true, fall back to git grep --no-index if git grep
is executed outside of a git repository. Defaults to false.
GIT
---
Part of the linkgit:git[1] suite

View file

@ -11,14 +11,6 @@ SYNOPSIS
[verse]
'git mktag'
OPTIONS
-------
--strict::
By default mktag turns on the equivalent of
linkgit:git-fsck[1] `--strict` mode. Use `--no-strict` to
disable it.
DESCRIPTION
-----------
@ -45,6 +37,14 @@ the appropriate `fsck.<msg-id>` varible:
git -c fsck.extraHeaderEntry=ignore mktag <my-tag-with-headers
OPTIONS
-------
--strict::
By default mktag turns on the equivalent of
linkgit:git-fsck[1] `--strict` mode. Use `--no-strict` to
disable it.
Tag Format
----------
A tag signature file, to be fed to this command's standard input,

View file

@ -762,3 +762,7 @@ IMPLEMENTATION DETAILS
message indicating the p4 depot location and change number. This
line is used by later 'git p4 sync' operations to know which p4
changes are new.
GIT
---
Part of the linkgit:git[1] suite

View file

@ -200,12 +200,6 @@ Alternatively, you can undo the 'git rebase' with
git rebase --abort
CONFIGURATION
-------------
include::config/rebase.txt[]
include::config/sequencer.txt[]
OPTIONS
-------
--onto <newbase>::
@ -1266,6 +1260,12 @@ merge tlsv1.3
merge cmake
------------
CONFIGURATION
-------------
include::config/rebase.txt[]
include::config/sequencer.txt[]
BUGS
----
The todo list presented by the deprecated `--preserve-merges --interactive`

View file

@ -1061,25 +1061,6 @@ with different name spaces. For example:
branches = stable/*:refs/remotes/svn/stable/*
branches = debug/*:refs/remotes/svn/debug/*
BUGS
----
We ignore all SVN properties except svn:executable. Any unhandled
properties are logged to $GIT_DIR/svn/<refname>/unhandled.log
Renamed and copied directories are not detected by Git and hence not
tracked when committing to SVN. I do not plan on adding support for
this as it's quite difficult and time-consuming to get working for all
the possible corner cases (Git doesn't do it, either). Committing
renamed and copied files is fully supported if they're similar enough
for Git to detect them.
In SVN, it is possible (though discouraged) to commit changes to a tag
(because a tag is just a directory copy, thus technically the same as a
branch). When cloning an SVN repository, 'git svn' cannot know if such a
commit to a tag will happen in the future. Thus it acts conservatively
and imports all SVN tags as branches, prefixing the tag name with 'tags/'.
CONFIGURATION
-------------
@ -1166,6 +1147,25 @@ $GIT_DIR/svn/\**/.rev_map.*::
if it is missing or not up to date. 'git svn reset' automatically
rewinds it.
BUGS
----
We ignore all SVN properties except svn:executable. Any unhandled
properties are logged to $GIT_DIR/svn/<refname>/unhandled.log
Renamed and copied directories are not detected by Git and hence not
tracked when committing to SVN. I do not plan on adding support for
this as it's quite difficult and time-consuming to get working for all
the possible corner cases (Git doesn't do it, either). Committing
renamed and copied files is fully supported if they're similar enough
for Git to detect them.
In SVN, it is possible (though discouraged) to commit changes to a tag
(because a tag is just a directory copy, thus technically the same as a
branch). When cloning an SVN repository, 'git svn' cannot know if such a
commit to a tag will happen in the future. Thus it acts conservatively
and imports all SVN tags as branches, prefixing the tag name with 'tags/'.
SEE ALSO
--------
linkgit:git-rebase[1]

View file

@ -62,3 +62,7 @@ git clone ext::'git --namespace=foo %s /tmp/prefixed.git'
----------
include::transfer-data-leaks.txt[]
GIT
---
Part of the linkgit:git[1] suite

View file

@ -1,71 +1,67 @@
#!/usr/bin/perl
use File::Find;
use Getopt::Long;
use strict;
use warnings;
my $basedir = ".";
GetOptions("basedir=s" => \$basedir)
or die("Cannot parse command line arguments\n");
# Parse arguments, a simple state machine for input like:
#
# howto/*.txt config/*.txt --section=1 git.txt git-add.txt [...] --to-lint git-add.txt a-file.txt [...]
my %TXT;
my %SECTION;
my $section;
my $lint_these = 0;
for my $arg (@ARGV) {
if (my ($sec) = $arg =~ /^--section=(\d+)$/s) {
$section = $sec;
next;
}
my $found_errors = 0;
my ($name) = $arg =~ /^(.*?)\.txt$/s;
unless (defined $section) {
$TXT{$name} = $arg;
next;
}
$SECTION{$name} = $section;
}
my $exit_code = 0;
sub report {
my ($where, $what, $error) = @_;
print "$where: $error: $what\n";
$found_errors = 1;
my ($pos, $line, $target, $msg) = @_;
substr($line, $pos) = "' <-- HERE";
$line =~ s/^\s+//;
print "$ARGV:$.: error: $target: $msg, shown with 'HERE' below:\n";
print "$ARGV:$.:\t'$line\n";
$exit_code = 1;
}
sub grab_section {
my ($page) = @_;
open my $fh, "<", "$basedir/$page.txt";
my $firstline = <$fh>;
chomp $firstline;
close $fh;
my ($section) = ($firstline =~ /.*\((\d)\)$/);
return $section;
}
@ARGV = sort values %TXT;
die "BUG: Nothing to process!" unless @ARGV;
while (<>) {
my $line = $_;
while ($line =~ m/linkgit:((.*?)\[(\d)\])/g) {
my $pos = pos $line;
my ($target, $page, $section) = ($1, $2, $3);
sub lint {
my ($file) = @_;
open my $fh, "<", $file
or return;
while (<$fh>) {
my $where = "$file:$.";
while (s/linkgit:((.*?)\[(\d)\])//) {
my ($target, $page, $section) = ($1, $2, $3);
# De-AsciiDoc
$page =~ s/{litdd}/--/g;
# De-AsciiDoc
$page =~ s/{litdd}/--/g;
if ($page !~ /^git/) {
report($where, $target, "nongit link");
next;
}
if (! -f "$basedir/$page.txt") {
report($where, $target, "no such source");
next;
}
$real_section = grab_section($page);
if ($real_section != $section) {
report($where, $target,
"wrong section (should be $real_section)");
next;
}
if (!exists $TXT{$page}) {
report($pos, $line, $target, "link outside of our own docs");
next;
}
if (!exists $SECTION{$page}) {
report($pos, $line, $target, "link outside of our sectioned docs");
next;
}
my $real_section = $SECTION{$page};
if ($section != $SECTION{$page}) {
report($pos, $line, $target, "wrong section (should be $real_section)");
next;
}
}
close $fh;
# this resets our $. for each file
close ARGV if eof;
}
sub lint_it {
lint($File::Find::name) if -f && /\.txt$/;
}
if (!@ARGV) {
find({ wanted => \&lint_it, no_chdir => 1 }, $basedir);
} else {
for (@ARGV) {
lint($_);
}
}
exit $found_errors;
exit $exit_code;

View file

@ -0,0 +1,24 @@
#!/usr/bin/perl
use strict;
use warnings;
my $exit_code = 0;
sub report {
my ($target, $msg) = @_;
print "error: $target: $msg\n";
$exit_code = 1;
}
local $/;
while (my $slurp = <>) {
report($ARGV, "has no 'Part of the linkgit:git[1] suite' end blurb")
unless $slurp =~ m[
^GIT\n
---\n
\QPart of the linkgit:git[1] suite\E \n
\z
]mx;
}
exit $exit_code;

View file

@ -0,0 +1,105 @@
#!/usr/bin/perl
use strict;
use warnings;
my %SECTIONS;
{
my $order = 0;
%SECTIONS = (
'NAME' => {
required => 1,
order => $order++,
},
'SYNOPSIS' => {
required => 1,
order => $order++,
},
'DESCRIPTION' => {
required => 1,
order => $order++,
},
'OPTIONS' => {
order => $order++,
required => 0,
},
'CONFIGURATION' => {
order => $order++,
},
'BUGS' => {
order => $order++,
},
'SEE ALSO' => {
order => $order++,
},
'GIT' => {
required => 1,
order => $order++,
},
);
}
my $SECTION_RX = do {
my ($names) = join "|", keys %SECTIONS;
qr/^($names)$/s;
};
my $exit_code = 0;
sub report {
my ($msg) = @_;
print "$ARGV:$.: $msg\n";
$exit_code = 1;
}
my $last_was_section;
my @actual_order;
while (my $line = <>) {
chomp $line;
if ($line =~ $SECTION_RX) {
push @actual_order => $line;
$last_was_section = 1;
# Have no "last" section yet, processing NAME
next if @actual_order == 1;
my @expected_order = sort {
$SECTIONS{$a}->{order} <=> $SECTIONS{$b}->{order}
} @actual_order;
my $expected_last = $expected_order[-2];
my $actual_last = $actual_order[-2];
if ($actual_last ne $expected_last) {
report("section '$line' incorrectly ordered, comes after '$actual_last'");
}
next;
}
if ($last_was_section) {
my $last_section = $actual_order[-1];
if (length $last_section ne length $line) {
report("dashes under '$last_section' should match its length!");
}
if ($line !~ /^-+$/) {
report("dashes under '$last_section' should be '-' dashes!");
}
$last_was_section = 0;
}
if (eof) {
# We have both a hash and an array to consider, for
# convenience
my %actual_sections;
@actual_sections{@actual_order} = ();
for my $section (sort keys %SECTIONS) {
next if !$SECTIONS{$section}->{required} or exists $actual_sections{$section};
report("has no required '$section' section!");
}
# Reset per-file state
{
@actual_order = ();
# this resets our $. for each file
close ARGV;
}
}
}
exit $exit_code;