Subject: [PATCH] Replace teh hard-code list of virtual packages with one that can be built with a script, which lists virtual packages provided by two or more packages.

From: Raphael Geissert <[email-masked]>
Date: Sat, 7 Feb 2009 12:54:49 -0600

This eases the maintenance of such list by knowing about new packages and
dropping obsolete packages.

Since as of the time of writing not all the packages that used to be on the
hard-coded list are provided by more than one package their inclusion on the
list can be forced as long as there is at least one package providing it on the
archive.
---
 checks/common_data.pm                 |   38 +----
 checks/fields                         |    6 +-
 data/fields/virtual-packages          |  326 +++++++++++++++++++++++++++++++++
 private/refresh-virtual-packages-data |  110 +++++++++++
 4 files changed, 444 insertions(+), 36 deletions(-)
 create mode 100644 data/fields/virtual-packages
 create mode 100755 private/refresh-virtual-packages-data

diff --git a/checks/common_data.pm b/checks/common_data.pm
index 6105b4e..1e5e956 100644
--- a/checks/common_data.pm
+++ b/checks/common_data.pm
@@ -8,9 +8,8 @@ our @EXPORT = qw
    %known_archs %known_sections %known_non_us_parts %known_archive_parts
    %known_prios %known_source_fields %known_binary_fields %known_udeb_fields
    %known_obsolete_fields %known_essential %known_build_essential
-   %known_obsolete_packages %known_obsolete_emacs %known_virtual_packages
-   %known_libstdcs %known_tcls %known_tclxs %known_tks %known_tkxs
-   %known_libpngs %known_x_metapackages
+   %known_obsolete_packages %known_obsolete_emacs %known_libstdcs %known_tcls
+   %known_tclxs %known_tks %known_tkxs %known_libpngs %known_x_metapackages
    %non_standard_archs %all_cpus %all_oses
    %known_doc_base_formats
    $known_shells_regex
@@ -22,9 +21,8 @@ use vars qw
   %known_archs %known_sections %known_non_us_parts %known_archive_parts
   %known_prios %known_source_fields %known_binary_fields %known_udeb_fields
   %known_obsolete_fields %known_essential %known_build_essential
-  %known_obsolete_emacs %known_virtual_packages
-  %known_libstdcs %known_tcls %known_tclxs %known_tks %known_tkxs
-  %known_libpngs %known_x_metapackages
+  %known_obsolete_emacs %known_libstdcs %known_tcls %known_tclxs %known_tks
+  %known_tkxs %known_libpngs %known_x_metapackages
   %all_cpus %all_oses
   %known_doc_base_formats
   $known_shells_regex
@@ -119,34 +117,6 @@ use vars qw
 %known_obsolete_emacs = map { $_ => 1 }
     ('emacs21');
 
-# Used only (at least lintian 1.23.1) for giving a warning about a
-# virtual-only dependency
-%known_virtual_packages = map { $_ => 1 }
-    ('x-terminal-emulator', 'x-window-manager', 'xserver', 'awk', 'c-compiler',
-     'c-shell', 'dotfile-module', 'emacsen', 'fortran77-compiler',
-     'ftp-server', 'httpd', 'ident-server', 'info-browser',
-     'ispell-dictionary', 'kernel-headers', 'kernel-image', 'kernel-source',
-     'linux-kernel-log-daemon', 'lambdamoo-core', 'lambdamoo-server',
-     'libc-dev', 'man-browser', 'pdf-preview', 'pdf-viewer',
-     'postscript-preview', 'postscript-viewer',
-     'system-log-daemon', 'tclsh', 'telnet-client', 'telnet-server',
-     'time-daemon', 'ups-monitor', 'wish', 'wordlist', 'www-browser',
-     'imap-client', 'imap-server', 'mail-reader', 'mail-transport-agent',
-     'news-reader', 'news-transport-system', 'pop3-server',
-     'mp3-encoder', 'mp3-decoder',
-     'java-compiler', 'java2-compiler',
-     'java-virtual-machine',
-     'java1-runtime', 'java2-runtime',
-     'dict-client',
-     'foomatic-data',
-     'audio-mixer', 'x-audio-mixer',
-     'debconf-2.0',
-     'aspell-dictionary',
-     'radius-server',
-     'libgl-dev', 'libglu-dev',
-     'automaken'
-    );
-
 %known_libstdcs = map { $_ => 1 }
     ('libstdc++2.9-glibc2.1', 'libstdc++2.10', 'libstdc++2.10-glibc2.2',
      'libstdc++3', 'libstdc++3.0', 'libstdc++4', 'libstdc++5',
diff --git a/checks/fields b/checks/fields
index f17e4c0..f1e5e19 100644
--- a/checks/fields
+++ b/checks/fields
@@ -133,6 +133,8 @@ my $arch_indep;
 
 # Load obsolete packages list.
 my $obsolete_packages = Lintian::Data->new ('fields/obsolete-packages');
+# Load virtual packages list.
+my $virtual_packages = Lintian::Data->new ('fields/virtual-packages');
 
 unless (-d "fields") {
 	fail("directory in lintian laboratory for $type package $pkg missing: fields");
@@ -472,7 +474,7 @@ if (($type eq "binary") || ($type eq 'udeb')) {
 
 				# Only for (Pre-)?Depends.
 				tag "virtual-package-depends-without-real-package-depends", "$field: $alternatives[0]->[0]"
-				    if ($known_virtual_packages{$alternatives[0]->[0]}
+				    if ($virtual_packages->known($alternatives[0]->[0])
 					&& ($field eq "depends" || $field eq "pre-depends"));
 
                                 # Check defaults for transitions.  Here, we only care that the first alternative is current.
@@ -679,7 +681,7 @@ if ($type eq "source") {
 				push @alternatives, [_split_dep($_), $_] for (split /\s*\|\s*/, $dep);
 
 				tag "virtual-package-depends-without-real-package-depends", "$field: $alternatives[0]->[0]"
-				    if ($known_virtual_packages{$alternatives[0]->[0]} && &$is_dep_field($field));
+				    if ($virtual_packages->known($alternatives[0]->[0]) && &$is_dep_field($field));
 
 				for my $part_d (@alternatives) {
 					my ($d_pkg, $d_version, $d_arch, $rest, $part_d_orig) = @$part_d;
diff --git a/data/fields/virtual-packages b/data/fields/virtual-packages
new file mode 100644
index 0000000..f1829a0
--- /dev/null
+++ b/data/fields/virtual-packages
@@ -0,0 +1,326 @@
+# The list of virtual packages in Debian that are provided by two or more
+# packages. Packages that wish to be listed but are not automagically found by
+# this script can be hard-coded in this file and they will be preserved across
+# multiple executions of this script as long as they are listed in a comment
+# line where the first non-space characters form the word "Keep:".
+# Multiple packages can be specified in the same line, separated by comma and/or
+# white space. Multiple "Keep: " lines can be used as well.
+#
+# Last updated: 2009-02-07
+
+# Keep: linux-source, linux-image, linux-headers
+# Keep: libc-dev, c-shell, dotfile-module, fortran77-compiler, kernel-headers
+# Keep: kernel-image, kernel-source, lambdamoo-core, lambdamoo-server
+# Keep: pdf-preview, mp3-encoder, java2-compiler, foomatic-data, libglu-dev
+
+aide-binary
+alsaplayer-interface
+alsaplayer-output
+apache2
+apache2-mpm
+aptitude-doc
+aspell6a-dictionary
+aspell-dictionary
+asterisk-prompt-fr
+atl2-modules
+audio-mixer
+aufs-modules
+automaken
+awk
+bacula-director
+bacula-sd-tools
+bochs-gui
+bogofilter-db
+boom-wad
+c++abi2-dev
+c-compiler
+c++-compiler
+childsplay-alphabet-sounds
+childsplay-lfc-names
+cl-sql-backend
+console-utilities
+c-shell
+cyrus21-imapd
+cyrus21-pop3d
+cyrus22-imapd
+cyrus22-pop3d
+debconf-2.0
+dhcp-client
+dict-client
+dictd-dictionary
+djvu-viewer
+docbook-xsl-doc
+drbd8-modules
+drbd-utils
+dssi-plugin
+dyndns-client
+editor
+emacs22
+emacsen
+epic4-script
+erlang-abi-11.b.3
+et131x-modules
+exim4-localscanapi-1.0
+exim4-localscanapi-1.1
+festival-voice
+fortran95-compiler
+fortune-cookie-db
+freeciv
+freeciv-client
+fsck-backend
+ftp-server
+fwbuilder-backend
+gcompris-sound
+gforge-mta
+gforge-plugin-scm
+ggz-core-client
+gift-client
+gift-plugin
+gimp-help
+gnome-www-browser
+gnustep-back0.14-alt
+gnustep-base-runtime-dbg
+grub
+gspca-modules
+gstreamer0.10-audiosink
+gstreamer0.10-videosink
+gtkicq
+guile
+gvim
+httpd
+httpd-cgi
+hunspell-dictionary
+hunspell-dictionary-de
+ident-server
+ike-server
+imap-client
+imap-server
+imaze
+inet-superserver
+inews
+info-browser
+irc
+ircd
+iscsitarget-modules
+ispell-dictionary
+itcl-doc
+itk-doc
+java1-runtime
+java1-runtime-headless
+java2-runtime
+java2-runtime-headless
+java2-sdk
+java5-runtime
+java5-runtime-headless
+java5-sdk
+java6-runtime
+java6-runtime-headless
+java6-sdk
+java-compiler
+java-runtime
+java-runtime-headless
+java-sdk
+java-virtual-machine
+jruby
+kaffe
+kde-i18n
+kfreebsd-source
+kile-i18n
+koffice-i18n
+ladspa-host
+ladspa-plugin
+libatlas-3gf.so
+libatlas.so.3gf
+libblas-3gf.so
+libblas.so.3gf
+libcurl-dev
+libcurl-ssl-dev
+libcyrus-imap-perl
+libcyrus-imap-perl21
+libdb-dev
+libdb++-dev
+libdb-java
+libdb-java-dev
+libdc1394-dev
+libdeps-renderer
+libdspam7-drv
+libedac
+libexif-ruby
+libfcgi-ruby
+libfilesystem-ruby
+libgd2
+libgdchart
+libgdchart-gd2-dev
+libgd-dev
+libgettext-ruby
+libggi-target
+libgl-dev
+libguile-dev
+libhdf5-1.6.6-0
+libhdf5-dev
+libhk-classes-driver
+libhtml-wikiconverter-dialect
+libimage-size-ruby
+liblapack-3gf.so
+liblapack.so.3gf
+libmpich-dev
+libneon-dev
+libnet-dev
+libsoqt-dev
+libstdc++-dev
+libstlport-dev
+libswfdec-dev
+libzlui
+licq-plugin
+linux-headers
+linux-headers-2.6
+linux-image
+linux-image-2.6
+linux-initramfs-tool
+linux-kernel-log-daemon
+linux-latest-modules-2.6.26-1-486
+linux-latest-modules-2.6.26-1-686
+linux-latest-modules-2.6.26-1-686-bigmem
+linux-latest-modules-2.6.26-1-amd64
+linux-latest-modules-2.6.26-1-openvz-686
+linux-latest-modules-2.6.26-1-vserver-686
+linux-latest-modules-2.6.26-1-vserver-686-bigmem
+linux-latest-modules-2.6.26-1-xen-686
+linux-source
+lisp-compiler
+locales
+loop-aes-modules
+lpr
+lsb-qt4-ia32
+lsb-qt4-noarch
+lua
+lzma-modules
+mail-reader
+mail-transport-agent
+mailx
+man-browser
+mnogosearch
+monodoc-viewer
+mp3-decoder
+mp3-encoder
+mpd-client
+mpg123
+mpipython
+myspell-dictionary
+myspell-dictionary-de
+myspell-dictionary-en
+myspell-dictionary-pt
+netcat
+nethack
+netkit-inetd
+netpbm-dev
+news-reader
+news-transport-system
+nfs-server
+nilfs2-modules
+objc-compiler
+objc++-compiler
+octave
+octave-doc
+octave-emacsen
+octave-headers
+octave-htmldoc
+octave-info
+open
+openoffice.org2-thesaurus
+openoffice.org2-thesaurus-ru
+openoffice.org-help-2.4
+openoffice.org-hyphenation
+openoffice.org-l10n-2.4
+openoffice.org-spellcheck-de-at
+openoffice.org-spellcheck-de-ch
+openoffice.org-spellcheck-de-de
+openoffice.org-spellcheck-eu
+openoffice.org-spellcheck-fi
+pascal-compiler
+paw-binary
+pcsc-ifd-handler
+pdf-viewer
+pdns-backend
+pgdocs
+phonon-backend
+phpapi-20060613+lfs
+pinentry
+pinentry-x11
+ping
+pop3-server
+postscript-preview
+postscript-viewer
+pure-ftpd
+radius-server
+ratbox-services
+redhat-cluster-modules
+root-db-client
+root-file-server
+root-fitter
+roundcube-db
+rsh-client
+rsh-server
+rxvt-unicode
+skkserv
+snort
+snort-rules
+speakup-modules
+sqlrelay-api
+sqlrelay-connection-daemon
+squashfs-modules
+ssh-askpass
+ssh-server
+stardict
+sword-comm
+sword-dict
+sword-frontend
+sword-text
+system-log-daemon
+talkd
+tcldoc
+tclsh
+tclx
+tclx-doc
+telepathy-connection-manager
+telnet-client
+telnet-server
+tesseract-ocr-language
+time-daemon
+tipptrainer-data
+tkdoc
+tp-smapi-modules
+ttf-japanese-gothic
+ttf-japanese-mincho
+ultrastar-ng
+ups-monitor
+usplash-theme
+vim
+vim-perl
+vim-python
+vim-ruby
+vim-tcl
+virtualbox-ose-guest-modules
+virtualbox-ose-modules
+vnc-viewer
+wims-extra
+wish
+wordlist
+www-browser
+wx-doc
+wx-i18n
+xabacus
+x-audio-mixer
+x-display-manager
+xemacs21
+xen-hypervisor
+xen-hypervisor-3
+xen-hypervisor-3.2-1
+xmp-player
+xserver
+xserver-xorg-input-2
+xserver-xorg-video-2
+x-session-manager
+x-terminal-emulator
+x-window-manager
+zcode-interpreter
diff --git a/private/refresh-virtual-packages-data b/private/refresh-virtual-packages-data
new file mode 100755
index 0000000..6ee8915
--- /dev/null
+++ b/private/refresh-virtual-packages-data
@@ -0,0 +1,110 @@
+#!/bin/sh
+# refresh-virtual-packages-data -- Refresh data about font packages in Debian
+
+# Copyright (C) 2008, 2009 Raphael Geissert <[email-masked]>
+#
+# This file 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 of the License, or
+# (at your option) any later version.
+#
+# This file 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 file.  If not, see <http://www.gnu.org/licenses/>.
+
+set -e
+
+if [ -z "$1" ]; then
+    printf "Usage: %s <path-to-data> [<packages>]\n" "$(basename "$0")"
+    cat <<INFO
+
+If <packages> is specified, it should be the path to the Packages file
+from the current unstable distribution.  It will be used to find all
+font files already packaged for Debian and update the list of known
+font files and the packages that contain them.  <path-to-data> should
+be the path to the root of the Lintian data directory to update.
+
+If the Packages file is not specified, the script will download the
+following files from a mirror.  The mirror can be specified with the
+DEB_MIRROR environment variable.  If it is not set, the default is
+http://i386-geomirror.debian.net/debian.
+
+* main/binary-i386/Packages.gz
+
+Any necessary special parameters for wget can be set via the
+environment variable WGET_ARGS.  The default arguments are -nv.
+
+To set additional virtual packages to be added to the list as Keep entries
+list them in the VIRTUAL_PACKAGES environment variable.
+
+INFO
+    exit
+fi
+
+readonly lintian_data="$(readlink -f "$1")"
+packages="$(readlink -f "$2")"
+
+[ -d "$lintian_data" ] || {
+    printf "%s is not a directory, aborting" "$lintian_data" >&2
+    exit 1
+}
+
+readonly workdir="$(mktemp -d)"
+
+cleanup () {
+    [ ! -d "$workdir" ] || rm -rf "$workdir"
+}; trap cleanup EXIT
+
+mirror="${DEB_MIRROR:=http://i386-geomirror.debian.net/debian}"
+WGET_ARGS="${WGET_ARGS:=-nv}"
+wget() {
+    echo wget "$mirror"/"$1"
+    /usr/bin/wget $WGET_ARGS -O "$workdir/$(basename "$1")" "$mirror"/"$1"
+}
+mkdir -p "$lintian_data/fields"
+
+cat > "$workdir/virtual-packages" <<EOF
+# The list of virtual packages in Debian that are provided by two or more
+# packages. Packages that wish to be listed but are not automagically found by
+# this script can be hard-coded in this file and they will be preserved across
+# multiple executions of this script as long as they are listed in a comment
+# line where the first non-space characters form the word "Keep:".
+# Multiple packages can be specified in the same line, separated by comma and/or
+# white space. Multiple "Keep: " lines can be used as well.
+#
+# Last updated: $(date -u +'%Y-%m-%d')
+
+EOF
+
+[ -f "$lintian_data/fields/virtual-packages" ] && {
+    egrep '^#\s*Keep:\s*.+$' "$lintian_data/fields/virtual-packages" \
+	>> "$workdir/virtual-packages" || true
+}
+[ -z "$VIRTUAL_PACKAGES" ] || {
+    printf "# Keep: %s\n" "$VIRTUAL_PACKAGES" >> "$workdir/virtual-packages"
+}
+
+if [ -z "$packages" ] ; then
+    wget dists/sid/main/binary-i386/Packages.gz
+    packages="$workdir/Packages.gz"
+fi
+
+{ zcat "$packages";
+  sed -rn 's/^#\s*Keep:\s*/Provides: /;T;s/([^,:])\s+([^,])/\1, \2/g;p' \
+	"$workdir/virtual-packages"
+} |
+    perl -w -E 'my %seen; while (<>) {
+		    next unless (s/^Provides:\s*//);
+		    for my $pkg (split /\s*,\s*/) {
+			$seen{$pkg}++;
+			print "$pkg\n"
+			    if ($seen{$pkg} eq 2);
+		    }
+		  };' \
+    | sort -u >> "$workdir/virtual-packages"
+
+mv "$workdir/virtual-packages" "$lintian_data/fields/"