From c7d6a40d02055c25e109048341a6723d35b0449a Mon Sep 17 00:00:00 2001 From: Denton Liu Date: Sun, 1 Jun 2025 19:18:10 -0700 Subject: [PATCH] Make the build reproducible help2man was vendored as part of d5d5253 (Fix bugs reported by Dominique, 2000-10-06) because at the time, help2man did not have a --version-option argument and one needed to be patched in. However, as of help2man 1.29, released in July 2003, this option was added. Remove the vendored version of help2man and use the help2man on the system. It's been released for long enough that all users should be using a version of help2man that's less than 22 years old. This helps because distros such as Arch Linux patch the vendored version of help2man in order to make the build reproducible[0]. However, help2man has been updated to support $SOURCE_DATE_EPOCH for a long time now. Add -n to the gzip call so that the timestamp of the files are not saved. While we're at it, add the generated files to the .gitignore. [0]: https://gitlab.archlinux.org/archlinux/packaging/packages/lsb-release/-/blob/e5ce86591a488e1089e1c246a296adc70679588b/lsb_release_make_man_page_reproducible.patch --- .gitignore | 2 + lsb_release/README | 10 +- lsb_release/src/Makefile | 4 +- lsb_release/src/help2man | 520 --------------------------------------- 4 files changed, 9 insertions(+), 527 deletions(-) create mode 100644 .gitignore delete mode 100755 lsb_release/src/help2man diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa006b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.1 +*.1.gz diff --git a/lsb_release/README b/lsb_release/README index 7f66090..833c665 100644 --- a/lsb_release/README +++ b/lsb_release/README @@ -1,6 +1,6 @@ This directory contains: -src - directory containing the source for lsb_release +src - directory containing the source for lsb_release lsb-release.spec - the spec file for generating RPM packages for lsb_release debian - directory containing the necessary configuration files for generating a deb packages for lsb_release @@ -9,10 +9,10 @@ debian - directory containing the necessary configuration files for Generating a release -------------------- -The man page for lsb_release is automatically created by a modified -version of the help2man program when the packages are constructed. The -Makefile in the src subdirectory contains the command line arguments -needed. The modified version of help2mn is included in this package. +The man page for lsb_release is automatically created by the help2man +program when the packages are constructed. Please ensure that the +program is available on the build system. The Makefile in the src +subdirectory contains the command line arguments needed. 1. Checkout a tagged release (eg Release_1_1) or a snapshot diff --git a/lsb_release/src/Makefile b/lsb_release/src/Makefile index a7dfdd9..f3ea18e 100644 --- a/lsb_release/src/Makefile +++ b/lsb_release/src/Makefile @@ -21,8 +21,8 @@ all: man man: lsb_release.1.gz lsb_release.1.gz: lsb_release - @./help2man -N --include ./lsb_release.examples --alt_version_key=program_version ./lsb_release >lsb_release.1 - @gzip -9f lsb_release.1 + @help2man -N --include ./lsb_release.examples --version-option=--program_version ./lsb_release >lsb_release.1 + @gzip -9fn lsb_release.1 install: all install -D -m 644 lsb_release.1.gz ${mandir}/man1/lsb_release.1.gz diff --git a/lsb_release/src/help2man b/lsb_release/src/help2man deleted file mode 100755 index 13015c2..0000000 --- a/lsb_release/src/help2man +++ /dev/null @@ -1,520 +0,0 @@ -#!/usr/bin/perl -w - -# Generate a short man page from --help and --version output. -# Copyright © 1997, 1998, 1999, 2000 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -# Written by Brendan O'Dea -# Available from ftp://ftp.gnu.org/gnu/help2man/ - -# This has been modified by Chris Yeoh to -# handle FSG programs and those which don't support --version -# to display the version - -use 5.004; -use strict; -use Getopt::Long; -use Text::Tabs qw(expand); -use POSIX qw(strftime setlocale LC_TIME); - -my $this_program = 'help2man'; -my $this_version = '1.022'; -my $version_info = < -EOT - -my $help_info = <. -EOT - -my $section = 1; -my ($opt_name, @opt_include, $opt_output, $opt_no_info); -my($opt_version_key) = "version"; - -# Parse options. -Getopt::Long::config('bundling'); -GetOptions ( - 'n|name=s' => \$opt_name, - 's|section=s' => \$section, - 'i|include=s' => sub { push @opt_include, [ pop, 1 ] }, - 'I|opt-include=s' => sub { push @opt_include, [ pop, 0 ] }, - 'o|output=s' => \$opt_output, - 'N|no-info' => \$opt_no_info, - 'alt_version_key=s' => \$opt_version_key, - help => sub { print $help_info; exit }, - version => sub { print $version_info; exit }, -) or die $help_info; - -die $help_info unless @ARGV == 1; - -my %include = (); -my %append = (); -my @include = (); # retain order given in include file - -# Provide replacement `quote-regex' operator for pre-5.005. -BEGIN { eval q(sub qr { '' =~ $_[0]; $_[0] }) if $] < 5.005 } - -# Process include file (if given). Format is: -# -# [section name] -# verbatim text -# -# or -# -# /pattern/ -# verbatim text -# - -for (@opt_include) -{ - my ($inc, $required) = @$_; - - next unless -f $inc or $required; - die "$this_program: can't open `$inc' ($!)\n" - unless open INC, $inc; - - my $key; - my $hash = \%include; - - while () - { - # [section] - if (/^\[([^]]+)\]/) - { - $key = uc $1; - $key =~ s/^\s+//; - $key =~ s/\s+$//; - $hash = \%include; - push @include, $key unless $include{$key}; - next; - } - - # /pattern/ - if (m!^/(.*)/([ims]*)!) - { - my $pat = $2 ? "(?$2)$1" : $1; - - # Check pattern. - eval { $key = qr($pat) }; - if ($@) - { - $@ =~ s/ at .*? line \d.*//; - die "$inc:$.:$@"; - } - - $hash = \%append; - next; - } - - # Silently ignore anything before the first - # section--allows for comments and revision info. - next unless $key; - - $hash->{$key} ||= ''; - $hash->{$key} .= $_; - } - - close INC; - - die "$this_program: no valid information found in `$inc'\n" - unless $key; -} - -# Compress trailing blank lines. -for my $hash (\(%include, %append)) -{ - for (keys %$hash) { $hash->{$_} =~ s/\n+$/\n/ } -} - -# Turn off localisation of executable's ouput. -@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; - -# Turn off localisation of date (for strftime). -setlocale LC_TIME, 'C'; - -# Grab help and version info from executable. -my ($help_text, $version_text) = map { - join '', map { s/ +$//; expand $_ } `$ARGV[0] --$_ 2>/dev/null` - or die "$this_program: can't get `--$_' info from $ARGV[0]\n" -} qw(help), $opt_version_key; - -my $date = strftime "%B %Y", localtime; -(my $program = $ARGV[0]) =~ s!.*/!!; -my $package = $program; -my $version; - -if ($opt_output) -{ - unlink $opt_output - or die "$this_program: can't unlink $opt_output ($!)\n" - if -e $opt_output; - - open STDOUT, ">$opt_output" - or die "$this_program: can't create $opt_output ($!)\n"; -} - -# The first line of the --version information is assumed to be in one -# of the following formats: -# -# -# -# {GNU,Free} -# ({GNU,Free} ) -# - {GNU,Free} -# -# and seperated from any copyright/author details by a blank line. - -($_, $version_text) = split /\n+/, $version_text, 2; - -if (/^(\S+) +\(((?:GNU|Free) +[^)]+)\) +(.*)/ or - /^(\S+) +- *((?:GNU|Free) +\S+) +(.*)/) -{ - $program = $1; - $package = $2; - $version = $3; -} -elsif (/^((?:GNU|Free) +)?(\S+) +(.*)/) -{ - $program = $2; - $package = $1 ? "$1$2" : $2; - $version = $3; -} -else -{ - $version = $_; -} - -$program =~ s!.*/!!; - -# No info for `info' itself. -$opt_no_info = 1 if $program eq 'info'; - -# --name overrides --include contents. -$include{NAME} = "$program \\- $opt_name\n" if $opt_name; - -# Default (useless) NAME paragraph. -$include{NAME} ||= "$program \\- manual page for $program $version\n"; - -# Man pages traditionally have the page title in caps. -my $PROGRAM = uc $program; - -# Extract usage clause(s) [if any] for SYNOPSIS. -if ($help_text =~ s/^Usage:( +(\S+))(.*)((?:\n(?: {6}\1| *or: +\S).*)*)//m) -{ - my @syn = $2 . $3; - - if ($_ = $4) - { - s/^\n//; - for (split /\n/) { s/^ *(or: +)?//; push @syn, $_ } - } - - my $synopsis = ''; - for (@syn) - { - $synopsis .= ".br\n" if $synopsis; - s!^\S*/!!; - s/^(\S+) *//; - $synopsis .= ".B $1\n"; - s/\s+$//; - s/(([][]|\.\.+)+)/\\fR$1\\fI/g; - s/^/\\fI/ unless s/^\\fR//; - $_ .= '\fR'; - s/(\\fI)( *)/$2$1/g; - s/\\fI\\fR//g; - s/^\\fR//; - s/\\fI$//; - s/^\./\\&./; - - $synopsis .= "$_\n"; - } - - $include{SYNOPSIS} ||= $synopsis; -} - -# Process text, initial section is DESCRIPTION. -my $sect = 'DESCRIPTION'; -$_ = "$help_text\n\n$version_text"; - -# Normalise paragraph breaks. -s/^\n+//; -s/\n*$/\n/; -s/\n\n+/\n\n/g; - -# Temporarily exchange leading dots and backslashes for tokens. -s/^\./\x80/mg; -s/\\/\x81/g; - -# Start a new paragraph (if required) for these. -s/([^\n])\n(Report +bugs|Email +bug +reports +to|Written +by)/$1\n\n$2/g; - -sub convert_option; - -while (length) -{ - # Convert some standard paragraph names. - if (s/^(Options|Examples): *\n//) - { - $sect = uc $1; - next; - } - - # Copyright section - if (/^Copyright +[(\xa9]/) - { - $sect = 'COPYRIGHT'; - $include{$sect} ||= ''; - $include{$sect} .= ".PP\n" if $include{$sect}; - - my $copy; - ($copy, $_) = split /\n\n/, $_, 2; - - for ($copy) - { - # Add back newline - s/\n*$/\n/; - - # Convert iso9959-1 copyright symbol or (c) to nroff - # character. - s/^Copyright +(?:\xa9|\([Cc]\))/Copyright \\(co/mg; - - # Insert line breaks before additional copyright messages - # and the disclaimer. - s/(.)\n(Copyright |This +is +free +software)/$1\n.br\n$2/g; - - # Join hyphenated lines. - s/([A-Za-z])-\n */$1/g; - } - - $include{$sect} .= $copy; - $_ ||= ''; - next; - } - - # Catch bug report text. - if (/^(Report +bugs|Email +bug +reports +to) /) - { - $sect = 'REPORTING BUGS'; - } - - # Author section. - elsif (/^Written +by/) - { - $sect = 'AUTHOR'; - } - - # Examples, indicated by an indented leading $, % or > are - # rendered in a constant width font. - if (/^( +)([\$\%>] )\S/) - { - my $indent = $1; - my $prefix = $2; - my $break = '.IP'; - $include{$sect} ||= ''; - while (s/^$indent\Q$prefix\E(\S.*)\n*//) - { - $include{$sect} .= "$break\n\\f(CW$prefix$1\\fR\n"; - $break = '.br'; - } - - next; - } - - my $matched = ''; - $include{$sect} ||= ''; - - # Sub-sections have a trailing colon and the second line indented. - if (s/^(\S.*:) *\n / /) - { - $matched .= $& if %append; - $include{$sect} .= qq(.SS "$1"\n); - } - - my $indent = 0; - my $content = ''; - - # Option with description. - if (s/^( {1,10}([+-]\S.*?))(?:( +)|\n( {20,}))(\S.*)\n//) - { - $matched .= $& if %append; - $indent = length ($4 || "$1$3"); - $content = ".TP\n\x82$2\n\x82$5\n"; - unless ($4) - { - # Indent may be different on second line. - $indent = length $& if /^ {20,}/; - } - } - - # Option without description. - elsif (s/^ {1,10}([+-]\S.*)\n//) - { - $matched .= $& if %append; - $content = ".HP\n\x82$1\n"; - $indent = 80; # not continued - } - - # Indented paragraph with tag. - elsif (s/^( +(\S.*?) +)(\S.*)\n//) - { - $matched .= $& if %append; - $indent = length $1; - $content = ".TP\n\x82$2\n\x82$3\n"; - } - - # Indented paragraph. - elsif (s/^( +)(\S.*)\n//) - { - $matched .= $& if %append; - $indent = length $1; - $content = ".IP\n\x82$2\n"; - } - - # Left justified paragraph. - else - { - s/(.*)\n//; - $matched .= $& if %append; - $content = ".PP\n" if $include{$sect}; - $content .= "$1\n"; - } - - # Append continuations. - while (s/^ {$indent}(\S.*)\n//) - { - $matched .= $& if %append; - $content .= "\x82$1\n" - } - - # Move to next paragraph. - s/^\n+//; - - for ($content) - { - # Leading dot protection. - s/\x82\./\x80/g; - s/\x82//g; - - # Convert options. - s/(^| )(-[][\w=-]+)/$1 . convert_option $2/mge; - } - - # Check if matched paragraph contains /pat/. - if (%append) - { - for my $pat (keys %append) - { - if ($matched =~ $pat) - { - $content .= ".PP\n" unless $append{$pat} =~ /^\./; - $content .= $append{$pat}; - } - } - } - - $include{$sect} .= $content; -} - -# Refer to the real documentation. -unless ($opt_no_info) -{ - $sect = 'SEE ALSO'; - $include{$sect} ||= ''; - $include{$sect} .= ".PP\n" if $include{$sect}; - $include{$sect} .= <