tags 477751 +patch
thanks

Hi,

I finally took the opportunity to work on this bug. As Joey Hess pointed
out the first thing to change is update-catalog. On the other hand
surely the debhelper snipped *will* have to change, because it
unconditionally removes a file in /etc. So let us have a look at the
current snippet:

$ cat /usr/share/debhelper/autoscripts/postinst-sgmlcatalog
if [ "$1" = "configure" ]; then
        rm -f #CENTRALCAT#
        for ordcat in #ORDCATS#; do
                update-catalog --quiet --add #CENTRALCAT# ${ordcat}
        done
        update-catalog --quiet --add --super #CENTRALCAT#
fi
$

So there are two places where we do not preserve user changes.

1) Changes to the root catalog. This is due to the update-catalog --quiet --add
--super. It is actually easy to solve, because it is a no-op if the catalog is
already added. Thus it should only be invoked when installing the package. It
should not be invoked when upgrading the package. A simple check on $2 being
empty solves this issue.

2) Changes to the central catalog of the package. This is more tricky
and requires changes to update-catalog. There needs to be some way to
remember what catalogs the user disabled. To achieve this I changed the
behaviour of --remove (see attached debdiff). It will now comment out
catalogs to be removed. Now removing that catalog is no longer a good
thing to do. Instead updatew-catalog needs to do something more clever.
This is where update-catalog --update #CENTRALCAT# #ORDCATS# comes in.
It will walk over the central catalog removing any (disabled or not)
entries not found in the passed #ORDCATS#. It will not touch entries
already present, but add new ones. So this should solve the issue.

The new snipped would look like this:

$ cat postinst-sgmlcatalog.new
if [ "$1" = configure" ]; then
        update-catalog --quiet --update #CENTRALCAT# #ORDCATS#
        if [ -z "$2" ]; then
                update-catalog --quiet --add --super #CENTRALCAT#
        fi
fi
$

So what are your thoughts on this?

Helmut
diff -Nru sgml-base-1.26+nmu1/debian/changelog 
sgml-base-1.26+nmu2/debian/changelog
--- sgml-base-1.26+nmu1/debian/changelog        2010-07-18 14:39:38.000000000 
+0200
+++ sgml-base-1.26+nmu2/debian/changelog        2011-12-04 12:50:15.000000000 
+0100
@@ -1,3 +1,10 @@
+sgml-base (1.26+nmu2) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * Rework update-catalog in a way that empowers debhelper to fix #477751.
+
+ -- Helmut Grohne <hel...@subdivi.de>  Sun, 04 Dec 2011 12:49:07 +0100
+
 sgml-base (1.26+nmu1) unstable; urgency=low
 
   * Non-maintainer upload
diff -Nru sgml-base-1.26+nmu1/tools/update-catalog 
sgml-base-1.26+nmu2/tools/update-catalog
--- sgml-base-1.26+nmu1/tools/update-catalog    2004-06-21 00:04:49.000000000 
+0200
+++ sgml-base-1.26+nmu2/tools/update-catalog    2011-12-04 12:41:06.000000000 
+0100
@@ -30,6 +30,7 @@
 use vars qw( $super );
 use vars qw( $template );
 use vars qw( $type );
+use vars qw( $update );
 
 ## ----------------------------------------------------------------------
 while ( $ARGV[0] =~ m/^--/ )
@@ -44,6 +45,10 @@
     {
         $remove = 1;
     }
+    elsif ( $_ eq '--update' )
+    {
+       $update = 1;
+    }
     elsif ( $_ eq '--quiet' )
     {
         $quiet = 1;
@@ -83,10 +88,14 @@
 }
 
 ## ----------------------------------------------------------------------
-if ( $add || $remove )
+if ( $add || $remove || $update )
 {
     if ( $super )
     {
+       if ( $update ) {
+           print "Updating the super catalog is not supported.\n";
+           exit 1;
+       }
        $catalog = '/etc/sgml/catalog';
     }
     else
@@ -104,6 +113,21 @@
 }
 
 ## ----------------------------------------------------------------------
+if ( $add + $remove + $update != 1)
+{
+    print "Huh? You have to use precisely one out of --add --remove and 
--update.\n";
+    exit 1;
+}
+if ( $update )
+{
+    print "Updating $catalog...\n"
+       unless $quiet;
+    &read_catalog_updating_argv;
+    &write_catalog;
+    exit 0;
+}
+
+## ----------------------------------------------------------------------
 $entry = shift( @ARGV );
 
 ## ----------------------------------------------------------------------
@@ -115,13 +139,6 @@
 }
 
 ## ----------------------------------------------------------------------
-if ( $add == $remove )
-{
-    print "Huh? You have to use --add or --remove (not both).\n";
-    exit 1;
-}
-
-## ----------------------------------------------------------------------
 print STDERR "$name: test mode - catalog file will not be updated\n"
     if $debug && ! $quiet;
 
@@ -131,8 +148,7 @@
     print "Adding entry $entry to catalog $catalog...\n"
         unless $quiet;
     
-    &read_catalog_without_entry;
-    &add_entry;
+    &read_catalog_enabling_entry;
     &write_catalog;
 }
 elsif ( $remove )
@@ -140,7 +156,7 @@
     print "Removing entry $entry from catalog $catalog...\n"
         unless $quiet;
     
-    &read_catalog_without_entry;
+    &read_catalog_disabling_entry;
     &write_catalog;
 }
 
@@ -148,8 +164,25 @@
 exit 0;
 
 ## ----------------------------------------------------------------------
- sub read_catalog_without_entry
+sub read_template
+{
+    $type = $super ? 'super' : 'centralized';
+    $template = "/usr/share/sgml-base/catalog.$type";
+    print "Reading template $template...\n"
+       if $debug;
+    open( TEMPLATE, "<$template" )
+       or die "cannot open template $template for reading: $!";
+    while ( <TEMPLATE> )
+    {
+       chop;
+       s|CATALOG|$catalog| if m/CATALOG/;
+       push( @data, $_ );
+    }
+    close( TEMPLATE );
+}
+sub read_catalog_enabling_entry
 {
+    my $enabled = 0;
     if ( -f $catalog )
     {
        print "Reading catalog $catalog and removing entry $entry...\n"
@@ -159,25 +192,83 @@
        while ( <CATALOG> )
        {
            chop;
-           push( @data, $_ ) unless m/$entry/;
+           if(m/$entry/ and m/^--.*--$/) {
+                   print "Enabling disabled catalog $catalog...\n"
+                       if $debug;
+                   s/^--//;
+                   s/--$//;
+                   $enabled = 1;
+           }
+           push( @data, $_ );
        }
        close( CATALOG );
+       &add_entry if(!$enabled);
     }
     else
     {
-       $type = $super ? 'super' : 'centralized';
-       $template = "/usr/share/sgml-base/catalog.$type";
-       print "Reading template $template...\n"
+       &read_template;
+       &add_entry;
+    }
+}
+sub read_catalog_disabling_entry
+{
+    if ( -f $catalog )
+    {
+       print "Reading catalog $catalog and removing entry $entry...\n"
            if $debug;
-       open( TEMPLATE, "<$template" )
-           or die "cannot open template $template for reading: $!";
-       while ( <TEMPLATE> )
+       open( CATALOG, "<$catalog" )
+           or die "cannot open catalog $catalog for reading: $!";
+       while ( <CATALOG> )
        {
            chop;
-           s|CATALOG|$catalog| if m/CATALOG/;
+           if(m/$entry/ and ! m/^--/) {
+                   s/^/--/;
+                   s/$/--/;
+           }
            push( @data, $_ );
        }
-       close( TEMPLATE );
+       close( CATALOG );
+    }
+    else
+    {
+       &read_template;
+    }
+}
+sub read_catalog_updating_argv
+{
+    my %entries;
+    map { $entries{$_} = 1 } @ARGV;
+    if ( -f $catalog )
+    {
+       print "Reading catalog $catalog and removing entry $entry...\n"
+           if $debug;
+       open( my $fh, "<", $catalog )
+           or die "cannot open catalog $catalog for reading: $!";
+       while ( <$fh> )
+       {
+           my $found = 0;
+           chomp;
+           foreach my $key (keys %entries) {
+               # We do not care whether it is commented out or not.
+               if(m/$key/) {
+                   $found = 1;
+                   delete $entries{$key};
+               }
+           }
+           push( @data, $_ ) if( $found );
+       }
+       close( $fh );
+       # add new entries.
+       foreach $entry (keys %entries) {
+           &add_entry;
+       }
+    }
+    else
+    {
+       &read_template;
+       foreach $entry (@ARGV) {
+            &add_entry;
+       }
     }
 }
 
diff -Nru sgml-base-1.26+nmu1/tools/update-catalog.8 
sgml-base-1.26+nmu2/tools/update-catalog.8
--- sgml-base-1.26+nmu1/tools/update-catalog.8  2004-06-21 00:04:49.000000000 
+0200
+++ sgml-base-1.26+nmu2/tools/update-catalog.8  2011-12-04 12:48:06.000000000 
+0100
@@ -34,6 +34,11 @@
 .RI [ options ]
 .B --remove
 .I centralized_catalog ordinary_catalog
+.PP
+.B update-catalog
+.RI [ options ]
+.B --update 
+.I centralized_catalog ordinary_catalogs
 .\"
 .\" ----------------------------------------------------------------------
 .SH DESCRIPTION
@@ -49,7 +54,7 @@
 .SH OPTIONS
 .TP
 .B --add
-Adds an entry for the
+Adds or enables an entry for the
 .I centralized_catalog
 in the super catalog
 .IR /etc/sgml/catalog ,
@@ -59,7 +64,7 @@
 .IR centralized_catalog .
 .TP
 .B --remove
-Removes the entry for the
+Disables the entry for the
 .I centralized_catalog
 from the super catalog
 .IR /etc/sgml/catalog ,
@@ -68,6 +73,13 @@
 from the
 .IR centralized_catalog .
 .TP
+.B --update
+Updates the given
+.I centralized_catalog
+with all the passed
+.I ordinary_catalogs
+by removing all no longer known catalogs (disabled or not) and adding 
previously unknown catalogs.
+.TP
 .B --quiet
 Prevents the usual diagnostic output.
 .TP

Reply via email to