I've reviewed (and rather extensively modified, see attached diff) this
patch. I have the following concerns for including this into debhelper:

- The script is too long and complex. It will be a maintenance burden.

- Why should dh_ocaml automatically add dependencies from -dev packages
  to library packages? This is not automatically done for regular C
  libraries and is a cause of complexity.

- I don't understand the other automatic dependencies listed in the man
  page either. Most of them seem unneccessary to be handled by
  debhelper.

- "(please note that the substvar for libXXX-ocaml will be
  filled while processing libXXX-ocaml-dev)" 

  This indictes that dh_ocaml is broken, the -p, -N, etc switches cannot
  relibably be used to make it operate on a single package at a time.
  This is a requirement for debhelper programs.

- The -l syntax is too complex to be allowed in debhelper both due to
  high learning curve because of all the complexity it adds to the code.
  This is what we have control files with individul, manually edited
  Depends fields for.

- exit 0 if $dh{NO_ACT};

  This makes --no-act mode useless, which removes an important debhelper
  debugging feature.

-- 
see shy jo
Index: autoscripts/postrm-ocaml
===================================================================
--- autoscripts/postrm-ocaml    (revision 0)
+++ autoscripts/postrm-ocaml    (revision 0)
@@ -0,0 +1,5 @@
+if [ "$1" = "remove" ]; then
+       if which ocaml-md5sums >/dev/null 2>&1; then
+               ocaml-md5sums update
+       fi
+fi
Index: autoscripts/postinst-ocaml
===================================================================
--- autoscripts/postinst-ocaml  (revision 0)
+++ autoscripts/postinst-ocaml  (revision 0)
@@ -0,0 +1,3 @@
+if [ "$1" = "configure" ]; then
+       ocaml-md5sums update
+fi
Index: debian/changelog
===================================================================
--- debian/changelog    (revision 1803)
+++ debian/changelog    (working copy)
@@ -1,3 +1,11 @@
+debhelper (4.9.16) UNRELEASED; urgency=low
+
+  * Add dh_ocaml. Closes: #328422
+  * Remove all unnecessry hardcoded paths in ocaml stuff.
+  * Reindent dh_ocaml to match rest of debhelper.
+
+ -- Joey Hess <[EMAIL PROTECTED]>  Thu, 27 Oct 2005 13:03:25 -0400
+
 debhelper (4.9.15) unstable; urgency=low
 
   * Patches from Ghe Rivero to fix outdated paths in French and Spanish
Index: debian/copyright
===================================================================
--- debian/copyright    (revision 1798)
+++ debian/copyright    (working copy)
@@ -9,7 +9,8 @@
 dh_scrollkeeper is by Ross Burton <[EMAIL PROTECTED]>.
 dh_usrlocal is by Andrew Stribblehill <[EMAIL PROTECTED]>.
 dh_installlogcheck is by Jon Middleton <[EMAIL PROTECTED]>.
-dh_scrollkeeper is by Ross Burton <[EMAIL PROTECTED]>
+dh_scrollkeeper is by Ross Burton <[EMAIL PROTECTED]>.
+dh_ocaml is by Stefano Zacchiroli <[EMAIL PROTECTED]>.
 
 Some of the dh_md5sums command is from a program by Charles
 Briscoe-Smith <[EMAIL PROTECTED]>.
Index: dh_ocaml
===================================================================
--- dh_ocaml    (revision 0)
+++ dh_ocaml    (revision 0)
@@ -0,0 +1,296 @@
+ #!/usr/bin/perl -w
+# TODO ask joeyh for a O_PARAMS and s/M_PARAMS/O_PARAMS/
+
+=head1 NAME
+
+dh_ocaml - calculates OCaml packages dependencies
+
+=cut
+
+use strict;
+use Debian::Debhelper::Dh_Lib;
+
+=head1 SYNOPSIS
+
+B<dh_ocaml> [S<I<debhelper options>>]
+
+=head1 DESCRIPTION
+
+dh_ocaml is a debhelper program that is responsible for filling the
+${ocaml:Depends} substitutions and adding them to the substvars files. It
+also adds postinst and postrm scripts for maintaining the system registry
+of OCaml md5sums where required.
+
+dh_ocaml acts on two kinds of binary packages: those shipping the
+development part of OCaml libraries (usually named libXXX-ocaml-dev), and
+those shipping OCaml bytecode non-custom executables (i.e. executables
+interpreted by ocamlrun).
+
+For OCaml library packages dh_ocaml will first look at OCaml objects (files
+matching *.cm[ao]) shipped by the package. Then, dh_ocaml uses ocamlobjinfo on
+them to collect information about OCaml modules (or units, in ocamlobjinfo
+terminology) defined and used by them. Information about defined units will be
+used to automatically create the OCaml md5sums registry entry for your package,
+e.g. /var/lib/ocaml/md5sums/libXXX-ocaml-dev.md5sums. Information about
+imported units will instead be used as keys in the OCaml md5sums registry for
+retrieving dependency information for the package. This information will then
+be used to fill the "${ocaml:Depends}" substvar.
+
+dh_ocaml takes also care of creating postinst and postrm autoscripts which
+update the global system registry (/var/lib/ocaml/md5sums/MD5SUMS) with the
+registry entry shipped by your package.
+
+On non-library packages, dh_ocaml tries to guess the OCaml objects 
corresponding
+to shipped bytecode binaries and extract from them information about imported
+units. Extracted information will then be used for filling "${ocaml:Depends}" 
as
+discussed for the library case.
+
+In addition to dependencies extracted from the system md5sum registry, dh_ocaml
+will add:
+
+=over
+
+=item 1.
+
+A dependency from libXXX-ocaml-dev to libXXX-ocaml (runtime part of the 
library),
+if there is a libXXX-ocaml package in debian/control;
+
+=item 2.
+
+A dependency from libXXX-ocaml-dev to ocaml-findlib if the package ships any 
META
+file in the OCaml library directory;
+
+=item 3.
+
+A dependency from libXXX-ocaml, if any, to the appropriate ocaml-base-* package
+(please note that the substvar for libXXX-ocaml will be filled while processing
+libXXX-ocaml-dev);
+
+=item 4.
+
+dependency on ocaml-base-nox-<ocaml_version> for packages shipping bytecode
+non-custom OCaml executables.
+
+=back
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-m> I<filename>
+
+By default, the list of OCaml objects shipped by your package which should be
+analyzed for retrieving dependency information is guessed by dh_ocaml.
+
+The -m option permit to specify a file which lists, one per line, the OCaml
+objects. They should be in one of the format understandable by ocamlobjinfo
+(*.cma, *.cmi, *.cmo) and are considered relative to the package build
+directory.
+
+=item B<-l> I<dev1:runtime1,dev2:runtime2,...>
+
+The association between the development part of libraries and their runtimes is
+guessed by dh_ocaml according to the OCaml packaging policy. Thus,
+libXXX-ocaml-dev is the name of the package shipping the development part of 
XXX
+library while libXXX-ocaml, if any, is the name of the package shipping the
+corresponding runtime.
+
+Using -l you could override the pairs development package name, runtime package
+name. The value passed to -l admits no spaces and must be a comma separated 
list
+of items. Each item can be a single package name (stating that that name
+corresponds to the development part of a library) or two package names 
separated
+by a colon (stating that the first corresponds to the development part of a
+library, while the second to its accompanying runtime part).
+
+=item B<-d>
+
+By default, a dependency on ocaml-findlib is generated for development
+parts of libraries which ship any META file. Using -d you can disable the
+generation of such dependency (even if this is discouraged and is very
+likely to violate the OCaml packaging policy)
+
+=back
+
+=head1 CONFORMS TO
+
+Debian policy, version 3.6.1.1
+
+OCaml packaging policy, version 0.6
+
+=cut
+
+my $ocaml_lib_dir = `ocamlc -where`;
+chomp $ocaml_lib_dir if defined $ocaml_lib_dir;
+my $ocaml_version = `ocamlc -version`;
+chomp $ocaml_version if defined $ocaml_version;
+if (! defined $ocaml_lib_dir || ! defined $ocaml_version ||
+    $ocaml_lib_dir eq "" || $ocaml_version eq '') {
+       error("OCaml is not installed, aborting. (Probably forgot to 
Build-Depend on ocaml.)");
+}
+
+my $md5dir = "/var/lib/ocaml/md5sums";
+my $md5ext = ".md5sums";
+my $ocaml_magic_line = "#!/usr/bin/ocamlrun";
+
+init();
+
+# find ocaml bytecode executables contained in a given directory
+# (i.e. executables whose first line is #!/usr/bin/ocamlrun)
+sub find_ocaml_bc_binaries {
+       my ($dir) = @_;
+       
+       my @binaries = split /\n/, `find $dir -type f -perm -0100`;
+       my @bc_binaries;
+       foreach my $bin (@binaries) {
+               my $line = `head -1 $bin` or next;
+               chomp $line;
+               push @bc_binaries, $bin if $line eq $ocaml_magic_line;
+       }
+       
+       return @bc_binaries;
+}
+
+# add an entry to the ocaml:Depends substvar, filter out dummy "-" values
+sub add_ocaml_dep {
+       my ($package, $dep, $version) = @_;
+       
+       return if $dep eq "-" or $package eq "";
+       
+       if ($version =~ /-\s*$/) { # ocaml-md5sums returns "-" for "no version"
+               addsubstvar $package, "ocaml:Depends", $dep;
+       }
+       else {
+               addsubstvar $package, "ocaml:Depends", $dep, $version;
+       }
+}
+
+# fill the ocaml:Depends substvar, reading info from file
+sub fill_ocaml_depends) {
+       my ($package, $tmp, $fname, $is_library, $runtime) = @_;
+  
+       delsubstvar $package, "ocaml:Depends"; # for idempotency
+       if (-f $fname) {
+               open DEPS, "< $fname" or die "can't open $fname";
+               while (my $line = <DEPS>) {
+                       chomp $line;
+                       if ($line =~ /^\s*(.+)\s+(.+)\s+(.+)\s*$/) {
+                               # matched groups: dev_dep, runtime_dep, 
dep_version
+                               if ($is_library) {
+                                       add_ocaml_dep $package, $1, ">= $3";
+                                       add_ocaml_dep $package, $runtime, "= 
$dh{VERSION}" if $runtime;
+                                       if (`find $tmp -type f -name "META*"` 
ne ""
+                                            and not $dh{D_FLAG}) {
+                                               # package has META and findlib
+                                               # dependency has not been 
forbidden
+                                               add_ocaml_dep $package, 
"ocaml-findlib", "-"
+                                       }
+                                       add_ocaml_dep $runtime, $2, ">= $3";
+                               }
+                               else {
+                                       add_ocaml_dep $package, $2, ">= $3";
+                               }
+                       }
+               }
+               close DEPS;
+       }
+       add_ocaml_dep $package, "ocaml-base-nox-$ocaml_version", "-" unless 
$is_library;
+}
+
+# check if a given binary package exists in debian/control
+sub package_exists {
+       my ($name) = @_;
+       my $retval = grep /^\Q$name\E$/, getpackages();
+       return $retval;
+}
+
+# return true if a given package has to be handled as an ocaml development
+# library package. Usually this implies that package has a name like
+# libXXX-ocaml-dev, but could be overridden with -l
+# -l argument has the form "devpkg:runtime,devpkg:runtime,..." devpkg is the
+# name of the development package :runtime (optional part) is the name of the
+# associated runtime package
+# examples: -l foo    -l foo:bar    -l foo:bar,baz,dum:dam
+sub is_library {
+       my ($package, $overrides) = @_;
+
+       return 1 if $overrides and $overrides =~ /(^|,)\Q$package\E($|:|,)/;
+       return ($package =~ /^lib.*-ocaml-dev$/);
+}
+
+# return true if a given package has to be handled as containing ocaml binaries
+# usually this implies that package name does not match libXXX-ocaml(-dev)? but
+# overrides should be considered as per is_library above
+sub is_binary {
+       my ($package, $overrides) = @_;
+       return 0 if $overrides and $overrides =~ /(^|,|:)\Q$package\E($|:|,)/;
+       return (not ($package =~ /^lib.*-ocaml(-dev)?$/));
+}
+
+# return the runtime package corresponding to a given library
+sub runtime_of_library {
+       my ($package, $overrides) = @_;
+       
+       my $runtime = "";
+       if ($overrides and $overrides =~ /(^|,)\Q$package\E:([^,]+)/) {
+               $runtime = $2;
+       }
+       elsif ($package =~ /^(lib.*-ocaml)-dev$/) {
+               $runtime = $1;
+       }
+       return (package_exists $runtime ? $runtime : "");
+}
+
+exit 0 if $dh{NO_ACT}; # WHY??? FIXME
+
+foreach my $package (@{$dh{DOPACKAGES}}) {
+       my $tmp = tmpdir $package;
+       my $ext = pkgext $package;
+       
+       isnative($package); # sets $dh{VERSION}
+       my $oinfo = "debian/$ext" . "oinfo.debhelper"; # ocaml objects info
+       my $olist = "debian/$ext" . "olist.debhelper"; # ocaml object list
+       $olist = $dh{M_PARAMS} if $dh{M_PARAMS}; # override object list with -m
+       my $odeps = "debian/$ext" . "odeps.debhelper"; # ocaml dependencies
+       
+       if (is_library $package, $dh{L_PARAMS}) { 
+               my $runtime = runtime_of_library $package, $dh{L_PARAMS};
+               my $flags = "--package $package --version $dh{VERSION}";
+               $flags .= " --runtime $runtime" if $runtime;
+               # create md5sum registry entry and post.* scripts
+               complex_doit "find $tmp$ocaml_lib_dir -type f -name '*.cm[ao]' 
> $olist"
+                       unless $dh{M_PARAMS};
+               complex_doit "mkdir -p $tmp$md5dir";
+               complex_doit("ocaml-md5sums $flags --dump-info $oinfo compute < 
$olist"
+                       . " | sort -k 2" # optional pass, just for "pretty" 
printing
+                       . " > $tmp$md5dir/$package$md5ext");
+               autoscript $package, "postinst", "postinst-ocaml";
+               autoscript $package, "postrm", "postrm-ocaml";
+               complex_doit "ocaml-md5sums --load-info $oinfo dep < $olist > 
$odeps"; #compute deps
+               fill_ocaml_depends $package, $tmp, $odeps, 1, $runtime;
+       }
+       elsif (is_binary $package, $dh{L_PARAMS}) {
+               my @binaries = find_ocaml_bc_binaries $tmp;
+               next unless @binaries; # nothing to do if no bytecode binary 
has been found
+               complex_doit "> $odeps";
+               if (not $dh{M_PARAMS}) {
+                       foreach my $bin (@binaries) { # try to find .cmo of bc 
binaries
+                               my $guess = basename $bin . ".cm[ao]";
+                               complex_doit "find . -type f -name '$guess' >> 
$olist"
+                       }
+               }
+               complex_doit "ocaml-md5sums dep < $olist > $odeps"; # compute 
deps
+               fill_ocaml_depends $package, $tmp, $odeps, 0, "";
+       }
+}
+
+=head1 SEE ALSO
+
+L<ocamlobjinfo(1)>, L<debhelper(7)>, L<ocaml-md5sums(1)>
+
+This program is a part of debhelper.
+
+=head1 AUTHOR
+
+Stefano Zacchiroli <[EMAIL PROTECTED]>
+
+=cut

Property changes on: dh_ocaml
___________________________________________________________________
Name: svn:executable
   + *

Attachment: signature.asc
Description: Digital signature

Reply via email to