On Thu, 18 Jan 2018 21:48:00 +0000 Niels Thykier <ni...@thykier.net> wrote:
> Control: reassign -1 javahelper
> 
> On Thu, 18 Jan 2018 23:41:19 +0200 Adrian Bunk <b...@debian.org> wrote:
> > Package: debhelper
> > Version: 11.1.2
> > Severity: serious
> > Control: affects -1 javahelper src:zabbix
> > 
> > https://tests.reproducible-builds.org/debian/rb-pkg/unstable/amd64/zabbix.html
> > 
> > ...
> >    jh_linkjars -O--max-parallel=4 -Nzabbix-frontend-php 
> > -Nzabbix-java-gateway
> > Invalid option: N
> > Usage: jh_linkjars [options] [target] 
> > Options:
> >     -h --help: show this text
> >     -V --version: show the version
> >     -v --verbose: show more information while running
> >     -t --transitive: transitively link jars
> >     -n --no-act: don't actually do anything, just print the results
> >     -u --unlink: remove the links instead of adding them
> > debian/rules:77: recipe for target 'binary' failed
> > make: *** [binary] Error 1
> > 
> > 
> > Works after downgrading to debhelper 11
> > 
> > 
> 
> 
> The -N option is a basic "shared" debhelper option required by any
> dh-like tool added to the debhelper sequence (similar to -p/-s/-i).  The
> solution here is to have javahelper support that option.
> 
> Thanks,
> ~Niels
> 
> 
> 

Hi,

I have written some patches to rewrite most of the javatools helpers
into perl using Debhelper's Dh_Lib[1].  This would fix this problem and
avoid future instances of it.

While the patches do include jh_linkjars, I doubt that the bug will be
fixed until jh_build and jh_depends have also been rewritten.
Therefore, I am not tagging this bug with "patch".

Thanks,
~Niels

[1] The 0001 patch is strictly unrelated but avoids relying (fake)root
when building the package.
>From bf05b0189e84660fae137060931a490ab58d0fa2 Mon Sep 17 00:00:00 2001
From: Niels Thykier <ni...@thykier.net>
Date: Sat, 7 Apr 2018 14:43:21 +0000
Subject: [PATCH 1/6] javatools can be built without (fake)root

Signed-off-by: Niels Thykier <ni...@thykier.net>
---
 debian/control | 1 +
 1 file changed, 1 insertion(+)

diff --git a/debian/control b/debian/control
index c127665..6616958 100644
--- a/debian/control
+++ b/debian/control
@@ -12,6 +12,7 @@ Build-Depends:
  libtest-strict-perl,
  markdown,
  perl
+Rules-Requires-Root: no
 Standards-Version: 4.1.3
 Vcs-Git: https://anonscm.debian.org/git/pkg-java/javatools.git
 Vcs-Browser: https://anonscm.debian.org/cgit/pkg-java/javatools.git
-- 
2.16.3

>From 4f6064fa0e380e8b8f50b16e8852987431f1776f Mon Sep 17 00:00:00 2001
From: Niels Thykier <ni...@thykier.net>
Date: Sat, 7 Apr 2018 15:05:06 +0000
Subject: [PATCH 2/6] Rewrite jh_classpath using Debhelper's Dh_Lib

Signed-off-by: Niels Thykier <ni...@thykier.net>
---
 debian/javahelper.manpages |   1 -
 debian/rules               |   1 +
 jh_classpath               | 221 +++++++++++++++++++++++++++------------------
 jh_classpath.1             |  30 ------
 t/strict.t                 |   1 +
 5 files changed, 135 insertions(+), 119 deletions(-)
 delete mode 100644 jh_classpath.1

diff --git a/debian/javahelper.manpages b/debian/javahelper.manpages
index 8527947..6f02dc7 100644
--- a/debian/javahelper.manpages
+++ b/debian/javahelper.manpages
@@ -1,5 +1,4 @@
 jh_build.1
-jh_classpath.1
 jh_depends.1
 jh_exec.1
 jh_installjavadoc.1
diff --git a/debian/rules b/debian/rules
index 703676a..600be8f 100755
--- a/debian/rules
+++ b/debian/rules
@@ -20,6 +20,7 @@ override_dh_auto_build: jh_lib.sh
 	$(POD2MAN) jh_setupenvironment tmp/jh_setupenvironment.1
 	$(POD2MAN) jh_compilefeatures tmp/jh_compilefeatures.1
 	$(POD2MAN) jh_manifest tmp/jh_manifest.1
+	$(POD2MAN) jh_classpath tmp/jh_classpath.1
 	$(POD2MAN) fetch-eclipse-source.pod tmp/fetch-eclipse-source.1
 	$(POD2MAN) -s 1 jh_clean.pod tmp/jh_clean.1
 	$(POD2MAN) $(MOD_PATH)/Eclipse.pm tmp/Debian::Javahelper::Eclipse.3
diff --git a/jh_classpath b/jh_classpath
index 3024f98..5aa61f2 100755
--- a/jh_classpath
+++ b/jh_classpath
@@ -1,94 +1,139 @@
-#!/bin/bash --
-
-set -e
-
-. /usr/share/javahelper/jh_lib.sh
-
-syntax()
-{
-   echo -e "Usage: jh_classpath [options] [jar(s)]"
-   echo -e "Options:"
-   echo -e "\t-h --help: show this text"
-   echo -e "\t-V --version: show the version"
-   echo -e "\t-i --indep: act on all Arch: all packages"
-   echo -e "\t-a --arch: act on all Arch-specific packages"
-   echo -e "\t-s --same-arch: alias of --arch for compatibility with debhelper"
-   echo -e "\t-p<package> --package=<package>: package to act on (default=all)"
-   echo -e "\t-P<packagedir> --tmpdir=<package>: package directory (default=\$CWD/debian/package)"
-   echo -e "\t-c<classpath> --classpath=<classpath>: The classpath to set on the jar(s)"
-   echo -e "\t-v --verbose: show more information while running"
-   echo -e "\t-n --no-act: don't actually do anything, just print the results"
-   exit 1
-}
+#!/usr/bin/perl
 
-ARGS="i indep a arch s same-arch p package P tmpdir v verbose n no-act c classpath" parseargs "$@"
+=head1 NAME
 
-dh_testdir
+jh_classpath - sets classpaths in jar files
 
-VERBOSE="`getarg v verbose`"
-NOACT="`getarg n noact`"
+=cut
 
-if [ "$ARGC" == "0" ]; then
-	# read debian/$package.classpath
-	for p in `findpackages`; do
-		if [ -f "debian/$p.classpath" ]; then
-			cat "debian/$p.classpath" | while read jar cpath; do
-				if [ ! -f "$jar" ] ; then
-                                    jar="debian/$p/$jar"
-                                fi
-				if [ -n "$VERBOSE" ]; then
-					echo "Setting classpath on $jar to $cpath"
-				fi
-				if [ -n "$NOACT" ]; then
-					echo "Would run jh_manifest -p$p --classpath=$cpath $jar"
-				else
-					jh_manifest "-p$p" "--classpath=$cpath" "$jar"
-				fi
-			done
-		elif [ -f "debian/classpath" ]; then
-			cat "debian/classpath" | while read jar cpath; do
-				if [ ! -f "$jar" ] ; then
-                                    jar="debian/$p/$jar"
-                                fi
-				if [ -n "$VERBOSE" ]; then
-					echo "Setting classpath on $jar to $cpath"
-				fi
-				if [ -n "$NOACT" ]; then
-					echo "Would run jh_manifest -p$p --classpath=$cpath $jar"
-				else
-					jh_manifest "-p$p" "--classpath=$cpath" "$jar"
-				fi
-			done
-		fi
-	done
-else
+use strict;
+use warnings;
+use Debian::Debhelper::Dh_Lib;
+
+=head1 SYNOPSIS
+
+B<jh_classpath> [S<I<debhelper options>>]
+
+B<jh_classpath> [S<I<debhelper options>>] [B<-p>I<package>] [B<--classpath=>I<cp>] [S<I<jar [...]>>]
+
+=head1 DESCRIPTION
+
+B<jh_classpath> is a javahelper program that can set the classpath on
+jar files for you.
+
+It has two modes of operations.  By default, it will read
+F<debian/I<package>.classpath> or F<debian/classpath> and set the
+classpath of all jar files listed in that file.  In this mode,
+B<jh_classpath> does not accept any non-option arguments.
+
+Alternatively, you can pass B<jh_classpath> a list of jar files
+to update.  It will process each of those and set the classpath
+of them to that value set by B<--classpath> if passed.  If
+B<--classpath> is omitted the environment variable CLASSPATH will
+be used instead (rewriting its contents as necessary).  In this
+mode, B<jh_classpath> will not read F<debian/I<package>.classpath>
+nor F<debian/classpath>.
+
+=head1 FILES
+
+=over 4
+
+=item F<debian/I<package>.classpath>, F<debian/classpath>
+
+Parsed to determine which jar files should be processed for the
+given package.  Note that unlike most other debhelper commands,
+B<jh_classpath> will use F<debian/classpath> as a fallback
+configuration file for I<all> packages that it acts on.  Other
+debhelper commands usually only apply this fallback to the
+"main package".
+
+The file consists of 0 or more lines with the following:
+
+     jarfile classpath-file1 [... classpath-file2]
+
+Note that each file in the classpath is space-separated in
+this configuration file.
+
+=back
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-c>I<cp>, B<--classpath=>I<cp>
+
+=back
+
+Beyond the above, B<jh_classpath> also accepts the shared
+debhelper options documented in L<debhelper(7)>.
+
+=cut
+
+my $classpath_arg;
+
+init(options => {
+	'classpath|c=s' => \$classpath_arg,
+});
+
+
+if (@ARGV) {
 	# process jars with -c or $CLASSPATH
-	for (( i=0 ; i<ARGC; i++ )); do
-		jar=${ARGV[i]}
-                p=$(firstpackage)
-		if [ -f "$jar" ]; then
-			cpath="`getarg c classpath`"
-			if [ ! -f "$jar" ] ; then
-				jar="debian/$p/$jar"
-                        fi
-			if [ -z "$cpath" ]; then
-				cpath="`sed 's/:/ /g' <<< $CLASSPATH`"
-			fi
-			if [ -z "$cpath" ]; then
-				echo "Could not find a classpath, doing nothing"
-				exit 0
-			fi
-			if [ -n "$VERBOSE" ]; then
-				echo "Setting classpath on $jar to $cpath"
-			fi
-			if [ -n "$NOACT" ]; then
-				echo "Would run jh_manifest -p$p --classpath=$cpath $jar"
-			else
-				jh_manifest "-p$p" "--classpath=$cpath" "$jar"
-			fi
-		else
-			echo "Cannot find $jar: skipping"
-		fi
-	done
-fi
+	my $tmpdir = tmpdir($dh{FIRSTPACKAGE});
+	if (not $classpath_arg) {
+		$classpath_arg = $ENV{'CLASSPATH'};
+		$classpath_arg =~ tr/:/ /;
+	}
+	if (not $classpath_arg) {
+		warning('Could not find a classpath, doing nothing');
+		exit(0);
+	}
+	for my $jar (@ARGV) {
+		if (not -f $jar) {
+			my $jar_in_tmp = "${tmpdir}/${jar}";
+			if (not -f $jar_in_tmp) {
+				warning("Cannot find $jar: skipping");
+				next;
+			}
+			$jar = $jar_in_tmp;
+			doit('jh_manifest', "-p$dh{FIRSTPACKAGE}", "--classpath=${classpath_arg}", $jar)
+		}
+
+	}
+} else {
+	# read debian/$package.classpath
+	foreach my $package (@{$dh{DOPACKAGES}}) {
+		my $tmpdir = tmpdir($dh{FIRSTPACKAGE});
+		my $pkgfile = pkgfile($package, 'classpath');
+		if (not $pkgfile and -f 'debian/classpath') {
+			$pkgfile = 'debian/classpath';
+		}
+		next if not $pkgfile;
+		my @lines = filedoublearray($pkgfile);
+		for my $line (@lines) {
+			my ($jar, @classpath_parts) = @{$line};
+			my $classpath = join(' ', @classpath_parts);
+			if (not -f $jar) {
+				my $jar_in_tmp = "${tmpdir}/${jar}";
+				if (not -f $jar_in_tmp) {
+					warning("Cannot find $jar: skipping");
+					next;
+				}
+				$jar = $jar_in_tmp;
+			}
+			doit('jh_manifest', "-p$dh{FIRSTPACKAGE}", "--classpath=${classpath}", $jar)
+		}
+	}
+}
+
+=head1 SEE ALSO
+
+L<debhelper(7)>
+
+This program is a part of javahelper and uses debhelper as backend. There are
+also tutorials in /usr/share/doc/javahelper.
+
+=head1 AUTHOR
+
+Niels Thykier <ni...@thykier.net>
 
+=cut
diff --git a/jh_classpath.1 b/jh_classpath.1
deleted file mode 100644
index 9e8cb9b..0000000
--- a/jh_classpath.1
+++ /dev/null
@@ -1,30 +0,0 @@
-.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.36.
-.TH JAVAHELPER "1" "January 2008" "Javahelper Version 0.5" "User Commands"
-.SH NAME
-Javahelper \- Part of the Java Helper packaging tools
-Refer to the tutorials in /usr/share/doc/javahelper for more detail
-.SH SYNOPSIS
-.B jh_classpath
-[\fIoptions\fR] [\fI<jar> \fR...]
-.SH OPTIONS
-.HP
-\fB\-h\fR \fB\-\-help\fR: show this text
-.HP
-\fB\-v\fR \fB\-\-verbose\fR: show more information while running
-.HP
-\fB\-V\fR \fB\-\-version\fR: print the version
-.HP
-\fB\-n\fR \fB\-\-no\-act\fR: don't actually do anything, just print the results
-.SS "When reading manifest files for packages:"
-.HP
-\fB\-i\fR \fB\-\-indep\fR: run for all Arch: all packages
-.HP
-\fB\-a\fR \fB\-\-arch\fR: run for all Arch\-specific packages
-.HP
-\fB\-p\fR<package> \fB\-\-package=\fR<package>: package to act on (default=all)
-.HP
-\fB\-P\fR<packagedir> \fB\-\-tmpdir=\fR<package>: package directory (default=$CWD/debian/package)
-.SS "When acting on a jar from the command line:"
-.HP
-\fB\-c\fR<classpath> \fB\-\-classpath=\fR<classpath>: The classpath to set (space separated)
-.HP
diff --git a/t/strict.t b/t/strict.t
index 878737b..ad7f964 100755
--- a/t/strict.t
+++ b/t/strict.t
@@ -12,6 +12,7 @@ my @FILES = qw(
   jh_generateorbitdir
   jh_installeclipse
   jh_manifest
+  jh_classpath
   jh_scanjavadoc
   jh_setupenvironment
 );
-- 
2.16.3

>From 0ceb5b217b3f56e09e9f049e093eece09b76ce8e Mon Sep 17 00:00:00 2001
From: Niels Thykier <ni...@thykier.net>
Date: Sat, 7 Apr 2018 15:42:52 +0000
Subject: [PATCH 3/6] Rewrite jh_installjavadoc using Debhelper's Dh_Lib

Signed-off-by: Niels Thykier <ni...@thykier.net>
---
 debian/javahelper.manpages |   1 -
 debian/rules               |   1 +
 jh_installjavadoc          | 244 ++++++++++++++++++++++++++-------------------
 jh_installjavadoc.1        |  27 -----
 t/strict.t                 |   1 +
 5 files changed, 142 insertions(+), 132 deletions(-)
 delete mode 100644 jh_installjavadoc.1

diff --git a/debian/javahelper.manpages b/debian/javahelper.manpages
index 6f02dc7..c636213 100644
--- a/debian/javahelper.manpages
+++ b/debian/javahelper.manpages
@@ -1,7 +1,6 @@
 jh_build.1
 jh_depends.1
 jh_exec.1
-jh_installjavadoc.1
 jh_installlibs.1
 jh_linkjars.1
 jh_makepkg.1
diff --git a/debian/rules b/debian/rules
index 600be8f..395aba1 100755
--- a/debian/rules
+++ b/debian/rules
@@ -21,6 +21,7 @@ override_dh_auto_build: jh_lib.sh
 	$(POD2MAN) jh_compilefeatures tmp/jh_compilefeatures.1
 	$(POD2MAN) jh_manifest tmp/jh_manifest.1
 	$(POD2MAN) jh_classpath tmp/jh_classpath.1
+	$(POD2MAN) jh_installjavadoc tmp/jh_installjavadoc.1
 	$(POD2MAN) fetch-eclipse-source.pod tmp/fetch-eclipse-source.1
 	$(POD2MAN) -s 1 jh_clean.pod tmp/jh_clean.1
 	$(POD2MAN) $(MOD_PATH)/Eclipse.pm tmp/Debian::Javahelper::Eclipse.3
diff --git a/jh_installjavadoc b/jh_installjavadoc
index 7dab62b..6864b29 100755
--- a/jh_installjavadoc
+++ b/jh_installjavadoc
@@ -1,121 +1,157 @@
-#!/bin/bash --
-
-set -e
-
-. /usr/share/javahelper/jh_lib.sh
-
-syntax()
-{
-   echo -e "Usage: jh_installjavadoc [options] [src] [target]"
-   echo -e "Options:"
-   echo -e "\t-h --help: show this text"
-   echo -e "\t-V --version: show the version"
-   echo -e "\t-i --indep: act on all Arch: all packages"
-   echo -e "\t-a --arch: act on all Arch-specific packages"
-   echo -e "\t-s --same-arch: alias of --arch for compatibility with debhelper"
-   echo -e "\t-p<package> --package=<package>: package to act on (default=all)"
-   echo -e "\t-P<packagedir> --tmpdir=<package>: package directory (default=\$CWD/debian/package)"
-   echo -e "\t-v --verbose: show more information while running"
-   echo -e "\t-n --no-act: don't actually do anything, just print the results"
-   echo -e "\t-A<author> --author=<author>: Author of the javadoc"
-   exit 1
-}
+#!/usr/bin/perl
+
+=head1 NAME
+
+jh_installjavadoc - install javadoc into packages
+
+=cut
+
+use strict;
+use warnings;
+use Debian::Debhelper::Dh_Lib;
+
+=head1 SYNOPSIS
+
+B<jh_installjavadoc> [S<I<debhelper options>>]
+
+B<jh_installjavadoc> [S<I<debhelper options>>] [B<-p>I<package>] [S<I<base-directory-of-javadoc>>] [S<I<install-location>>]
+
+=head1 DESCRIPTION
+
+B<jh_installjavadoc> is a javahelper program that can install generated
+javadoc for you.
+
+If you have javadoc which has been built by your build system, then
+B<jh_installjavadoc> will install it in the correct location and register
+it with doc-base for you. Either run B<jh_installjavadoc> with the
+directory containing the javadoc as a parameter, or it will read
+F<debian/I<package>.javadoc> or F<debian/javadoc>, which should contain
+a single path to the javadoc for that package.
+
+If you have used L<jh_build(1)> that will automatically have created
+javadoc.  To install that put the string "internal" in the javadoc
+file and it will be installed.
+
+The second parameter, or the second string on the line in the javadoc
+file, can be used to override the install location, for example, so
+that a -doc package can install to F</usr/share/doc/I<library>/api>.
+
+=head1 FILES
+
+=over 4
+
+=item F<debian/I<package>.javadoc>, F<debian/javadoc>
+
+Parsed to determine which javadoc directory should be processed for the
+given package.  Note that unlike most other debhelper commands,
+B<jh_installjavadoc> will use F<debian/javadoc> as a fallback
+configuration file for I<all> packages that it acts on.  Other
+debhelper commands usually only apply this fallback to the
+"main package".
 
-ARGS="A author i indep a arch s same-arch p package P tmpdir v verbose n no-act" parseargs "$@"
-
-dh_testdir
-
-VERBOSE="`getarg v verbose`"
-AUTHOR="`getarg A author`"
-
-function installjavadoc()
-{
-
-	package="$1"
-	src="$2"
-	target="$3"
-
-	if [ -z "$AUTHOR" ]; then
-		AUTHOR="The authors of $package"
-	fi
-	if [ -z "$src" ]; then
-		echo "Error: trying to install from empty source"
-		exit 1
-	fi
-	if [ ! -d "$src" ]; then
-		echo "Javadoc source $src does not exist or is not a directory, skipping"
-		return
-	fi
-
-	if [ -z "$target" ]; then
-		target="debian/$package/usr/share/doc/$package/api"
-		docbasepath="/usr/share/doc/$package/api"
-	else
-		docbasepath="/$target"
-		target="debian/$package/$target"
-	fi
-
-	if [ -n "$VERBOSE" ]; then
-		echo "Installing javadoc from $src into package $package"
-	fi
-
-	if [ -n "`getarg n no-act`" ]; then
-		echo mkdir -p "`dirname "$target"`"
-		echo cp -r "$src" "$target"
-		echo cat \> debian/$package.doc-base.javadoc
-	else
-		cat > debian/$package.doc-base.javadoc <<END
+The file consists a single line listing the javadoc directory (or
+the word "internal").  This is optionally followed path the path
+to the desired install location if the default location is
+incorrect.
+
+Examples:
+
+     internal
+
+     build/javadoc /usr/share/doc/somewhere/libapi
+
+=back
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-A>I<author>, B<--author=>I<author>
+
+=back
+
+Beyond the above, B<jh_installjavadoc> also accepts the shared
+debhelper options documented in L<debhelper(7)>.
+
+=cut
+
+my $AUTHOR;
+
+init(options => {
+	'author|A=s' => \$AUTHOR,
+});
+
+sub installjavadoc {
+	my ($package, $source, $target) = @_;
+	my $author = $AUTHOR // "The authors of $package";
+	my $docbase_path;
+	my $tmpdir = tmpdir($package);
+	if (not -d $source) {
+		warning("Javadoc source ${source} does not exist or is not a directory, skipping");
+		return;
+	}
+	if (defined($target)) {
+		$target = "${tmpdir}/$target";
+		$docbase_path = "/$target";
+	} else {
+		$target = "${tmpdir}/usr/share/doc/$package/api";
+		$docbase_path="/usr/share/doc/$package/api";
+	}
+	verbose_print("Installing javadoc from ${source} into package $package");
+	doit('cp', '-r', $source, $target);
+	verbose_print("cat > debian/$package.doc-base.javadoc");
+	if (not $dh{NO_ACT}) {
+		open(my $fd, '>', "debian/$package.doc-base.javadoc")
+			or error("open debian/$package.doc-base.javadoc failed: $!");
+		print {$fd} <<EOF ;
 Document: $package
 Title: API JavaDoc for $package
-Author: $AUTHOR
+Author: $author
 Abstract: This is the API JavaDoc for $package
 Section: Programming/Java
 
 Format: HTML
-Index: $docbasepath
-Files: $docbasepath/*.html
-END
-	echo "debian/$package.doc-base.javadoc" >> debian/.javahelper_clean
-
-		mkdir -p "`dirname "$target"`"
-		cp -r "$src" "$target"
-	fi
+Index: $docbase_path
+Files: $docbase_path/*.html
+EOF
+		close($fd) or error("close debian/$package.doc-base.javadoc failed: $!");
+		open(my $cfd, '>>', 'debian/.javahelper_clean') or error("open debian/.javahelper_clean failed: $!");
+		print {$cfd} "debian/$package.doc-base.javadoc\n";
+		close($cfd) or error("close debian/.javahelper_clean failed: $!");
+	}
 }
 
+if (@ARGV) {
+	my ($source, $target) = @ARGV;
+	installjavadoc($dh{FIRSTPACKAGE}, $source, $target);
+	exit(0);
+}
 
-if [ "$ARGC" != "0" ] ; then
-
-   p="`firstpackage`"
-	installjavadoc "$p" "${ARGV[0]}" "${ARGV[1]}"
-   exit 0
-fi
+# read debian/$package.javadoc
+foreach my $package (@{$dh{DOPACKAGES}}) {
+	my $pkgfile = pkgfile($package, 'javadoc');
+	if (not $pkgfile and -f 'debian/javadoc') {
+		$pkgfile = 'debian/javadoc';
+	}
+	next if not $pkgfile;
+	my ($source, $target) = filedoublearray($pkgfile);
+
+	if ($source eq 'internal' and -d 'debian/_jh_build.javadoc/api') {
+		$source = 'debian/_jh_build.javadoc/api';
+	}
+	installjavadoc($package, $source, $target);
+}
 
-for p in `findpackages`; do
 
-   PACKAGEDIR="`getarg P tmpdir`"
-   if [ -z "$PACKAGEDIR" ]; then
-      PACKAGEDIR="`pwd`/debian/$p"
-   else
-      PACKAGEDIR=`readlink -f $PACKAGEDIR`
-   fi
+=head1 SEE ALSO
 
-   DIR=
-   if [ -f debian/$p.javadoc ]; then
-      DIR="`awk '{print $1}' debian/$p.javadoc`"
-      TARGET="`awk '{print $2}' debian/$p.javadoc`"
-   elif [ -f debian/javadoc ]; then
-      DIR="`awk '{print $1}' debian/javadoc`"
-      TARGET="`awk '{print $2}' debian/javadoc`"
-	else
-      continue
-   fi
+L<debhelper(7)>
 
-	if [ "$DIR" = "internal" ] && [ -d debian/_jh_build.javadoc/api ]; then
-		DIR=debian/_jh_build.javadoc/api
-	fi
+This program is a part of javahelper and uses debhelper as backend. There are
+also tutorials in /usr/share/doc/javahelper.
 
-   installjavadoc "$p" "$DIR" "$TARGET"
-   unset PACKAGEDIR
+=head1 AUTHOR
 
-done
+Niels Thykier <ni...@thykier.net>
 
+=cut
diff --git a/jh_installjavadoc.1 b/jh_installjavadoc.1
deleted file mode 100644
index 0e06f3b..0000000
--- a/jh_installjavadoc.1
+++ /dev/null
@@ -1,27 +0,0 @@
-.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.36.
-.TH JAVAHELPER "1" "January 2008" "Javahelper Version 0.5" "User Commands"
-.SH NAME
-Javahelper \- Part of the Java Helper packaging tools
-Refer to the tutorials in /usr/share/doc/javahelper for more detail
-.SH SYNOPSIS
-.B jh_installjavadoc
-[\fIoptions\fR] [\fIsourcedir\fR]
-.SH OPTIONS
-.HP
-\fB\-h\fR \fB\-\-help\fR: show this text
-.HP
-\fB\-V\fR \fB\-\-version\fR: show the version
-.HP
-\fB\-i\fR \fB\-\-indep\fR: act on all Arch: all packages
-.HP
-\fB\-a\fR \fB\-\-arch\fR: act on all Arch\-specific packages
-.HP
-\fB\-p\fR<package> \fB\-\-package=\fR<package>: package to act on (default=all)
-.HP
-\fB\-P\fR<packagedir> \fB\-\-tmpdir=\fR<package>: package directory (default=$CWD/debian/package)
-.HP
-\fB\-v\fR \fB\-\-verbose\fR: show more information while running
-.HP
-\fB\-n\fR \fB\-\-no\-act\fR: don't actually do anything, just print the results
-.HP
-\fB\-a\fR<author> \fB\-\-author=\fR<author>: Javadoc author
diff --git a/t/strict.t b/t/strict.t
index ad7f964..099b1b2 100755
--- a/t/strict.t
+++ b/t/strict.t
@@ -11,6 +11,7 @@ my @FILES = qw(
   jh_compilefeatures
   jh_generateorbitdir
   jh_installeclipse
+  jh_installjavadoc
   jh_manifest
   jh_classpath
   jh_scanjavadoc
-- 
2.16.3

>From 85d39a2155601ea5d59a26f49f40563b527e4cd7 Mon Sep 17 00:00:00 2001
From: Niels Thykier <ni...@thykier.net>
Date: Sat, 7 Apr 2018 16:11:11 +0000
Subject: [PATCH 4/6] Rewrite jh_exec using Debhelper's Dh_Lib

Signed-off-by: Niels Thykier <ni...@thykier.net>
---
 debian/javahelper.manpages |   1 -
 debian/rules               |   1 +
 jh_exec                    | 117 ++++++++++++++++++++++++---------------------
 jh_exec.1                  |  25 ----------
 t/strict.t                 |   1 +
 5 files changed, 64 insertions(+), 81 deletions(-)
 delete mode 100644 jh_exec.1

diff --git a/debian/javahelper.manpages b/debian/javahelper.manpages
index c636213..6911449 100644
--- a/debian/javahelper.manpages
+++ b/debian/javahelper.manpages
@@ -1,6 +1,5 @@
 jh_build.1
 jh_depends.1
-jh_exec.1
 jh_installlibs.1
 jh_linkjars.1
 jh_makepkg.1
diff --git a/debian/rules b/debian/rules
index 395aba1..9cf5bf3 100755
--- a/debian/rules
+++ b/debian/rules
@@ -19,6 +19,7 @@ override_dh_auto_build: jh_lib.sh
 	$(POD2MAN) jh_generateorbitdir tmp/jh_generateorbitdir.1
 	$(POD2MAN) jh_setupenvironment tmp/jh_setupenvironment.1
 	$(POD2MAN) jh_compilefeatures tmp/jh_compilefeatures.1
+	$(POD2MAN) jh_exec tmp/jh_exec.1
 	$(POD2MAN) jh_manifest tmp/jh_manifest.1
 	$(POD2MAN) jh_classpath tmp/jh_classpath.1
 	$(POD2MAN) jh_installjavadoc tmp/jh_installjavadoc.1
diff --git a/jh_exec b/jh_exec
index 65635aa..36fb63c 100755
--- a/jh_exec
+++ b/jh_exec
@@ -1,65 +1,72 @@
-#!/bin/bash --
-
-EXECDIRS="bin usr/bin usr/games"
-
-set -e
-
-. /usr/share/javahelper/jh_lib.sh
-
-syntax()
-{
-   echo "Usage: jh_exec [options]"
-   echo "Options:"
-   echo -e "\t-h --help: show this text"
-   echo -e "\t-V --version: print the version"
-   echo -e "\t-i --indep: run for all Arch: all packages"
-   echo -e "\t-a --arch: run for all Arch-specific packages"
-   echo -e "\t-s --same-arch: alias of --arch for compatibility with debhelper"
-   echo -e "\t-p<package> --package=<package>: package to act on (default=all)"
-   echo -e "\t-P<packagedir> --tmpdir=<package>: package directory (default=\$CWD/debian/package)"
-   echo -e "\t-v --verbose: show more information while running"
-   echo -e "\t-n --no-act: don't actually do anything, just print the results"
-   exit 1
-}
+#!/usr/bin/perl
+
+=head1 NAME
+
+jh_exec - make jar files in PATH executable
+
+=cut
+
+use strict;
+use warnings;
+use Cwd qw(realpath);
+use Debian::Debhelper::Dh_Lib;
+
+=head1 SYNOPSIS
+
+B<jh_exec> [S<I<debhelper options>>]
 
-ARGS="i indep a arch s same-arch p package P tmpdir v verbose n no-act" parseargs "$@"
+=head1 DESCRIPTION
 
-VERBOSE="`getarg v verbose`"
-dh_testdir
+B<jh_exec> will scan package directories for jars in the paths,
+or symlinks to jar from the paths, and ensure that they have been set
+executable if necessary.
 
-for p in `findpackages`; do
+Note that executable jar files requires L<jarwrapper(1)>.  Please see
+the tutorials in /usr/share/doc/javahelper for more information.
 
-   PACKAGEDIR="`getarg P tmpdir`"
-   if [ -z "$PACKAGEDIR" ]; then
-      PACKAGEDIR="`pwd`/debian/$p"
-   else
-      PACKAGEDIR=`readlink -f $PACKAGEDIR`
-   fi
+=head1 OPTIONS
+
+B<jh_exec> accepts the shared debhelper options documented in L<debhelper(7)>.
+
+=cut
+
+init();
+
+# Define PATH_DIRS next to the NOOP promise as they should be in sync.
+use constant PATH_DIRS => qw(bin usr/bin usr/games);
+# PROMISE: DH NOOP WITHOUT tmp(bin) tmp(usr/bin) tmp(usr/games)
+
+my @chmod_paths;
+foreach my $package (@{$dh{DOPACKAGES}}) {
+   my $tmpdir = tmpdir($package);
+   for my $path_dir (PATH_DIRS) {
+      my $dir = "${tmpdir}/${path_dir}";
+      opendir(my $dirfd, $dir) or error("opendir($dir) failed: $!");
+      for my $file (readdir($dirfd)) {
+         next if $file eq '.' or $file eq '..';
+         my $path = "${dir}/${file}";
+         # Must be a (symlink to a) file.
+         next if not -f $path;
+         # Resolve as we want to work on the file (and not the symlink)
+         my $resolved = realpath($path) // error("Cannot resolve $path: $!");
+         # Only work on .jar files.
+         next if $resolved !~ m{[.]jar$};
+         push(@chmod_paths, $resolved);
+      }
+      closedir($dirfd) or error("closedir($dir) failed: $!");
+   }
+}
+xargs(\@chmod_paths, 'chmod', '-x') if @chmod_paths;
 
-   if [ -n "$VERBOSE" ]; then
-      echo "Searching $PACKAGEDIR for $p"
-   fi
+=head1 SEE ALSO
 
-   for d in $EXECDIRS; do
-      for j in $PACKAGEDIR/$d/*; do
-         if [ -h "$j" ]; then
-            TARGET=`readlink -f "$j"`
-            if [ "${TARGET%.jar}" != "$TARGET" ]; then
-               if [ -n "$VERBOSE" ]; then
-                  echo "Making $TARGET executable"
-               fi
+L<debhelper(7)>
 
-               if [ -z "`getarg n no-act`" ]; then
-                  chmod +x "$TARGET"
-               else
-                  echo chmod +x "$TARGET"
-               fi
-            fi
-         fi
-      done
-   done
+This program is a part of javahelper and uses debhelper as backend. There are
+also tutorials in /usr/share/doc/javahelper.
 
-   unset PACKAGEDIR
+=head1 AUTHOR
 
-done
+Niels Thykier <ni...@thykier.net>
 
+=cut
diff --git a/jh_exec.1 b/jh_exec.1
deleted file mode 100644
index 50ed0cb..0000000
--- a/jh_exec.1
+++ /dev/null
@@ -1,25 +0,0 @@
-.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.36.
-.TH JAVAHELPER "1" "January 2008" "Javahelper Version 0.5" "User Commands"
-.SH NAME
-Javahelper \- Part of the Java Helper packaging tools
-Refer to the tutorials in /usr/share/doc/javahelper for more detail
-.SH SYNOPSIS
-.B jh_exec
-[\fIoptions\fR]
-.SH OPTIONS
-.HP
-\fB\-h\fR \fB\-\-help\fR: show this text
-.HP
-\fB\-V\fR \fB\-\-version\fR: print the version
-.HP
-\fB\-i\fR \fB\-\-indep\fR: run for all Arch: all packages
-.HP
-\fB\-a\fR \fB\-\-arch\fR: run for all Arch\-specific packages
-.HP
-\fB\-p\fR <package> \fB\-\-package=\fR<package>: package to act on (default=all)
-.HP
-\fB\-P\fR <packagedir> \fB\-\-tmpdir=\fR<package>: package directory (default=$CWD/debian/package)
-.HP
-\fB\-v\fR \fB\-\-verbose\fR: show more information while running
-.HP
-\fB\-n\fR \fB\-\-no\-act\fR: don't actually do anything, just print the results
diff --git a/t/strict.t b/t/strict.t
index 099b1b2..bf95e76 100755
--- a/t/strict.t
+++ b/t/strict.t
@@ -9,6 +9,7 @@ plan skip_all => 'Test::Strict required to run this test' if $@;
 
 my @FILES = qw(
   jh_compilefeatures
+  jh_exec
   jh_generateorbitdir
   jh_installeclipse
   jh_installjavadoc
-- 
2.16.3

>From c4f938684b0c3eaa6f0ead49b9738359bfb199a8 Mon Sep 17 00:00:00 2001
From: Niels Thykier <ni...@thykier.net>
Date: Sat, 7 Apr 2018 16:44:05 +0000
Subject: [PATCH 5/6] Rewrite jh_installibs using Debhelper's Dh_Lib

Signed-off-by: Niels Thykier <ni...@thykier.net>
---
 debian/javahelper.manpages |   1 -
 debian/rules               |   1 +
 jh_installlibs             | 268 ++++++++++++++++++++++++++-------------------
 jh_installlibs.1           |  31 ------
 t/strict.t                 |   1 +
 5 files changed, 156 insertions(+), 146 deletions(-)
 delete mode 100644 jh_installlibs.1

diff --git a/debian/javahelper.manpages b/debian/javahelper.manpages
index 6911449..0f7425e 100644
--- a/debian/javahelper.manpages
+++ b/debian/javahelper.manpages
@@ -1,6 +1,5 @@
 jh_build.1
 jh_depends.1
-jh_installlibs.1
 jh_linkjars.1
 jh_makepkg.1
 jh_repack.1
diff --git a/debian/rules b/debian/rules
index 9cf5bf3..e056833 100755
--- a/debian/rules
+++ b/debian/rules
@@ -23,6 +23,7 @@ override_dh_auto_build: jh_lib.sh
 	$(POD2MAN) jh_manifest tmp/jh_manifest.1
 	$(POD2MAN) jh_classpath tmp/jh_classpath.1
 	$(POD2MAN) jh_installjavadoc tmp/jh_installjavadoc.1
+	$(POD2MAN) jh_installlibs tmp/jh_installlibs.1
 	$(POD2MAN) fetch-eclipse-source.pod tmp/fetch-eclipse-source.1
 	$(POD2MAN) -s 1 jh_clean.pod tmp/jh_clean.1
 	$(POD2MAN) $(MOD_PATH)/Eclipse.pm tmp/Debian::Javahelper::Eclipse.3
diff --git a/jh_installlibs b/jh_installlibs
index d8ce242..30679a9 100755
--- a/jh_installlibs
+++ b/jh_installlibs
@@ -1,119 +1,159 @@
-#!/bin/bash --
-
-set -e
-
-. /usr/share/javahelper/jh_lib.sh
-
-syntax()
-{
-   echo -e "Usage: jh_installlibs [options] [jars]"
-   echo -e "Options:"
-   echo -e "\t-h --help: show this text"
-   echo -e "\t-V --version: show the version"
-   echo -e "\t-i --indep: act on all Arch: all packages"
-   echo -e "\t-a --arch: act on all Arch-specific packages"
-   echo -e "\t-s --same-arch: alias of --arch for compatibility with debhelper"
-   echo -e "\t-p<package> --package=<package>: package to act on (default=all)"
-   echo -e "\t-P<packagedir> --tmpdir=<package>: package directory (default=\$CWD/debian/package)"
-   echo -e "\t-v --verbose: show more information while running"
-   echo -e "\t-n --no-act: don't actually do anything, just print the results"
-   echo -e "\t--no-mangle: don't try and sanitize the upstream version number"
-   echo -e "\t--upstream-version=<version>: manually set the upstream version"
-   echo -e "\t--version-strip=<regex>: manually supply the regex to remove from the upstream version number"
-   exit 1
+#!/usr/bin/perl
+
+=head1 NAME
+
+jh_installlibs - installs jar files in usr/share/java of a package
+
+=cut
+
+use strict;
+use warnings;
+use Debian::Debhelper::Dh_Lib;
+
+=head1 SYNOPSIS
+
+B<jh_installlibs> [S<I<debhelper options>>]
+
+B<jh_installlibs> [S<I<debhelper options>>] [B<-p>I<package>] [B<--classpath=>I<cp>] [S<I<jar [...]>>]
+
+=head1 DESCRIPTION
+
+For library packages Debian Java policy currently requires that the
+libraries be installed to /usr/share/java in a versioned format and
+with an unversioned symlink. B<jh_installlibs> will take a jar and
+correctly install it.
+
+As with debhelper programs, this can either take a jar as a parameter,
+or read a list of jars from a file in the Debian directory. It also
+follows the -p, -i and -a semantics of debhelper for selecting which
+packages to install the jar to. When operating on a package,
+B<jh_installlibs> will read the list of library jars from
+F<debian/I<package>.jlibs> or F<debian/jlibs>.
+
+The F<jlibs> file is a list of jars to install, one per line, and works
+exactly the same as listing them on the command line. Each jar is
+installed to debian/I<package>/usr/share/java/ in the appropriate
+versioned and unversioned forms.
+
+If the jars built by upstream already contain the version number, this
+will be stripped before installing. B<jh_installlibs> will also try to
+strip the upstream version number of any ds or dfsg suffix. Other
+version-mangling options or explicit version numbers can also be
+provided.
+
+=head1 FILES
+
+=over 4
+
+=item F<debian/I<package>.jlibs>, F<debian/jlibs>
+
+The F<jlibs> file is a list of jars to install, one per line, and works
+exactly the same as listing them on the command line. Each jar is
+installed to debian/I<package>/usr/share/java/ in the appropriate
+versioned and unversioned forms.
+
+Note that unlike most other debhelper commands,
+B<jh_installlibs> will use F<debian/jlibs> as a fallback
+configuration file for I<all> packages that it acts on.  Other
+debhelper commands usually only apply this fallback to the
+"main package".
+
+=back
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<--no-mangle>
+
+Do not try to sanitize the upstream version number.
+
+=item B<--upstream-version=>I<version>
+
+Use I<version> as the upstream version.  This option implies B<--no-mangle>
+
+=item B<--version-strip=>I<regex>
+
+Use I<regex> instead of the built-in rules for sanitizing the upstream
+version number.
+
+This option is ignored when B<--no-mangle> is passed (or implied by another
+option).
+
+=back
+
+Beyond the above, B<jh_classpath> also accepts the shared
+debhelper options documented in L<debhelper(7)>.
+
+=cut
+
+my ($UPSTREAM_VERSION, $NO_MANGLE);
+# Strip ds and dfsg in various forms by default.
+my $VERSION_STRIP = '[\.+~-]ds(?:fg)?[0-9]*$';
+init(options => {
+    'upstream-version=s' => \$UPSTREAM_VERSION,
+    'no-mangle'          => \$NO_MANGLE,
+    'version-strip=s'    => \$VERSION_STRIP,
+});
+
+# Explicitly defined upstream version
+if (defined($UPSTREAM_VERSION)) {
+    $NO_MANGLE = 1;
+} else {
+    # For the side effect of setting $dh{VERSION}
+    isnative($dh{MAINPACKAGE});
+    my $full_version = $dh{'VERSION'};
+    # Strip epoch
+    $full_version =~ s/^\d+://;
+    # Strip debian revision
+    $full_version =~ s/-[^-]+$//;
+    if (not $NO_MANGLE) {
+        $full_version =~ s/$VERSION_STRIP//;
+    }
+    $UPSTREAM_VERSION = $full_version;
 }
 
-ARGS="i indep a arch s same-arch p package P tmpdir v verbose n no-act no-mangle upstream-version version-strip" parseargs "$@"
-
-dh_testdir
-
-FULL_VERSION="`dpkg-parsechangelog  | sed -n '/^Version:/s/^[^:]*: \(.*\)$/\1/p'`"
-VERSION="`echo "$FULL_VERSION" | sed -n 's/\(.*:\)\?\([^-]*\)\(-.*\)\?/\2/p' `"
-VERBOSE="`getarg v verbose`"
-DEFAULT_VERSION_MANGLE=".dfsg[0-9]*$"
-
-function processjar()
-{
-	p="$1"
-	j="$2"
-	from="$j"
-	to="`basename "$j"`"
-
-	if [ -n "`getarg upstream-version`" ]; then
-		VERSION="`getarg upstream-version`"
-	elif [ -n "`getarg no-mangle`" ]; then
-		true
-	elif [ -n "`getarg version-strip`" ]; then
-		VERSION="$(sed "s/`getarg version-strip`//" <<< $VERSION )"
-	else
-		VERSION="$(sed "s/$DEFAULT_VERSION_MANGLE//" <<< $VERSION )"
-	fi
-
-	if [ "$to" != "${to%-${VERSION}.jar}" ]; then
-		to="${to%-${VERSION}.jar}.jar"
-	fi
-
-	if [ -n "`getarg n no-act`" ]; then
-	        echo mkdir -p "$PACKAGEDIR/usr/share/java"
-		echo install -m 644 "$from" "$PACKAGEDIR/usr/share/java/${to%.jar}-${VERSION}.jar"
-		echo ln -sf ${to%.jar}-${VERSION}.jar "$PACKAGEDIR/usr/share/java/$to"
-	else
-		if [ -n "$VERBOSE" ]; then
-			echo "Installing library $j into package $p"
-		fi
-		mkdir -p "$PACKAGEDIR/usr/share/java"
-		install -m 644 "$from" "$PACKAGEDIR/usr/share/java/${to%.jar}-${VERSION}.jar"
-		ln -sf ${to%.jar}-${VERSION}.jar "$PACKAGEDIR/usr/share/java/$to"
-	fi
+sub process_jars {
+    my ($tmpdir, @jars) = @_;
+    for my $jar (@jars) {
+        my $basename = basename($jar);
+
+        $basename =~ s/[.]jar$//;
+
+        install_dir("${tmpdir}/usr/share/java");
+        install_file($jar, "${tmpdir}/usr/share/java/${basename}-${UPSTREAM_VERSION}.jar");
+        make_symlink_raw_target("${basename}-${UPSTREAM_VERSION}.jar", "${tmpdir}/usr/share/java/${basename}.jar");
+    }
+}
+
+if (@ARGV) {
+    my $tmpdir = tmpdir($dh{FIRSTPACKAGE});
+    process_jars($tmpdir, @ARGV);
+    exit(0);
+}
+
+# read debian/$package.jlibs
+foreach my $package (@{$dh{DOPACKAGES}}) {
+    my $pkgfile = pkgfile($package, 'jlibs');
+    if (not $pkgfile and -f 'debian/jlibs') {
+        $pkgfile = 'debian/jlibs';
+    }
+    next if not $pkgfile;
+    my @jars = filearray($pkgfile);
+    my $tmpdir = tmpdir($package);
+    process_jars($tmpdir, @jars);
 }
 
-if [ "$ARGC" != "0" ] ; then
-
-   p="`firstpackage`"
-   PACKAGEDIR="`getarg P tmpdir`"
-   if [ -z "$PACKAGEDIR" ]; then
-      PACKAGEDIR="`pwd`/debian/$p"
-   else
-      PACKAGEDIR=`readlink -f $PACKAGEDIR`
-   fi
-
-   for (( i=0; i < $ARGC; i++ )); do
-      j=${ARGV[i]}
-		processjar "$p" "$j"
-   done
-   exit 0
-fi
-
-for p in `findpackages`; do
-
-   PACKAGEDIR="`getarg P tmpdir`"
-   if [ -z "$PACKAGEDIR" ]; then
-      PACKAGEDIR="`pwd`/debian/$p"
-   else
-      PACKAGEDIR=`readlink -f $PACKAGEDIR`
-   fi
-
-   if [ -n "$VERBOSE" ]; then
-      echo "Searching $PACKAGEDIR for $p"
-   fi
-
-   FILE=
-   if [ -f debian/$p.jlibs ]; then
-      FILE=debian/$p.jlibs
-   elif [ -f debian/jlibs ]; then
-      FILE=debian/jlibs
-   else
-      continue
-   fi
-
-   IFS='
-'
-   for i in `cat "$FILE"`; do
-		processjar "$p" "$i"
-
-   done
-
-   unset PACKAGEDIR
-
-done
+=head1 SEE ALSO
+
+L<debhelper(7)>
+
+This program is a part of javahelper and uses debhelper as backend. There are
+also tutorials in /usr/share/doc/javahelper.
+
+=head1 AUTHOR
+
+Niels Thykier <ni...@thykier.net>
+
+=cut
 
diff --git a/jh_installlibs.1 b/jh_installlibs.1
deleted file mode 100644
index a61cb9e..0000000
--- a/jh_installlibs.1
+++ /dev/null
@@ -1,31 +0,0 @@
-.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.36.
-.TH JAVAHELPER "1" "January 2008" "Javahelper Version 0.5" "User Commands"
-.SH NAME
-Javahelper \- Part of the Java Helper packaging tools
-Refer to the tutorials in /usr/share/doc/javahelper for more detail
-.SH SYNOPSIS
-.B jh_installlibs
-[\fIoptions\fR] [\fIjars\fR]
-.SH OPTIONS
-.HP
-\fB\-h\fR \fB\-\-help\fR: show this text
-.HP
-\fB\-V\fR \fB\-\-version\fR: show the version
-.HP
-\fB\-i\fR \fB\-\-indep\fR: act on all Arch: all packages
-.HP
-\fB\-a\fR \fB\-\-arch\fR: act on all Arch\-specific packages
-.HP
-\fB\-p\fR<package> \fB\-\-package=\fR<package>: package to act on (default=all)
-.HP
-\fB\-P\fR<packagedir> \fB\-\-tmpdir=\fR<package>: package directory (default=$CWD/debian/package)
-.HP
-\fB\-v\fR \fB\-\-verbose\fR: show more information while running
-.HP
-\fB\-n\fR \fB\-\-no\-act\fR: don't actually do anything, just print the results
-.HP
-\fB\-\-no\-mangle\fR: don't try and sanitize the upstream version number
-.HP
-\fB\-\-upstream\-version=\fR<version>: manually set the upstream version
-.HP
-\fB\-\-version\-strip=\fR<regex>: manually supply the regex to remove from the upstream version number
diff --git a/t/strict.t b/t/strict.t
index bf95e76..ffaee10 100755
--- a/t/strict.t
+++ b/t/strict.t
@@ -13,6 +13,7 @@ my @FILES = qw(
   jh_generateorbitdir
   jh_installeclipse
   jh_installjavadoc
+  jh_installlibs
   jh_manifest
   jh_classpath
   jh_scanjavadoc
-- 
2.16.3

>From f47bd38455fad6edb0fbf5d6906799a2edc8076c Mon Sep 17 00:00:00 2001
From: Niels Thykier <ni...@thykier.net>
Date: Sat, 7 Apr 2018 17:43:17 +0000
Subject: [PATCH 6/6] Rewrite jh_linkjars using Debhelper's Dh_Lib

Signed-off-by: Niels Thykier <ni...@thykier.net>
---
 debian/javahelper.manpages |   1 -
 debian/rules               |   1 +
 jh_linkjars                | 271 +++++++++++++++++++++++++++++----------------
 jh_linkjars.1              |  19 ----
 t/strict.t                 |   1 +
 5 files changed, 178 insertions(+), 115 deletions(-)
 delete mode 100644 jh_linkjars.1

diff --git a/debian/javahelper.manpages b/debian/javahelper.manpages
index 0f7425e..ec5a534 100644
--- a/debian/javahelper.manpages
+++ b/debian/javahelper.manpages
@@ -1,6 +1,5 @@
 jh_build.1
 jh_depends.1
-jh_linkjars.1
 jh_makepkg.1
 jh_repack.1
 tmp/*.1
diff --git a/debian/rules b/debian/rules
index e056833..27c9b44 100755
--- a/debian/rules
+++ b/debian/rules
@@ -20,6 +20,7 @@ override_dh_auto_build: jh_lib.sh
 	$(POD2MAN) jh_setupenvironment tmp/jh_setupenvironment.1
 	$(POD2MAN) jh_compilefeatures tmp/jh_compilefeatures.1
 	$(POD2MAN) jh_exec tmp/jh_exec.1
+	$(POD2MAN) jh_linkjars tmp/jh_linkjars.1
 	$(POD2MAN) jh_manifest tmp/jh_manifest.1
 	$(POD2MAN) jh_classpath tmp/jh_classpath.1
 	$(POD2MAN) jh_installjavadoc tmp/jh_installjavadoc.1
diff --git a/jh_linkjars b/jh_linkjars
index b8e54a4..7f122bf 100755
--- a/jh_linkjars
+++ b/jh_linkjars
@@ -1,103 +1,184 @@
-#!/bin/bash --
-
-set -e
-
-. /usr/share/javahelper/jh_lib.sh
-
-syntax()
-{
-   echo -e "Usage: jh_linkjars [options] [target]"
-   echo -e "Options:"
-   echo -e "\t-h --help: show this text"
-   echo -e "\t-V --version: show the version"
-   echo -e "\t-v --verbose: show more information while running"
-	echo -e "\t-t --transitive: transitively link jars"
-   echo -e "\t-n --no-act: don't actually do anything, just print the results"
-   echo -e "\t-u --unlink: remove the links instead of adding them"
-   exit 1
+#!/usr/bin/perl
+
+=head1 NAME
+
+jh_linkjars - populate folders with symlinks to jar files
+
+=cut
+
+use strict;
+use warnings;
+use Debian::Debhelper::Dh_Lib;
+
+=head1 SYNOPSIS
+
+B<jh_classpath> [S<I<debhelper options>>]
+
+B<jh_classpath> [S<I<debhelper options>>] [B<-p>I<package>] [B<--classpath=>I<cp>] [S<I<jar [...]>>]
+
+=head1 DESCRIPTION
+
+If upstream ship convenience copies of third-party jar files which
+have been removed (see L<jh_repack(1)>), but the build system refers
+to that directory, B<jh_linkjars> can be used to populate the directory
+with symlinks to the packaged jars in /usr/share/java.
+
+It is called either with a directory on the command line or by
+specifying one target directory per line in the file debian/linkjars.
+
+B<jh_linkjars> will scan all of the (installed) build-dependencies and
+create a symlink to every jar which is installed by those packages in
+the target directory.
+
+B<jh_linkjars> can be called with -u to remove all the symlinks in the
+clean target.  This is done automatically by L<jh_clean(1)>.
+
+=head1 FILES
+
+=over 4
+
+=item F<debian/linkjars>
+
+List of directories to populate; one directory per line.
+
+=back
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-t>, B<--transitive>
+
+Transitively link jar files (i.e. also include indirect dependencies in the target directory).
+
+=item B<-u>, B<--unlink>
+
+Remove all files/links in the target directories that B<jh_linkjars> created
+(or would have created).
+
+=back
+
+Beyond the above, B<jh_classpath> also accepts the shared
+debhelper options documented in L<debhelper(7)>.
+
+=cut
+
+my ($UNLINK_JARS, $TRANSITIVE, @TARGET_DIRS, @JARS);
+
+init(options => {
+    'transitive|t' => \$TRANSITIVE,
+    'unlink|u'     => \$UNLINK_JARS,
+});
+
+sub parse_deps_fields {
+    my ($field) = @_;
+    my @packages;
+    $field =~ s/^\s++//;
+    $field =~ s/\s++$//;
+    for my $clause (split(m/\s*+[,|]\s*+/, $field)) {
+        # Drop everything after [, ( or <.
+        $clause =~ s/\s*+[\(\[\<].*$//;
+        push(@packages, $clause);
+    }
+    return @packages;
+}
+
+sub parse_dpkg_L {
+    my ($output) = @_;
+    my @lines;
+    for my $line (split(qr/\n/, $output)) {
+        $line =~ s/\s++$//;
+        if ($line =~ m{^/usr/share/java/.+\.jar$}) {
+            push(@lines, $line);
+        }
+    }
+    return @lines;
 }
 
-ARGS="v verbose n no-act u unlink t transitive" parseargs "$@"
-
-
-function findjars()
-{
-	pkg="$1"
-	if [ -z "$pkg" ]; then
-		pkg="$(sed -n '/^Source:/s/.*: //p' < debian/control)"
-		BDS=$(grep-dctrl --no-field-names --show-field Build-Depends,Build-Depends-Indep -F source "$pkg" debian/control | tr , ' ' | sed 's/([^)]*)//g')
-	else
-		BDS=$(dpkg -s "$pkg" | sed -n 's/([^)]*)//g;s/,/ /g;/^Depends:/s/.*: //p')
-	fi
-
-	JARS=""
-	for d in $BDS; do
-		j="$(dpkg -L $d | grep "^/usr/share/java/.*\.jar$")"
-		k=""
-		if [ -n "$j" ] &&  [ `getarg t transitive` ]; then
-			k=$(findjars "$d")
-		fi
-		JARS="$JARS $j $k"
-	done
-	echo $JARS
+sub find_jars {
+    my $source = sourcepackage();
+    my $bd = `grep-dctrl --no-field-names --show-field Build-Depends,Build-Depends-Indep -F source "${source}" debian/control`;
+    error_exitcode("grep-dctrl --no-field-names --show-field Build-Depends,Build-Depends-Indep -F source \"${source}\" debian/control")
+        if $?;
+    my @packages = parse_deps_fields($bd);
+    my %seen = map { $_ => 1 } @packages;
+    my @all_jars;
+    while (@packages) {
+        my $pkg = pop(@packages);
+        my $dpkg_output = `dpkg -L "$pkg"`;
+        error_exitcode("dpkg -L \"$pkg\"") if $?;
+        my @jars = parse_dpkg_L($dpkg_output);
+        push(@all_jars, @jars);
+        if (@jars and $TRANSITIVE) {
+            my $raw_deps = `dpkg -s "$pkg" | sed -n '/^Depends:/s/.*: //p'`;
+            error_exitcode("dpkg -s \"$pkg\" | sed -n '/^Depends:/s/.*: //p'") if $?;
+            my @deps = grep { not exists($seen{$_}) } parse_deps_fields($raw_deps);
+            $seen{$_} = 1 for @deps;
+            push(@packages, @deps);
+        }
+    }
+    return @all_jars;
 }
 
-function unlinkjars()
-{
-	target="$1"
-	JARS="`findjars`"
-
-	for j in $JARS; do
-		if [ -n "`getarg n no-act`" ]; then
-			echo rm -f "$target/`basename "$j"`"
-			continue
-		fi
-		if [ -n "`getarg v verbose`" ]; then
-			echo Removing link for $j from $target
-		fi
-		rm -f "$target/`basename "$j"`"
-	done
+#function findjars()
+#{
+#	pkg="$1"
+#	if [ -z "$pkg" ]; then
+#		pkg="$(sed -n '/^Source:/s/.*: //p' < debian/control)"
+#		BDS=$(grep-dctrl --no-field-names --show-field Build-Depends,Build-Depends-Indep -F source "$pkg" debian/control | tr , ' ' | sed 's/([^)]*)//g')
+#	else
+#		BDS=$(dpkg -s "$pkg" | sed -n 's/([^)]*)//g;s/,/ /g;/^Depends:/s/.*: //p')
+#	fi
+#
+#	JARS=""
+#	for d in $BDS; do
+#		j="$(dpkg -L $d | grep "^/usr/share/java/.*\.jar$")"
+#		k=""
+#		if [ -n "$j" ] &&  [ `getarg t transitive` ]; then
+#			k=$(findjars "$d")
+#		fi
+#		JARS="$JARS $j $k"
+#	done
+#	echo $JARS
+#}
+
+if (@ARGV) {
+    @TARGET_DIRS = $ARGV[0];
+} elsif ( -f 'debian/linkjars') {
+    @TARGET_DIRS = filearray('debian/linkjars');
 }
-function linkjars()
-{
-	target="$1"
-	JARS="`findjars`"
-
-	if [ -z "`getarg n no-act`" ]; then
-		mkdir -p "$target"
-	fi
-	
-	for j in $JARS; do
-		if [ -f "$j" ]; then
-			if [ -n "`getarg n no-act`" ]; then
-				echo ln -sf "$j" "$target/"
-				continue
-			fi
-			if [ -n "`getarg v verbose`" ]; then
-				echo Adding link for $j to $target
-			fi
-			ln -sf "$j" "$target/"
-		fi
-	done
+
+# Stop here if there is nothing to do.
+exit(0) if not @TARGET_DIRS;
+
+@JARS = find_jars();
+
+if ($UNLINK_JARS) {
+    my @basenames = map { basename($_) } @JARS;
+    for my $target_dir (@TARGET_DIRS) {
+        rm_files(map {"${target_dir}/$_"} @basenames);
+    }
+} else {
+    doit('mkdir', '-p', @TARGET_DIRS);
+    for my $target_dir (@TARGET_DIRS) {
+        for my $jar (@JARS) {
+            my $basename = basename($jar);
+            verbose_print("Adding link for $jar to ${target_dir}");
+            make_symlink_raw_target($jar, "${target_dir}/${basename}");
+        }
+    }
 }
 
-dh_testdir
-
-if [ "$ARGC" != "0" ] ; then
-
-	target="${ARGV[0]}"
-	if [ -n "`getarg u unlink`" ]; then
-		unlinkjars "$target"
-	else
-		linkjars "$target"
-	fi
-elif [ -f debian/linkjars ]; then
-	for target in `cat debian/linkjars`; do
-		if [ -n "`getarg u unlink`" ]; then
-			unlinkjars "$target"
-		else
-			linkjars "$target"
-		fi
-	done
-fi
 
+=head1 SEE ALSO
+
+L<debhelper(7)>
+
+This program is a part of javahelper and uses debhelper as backend. There are
+also tutorials in /usr/share/doc/javahelper.
+
+=head1 AUTHOR
+
+Niels Thykier <ni...@thykier.net>
+
+=cut
diff --git a/jh_linkjars.1 b/jh_linkjars.1
deleted file mode 100644
index ead88c5..0000000
--- a/jh_linkjars.1
+++ /dev/null
@@ -1,19 +0,0 @@
-.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.36.
-.TH JAVAHELPER "1" "January 2008" "Javahelper Version 0.5" "User Commands"
-.SH NAME
-Javahelper \- Part of the Java Helper packaging tools
-Refer to the tutorials in /usr/share/doc/javahelper for more detail
-.SH SYNOPSIS
-.B jh_installlibs
-[\fIoptions\fR] [\fIjars\fR]
-.SH OPTIONS
-.HP
-\fB\-h\fR \fB\-\-help\fR: show this text
-.HP
-\fB\-V\fR \fB\-\-version\fR: show the version
-.HP
-\fB\-v\fR \fB\-\-verbose\fR: show more information while running
-.HP
-\fB\-n\fR \fB\-\-no\-act\fR: don't actually do anything, just print the results
-.HP
-\fB\-u\fR \fB\-\-unlink\fR: Remove the links rather than adding them
diff --git a/t/strict.t b/t/strict.t
index ffaee10..64fd4b3 100755
--- a/t/strict.t
+++ b/t/strict.t
@@ -14,6 +14,7 @@ my @FILES = qw(
   jh_installeclipse
   jh_installjavadoc
   jh_installlibs
+  jh_linkjars
   jh_manifest
   jh_classpath
   jh_scanjavadoc
-- 
2.16.3

__
This is the maintainer address of Debian's Java team
<http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-java-maintainers>. 
Please use
debian-j...@lists.debian.org for discussions and questions.

Reply via email to