Hi folks,

The wiki page at http://wiki.debian.org/Java/MavenBuilder mentions that
supporting dh(1) is on the todo list.  As getting rid of cdbs interests me,
I took a stab at implementing this.  The result is attached.

With this on the system, a maven-using package can have a dh(1) debian/rules
that looks like this (taken from activemq):

#!/usr/bin/make -f

%:
        dh $@ --buildsystem=maven

override_dh_auto_build:
        dh_auto_build -- install

override_dh_install:
        dh_install
        chmod 644 
debian/activemq/etc/activemq/instances-available/main/log4j.properties
        chmod 644 
debian/activemq/usr/share/doc/activemq/examples/conf/log4j.properties
        chmod 644 debian/activemq/usr/share/activemq/README.txt

get-orig-source:
        uscan --download-version $(DEB_UPSTREAM_VERSION) --force-download 
--rename


There are a few things that I feel are still moderately un-dh-like about
this system, however, and I wonder if anyone here has ideas about how to
improve it.

 - dh_auto_test isn't usable with this build system, because there is
   evidently no standard 'check' target.  Is there some way that the
   existence of a suitable target could be detected at build time?  (As a
   fallback, we could make dh_auto_test a no-op except when overridden and
   an extra argument has been passed for the target.)

 - Likewise, the only target supported by the build system is 'package', and
   if the build system uses another, this must be passed as an argument to
   dh_auto_build (see above).  Torsten assures me that 'package' is the
   standard target and everything else is non-standard, but in my
   unscientific examination of packages so far, 'install' seems to be a
   fairly common alternative.

 - Extending the classpath for maven is done using a DEB_JARS envvar.  This
   is rather un-dh; it also has weird semantics (inherited from the cdbs
   class) in that it takes jar names in various formats and tries to search
   the system for them.  At the very least, the variable name should
   probably be changed for dh; DEB_ as a prefix for variables defined within
   debian/rules is a cdbs-ism.  Would MAVEN_JARS be ok here?

 - The double invocation of classworlds.jar, once for the main package and
   once for the docs package, is a bit awkward, and feeds into some of the
   problems above.  For instance, since there's only one invocation of
   dh_auto_build, you can't easily specify extra/alternative arguments that
   you want to have passed for docs building but not for building of the
   main package.  (BTW, does anyone know why the CDBS rules pass
   -Ddebian.package when building docs, but not when building the main
   package?)

 - The build system has to know the names of the binary packages its
   building for.  This is certainly unusual, since dh_auto_build means
   "build the upstream code", dh_auto_install means "install the upstream
   software relative to a target directory", and only dh_install is used to
   split the software into component binary packages.  In this case,
   however, we have to know the name of the binary package we're acting on
   to even call mh_patchpoms.  I don't see any way around this, but the net
   effect is that dh_auto_* always have to be called in such a way that the
   main java package is the first package it's acting on - either by being
   listed first in debian/control, or by being passed as a -p option.

 - Above all, this build system does *not* degrade gracefully.  Degrading
   gracefully is one of the most important design criteria of dh(1); if
   dh_auto_build doesn't do what a package needs, that's not supposed to be
   a problem, just override it and call the upstream target by hand.  But
   with maven-debian-helper, that's difficult to do:  far from just being
   able to call 'make', we have to call 'java -noverify -cp [...]
   -Dclasswords.conf= [...]'.  I think it would be a very good idea to
   encapsulate this commandline in some sort of standard wrapper, which
   could then be invoked both by dh_auto_build and by a package's override
   rule when needed.  Something like the 'mvn-debian' command - except that
   mvn-debian is explicitly marked as "not supported" by the maintainers...
   :)  Is that something that could be changed?

I look forward to hearing your thoughts on these questions!

-- 
Steve Langasek                   Give me a lever long enough and a Free OS
Debian Developer                   to set it on, and I can move the world.
Ubuntu Developer                                    http://www.debian.org/
slanga...@ubuntu.com                                     vor...@debian.org
diff -Nru maven-debian-helper-1.4.3/debian/changelog maven-debian-helper-1.4.3+nmu1/debian/changelog
--- maven-debian-helper-1.4.3/debian/changelog	2011-06-09 00:11:15.000000000 +0200
+++ maven-debian-helper-1.4.3+nmu1/debian/changelog	2012-01-02 02:59:35.000000000 +0100
@@ -1,3 +1,9 @@
+maven-debian-helper (1.4.3+nmu1) UNRELEASED; urgency=low
+
+  * debian/maven.pm: port share/cdbs/1/class/maven.mk to dh.
+
+ -- Steve Langasek <vor...@debian.org>  Wed, 17 Aug 2011 15:09:39 -0700
+
 maven-debian-helper (1.4.3) unstable; urgency=low
 
   * DependenciesSolver: Don't use Properties.store() method since
diff -Nru maven-debian-helper-1.4.3/debian/install maven-debian-helper-1.4.3+nmu1/debian/install
--- maven-debian-helper-1.4.3/debian/install	2010-07-26 13:56:06.000000000 +0200
+++ maven-debian-helper-1.4.3+nmu1/debian/install	2012-01-02 03:08:07.000000000 +0100
@@ -4,3 +4,4 @@
 etc/*.xml			/etc/maven2/
 share/cdbs/1/class/*.mk		/usr/share/cdbs/1/class
 share/maven-debian-helper/*.sh	/usr/share/maven-debian-helper
+usr/share/perl5
diff -Nru maven-debian-helper-1.4.3/debian/maven.pm maven-debian-helper-1.4.3+nmu1/debian/maven.pm
--- maven-debian-helper-1.4.3/debian/maven.pm	1970-01-01 01:00:00.000000000 +0100
+++ maven-debian-helper-1.4.3+nmu1/debian/maven.pm	2012-01-02 23:53:50.000000000 +0100
@@ -0,0 +1,156 @@
+# A debhelper build system class for handling Maven-based projects.
+#
+# Copyright: 2011 Canonical Ltd.
+# License: GPL-3
+
+package Debian::Debhelper::Buildsystem::maven;
+
+use strict;
+use base 'Debian::Debhelper::Buildsystem';
+use Debian::Debhelper::Dh_Lib qw(%dh doit);
+
+sub DESCRIPTION {
+	"Maven (pom.xml)"
+}
+
+sub check_auto_buildable {
+	my $this=shift;
+	return (-e $this->get_sourcepath("pom.xml")) ? 1 : 0;
+}
+
+sub new {
+	my $class=shift;
+	my $this=$class->SUPER::new(@_);
+	my $java_home = (exists $ENV{JAVA_HOME}) ? $ENV{JAVA_HOME} : '/usr/lib/jvm/default-java';
+
+	my @packages = @{$dh{DOPACKAGES}};
+	$this->{package} = shift @packages;
+	$this->{doc_package} = (grep /-doc$/, @packages)[0];
+	my $classconf = '/etc/maven2/m2-debian.conf';
+	if (!$this->{doc_package}) {
+		$classconf = '/etc/maven2/m2-debian-nodocs.conf';
+	}
+
+	my @classpath = ('/usr/share/maven2/boot/classworlds.jar');
+	# FIXME: we don't want to do this via an env variable, but via a build
+	# system argument, I think?  Pull out -cp $foo from @_ and jam it in.
+	foreach my $jar (split $ENV{DEB_JARS}) {
+		if (-e $jar) {
+			push(@classpath,$jar);
+		} elsif (-e "$jar.jar") {
+			push(@classpath,"$jar.jar");
+		} elsif (-e "/usr/share/java/$jar") {
+			push(@classpath,"/usr/share/java/$jar");
+		} elsif (-e "/usr/share/java/$jar.jar") {
+			push(@classpath,"/usr/share/java/$jar.jar");
+		}
+	}
+	# This classpath order doesn't make much sense to me, but it's
+	# inherited from the cdbs rules.
+	if (-e "$java_home/lib/tools.jar") {
+		push(@classpath, "$java_home/lib/tools.jar");
+	}
+
+	@{$this->{maven_cmd}} = ($java_home . '/bin/java',
+		'-noverify', '-cp', join(':',@classpath),
+		"-Dclassworlds.conf=$classconf",
+		"org.codehaus.classworlds.Launcher",
+		"-s/etc/maven2/settings-debian.xml",
+		"-Dmaven.repo.local=$this->{cwd}/debian/maven-repo");
+	if (-e "$this->{cwd}/debian/maven.properties") {
+		push (@{$this->{maven_cmd}}, "-Dproperties.file.manual=$this->{cwd}/debian/maven.properties");
+	}
+	return $this;
+}
+
+sub configure {
+	my $this=shift;
+	my @patch_args;
+	if (! $this->{doc_package}) {
+		push(@patch_args, "--build-no-docs");
+	}
+
+	doit("/usr/share/maven-debian-helper/copy-repo.sh", "$this->{cwd}/debian");
+	$this->doit_in_sourcedir("mh_patchpoms", "-p$this->{package}",
+		"--debian-build", "--keep-pom-version",
+		"--maven-repo=$this->{cwd}/debian/maven-repo", @patch_args);
+}
+
+sub build {
+ 	my $this=shift;
+
+	if (!@_) {
+		push(@_, "package");
+	}
+
+	# FIXME: how can we support alternate targets?
+	# Do we need to support installing to a package other than the 
+	# first one? or does that matter at all for the build target?
+	$this->doit_in_builddir(@{$this->{maven_cmd}}, @_);
+	if ($this->{doc_package})
+	{
+		$this->doit_in_builddir(@{$this->{maven_cmd}},
+			"-Ddebian.dir=$this->{cwd}/debian",
+			"-Ddebian.package=$this->{doc_package}", "javadoc:jar",
+			"javadoc:aggregate");
+	}
+}
+
+sub install {
+	my $this=shift;
+	my @resolvedep_args;
+
+	opendir(my $dirhandle, "/usr/share/maven-repo/org/debian/maven/maven-packager-utils/")
+		|| die "maven debian helper not found";
+	my $maven_debian_version = (grep { !/^\./ } readdir($dirhandle))[0];
+	closedir $dirhandle;
+
+	if ($this->{doc_package}) {
+		push(@resolvedep_args, "--javadoc");
+	}
+
+	$this->doit_in_builddir(@{$this->{maven_cmd}},
+		"-Ddebian.dir=$this->{cwd}/debian",
+		"-Ddebian.package=$this->{package}",
+		"-Dinstall.to.usj=true",
+		"org.debian.maven:maven-debian-plugin:$maven_debian_version:install");
+	$this->doit_in_builddir("mh_resolve_dependencies", "--non-interactive",
+		"--offline", "-p$this->{package}", @resolvedep_args);
+	if ($this->{doc_package}) {
+		$this->doit_in_builddir(@{$this->{maven_cmd}},
+			"-Ddebian.dir=$this->{cwd}/debian",
+			"-Ddebian.package=$this->{doc_package}",
+			"org.debian.maven:maven-debian-plugin:$maven_debian_version:install-doc");
+		doit("cp","debian/$this->{package}.substvars",
+			"debian/$this->{doc_package}.substvars");
+		# clean up generated docs
+		$this->doit_in_builddir("rm", "-f", "target/apidocs/*.sh",
+			"target/apidocs/options");
+	}
+}
+
+sub clean {
+	my $this=shift;
+
+	# If this directory if absent, we must not have anything to clean;
+	# don't populate the directory just to run a clean target.
+	if (-e "$this->{cwd}/debian/maven-repo")
+	{
+		$this->doit_in_builddir(@{$this->{maven_cmd}}, "clean");
+		doit("rm", "-r", "$this->{cwd}/debian/maven-repo");
+	}
+	$this->doit_in_sourcedir("mh_unpatchpoms", "-p$this->{package}");
+	doit("mh_clean");
+}
+
+# FIXME: no standard check target to use here?
+#sub test {
+#	my $this=shift;
+#	$this->doit_in_builddir(@{$this->{maven_cmd}},
+#		"-Ddebian.dir=$this->{cwd}/debian",
+#		"-Ddebian.package=$this->{package}",
+#		"-Dinstall.to.usj=true",
+#		??);
+#}
+
+1
diff -Nru maven-debian-helper-1.4.3/debian/rules maven-debian-helper-1.4.3+nmu1/debian/rules
--- maven-debian-helper-1.4.3/debian/rules	2010-12-05 18:23:07.000000000 +0100
+++ maven-debian-helper-1.4.3+nmu1/debian/rules	2012-01-02 02:58:22.000000000 +0100
@@ -47,6 +47,7 @@
 	  -r maven-debian-helper-$(DEB_UPSTREAM_VERSION) \
 	  man/mvn-debian.pod > man/mvn-debian.1
 	dh_installman $(MAN_PAGES) man/mvn-debian.1
+	install -D debian/maven.pm debian/tmp/$$(perl -MConfig -e 'print $$Config{vendorlib}')/Debian/Debhelper/Buildsystem/maven.pm
 
 clean::
 	-$(RM) man/mvn-debian.1

Attachment: signature.asc
Description: Digital signature

__
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