[csw-devel] SF.net SVN: gar:[7856] csw/mgar/gar/v2

wahwah at users.sourceforge.net wahwah at users.sourceforge.net
Mon Jan 4 11:28:16 CET 2010


Revision: 7856
          http://gar.svn.sourceforge.net/gar/?rev=7856&view=rev
Author:   wahwah
Date:     2010-01-04 10:28:15 +0000 (Mon, 04 Jan 2010)

Log Message:
-----------
mGAR v2: Merging the v2-checkpkg branch in

Modified Paths:
--------------
    csw/mgar/gar/v2/bin/checkpkg

Added Paths:
-----------
    csw/mgar/gar/v2/bin/checkpkg.d/
    csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-dummy.py
    csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-libs.py
    csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-obsolete-deps.py
    csw/mgar/gar/v2/bin/checkpkg.d/checkpkg.py
    csw/mgar/gar/v2/bin/checkpkg.d/checkpkg_test.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/__init__.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/checkpkg_test_data_CSWlibpq_84.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/checkpkg_test_data_CSWmysql51.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/checkpkg_test_data_CSWmysql51client.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/checkpkg_test_data_CSWmysql51devel.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/checkpkg_test_data_CSWmysql51rt.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/checkpkg_test_data_CSWmysql5client_8x.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/dump_output_1.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/dump_output_2.py

Removed Paths:
-------------
    csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-dummy.py
    csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-libs.py
    csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-obsolete-deps.py
    csw/mgar/gar/v2/bin/checkpkg.d/checkpkg.py
    csw/mgar/gar/v2/bin/checkpkg.d/checkpkg_test.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/__init__.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/checkpkg_test_data_CSWlibpq_84.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/checkpkg_test_data_CSWmysql51.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/checkpkg_test_data_CSWmysql51client.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/checkpkg_test_data_CSWmysql51devel.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/checkpkg_test_data_CSWmysql51rt.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/checkpkg_test_data_CSWmysql5client_8x.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/dump_output_1.py
    csw/mgar/gar/v2/bin/checkpkg.d/testdata/dump_output_2.py

Property Changed:
----------------
    csw/mgar/gar/v2/
    csw/mgar/gar/v2/bin/checkpkg
    csw/mgar/gar/v2/pkglib/csw/depend


Property changes on: csw/mgar/gar/v2
___________________________________________________________________
Modified: svn:mergeinfo
   - /csw/mgar/gar/v2:4936-6678
/csw/mgar/gar/v2-collapsed-modulations:6895
/csw/mgar/gar/v2-migrateconf:7082-7211
/csw/mgar/gar/v2-skayser:6087-6132
   + /csw/mgar/gar/v2:4936-6678
/csw/mgar/gar/v2-checkpkg:7722-7855
/csw/mgar/gar/v2-collapsed-modulations:6895
/csw/mgar/gar/v2-migrateconf:7082-7211
/csw/mgar/gar/v2-skayser:6087-6132

Modified: csw/mgar/gar/v2/bin/checkpkg
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg	2010-01-04 03:57:34 UTC (rev 7855)
+++ csw/mgar/gar/v2/bin/checkpkg	2010-01-04 10:28:15 UTC (rev 7856)
@@ -1,6 +1,13 @@
 #!/bin/ksh -p
-
-# checkpkg 1.50 (diff to 1.46a: check multiple package files)
+# 
+# $Id$
+#
+# checkpkg 1.51
+#
+# diff to 1.46a
+#  - check multiple package files
+#  - checkpkg.d plugin support
+#
 # This script examines a package that has been put together
 # for submittal to the CSW archive at opencsw.org
 #
@@ -18,7 +25,22 @@
 PATH=$PATH:/usr/sbin
 
 LOCAL_ARCH=`uname -p`
+if [[ -z "${CHECKPKG_TMPDIR}" ]]; then
+  readonly CHECKPKG_TMPDIR="/var/tmp"
+else
+  readonly CHECKPKG_TMPDIR
+fi
 
+# Colors only when running interactively
+if [[ -t 1 ]]; then
+	GREEN="\\033[0;32;40m"
+	RED="\\033[1;31;40m"
+	COLOR_RESET="\\033[00m"
+else
+	GREEN=""
+	RED=""
+	COLOR_RESET=""
+fi
 
 # always print out a warning message. (to stderr)
 # exit script, if quit_on_warn set
@@ -28,11 +50,17 @@
 	if [[ -d "$EXTRACTDIR" ]] ; then
 		rm -rf $EXTRACTDIR
 	fi
-	if [[ "$TMPARCHIVE" != "" ]] ; then
-		[ -f "$TMPARCHIVE" ] && rm $TMPARCHIVE
-	fi
+	cleantmparchives
 }
 
+cleantmparchives() {
+	for TMPARCHIVE in $tmparchives; do
+		if [[ "$TMPARCHIVE" != "" ]]; then
+			[ -f "$TMPARCHIVE" ] && rm $TMPARCHIVE
+		fi
+	done
+}
+
 cleanupset(){
     if [ "`echo $SETINF*`" != "$SETINF*" ]; then
 	rm $SETINF*
@@ -54,6 +82,33 @@
 	exit 1
 }
 
+debugmsg() {
+	if [[ "${DEBUG}" != "" ]]; then
+		print "DEBUG: $*" > /dev/fd/2
+	fi
+}
+
+set_variables_for_individual_package_check() {
+	f=$1
+	file $f |sed 's/^.*://' |grep gzip >/dev/null
+	if [ $? -eq 0 ] ; then
+		TMPARCHIVE=$CHECKPKG_TMPDIR/`basename $f`
+		if [[ -f $TMPARCHIVE ]] ; then
+			print ERROR: $TMPARCHIVE already exists
+			
+		fi
+		gzcat $f >$TMPARCHIVE || exit 1
+		f=$TMPARCHIVE
+	fi
+	pkgname=`nawk 'NR == 2 {print $1; exit;}' $f`
+	pkgnames="$pkgnames $pkgname"
+}
+
+if [[ "$1" == "-d" ]] ; then
+	DEBUG=1
+	shift
+fi
+
 if [[ "$1" == "-e" ]] ; then
 	quit_on_warn=1;
 	shift
@@ -65,11 +120,19 @@
 fi
 
 # a unique filename for the list of package deps and libs we see in a 'set'
-SETINF=/tmp/checkpkg.$$.`date +%Y%m%d%H%M%S`
+SETINF=$CHECKPKG_TMPDIR/checkpkg.$$.`date +%Y%m%d%H%M%S`
 SETLIBS=$SETINF.libs
 SETDEPS=$SETINF.deps
+pkgnames=""
+tmparchives=""
 
+EXTRACTDIR=$CHECKPKG_TMPDIR/dissect.$$
 
+if [ -d $EXTRACTDIR ] ; then
+	print ERROR: $EXTRACTDIR already exists
+	exit 1
+fi
+
 for f in "$@"
 do
 
@@ -82,9 +145,6 @@
 
 
 case $f in
-	cswutils-*)
-		:
-	;;
 	*)
 	print Examining $f
 
@@ -111,30 +171,13 @@
 	done
 esac
 
-print Extracting files for more detailed inspection...
+print Extracting all files for more detailed inspection...
 
-file $f |sed 's/^.*://' |grep gzip >/dev/null
-if [ $? -eq 0 ] ; then
-	TMPARCHIVE=/tmp/`basename $f`
-	if [[ -f $TMPARCHIVE ]] ; then
-		print ERROR: $TMPARCHIVE already exists
-		
-	fi
-	gzcat $f >$TMPARCHIVE || exit 1
-	f=$TMPARCHIVE
-fi
+set_variables_for_individual_package_check "$f"
 
-pkgname=`nawk 'NR == 2 {print $1; exit;}' $f`
-
-EXTRACTDIR=/tmp/dissect.$$
-
-if [ -d $EXTRACTDIR ] ; then
-	print ERROR: $EXTRACTDIR already exists
-	exit 1
-fi
-
 mkdir $EXTRACTDIR
 
+# FIXME: This doesn't support multiple packages
 TMPFILE=$EXTRACTDIR/pkginfo
 
 
@@ -304,7 +347,6 @@
 print Extracing pkg for examination of files...
 pkgtrans $f $EXTRACTDIR $pkgname
 
-
 #############################################################
 # We now have the package expanded, in "directory" form, in
 # $EXTRACTDIR/$pkgname
@@ -406,7 +448,7 @@
 	#cat $EXTRACTDIR/elflist| xargs ldd  2>/dev/null |fgrep  '.so' |
 	#              sed 's:^.*=>[^/]*::' | nawk '{print $1}' |sort -u >$EXTRACTDIR/liblist
 
-		cat $EXTRACTDIR/elflist| xargs dump -Lv |nawk '$2=="NEEDED"{print $3}' |
+		cat $EXTRACTDIR/elflist| xargs /usr/ccs/bin/dump -Lv |nawk '$2=="NEEDED"{print $3}' |
 			sort -u | egrep -v $EXTRACTDIR >$EXTRACTDIR/liblist
 
 			
@@ -443,13 +485,12 @@
 	exit 1
 fi
 
-# Verify that there are no double depends
+# Verify that there are no multiple depends
 repeated_depends="$(awk '{print $2}' $EXTRACTDIR/$pkgname/install/depend \
   | sort | uniq -c | awk '{print $1}' | sort | uniq | wc -l)"
 if [[ "$repeated_depends" -gt 1 ]]; then
         cat $EXTRACTDIR/$pkgname/install/depend
-        print ERROR: $pkgname has double depends
-        exit 1
+        errmsg "$pkgname has multiple depends"
 fi
 
 #to retain a record of all packages currently being examined from $@
@@ -474,47 +515,6 @@
     fi
 done
 
-egrep -v 'SUNWbcp|SUNWowbcp|SUNWucb' /var/sadm/install/contents |
-		fgrep -f $EXTRACTDIR/liblist >$EXTRACTDIR/shortcatalog
-
-
-
-for lib in `cat $EXTRACTDIR/liblist` ; do
-	grep "[/=]$lib[ =]" $EXTRACTDIR/$pkgname/pkgmap
-	if [[ $? -eq 0 ]] ; then
-		echo $lib provided by package itself
-		continue
-	else
-	    grep "[/=]$lib[ =]" $SETLIBS
-	    if [[ $? -eq 0 ]]; then
-		echo "$lib provided by package set being evaluated."
-		continue
-	    fi
-	fi
-
-	libpkg=`grep /$lib $EXTRACTDIR/shortcatalog |
-	      sed 's/^.* \([^ ]*\)$/\1/' |sort -u`
-
-	if [[ -z "$libpkg" ]] ; then
-		echo "$lib $pkgname" >> $SETLIBS.missing
-		print Cannot find package providing $lib.  Storing for delayed validation.
-	else
-		print $libpkg | fmt -1 >>$EXTRACTDIR/libpkgs
-	fi
-done
-
-sort -u $EXTRACTDIR/libpkgs >$EXTRACTDIR/libpkgs.x
-mv $EXTRACTDIR/libpkgs.x $EXTRACTDIR/libpkgs
-
-diff $EXTRACTDIR/deppkgs $EXTRACTDIR/libpkgs >/dev/null
-if [[ $? -ne 0 ]] ; then
-	print SUGGESTION: you may want to add some or all of the following as depends:
-	print '   (Feel free to ignore SUNW or SPRO packages)'
-	diff $EXTRACTDIR/deppkgs $EXTRACTDIR/libpkgs | fgrep '>'
-fi
-
-
-
 if [[ "$basedir" != "" ]] ; then
 	print
 	if [[ -f $EXTRACTDIR/elflist ]] ; then
@@ -530,13 +530,78 @@
 	fi
 fi
 
+# Plugin section.
+#
+# Plugins should live in checkpkg.d subdirectory in the same directory in which
+# checkpkg is.  Each plugin file name should be an executable and begin with
+# "checkpkg-".
 
-cleanup
+tmparchives="$tmparchives $TMPARCHIVE"
+done
 
-print ""
+# All packages have been extracted.
 
+# Now running all the plugin checks
+
+set_variables_for_individual_package_check "$f"
+
+echo "Running the experimental plugin infrastructure."
+test_suite_ok=1
+checkpkg_scriptname=`basename $0`
+checkpkg_basedir=${0%/${checkpkg_scriptname}}
+plugindir=${checkpkg_basedir}/checkpkg.d
+if [[ "${DEBUG}" != "" ]]; then
+	extra_options="--debug"
+fi
+debugmsg "plugindir: '$plugindir'"
+log_files=""
+if [[ -d "$plugindir" ]]; then
+	# echo plugin dir exists
+	for plugin in "${plugindir}"/checkpkg-*; do
+		if [[ -x "${plugin}" ]]; then
+			debugmsg "Executing: ${plugin} $extra_options -e \"${EXTRACTDIR}\" ${pkgnames}"
+			plugin_base_name=`basename ${plugin}`
+			plugin_log="${EXTRACTDIR}/${plugin_base_name}.log"
+			log_files="${log_files} ${plugin_log}"
+			printf "TEST: ${plugin} running..."
+			${plugin} $extra_options -e "${EXTRACTDIR}" ${pkgnames} > "${plugin_log}" 2>&1
+			if [[ "$?" -ne 0 ]]; then
+				printf "\rTEST: ${plugin} ${RED}[FAIL]${COLOR_RESET}        \\n"
+				test_suite_ok=0
+			else
+				printf "\rTEST: ${plugin} ${GREEN}[OK]${COLOR_RESET}        \\n"
+			fi
+		else
+			debugmsg "'${plugin}' is not executable"
+		fi
+	done
+else
+	debugmsg "plugin dir does not exist"
+fi
+
+echo
+for log_file in ${log_files}; do
+	if [[ -s "${log_file}" ]]; then
+		echo "LOG START: ${log_file}"
+		echo
+		cat "${log_file}"
+		echo
+		echo "LOG END: ${log_file}"
+	fi
 done
+echo
 
+if [[ ${test_suite_ok} -ne 1 ]]; then
+	errmsg "One or more tests have failed."
+else
+	print "All tests were successful."
+fi
+
+print ""
+
+# Cleaning up after all packages
+cleanup
+
 if [ -s $SETDEPS.missing ]; then
     print "Doing late evaluations of package dependencies."
     while read mdep; do
@@ -551,19 +616,4 @@
     done < $SETDEPS.missing
 fi
 
-if [ -s $SETLIBS.missing ]; then
-    print "Doing late evaluations of package library dependencies."
-    while read ldep; do
-	lib=`echo $ldep | nawk '{print $1}'`
-        [ "$lib" = "libm.so.2" ] && continue
-	pkg=`echo $ldep | nawk '{print $2}'`
-	/usr/bin/grep "[/=]$lib[ =]" $SETLIBS >/dev/null
-	if [ $? -ne 0 ]; then
-	    errmsg "Couldn't find a package providing $lib"
-	else
-	    print "A package in the set being evaluated provides $lib"
-	fi
-    done < $SETLIBS.missing
-fi
-
 cleanupset


Property changes on: csw/mgar/gar/v2/bin/checkpkg
___________________________________________________________________
Added: svn:keywords
   + Id

Deleted: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-dummy.py
===================================================================
--- csw/mgar/gar/v2-checkpkg/bin/checkpkg.d/checkpkg-dummy.py	2010-01-04 03:57:34 UTC (rev 7855)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-dummy.py	2010-01-04 10:28:15 UTC (rev 7856)
@@ -1,21 +0,0 @@
-#!/opt/csw/bin/python2.6
-# $Id$
-
-import checkpkg
-import os.path
-import logging
-
-def main():
-  options, args = checkpkg.GetOptions()
-  if not os.path.isdir(options.extractdir):
-  	raise checkpkg.PackageError("The extract base directory doesn't exist: %s" % options.extractdir)
-  for pkgname in args:
-    pkgpath = os.path.join(options.extractdir, pkgname)
-    if not os.path.isdir(pkgpath):
-      raise checkpkg.PackageError("The package directory doesn't exist: %s" % pkgpath)
-    logging.debug("Dummy plugin says the package %s is extracted to %s",
-                  pkgname, options.extractdir)
-
-
-if __name__ == '__main__':
-	main()

Copied: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-dummy.py (from rev 7855, csw/mgar/gar/v2-checkpkg/bin/checkpkg.d/checkpkg-dummy.py)
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-dummy.py	                        (rev 0)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-dummy.py	2010-01-04 10:28:15 UTC (rev 7856)
@@ -0,0 +1,21 @@
+#!/opt/csw/bin/python2.6
+# $Id$
+
+import checkpkg
+import os.path
+import logging
+
+def main():
+  options, args = checkpkg.GetOptions()
+  if not os.path.isdir(options.extractdir):
+  	raise checkpkg.PackageError("The extract base directory doesn't exist: %s" % options.extractdir)
+  for pkgname in args:
+    pkgpath = os.path.join(options.extractdir, pkgname)
+    if not os.path.isdir(pkgpath):
+      raise checkpkg.PackageError("The package directory doesn't exist: %s" % pkgpath)
+    logging.debug("Dummy plugin says the package %s is extracted to %s",
+                  pkgname, options.extractdir)
+
+
+if __name__ == '__main__':
+	main()

Deleted: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-libs.py
===================================================================
--- csw/mgar/gar/v2-checkpkg/bin/checkpkg.d/checkpkg-libs.py	2010-01-04 03:57:34 UTC (rev 7855)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-libs.py	2010-01-04 10:28:15 UTC (rev 7856)
@@ -1,225 +0,0 @@
-#!/opt/csw/bin/python2.6
-#
-# $Id$
-#
-# A check for dependencies between shared libraries.
-#
-# This is currently more of a prototype than a mature program, but it has some
-# unit tests and it appears to be working.  The main problem is that it's not
-# divided into smaller testable sections.
-
-import checkpkg
-import os
-import os.path
-import copy
-import re
-import subprocess
-import logging
-import sys
-import textwrap
-
-DUMP_BIN = "/usr/ccs/bin/dump"
-
-def GetIsalist():
-  args = ["isalist"]
-  isalist_proc = subprocess.Popen(args, stdout=subprocess.PIPE)
-  stdout, stderr = isalist_proc.communicate()
-  ret = isalist_proc.wait()
-  if ret:
-    logging.error("Calling isalist has failed.")
-  isalist = re.split(r"\s+", stdout.strip())
-  return isalist
-
-
-def main():
-  result_ok = True
-  errors = []
-  options, args = checkpkg.GetOptions()
-  pkgnames = args
-  if options.debug:
-    logging.basicConfig(level=logging.DEBUG)
-  else:
-    logging.basicConfig(level=logging.INFO)
-  checkers = []
-  for pkgname in pkgnames:
-    checker = checkpkg.CheckpkgBase(options.extractdir, pkgname)
-    checkers.append(checker)
-  binaries = []
-  binaries_by_pkgname = {}
-  sonames_by_pkgname = {}
-  pkg_by_any_filename = {}
-  for checker in checkers:
-    pkg_binary_paths = checker.ListBinaries()
-    binaries_base = [os.path.split(x)[1] for x in pkg_binary_paths]
-    binaries_by_pkgname[checker.pkgname] = binaries_base
-    binaries.extend(pkg_binary_paths)
-    for filename in checker.GetAllFilenames():
-      pkg_by_any_filename[filename] = checker.pkgname
-  # Making the binaries unique
-  binaries = set(binaries)
-  ws_re = re.compile(r"\s+")
-
-  # man ld.so.1 for more info on this hack
-  env = copy.copy(os.environ)
-  env["LD_NOAUXFLTR"] = "1"
-  needed_sonames_by_binary = {}
-  filenames_by_soname = {}
-  # Assembling a data structure with the data about binaries.
-  # {
-  #   <binary1 name>: { checkpkg.NEEDED_SONAMES: [...],
-  #                     checkpkg.RUNPATH:        [...]},
-  #   <binary2 name>: ...,
-  #   ...
-  # }
-  #
-  for binary in binaries:
-    binary_base_name = binary.split("/")[-1]
-    args = [DUMP_BIN, "-Lv", binary]
-    dump_proc = subprocess.Popen(args, stdout=subprocess.PIPE, env=env)
-    stdout, stderr = dump_proc.communicate()
-    ret = dump_proc.wait()
-    binary_data = checkpkg.ParseDumpOutput(stdout)
-    needed_sonames_by_binary[binary_base_name] = binary_data
-    if checkpkg.SONAME not in binary_data:
-      logging.info("The %s shared library doesn't provide a SONAME.",
-                   binary_base_name)
-      # The shared library doesn't tell its SONAME.  We're guessing it's the
-      # same as the base file name.
-      binary_data[checkpkg.SONAME] = binary_base_name
-    filenames_by_soname[binary_data[checkpkg.SONAME]] = binary_base_name
-
-  isalist = GetIsalist()
-
-  # Building indexes by soname to simplify further processing
-  # These are indexes "by soname".
-  (needed_sonames,
-   binaries_by_soname,
-   runpath_by_needed_soname) = checkpkg.BuildIndexesBySoname(
-       needed_sonames_by_binary)
-
-  pkgmap = checkpkg.SystemPkgmap()
-  logging.debug("Determining the soname-package relationships.")
-  # lines by soname is an equivalent of $EXTRACTDIR/shortcatalog
-  lines_by_soname = checkpkg.GetLinesBySoname(
-      pkgmap, needed_sonames, runpath_by_needed_soname, isalist)
-
-  # Creating a map from files to packages.
-  pkgs_by_filename = {}
-  for soname, line in lines_by_soname.iteritems():
-    # TODO: Find all the packages, not just the last field.
-    fields = re.split(ws_re, line.strip())
-    # For now, we'll assume that the last field is the package.
-    pkgname = fields[-1]
-    pkgs_by_filename[soname] = pkgname
-
-  # A shared object dependency/provisioning report, plus checking.
-  #
-  # This section is somewhat overlapping with checkpkg.AnalyzeDependencies(),
-  # it has a different purpose: it reports the relationships between shared
-  # libraries, binaries using them and packages providing them.  Ideally, the
-  # same bit of code with do checking and reporting.
-  #
-  # TODO: Rewrite this using cheetah templates
-  if needed_sonames:
-    print "Analysis of sonames needed by the package set:"
-    binaries_with_missing_sonames = set([])
-    for soname in needed_sonames:
-      logging.debug("Analyzing: %s", soname)
-      if soname in filenames_by_soname:
-        print "%s is provided by the package itself" % soname
-      elif soname in lines_by_soname:
-        print ("%s is provided by %s and required by:" 
-               % (soname,
-                  repr(pkgs_by_filename[soname])))
-        filename_lines = " ".join(sorted(binaries_by_soname[soname]))
-        for line in textwrap.wrap(filename_lines, 70):
-          print " ", line
-      else:
-        print ("%s is required by %s, but we don't know what provides it."
-               % (soname, binaries_by_soname[soname]))
-        for binary in binaries_by_soname[soname]:
-          binaries_with_missing_sonames.add(binary)
-        if soname in checkpkg.ALLOWED_ORPHAN_SONAMES:
-          print "However, it's a whitelisted soname."
-        else:
-          errors.append(
-              checkpkg.Error("%s is required by %s, but "
-                             "we don't know what provides it."
-                             % (soname, binaries_by_soname[soname])))
-    if binaries_with_missing_sonames:
-      print "The following are binaries with missing sonames:"
-      binary_lines = " ".join(sorted(binaries_with_missing_sonames))
-      for line in textwrap.wrap(binary_lines, 70):
-        print " ", line
-    print
-
-  dependent_pkgs = {}
-  for checker in checkers:
-    pkgname = checker.pkgname
-    declared_dependencies = checker.GetDependencies()
-    if options.debug:
-      sanitized_pkgname = pkgname.replace("-", "_")
-      data_file_name = "/var/tmp/checkpkg_test_data_%s.py" % sanitized_pkgname
-      logging.warn("Saving test data to %s." % repr(data_file_name))
-      test_fd = open(data_file_name, "w")
-      print >>test_fd, "# Testing data for %s" % pkgname
-      print >>test_fd, "# $Id$"
-      print >>test_fd, "DATA_PKGNAME                  =", repr(pkgname)
-      print >>test_fd, "DATA_DECLARED_DEPENDENCIES    =", repr(declared_dependencies)
-      print >>test_fd, "DATA_BINARIES_BY_PKGNAME      =", repr(binaries_by_pkgname)
-      print >>test_fd, "DATA_NEEDED_SONAMES_BY_BINARY =", repr(needed_sonames_by_binary)
-      print >>test_fd, "DATA_PKGS_BY_FILENAME         =", repr(pkgs_by_filename)
-      print >>test_fd, "DATA_FILENAMES_BY_SONAME      =", repr(filenames_by_soname)
-      print >>test_fd, "DATA_PKG_BY_ANY_FILENAME      =", repr(pkg_by_any_filename)
-      print >>test_fd, "DATA_LINES_BY_SONAME          =", repr(lines_by_soname)
-      print >>test_fd, "DATA_PKGMAP_CACHE             =", repr(pkgmap.cache)
-      print >>test_fd, "DATA_BINARIES_BY_SONAME       =", repr(binaries_by_soname)
-      print >>test_fd, "DATA_ISALIST                  =", repr(isalist)
-      test_fd.close()
-
-    missing_deps, surplus_deps, orphan_sonames = checkpkg.AnalyzeDependencies(
-        pkgname,
-        declared_dependencies,
-        binaries_by_pkgname,
-        needed_sonames_by_binary,
-        pkgs_by_filename,
-        filenames_by_soname,
-        pkg_by_any_filename)
-
-    # TODO: Rewrite this using cheetah templates.
-    print "%s:" % pkgname
-    msg_printed = False
-    if missing_deps:
-      print "SUGGESTION: you may want to add some or all of the following as depends:"
-      print "   (Feel free to ignore SUNW or SPRO packages)"
-      for dep_pkgname in sorted(missing_deps):
-        print ">", dep_pkgname
-      msg_printed = True
-    if surplus_deps:
-      print "The following packages might be unnecessary dependencies:"
-      for dep_pkgname in surplus_deps:
-        print "? ", dep_pkgname
-      msg_printed = True
-    if orphan_sonames:
-      print "The following sonames don't belong to any package:"
-      for soname in sorted(orphan_sonames):
-        errors.append(checkpkg.Error("The following soname does't belong to "
-                                     "any package: %s" % soname))
-        print "! ", soname
-      msg_printed = True
-    if not msg_printed:
-      print "+  Dependencies of %s look good." % pkgname
-    print
-
-  if errors:
-    for error in errors:
-      logging.error(error)
-    sys.exit(1)
-  else:
-    sys.exit(0)
-
-
-if __name__ == '__main__':
-  main()
-
-# vim:set sw=2 ts=2 sts=2 expandtab:

Copied: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-libs.py (from rev 7855, csw/mgar/gar/v2-checkpkg/bin/checkpkg.d/checkpkg-libs.py)
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-libs.py	                        (rev 0)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-libs.py	2010-01-04 10:28:15 UTC (rev 7856)
@@ -0,0 +1,225 @@
+#!/opt/csw/bin/python2.6
+#
+# $Id$
+#
+# A check for dependencies between shared libraries.
+#
+# This is currently more of a prototype than a mature program, but it has some
+# unit tests and it appears to be working.  The main problem is that it's not
+# divided into smaller testable sections.
+
+import checkpkg
+import os
+import os.path
+import copy
+import re
+import subprocess
+import logging
+import sys
+import textwrap
+
+DUMP_BIN = "/usr/ccs/bin/dump"
+
+def GetIsalist():
+  args = ["isalist"]
+  isalist_proc = subprocess.Popen(args, stdout=subprocess.PIPE)
+  stdout, stderr = isalist_proc.communicate()
+  ret = isalist_proc.wait()
+  if ret:
+    logging.error("Calling isalist has failed.")
+  isalist = re.split(r"\s+", stdout.strip())
+  return isalist
+
+
+def main():
+  result_ok = True
+  errors = []
+  options, args = checkpkg.GetOptions()
+  pkgnames = args
+  if options.debug:
+    logging.basicConfig(level=logging.DEBUG)
+  else:
+    logging.basicConfig(level=logging.INFO)
+  checkers = []
+  for pkgname in pkgnames:
+    checker = checkpkg.CheckpkgBase(options.extractdir, pkgname)
+    checkers.append(checker)
+  binaries = []
+  binaries_by_pkgname = {}
+  sonames_by_pkgname = {}
+  pkg_by_any_filename = {}
+  for checker in checkers:
+    pkg_binary_paths = checker.ListBinaries()
+    binaries_base = [os.path.split(x)[1] for x in pkg_binary_paths]
+    binaries_by_pkgname[checker.pkgname] = binaries_base
+    binaries.extend(pkg_binary_paths)
+    for filename in checker.GetAllFilenames():
+      pkg_by_any_filename[filename] = checker.pkgname
+  # Making the binaries unique
+  binaries = set(binaries)
+  ws_re = re.compile(r"\s+")
+
+  # man ld.so.1 for more info on this hack
+  env = copy.copy(os.environ)
+  env["LD_NOAUXFLTR"] = "1"
+  needed_sonames_by_binary = {}
+  filenames_by_soname = {}
+  # Assembling a data structure with the data about binaries.
+  # {
+  #   <binary1 name>: { checkpkg.NEEDED_SONAMES: [...],
+  #                     checkpkg.RUNPATH:        [...]},
+  #   <binary2 name>: ...,
+  #   ...
+  # }
+  #
+  for binary in binaries:
+    binary_base_name = binary.split("/")[-1]
+    args = [DUMP_BIN, "-Lv", binary]
+    dump_proc = subprocess.Popen(args, stdout=subprocess.PIPE, env=env)
+    stdout, stderr = dump_proc.communicate()
+    ret = dump_proc.wait()
+    binary_data = checkpkg.ParseDumpOutput(stdout)
+    needed_sonames_by_binary[binary_base_name] = binary_data
+    if checkpkg.SONAME not in binary_data:
+      logging.info("The %s shared library doesn't provide a SONAME.",
+                   binary_base_name)
+      # The shared library doesn't tell its SONAME.  We're guessing it's the
+      # same as the base file name.
+      binary_data[checkpkg.SONAME] = binary_base_name
+    filenames_by_soname[binary_data[checkpkg.SONAME]] = binary_base_name
+
+  isalist = GetIsalist()
+
+  # Building indexes by soname to simplify further processing
+  # These are indexes "by soname".
+  (needed_sonames,
+   binaries_by_soname,
+   runpath_by_needed_soname) = checkpkg.BuildIndexesBySoname(
+       needed_sonames_by_binary)
+
+  pkgmap = checkpkg.SystemPkgmap()
+  logging.debug("Determining the soname-package relationships.")
+  # lines by soname is an equivalent of $EXTRACTDIR/shortcatalog
+  lines_by_soname = checkpkg.GetLinesBySoname(
+      pkgmap, needed_sonames, runpath_by_needed_soname, isalist)
+
+  # Creating a map from files to packages.
+  pkgs_by_filename = {}
+  for soname, line in lines_by_soname.iteritems():
+    # TODO: Find all the packages, not just the last field.
+    fields = re.split(ws_re, line.strip())
+    # For now, we'll assume that the last field is the package.
+    pkgname = fields[-1]
+    pkgs_by_filename[soname] = pkgname
+
+  # A shared object dependency/provisioning report, plus checking.
+  #
+  # This section is somewhat overlapping with checkpkg.AnalyzeDependencies(),
+  # it has a different purpose: it reports the relationships between shared
+  # libraries, binaries using them and packages providing them.  Ideally, the
+  # same bit of code with do checking and reporting.
+  #
+  # TODO: Rewrite this using cheetah templates
+  if needed_sonames:
+    print "Analysis of sonames needed by the package set:"
+    binaries_with_missing_sonames = set([])
+    for soname in needed_sonames:
+      logging.debug("Analyzing: %s", soname)
+      if soname in filenames_by_soname:
+        print "%s is provided by the package itself" % soname
+      elif soname in lines_by_soname:
+        print ("%s is provided by %s and required by:" 
+               % (soname,
+                  repr(pkgs_by_filename[soname])))
+        filename_lines = " ".join(sorted(binaries_by_soname[soname]))
+        for line in textwrap.wrap(filename_lines, 70):
+          print " ", line
+      else:
+        print ("%s is required by %s, but we don't know what provides it."
+               % (soname, binaries_by_soname[soname]))
+        for binary in binaries_by_soname[soname]:
+          binaries_with_missing_sonames.add(binary)
+        if soname in checkpkg.ALLOWED_ORPHAN_SONAMES:
+          print "However, it's a whitelisted soname."
+        else:
+          errors.append(
+              checkpkg.Error("%s is required by %s, but "
+                             "we don't know what provides it."
+                             % (soname, binaries_by_soname[soname])))
+    if binaries_with_missing_sonames:
+      print "The following are binaries with missing sonames:"
+      binary_lines = " ".join(sorted(binaries_with_missing_sonames))
+      for line in textwrap.wrap(binary_lines, 70):
+        print " ", line
+    print
+
+  dependent_pkgs = {}
+  for checker in checkers:
+    pkgname = checker.pkgname
+    declared_dependencies = checker.GetDependencies()
+    if options.debug:
+      sanitized_pkgname = pkgname.replace("-", "_")
+      data_file_name = "/var/tmp/checkpkg_test_data_%s.py" % sanitized_pkgname
+      logging.warn("Saving test data to %s." % repr(data_file_name))
+      test_fd = open(data_file_name, "w")
+      print >>test_fd, "# Testing data for %s" % pkgname
+      print >>test_fd, "# $Id$"
+      print >>test_fd, "DATA_PKGNAME                  =", repr(pkgname)
+      print >>test_fd, "DATA_DECLARED_DEPENDENCIES    =", repr(declared_dependencies)
+      print >>test_fd, "DATA_BINARIES_BY_PKGNAME      =", repr(binaries_by_pkgname)
+      print >>test_fd, "DATA_NEEDED_SONAMES_BY_BINARY =", repr(needed_sonames_by_binary)
+      print >>test_fd, "DATA_PKGS_BY_FILENAME         =", repr(pkgs_by_filename)
+      print >>test_fd, "DATA_FILENAMES_BY_SONAME      =", repr(filenames_by_soname)
+      print >>test_fd, "DATA_PKG_BY_ANY_FILENAME      =", repr(pkg_by_any_filename)
+      print >>test_fd, "DATA_LINES_BY_SONAME          =", repr(lines_by_soname)
+      print >>test_fd, "DATA_PKGMAP_CACHE             =", repr(pkgmap.cache)
+      print >>test_fd, "DATA_BINARIES_BY_SONAME       =", repr(binaries_by_soname)
+      print >>test_fd, "DATA_ISALIST                  =", repr(isalist)
+      test_fd.close()
+
+    missing_deps, surplus_deps, orphan_sonames = checkpkg.AnalyzeDependencies(
+        pkgname,
+        declared_dependencies,
+        binaries_by_pkgname,
+        needed_sonames_by_binary,
+        pkgs_by_filename,
+        filenames_by_soname,
+        pkg_by_any_filename)
+
+    # TODO: Rewrite this using cheetah templates.
+    print "%s:" % pkgname
+    msg_printed = False
+    if missing_deps:
+      print "SUGGESTION: you may want to add some or all of the following as depends:"
+      print "   (Feel free to ignore SUNW or SPRO packages)"
+      for dep_pkgname in sorted(missing_deps):
+        print ">", dep_pkgname
+      msg_printed = True
+    if surplus_deps:
+      print "The following packages might be unnecessary dependencies:"
+      for dep_pkgname in surplus_deps:
+        print "? ", dep_pkgname
+      msg_printed = True
+    if orphan_sonames:
+      print "The following sonames don't belong to any package:"
+      for soname in sorted(orphan_sonames):
+        errors.append(checkpkg.Error("The following soname does't belong to "
+                                     "any package: %s" % soname))
+        print "! ", soname
+      msg_printed = True
+    if not msg_printed:
+      print "+  Dependencies of %s look good." % pkgname
+    print
+
+  if errors:
+    for error in errors:
+      logging.error(error)
+    sys.exit(1)
+  else:
+    sys.exit(0)
+
+
+if __name__ == '__main__':
+  main()
+
+# vim:set sw=2 ts=2 sts=2 expandtab:

Deleted: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-obsolete-deps.py
===================================================================
--- csw/mgar/gar/v2-checkpkg/bin/checkpkg.d/checkpkg-obsolete-deps.py	2010-01-04 03:57:34 UTC (rev 7855)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-obsolete-deps.py	2010-01-04 10:28:15 UTC (rev 7856)
@@ -1,43 +0,0 @@
-#!/opt/csw/bin/python2.6
-# $Id$
-
-import checkpkg
-import logging
-import os.path
-import sys
-
-OBSOLETE_DEPS = {
-    # "CSWfoo": {
-    #   "hint": "Do this...",
-    #   "url": "http://www.opencsw.org/bugtrack/view.php?id=..."
-    # },
-    "CSWpython-rt": {
-      "hint": "CSWpython-rt is deprecated, use CSWpython instead.",
-      "url": "http://www.opencsw.org/bugtrack/view.php?id=4031"
-    },
-}
-
-def main():
-  options, args = checkpkg.GetOptions()
-  ok = True
-  for pkgname in args:
-    pkgpath = os.path.join(options.extractdir, pkgname)
-    checker = checkpkg.CheckpkgBase(options.extractdir, pkgname)
-    deps = set(checker.GetDependencies())
-    obsolete_pkg_deps = deps.intersection(set(OBSOLETE_DEPS))
-    if obsolete_pkg_deps:
-      ok = False
-      for pkg in obsolete_pkg_deps:
-        print ("ERROR: Package %s should not depend on %s."
-               % (checker.pkgname, pkg))
-        if "hint" in OBSOLETE_DEPS[pkg]:
-          print "Hint:", OBSOLETE_DEPS[pkg]["hint"]
-        if "url" in OBSOLETE_DEPS[pkg]:
-          print "URL:", OBSOLETE_DEPS[pkg]["url"]
-  if ok:
-    sys.exit(0)
-  else:
-    sys.exit(1)
-
-if __name__ == '__main__':
-  main()

Copied: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-obsolete-deps.py (from rev 7855, csw/mgar/gar/v2-checkpkg/bin/checkpkg.d/checkpkg-obsolete-deps.py)
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-obsolete-deps.py	                        (rev 0)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-obsolete-deps.py	2010-01-04 10:28:15 UTC (rev 7856)
@@ -0,0 +1,43 @@
+#!/opt/csw/bin/python2.6
+# $Id$
+
+import checkpkg
+import logging
+import os.path
+import sys
+
+OBSOLETE_DEPS = {
+    # "CSWfoo": {
+    #   "hint": "Do this...",
+    #   "url": "http://www.opencsw.org/bugtrack/view.php?id=..."
+    # },
+    "CSWpython-rt": {
+      "hint": "CSWpython-rt is deprecated, use CSWpython instead.",
+      "url": "http://www.opencsw.org/bugtrack/view.php?id=4031"
+    },
+}
+
+def main():
+  options, args = checkpkg.GetOptions()
+  ok = True
+  for pkgname in args:
+    pkgpath = os.path.join(options.extractdir, pkgname)
+    checker = checkpkg.CheckpkgBase(options.extractdir, pkgname)
+    deps = set(checker.GetDependencies())
+    obsolete_pkg_deps = deps.intersection(set(OBSOLETE_DEPS))
+    if obsolete_pkg_deps:
+      ok = False
+      for pkg in obsolete_pkg_deps:
+        print ("ERROR: Package %s should not depend on %s."
+               % (checker.pkgname, pkg))
+        if "hint" in OBSOLETE_DEPS[pkg]:
+          print "Hint:", OBSOLETE_DEPS[pkg]["hint"]
+        if "url" in OBSOLETE_DEPS[pkg]:
+          print "URL:", OBSOLETE_DEPS[pkg]["url"]
+  if ok:
+    sys.exit(0)
+  else:
+    sys.exit(1)
+
+if __name__ == '__main__':
+  main()

Deleted: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg.py
===================================================================
--- csw/mgar/gar/v2-checkpkg/bin/checkpkg.d/checkpkg.py	2010-01-04 03:57:34 UTC (rev 7855)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg.py	2010-01-04 10:28:15 UTC (rev 7856)
@@ -1,486 +0,0 @@
-# $Id$
-#
-# This is the checkpkg library, common for all checkpkg tests written in
-# Python.
-
-import itertools
-import logging
-import optparse
-import os
-import os.path
-import re
-import socket
-import sqlite3
-import subprocess
-
-SYSTEM_PKGMAP = "/var/sadm/install/contents"
-WS_RE = re.compile(r"\s+")
-NEEDED_SONAMES = "needed sonames"
-RUNPATH = "runpath"
-SONAME = "soname"
-CONFIG_MTIME = "mtime"
-DO_NOT_REPORT_SURPLUS = set([u"CSWcommon", u"CSWcswclassutils", u"CSWisaexec"])
-DO_NOT_REPORT_MISSING = set([u"SUNWlibC", u"SUNWcsl", u"SUNWlibms",
-                             u"*SUNWcslr", u"*SUNWlibC", u"*SUNWlibms"])
-
-# This shared library is present on Solaris 10 on amd64, but it's missing on
-# Solaris 8 on i386.  It's okay if it's missing.
-ALLOWED_ORPHAN_SONAMES = set([u"libm.so.2"])
-
-class Error(Exception):
-  pass
-
-
-class ConfigurationError(Error):
-  pass
-
-
-class PackageError(Error):
-  pass
-
-
-def GetOptions():
-  parser = optparse.OptionParser()
-  parser.add_option("-e", dest="extractdir",
-                    help="The directory into which the package has been extracted")
-  parser.add_option("-d", "--debug", dest="debug",
-                    default=False, action="store_true",
-                    help="Turn on debugging messages")
-  (options, args) = parser.parse_args()
-  if not options.extractdir:
-    raise ConfigurationError("ERROR: -e option is missing.")
-  # Using set() to make the arguments unique.
-  return options, set(args)
-
-
-class CheckpkgBase(object):
-  """This class has functionality overlapping with DirectoryFormatPackage
-  from the opencsw.py library. The classes should be merged.
-  """
-
-  def __init__(self, extractdir, pkgname):
-    self.extractdir = extractdir
-    self.pkgname = pkgname
-    self.pkgpath = os.path.join(self.extractdir, self.pkgname)
-
-  def CheckPkgpathExists(self):
-    if not os.path.isdir(self.pkgpath):
-      raise PackageError("%s does not exist or is not a directory"
-                         % self.pkgpath)
-
-  def ListBinaries(self):
-    """Shells out to list all the binaries from a given package.
-
-    Original checkpkg code:
-
-    # #########################################
-    # # find all executables and dynamic libs,and list their filenames.
-    # listbinaries() {
-    #   if [ ! -d $1 ] ; then
-    #     print errmsg $1 not a directory
-    #     rm -rf $EXTRACTDIR
-    #     exit 1
-    #   fi
-    # 
-    #   find $1 -print | xargs file |grep ELF |nawk -F: '{print $1}'
-    # }
-    """
-    self.CheckPkgpathExists()
-    find_tmpl = "find %s -print | xargs file | grep ELF | nawk -F: '{print $1}'"
-    find_proc = subprocess.Popen(find_tmpl % self.pkgpath,
-                                 shell=True, stdout=subprocess.PIPE)
-    stdout, stderr = find_proc.communicate()
-    ret = find_proc.wait()
-    if ret:
-      logging.error("The find command returned an error.")
-    return stdout.splitlines()
-
-  def GetAllFilenames(self):
-    self.CheckPkgpathExists()
-    file_basenames = []
-    for root, dirs, files in os.walk(self.pkgpath):
-      file_basenames.extend(files)
-    return file_basenames
-
-  def GetDependencies(self):
-    fd = open(os.path.join(self.pkgpath, "install", "depend"), "r")
-    depends = {}
-    for line in fd:
-      fields = re.split(WS_RE, line)
-      if fields[0] == "P":
-        depends[fields[1]] = " ".join(fields[1:])
-    fd.close()
-    return depends
-
-
-class SystemPkgmap(object):
-  """A class to hold and manipulate the /var/sadm/install/contents file.
-
-  TODO: Implement timestamp checking and refreshing the cache.
-  """
-  
-  STOP_PKGS = ["SUNWbcp", "SUNWowbcp", "SUNWucb"] 
-  CHECKPKG_DIR = ".checkpkg"
-  SQLITE3_DBNAME_TMPL = "var-sadm-install-contents-cache-%s"
-
-  def __init__(self):
-    """There is no need to re-parse it each time.
-
-    Read it slowly the first time and cache it for later."""
-    self.cache = {}
-    self.checkpkg_dir = os.path.join(os.environ["HOME"], self.CHECKPKG_DIR)
-    self.fqdn = socket.getfqdn()
-    self.db_path = os.path.join(self.checkpkg_dir,
-                                self.SQLITE3_DBNAME_TMPL % self.fqdn)
-    self.file_mtime = None
-    self.cache_mtime = None
-    if os.path.exists(self.db_path):
-      logging.debug("Connecting to the %s database.", self.db_path)
-      self.conn = sqlite3.connect(self.db_path)
-      if not self.IsDatabaseUpToDate():
-        self.PurgeDatabase()
-        self.PopulateDatabase()
-    else:
-      print "Building a cache of /var/sadm/install/contents."
-      print "The cache will be kept in %s." % self.db_path
-      if not os.path.exists(self.checkpkg_dir):
-        logging.debug("Creating %s", self.checkpkg_dir)
-        os.mkdir(self.checkpkg_dir)
-      self.conn = sqlite3.connect(self.db_path)
-      c = self.conn.cursor()
-      c.execute("""
-          CREATE TABLE systempkgmap (
-            id INTEGER PRIMARY KEY,
-            basename TEXT,
-            path TEXT,
-            line TEXT
-          );
-      """)
-      logging.debug("Creating the config table.")
-      c.execute("""
-          CREATE TABLE config (
-            key VARCHAR(255) PRIMARY KEY,
-            float_value FLOAT,
-            str_value VARCHAR(255)
-          );
-      """)
-      self.PopulateDatabase()
-
-  def PopulateDatabase(self):
-    """Imports data into the database.
-
-    Original bit of code from checkpkg:
-    
-    egrep -v 'SUNWbcp|SUNWowbcp|SUNWucb' /var/sadm/install/contents |
-        fgrep -f $EXTRACTDIR/liblist >$EXTRACTDIR/shortcatalog
-    """
-
-    system_pkgmap_fd = open(SYSTEM_PKGMAP, "r")
-    stop_re = re.compile("(%s)" % "|".join(self.STOP_PKGS))
-    # Creating a data structure:
-    # soname - {<path1>: <line1>, <path2>: <line2>, ...}
-    logging.debug("Building sqlite3 cache db of the %s file",
-                  SYSTEM_PKGMAP)
-    c = self.conn.cursor()
-    count = itertools.count()
-    for line in system_pkgmap_fd:
-      i = count.next()
-      if not i % 1000:
-        print "\r%s" % i,
-      if stop_re.search(line):
-        continue
-      fields = re.split(WS_RE, line)
-      pkgmap_entry_path = fields[0].split("=")[0]
-      pkgmap_entry_dir, pkgmap_entry_base_name = os.path.split(pkgmap_entry_path)
-      sql = "INSERT INTO systempkgmap (basename, path, line) VALUES (?, ?, ?);"
-      c.execute(sql, (pkgmap_entry_base_name, pkgmap_entry_dir, line.strip()))
-    print
-    print "Creating the main database index."
-    sql = "CREATE INDEX basename_idx ON systempkgmap(basename);"
-    c.execute(sql)
-    self.SetDatabaseMtime()
-    self.conn.commit()
-
-  def SetDatabaseMtime(self):
-    c = self.conn.cursor()
-    sql = "DELETE FROM config WHERE key = ?;"
-    c.execute(sql, [CONFIG_MTIME])
-    mtime = self.GetFileMtime()
-    logging.debug("Inserting the mtime (%s) into the database.", mtime)
-    sql = """
-    INSERT INTO config (key, float_value)
-    VALUES (?, ?);
-    """
-    c.execute(sql, [CONFIG_MTIME, mtime])
-
-  def GetPkgmapLineByBasename(self, filename):
-    if filename in self.cache:
-      return self.cache[filename]
-    sql = "SELECT path, line FROM systempkgmap WHERE basename = ?;"
-    c = self.conn.cursor()
-    c.execute(sql, [filename])
-    lines = {}
-    for row in c:
-      lines[row[0]] = row[1]
-    if len(lines) == 0:
-      logging.debug("Cache doesn't contain filename %s", filename)
-    self.cache[filename] = lines
-    return lines
-
-  def GetDatabaseMtime(self):
-    if not self.cache_mtime:
-      sql = """
-      SELECT float_value FROM config
-      WHERE key = ?;
-      """
-      c = self.conn.cursor()
-      c.execute(sql, [CONFIG_MTIME])
-      row = c.fetchone()
-      if not row:
-      	# raise ConfigurationError("Could not find the mtime setting")
-        self.cache_mtime = 1
-      else:
-        self.cache_mtime = row[0]
-    return self.cache_mtime
-
-  def GetFileMtime(self):
-    if not self.file_mtime:
-      stat_data = os.stat(SYSTEM_PKGMAP)
-      self.file_mtime = stat_data.st_mtime
-    return self.file_mtime
-
-  def IsDatabaseUpToDate(self):
-    f_mtime = self.GetFileMtime()
-    d_mtime = self.GetDatabaseMtime()
-    logging.debug("f_mtime", f_mtime, "d_time", d_mtime)
-    return self.GetFileMtime() <= self.GetDatabaseMtime()
-
-  def PurgeDatabase(self):
-    c = self.conn.cursor()
-    sql = "DELETE FROM config;"
-    c.execute(sql)
-    sql = "DELETE FROM systempkgmap;"
-    c.execute(sql)
-    sql = "DROP INDEX basename_idx;"
-    try:
-      c.execute(sql)
-    except sqlite3.OperationalError, e:
-      logging.warn(e)
-
-def SharedObjectDependencies(pkgname,
-                             binaries_by_pkgname,
-                             needed_sonames_by_binary,
-                             pkgs_by_soname,
-                             filenames_by_soname,
-                             pkg_by_any_filename):
-  """This is one of the more obscure and more important pieces of code.
-
-  I tried to make it simpler, but given that the operations here involve
-  whole sets of packages, it's not easy.
-  """
-  so_dependencies = set()
-  orphan_sonames = set()
-  self_provided = set()
-  for binary in binaries_by_pkgname[pkgname]:
-    needed_sonames = needed_sonames_by_binary[binary][NEEDED_SONAMES]
-    for soname in needed_sonames:
-      if soname in filenames_by_soname:
-        filename = filenames_by_soname[soname]
-        pkg = pkg_by_any_filename[filename]
-        self_provided.add(soname)
-        so_dependencies.add(pkg)
-      elif soname in pkgs_by_soname:
-        so_dependencies.add(pkgs_by_soname[soname])
-      else:
-        orphan_sonames.add(soname)
-  return so_dependencies, self_provided, orphan_sonames
-
-
-def GuessDepsByFilename(pkgname, pkg_by_any_filename):
-  """Guesses dependencies based on filename regexes."""
-  guessed_deps = set()
-  patterns = (
-      (r".*\.py", u"CSWpython"),
-      (r".*\.pl", u"CSWperl"),
-      (r".*\.rb", u"CSWruby"),
-  )
-  for pattern, dep_pkgname in patterns:
-    # If any file name matches, add the dep, go to the next pattern/pkg
-    # combination.
-    pattern_re = re.compile("^%s$" % pattern)
-    for filename in pkg_by_any_filename:
-      if (re.match(pattern_re, filename)
-            and
-          pkgname == pkg_by_any_filename[filename]):
-        guessed_deps.add(dep_pkgname)
-        break
-  return guessed_deps
-
-
-def GuessDepsByPkgname(pkgname, pkg_by_any_filename):
-  # More guessed dependencies: If one package is a substring of another, it
-  # might be a hint. For example, CSWmysql51test should depend on CSWmysql51.
-  # However, the rt (runtime) packages should not want to depend on the main
-  # package.
-  guessed_deps = set()
-  all_other_pkgs = set(pkg_by_any_filename.values())
-  for other_pkg in all_other_pkgs:
-    other_pkg = unicode(other_pkg)
-    if pkgname == other_pkg:
-      continue
-    if pkgname.startswith(other_pkg):
-      endings = ["devel", "test", "bench", "dev"]
-      for ending in endings:
-        if pkgname.endswith(ending):
-          guessed_deps.add(other_pkg)
-  return guessed_deps
-
-
-def AnalyzeDependencies(pkgname,
-                        declared_dependencies,
-                        binaries_by_pkgname,
-                        needed_sonames_by_binary,
-                        pkgs_by_soname,
-                        filenames_by_soname,
-                        pkg_by_any_filename):
-  """Gathers and merges dependency results from other functions.
-
-  declared_dependencies: Dependencies that the package in question claims to
-                         have.
-
-  binaries_by_pkgname: A dictionary mapping pkgnames (CSWfoo) to binary names
-                       (without paths)
-
-  needed_sonames_by_binary: A dictionary mapping binary file name to
-                            a dictionary containing: "needed sonames",
-                            "soname", "rpath". Based on examining the binary
-                            files within the packages.
-
-  pkgs_by_soname: A dictionary mapping sonames to pkgnames, based on the
-                  contents of the system wide pkgmap
-                  (/var/sadm/install/contents)
-
-  filenames_by_soname: A dictionary mapping shared library sonames to filenames,
-                       based on files within packages
-
-  pkg_by_any_filename: Mapping from file names to packages names, based on the
-                       contents of the packages under examination.
-  """
-  declared_dependencies_set = set(declared_dependencies)
-
-  so_dependencies, self_provided, orphan_sonames = SharedObjectDependencies(
-      pkgname,
-      binaries_by_pkgname,
-      needed_sonames_by_binary,
-      pkgs_by_soname,
-      filenames_by_soname,
-      pkg_by_any_filename)
-  auto_dependencies = reduce(lambda x, y: x.union(y),
-      [
-        so_dependencies,
-        GuessDepsByFilename(pkgname, pkg_by_any_filename),
-        GuessDepsByPkgname(pkgname, pkg_by_any_filename),
-      ])
-  missing_deps = auto_dependencies.difference(declared_dependencies_set)
-  # Don't report itself as a suggested dependency.
-  missing_deps = missing_deps.difference(set([pkgname]))
-  missing_deps = missing_deps.difference(set(DO_NOT_REPORT_MISSING))
-  surplus_deps = declared_dependencies_set.difference(auto_dependencies)
-  surplus_deps = surplus_deps.difference(DO_NOT_REPORT_SURPLUS)
-  orphan_sonames = orphan_sonames.difference(ALLOWED_ORPHAN_SONAMES)
-  return missing_deps, surplus_deps, orphan_sonames
-
-
-def ExpandRunpath(runpath, isalist):
-  # Emulating $ISALIST expansion
-  if '$ISALIST' in runpath:
-    expanded_list = [runpath.replace('$ISALIST', isa) for isa in isalist]
-  else:
-    expanded_list = [runpath]
-  return expanded_list
-
-def Emulate64BitSymlinks(runpath_list):
-  """Need to emulate the 64 -> amd64, 64 -> sparcv9 symlink
-
-  Since we don't know the architecture, we'll adding both amd64 and sparcv9.
-  It should be safe.
-  """
-  symlinked_list = []
-  for runpath in runpath_list:
-    if "/64" in runpath:
-      symlinked_list.append(runpath.replace("/64", "/amd64"))
-      symlinked_list.append(runpath.replace("/64", "/sparcv9"))
-    else:
-      symlinked_list.append(runpath)
-  return symlinked_list
-
-
-def GetLinesBySoname(pkgmap, needed_sonames, runpath_by_needed_soname, isalist):
-  """Works out which system pkgmap lines correspond to given sonames."""
-  lines_by_soname = {}
-  for soname in needed_sonames:
-    # This is the critical part of the algorithm: it iterates over the
-    # runpath and finds the first matching one.
-    runpath_found = False
-    for runpath in runpath_by_needed_soname[soname]:
-      runpath_list = ExpandRunpath(runpath, isalist)
-      runpath_list = Emulate64BitSymlinks(runpath_list)
-      soname_runpath_data = pkgmap.GetPkgmapLineByBasename(soname)
-      logging.debug("%s: will be looking for %s in %s" %
-                    (soname, runpath_list, soname_runpath_data.keys()))
-      for runpath_expanded in runpath_list:
-        if runpath_expanded in soname_runpath_data:
-          lines_by_soname[soname] = soname_runpath_data[runpath_expanded]
-          runpath_found = True
-          # This break only goes out of the inner loop,
-          # need another one below to finish the outer loop.
-          break
-      if runpath_found:
-        break
-  return lines_by_soname
-
-
-def BuildIndexesBySoname(needed_sonames_by_binary):
-  """Builds data structures indexed by soname.
-
-  Building indexes
-  {"foo.so": ["/opt/csw/lib/gcc4", "/opt/csw/lib", ...],
-   ...
-  }
-  """
-  needed_sonames = set()
-  binaries_by_soname = {}
-  runpath_by_needed_soname = {}
-  for binary_name, data in needed_sonames_by_binary.iteritems():
-    for soname in data[NEEDED_SONAMES]:
-      needed_sonames.add(soname)
-      if soname not in runpath_by_needed_soname:
-        runpath_by_needed_soname[soname] = []
-      runpath_by_needed_soname[soname].extend(data[RUNPATH])
-      if soname not in binaries_by_soname:
-        binaries_by_soname[soname] = set()
-      binaries_by_soname[soname].add(binary_name)
-  return needed_sonames, binaries_by_soname, runpath_by_needed_soname
-
-
-def ParseDumpOutput(dump_output):
-  binary_data = {RUNPATH: [],
-                 NEEDED_SONAMES: []}
-  for line in dump_output.splitlines():
-    fields = re.split(WS_RE, line)
-    # TODO: Make it a unit test
-    # logging.debug("%s says: %s", DUMP_BIN, fields)
-    if len(fields) < 3:
-      continue
-    if fields[1] == "NEEDED":
-      binary_data[NEEDED_SONAMES].append(fields[2])
-    elif fields[1] == "RUNPATH":
-      binary_data[RUNPATH].extend(fields[2].split(":"))
-    elif fields[1] == "SONAME":
-      binary_data[SONAME] = fields[2]
-  # Adding the default runtime path search option.
-  binary_data[RUNPATH].append("/usr/lib/$ISALIST")
-  binary_data[RUNPATH].append("/usr/lib")
-  binary_data[RUNPATH].append("/lib/$ISALIST")
-  binary_data[RUNPATH].append("/lib")
-  return binary_data

Copied: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg.py (from rev 7855, csw/mgar/gar/v2-checkpkg/bin/checkpkg.d/checkpkg.py)
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg.d/checkpkg.py	                        (rev 0)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg.py	2010-01-04 10:28:15 UTC (rev 7856)
@@ -0,0 +1,486 @@
+# $Id$
+#
+# This is the checkpkg library, common for all checkpkg tests written in
+# Python.
+
+import itertools
+import logging
+import optparse
+import os
+import os.path
+import re
+import socket
+import sqlite3
+import subprocess
+
+SYSTEM_PKGMAP = "/var/sadm/install/contents"
+WS_RE = re.compile(r"\s+")
+NEEDED_SONAMES = "needed sonames"
+RUNPATH = "runpath"
+SONAME = "soname"
+CONFIG_MTIME = "mtime"
+DO_NOT_REPORT_SURPLUS = set([u"CSWcommon", u"CSWcswclassutils", u"CSWisaexec"])
+DO_NOT_REPORT_MISSING = set([u"SUNWlibC", u"SUNWcsl", u"SUNWlibms",
+                             u"*SUNWcslr", u"*SUNWlibC", u"*SUNWlibms"])
+
+# This shared library is present on Solaris 10 on amd64, but it's missing on
+# Solaris 8 on i386.  It's okay if it's missing.
+ALLOWED_ORPHAN_SONAMES = set([u"libm.so.2"])
+
+class Error(Exception):
+  pass
+
+
+class ConfigurationError(Error):
+  pass
+
+
+class PackageError(Error):
+  pass
+
+
+def GetOptions():
+  parser = optparse.OptionParser()
+  parser.add_option("-e", dest="extractdir",
+                    help="The directory into which the package has been extracted")
+  parser.add_option("-d", "--debug", dest="debug",
+                    default=False, action="store_true",
+                    help="Turn on debugging messages")
+  (options, args) = parser.parse_args()
+  if not options.extractdir:
+    raise ConfigurationError("ERROR: -e option is missing.")
+  # Using set() to make the arguments unique.
+  return options, set(args)
+
+
+class CheckpkgBase(object):
+  """This class has functionality overlapping with DirectoryFormatPackage
+  from the opencsw.py library. The classes should be merged.
+  """
+
+  def __init__(self, extractdir, pkgname):
+    self.extractdir = extractdir
+    self.pkgname = pkgname
+    self.pkgpath = os.path.join(self.extractdir, self.pkgname)
+
+  def CheckPkgpathExists(self):
+    if not os.path.isdir(self.pkgpath):
+      raise PackageError("%s does not exist or is not a directory"
+                         % self.pkgpath)
+
+  def ListBinaries(self):
+    """Shells out to list all the binaries from a given package.
+
+    Original checkpkg code:
+
+    # #########################################
+    # # find all executables and dynamic libs,and list their filenames.
+    # listbinaries() {
+    #   if [ ! -d $1 ] ; then
+    #     print errmsg $1 not a directory
+    #     rm -rf $EXTRACTDIR
+    #     exit 1
+    #   fi
+    # 
+    #   find $1 -print | xargs file |grep ELF |nawk -F: '{print $1}'
+    # }
+    """
+    self.CheckPkgpathExists()
+    find_tmpl = "find %s -print | xargs file | grep ELF | nawk -F: '{print $1}'"
+    find_proc = subprocess.Popen(find_tmpl % self.pkgpath,
+                                 shell=True, stdout=subprocess.PIPE)
+    stdout, stderr = find_proc.communicate()
+    ret = find_proc.wait()
+    if ret:
+      logging.error("The find command returned an error.")
+    return stdout.splitlines()
+
+  def GetAllFilenames(self):
+    self.CheckPkgpathExists()
+    file_basenames = []
+    for root, dirs, files in os.walk(self.pkgpath):
+      file_basenames.extend(files)
+    return file_basenames
+
+  def GetDependencies(self):
+    fd = open(os.path.join(self.pkgpath, "install", "depend"), "r")
+    depends = {}
+    for line in fd:
+      fields = re.split(WS_RE, line)
+      if fields[0] == "P":
+        depends[fields[1]] = " ".join(fields[1:])
+    fd.close()
+    return depends
+
+
+class SystemPkgmap(object):
+  """A class to hold and manipulate the /var/sadm/install/contents file.
+
+  TODO: Implement timestamp checking and refreshing the cache.
+  """
+  
+  STOP_PKGS = ["SUNWbcp", "SUNWowbcp", "SUNWucb"] 
+  CHECKPKG_DIR = ".checkpkg"
+  SQLITE3_DBNAME_TMPL = "var-sadm-install-contents-cache-%s"
+
+  def __init__(self):
+    """There is no need to re-parse it each time.
+
+    Read it slowly the first time and cache it for later."""
+    self.cache = {}
+    self.checkpkg_dir = os.path.join(os.environ["HOME"], self.CHECKPKG_DIR)
+    self.fqdn = socket.getfqdn()
+    self.db_path = os.path.join(self.checkpkg_dir,
+                                self.SQLITE3_DBNAME_TMPL % self.fqdn)
+    self.file_mtime = None
+    self.cache_mtime = None
+    if os.path.exists(self.db_path):
+      logging.debug("Connecting to the %s database.", self.db_path)
+      self.conn = sqlite3.connect(self.db_path)
+      if not self.IsDatabaseUpToDate():
+        self.PurgeDatabase()
+        self.PopulateDatabase()
+    else:
+      print "Building a cache of /var/sadm/install/contents."
+      print "The cache will be kept in %s." % self.db_path
+      if not os.path.exists(self.checkpkg_dir):
+        logging.debug("Creating %s", self.checkpkg_dir)
+        os.mkdir(self.checkpkg_dir)
+      self.conn = sqlite3.connect(self.db_path)
+      c = self.conn.cursor()
+      c.execute("""
+          CREATE TABLE systempkgmap (
+            id INTEGER PRIMARY KEY,
+            basename TEXT,
+            path TEXT,
+            line TEXT
+          );
+      """)
+      logging.debug("Creating the config table.")
+      c.execute("""
+          CREATE TABLE config (
+            key VARCHAR(255) PRIMARY KEY,
+            float_value FLOAT,
+            str_value VARCHAR(255)
+          );
+      """)
+      self.PopulateDatabase()
+
+  def PopulateDatabase(self):
+    """Imports data into the database.
+
+    Original bit of code from checkpkg:
+    
+    egrep -v 'SUNWbcp|SUNWowbcp|SUNWucb' /var/sadm/install/contents |
+        fgrep -f $EXTRACTDIR/liblist >$EXTRACTDIR/shortcatalog
+    """
+
+    system_pkgmap_fd = open(SYSTEM_PKGMAP, "r")
+    stop_re = re.compile("(%s)" % "|".join(self.STOP_PKGS))
+    # Creating a data structure:
+    # soname - {<path1>: <line1>, <path2>: <line2>, ...}
+    logging.debug("Building sqlite3 cache db of the %s file",
+                  SYSTEM_PKGMAP)
+    c = self.conn.cursor()
+    count = itertools.count()
+    for line in system_pkgmap_fd:
+      i = count.next()
+      if not i % 1000:
+        print "\r%s" % i,
+      if stop_re.search(line):
+        continue
+      fields = re.split(WS_RE, line)
+      pkgmap_entry_path = fields[0].split("=")[0]
+      pkgmap_entry_dir, pkgmap_entry_base_name = os.path.split(pkgmap_entry_path)
+      sql = "INSERT INTO systempkgmap (basename, path, line) VALUES (?, ?, ?);"
+      c.execute(sql, (pkgmap_entry_base_name, pkgmap_entry_dir, line.strip()))
+    print
+    print "Creating the main database index."
+    sql = "CREATE INDEX basename_idx ON systempkgmap(basename);"
+    c.execute(sql)
+    self.SetDatabaseMtime()
+    self.conn.commit()
+
+  def SetDatabaseMtime(self):
+    c = self.conn.cursor()
+    sql = "DELETE FROM config WHERE key = ?;"
+    c.execute(sql, [CONFIG_MTIME])
+    mtime = self.GetFileMtime()
+    logging.debug("Inserting the mtime (%s) into the database.", mtime)
+    sql = """
+    INSERT INTO config (key, float_value)
+    VALUES (?, ?);
+    """
+    c.execute(sql, [CONFIG_MTIME, mtime])
+
+  def GetPkgmapLineByBasename(self, filename):
+    if filename in self.cache:
+      return self.cache[filename]
+    sql = "SELECT path, line FROM systempkgmap WHERE basename = ?;"
+    c = self.conn.cursor()
+    c.execute(sql, [filename])
+    lines = {}
+    for row in c:
+      lines[row[0]] = row[1]
+    if len(lines) == 0:
+      logging.debug("Cache doesn't contain filename %s", filename)
+    self.cache[filename] = lines
+    return lines
+
+  def GetDatabaseMtime(self):
+    if not self.cache_mtime:
+      sql = """
+      SELECT float_value FROM config
+      WHERE key = ?;
+      """
+      c = self.conn.cursor()
+      c.execute(sql, [CONFIG_MTIME])
+      row = c.fetchone()
+      if not row:
+      	# raise ConfigurationError("Could not find the mtime setting")
+        self.cache_mtime = 1
+      else:
+        self.cache_mtime = row[0]
+    return self.cache_mtime
+
+  def GetFileMtime(self):
+    if not self.file_mtime:
+      stat_data = os.stat(SYSTEM_PKGMAP)
+      self.file_mtime = stat_data.st_mtime
+    return self.file_mtime
+
+  def IsDatabaseUpToDate(self):
+    f_mtime = self.GetFileMtime()
+    d_mtime = self.GetDatabaseMtime()
+    logging.debug("f_mtime", f_mtime, "d_time", d_mtime)
+    return self.GetFileMtime() <= self.GetDatabaseMtime()
+
+  def PurgeDatabase(self):
+    c = self.conn.cursor()
+    sql = "DELETE FROM config;"
+    c.execute(sql)
+    sql = "DELETE FROM systempkgmap;"
+    c.execute(sql)
+    sql = "DROP INDEX basename_idx;"
+    try:
+      c.execute(sql)
+    except sqlite3.OperationalError, e:
+      logging.warn(e)
+
+def SharedObjectDependencies(pkgname,
+                             binaries_by_pkgname,
+                             needed_sonames_by_binary,
+                             pkgs_by_soname,
+                             filenames_by_soname,
+                             pkg_by_any_filename):
+  """This is one of the more obscure and more important pieces of code.
+
+  I tried to make it simpler, but given that the operations here involve
+  whole sets of packages, it's not easy.
+  """
+  so_dependencies = set()
+  orphan_sonames = set()
+  self_provided = set()
+  for binary in binaries_by_pkgname[pkgname]:
+    needed_sonames = needed_sonames_by_binary[binary][NEEDED_SONAMES]
+    for soname in needed_sonames:
+      if soname in filenames_by_soname:
+        filename = filenames_by_soname[soname]
+        pkg = pkg_by_any_filename[filename]
+        self_provided.add(soname)
+        so_dependencies.add(pkg)
+      elif soname in pkgs_by_soname:
+        so_dependencies.add(pkgs_by_soname[soname])
+      else:
+        orphan_sonames.add(soname)
+  return so_dependencies, self_provided, orphan_sonames
+
+
+def GuessDepsByFilename(pkgname, pkg_by_any_filename):
+  """Guesses dependencies based on filename regexes."""
+  guessed_deps = set()
+  patterns = (
+      (r".*\.py", u"CSWpython"),
+      (r".*\.pl", u"CSWperl"),
+      (r".*\.rb", u"CSWruby"),
+  )
+  for pattern, dep_pkgname in patterns:
+    # If any file name matches, add the dep, go to the next pattern/pkg
+    # combination.
+    pattern_re = re.compile("^%s$" % pattern)
+    for filename in pkg_by_any_filename:
+      if (re.match(pattern_re, filename)
+            and
+          pkgname == pkg_by_any_filename[filename]):
+        guessed_deps.add(dep_pkgname)
+        break
+  return guessed_deps
+
+
+def GuessDepsByPkgname(pkgname, pkg_by_any_filename):
+  # More guessed dependencies: If one package is a substring of another, it
+  # might be a hint. For example, CSWmysql51test should depend on CSWmysql51.
+  # However, the rt (runtime) packages should not want to depend on the main
+  # package.
+  guessed_deps = set()
+  all_other_pkgs = set(pkg_by_any_filename.values())
+  for other_pkg in all_other_pkgs:
+    other_pkg = unicode(other_pkg)
+    if pkgname == other_pkg:
+      continue
+    if pkgname.startswith(other_pkg):
+      endings = ["devel", "test", "bench", "dev"]
+      for ending in endings:
+        if pkgname.endswith(ending):
+          guessed_deps.add(other_pkg)
+  return guessed_deps
+
+
+def AnalyzeDependencies(pkgname,
+                        declared_dependencies,
+                        binaries_by_pkgname,
+                        needed_sonames_by_binary,
+                        pkgs_by_soname,
+                        filenames_by_soname,
+                        pkg_by_any_filename):
+  """Gathers and merges dependency results from other functions.
+
+  declared_dependencies: Dependencies that the package in question claims to
+                         have.
+
+  binaries_by_pkgname: A dictionary mapping pkgnames (CSWfoo) to binary names
+                       (without paths)
+
+  needed_sonames_by_binary: A dictionary mapping binary file name to
+                            a dictionary containing: "needed sonames",
+                            "soname", "rpath". Based on examining the binary
+                            files within the packages.
+
+  pkgs_by_soname: A dictionary mapping sonames to pkgnames, based on the
+                  contents of the system wide pkgmap
+                  (/var/sadm/install/contents)
+
+  filenames_by_soname: A dictionary mapping shared library sonames to filenames,
+                       based on files within packages
+
+  pkg_by_any_filename: Mapping from file names to packages names, based on the
+                       contents of the packages under examination.
+  """
+  declared_dependencies_set = set(declared_dependencies)
+
+  so_dependencies, self_provided, orphan_sonames = SharedObjectDependencies(
+      pkgname,
+      binaries_by_pkgname,
+      needed_sonames_by_binary,
+      pkgs_by_soname,
+      filenames_by_soname,
+      pkg_by_any_filename)
+  auto_dependencies = reduce(lambda x, y: x.union(y),
+      [
+        so_dependencies,
+        GuessDepsByFilename(pkgname, pkg_by_any_filename),
+        GuessDepsByPkgname(pkgname, pkg_by_any_filename),
+      ])
+  missing_deps = auto_dependencies.difference(declared_dependencies_set)
+  # Don't report itself as a suggested dependency.
+  missing_deps = missing_deps.difference(set([pkgname]))
+  missing_deps = missing_deps.difference(set(DO_NOT_REPORT_MISSING))
+  surplus_deps = declared_dependencies_set.difference(auto_dependencies)
+  surplus_deps = surplus_deps.difference(DO_NOT_REPORT_SURPLUS)
+  orphan_sonames = orphan_sonames.difference(ALLOWED_ORPHAN_SONAMES)
+  return missing_deps, surplus_deps, orphan_sonames
+
+
+def ExpandRunpath(runpath, isalist):
+  # Emulating $ISALIST expansion
+  if '$ISALIST' in runpath:
+    expanded_list = [runpath.replace('$ISALIST', isa) for isa in isalist]
+  else:
+    expanded_list = [runpath]
+  return expanded_list
+
+def Emulate64BitSymlinks(runpath_list):
+  """Need to emulate the 64 -> amd64, 64 -> sparcv9 symlink
+
+  Since we don't know the architecture, we'll adding both amd64 and sparcv9.
+  It should be safe.
+  """
+  symlinked_list = []
+  for runpath in runpath_list:
+    if "/64" in runpath:
+      symlinked_list.append(runpath.replace("/64", "/amd64"))
+      symlinked_list.append(runpath.replace("/64", "/sparcv9"))
+    else:
+      symlinked_list.append(runpath)
+  return symlinked_list
+
+
+def GetLinesBySoname(pkgmap, needed_sonames, runpath_by_needed_soname, isalist):
+  """Works out which system pkgmap lines correspond to given sonames."""
+  lines_by_soname = {}
+  for soname in needed_sonames:
+    # This is the critical part of the algorithm: it iterates over the
+    # runpath and finds the first matching one.
+    runpath_found = False
+    for runpath in runpath_by_needed_soname[soname]:
+      runpath_list = ExpandRunpath(runpath, isalist)
+      runpath_list = Emulate64BitSymlinks(runpath_list)
+      soname_runpath_data = pkgmap.GetPkgmapLineByBasename(soname)
+      logging.debug("%s: will be looking for %s in %s" %
+                    (soname, runpath_list, soname_runpath_data.keys()))
+      for runpath_expanded in runpath_list:
+        if runpath_expanded in soname_runpath_data:
+          lines_by_soname[soname] = soname_runpath_data[runpath_expanded]
+          runpath_found = True
+          # This break only goes out of the inner loop,
+          # need another one below to finish the outer loop.
+          break
+      if runpath_found:
+        break
+  return lines_by_soname
+
+
+def BuildIndexesBySoname(needed_sonames_by_binary):
+  """Builds data structures indexed by soname.
+
+  Building indexes
+  {"foo.so": ["/opt/csw/lib/gcc4", "/opt/csw/lib", ...],
+   ...
+  }
+  """
+  needed_sonames = set()
+  binaries_by_soname = {}
+  runpath_by_needed_soname = {}
+  for binary_name, data in needed_sonames_by_binary.iteritems():
+    for soname in data[NEEDED_SONAMES]:
+      needed_sonames.add(soname)
+      if soname not in runpath_by_needed_soname:
+        runpath_by_needed_soname[soname] = []
+      runpath_by_needed_soname[soname].extend(data[RUNPATH])
+      if soname not in binaries_by_soname:
+        binaries_by_soname[soname] = set()
+      binaries_by_soname[soname].add(binary_name)
+  return needed_sonames, binaries_by_soname, runpath_by_needed_soname
+
+
+def ParseDumpOutput(dump_output):
+  binary_data = {RUNPATH: [],
+                 NEEDED_SONAMES: []}
+  for line in dump_output.splitlines():
+    fields = re.split(WS_RE, line)
+    # TODO: Make it a unit test
+    # logging.debug("%s says: %s", DUMP_BIN, fields)
+    if len(fields) < 3:
+      continue
+    if fields[1] == "NEEDED":
+      binary_data[NEEDED_SONAMES].append(fields[2])
+    elif fields[1] == "RUNPATH":
+      binary_data[RUNPATH].extend(fields[2].split(":"))
+    elif fields[1] == "SONAME":
+      binary_data[SONAME] = fields[2]
+  # Adding the default runtime path search option.
+  binary_data[RUNPATH].append("/usr/lib/$ISALIST")
+  binary_data[RUNPATH].append("/usr/lib")
+  binary_data[RUNPATH].append("/lib/$ISALIST")
+  binary_data[RUNPATH].append("/lib")
+  return binary_data

Deleted: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg_test.py
===================================================================
--- csw/mgar/gar/v2-checkpkg/bin/checkpkg.d/checkpkg_test.py	2010-01-04 03:57:34 UTC (rev 7855)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg_test.py	2010-01-04 10:28:15 UTC (rev 7856)
@@ -1,438 +0,0 @@
-#!/opt/csw/bin/python2.6
-# $Id$
-
-import unittest
-import mox
-import checkpkg
-import testdata.checkpkg_test_data_CSWmysql51rt as d1
-import testdata.checkpkg_test_data_CSWmysql51client as d2
-import testdata.checkpkg_test_data_CSWmysql51 as d3
-import testdata.checkpkg_test_data_CSWmysql51devel as d4
-import testdata.checkpkg_test_data_CSWlibpq_84 as d5
-import testdata.checkpkg_test_data_CSWmysql5client_8x as d6
-import testdata.dump_output_1 as dump_1
-import testdata.dump_output_2 as dump_2
-
-"""A set of unit tests for the library checking code.
-
-A bunch of lines to test in the interactive Python shell.
-
-import sys
-sys.path.append("gar/bin/checkpkg.d")
-import checkpkg
-import testdata.checkpkg_test_data_CSWmysql5client_8x as d6
-
-checkpkg.SharedObjectDependencies("CSWmysql5client",
-d6.DATA_BINARIES_BY_PKGNAME, d6.DATA_NEEDED_SONAMES_BY_BINARY,
-d6.DATA_PKGS_BY_FILENAME, d6.DATA_FILENAMES_BY_SONAME,
-d6.DATA_PKG_BY_ANY_FILENAME)
-
-sqlite3 ~/.checkpkg/var-sadm-install-contents-cache-build8x
-SELECT * FROM systempkgmap WHERE basename = 'libncursesw.so.5';
-"""
-
-class DependenciesUnitTest_1(unittest.TestCase):
-
-  def setUp(self):
-    self.missing_deps, self.surplus_deps, self.orphan_sonames = checkpkg.AnalyzeDependencies(
-        d1.DATA_PKGNAME,
-        d1.DATA_DECLARED_DEPENDENCIES,
-        d1.DATA_BINARIES_BY_PKGNAME,
-        d1.DATA_NEEDED_SONAMES_BY_BINARY,
-        d1.DATA_PKGS_BY_FILENAME,
-        d1.DATA_FILENAMES_BY_SONAME,
-        d1.DATA_PKG_BY_ANY_FILENAME,
-    )
-
-  def testSurplusDeps(self):
-    self.assertEquals(set([]), self.surplus_deps)
-
-  def testOrphanSonames(self):
-    self.assertEquals(set([]), self.orphan_sonames)
-
-  def testMissingDeps(self):
-    expected = set([])
-    self.assertEquals(expected, self.missing_deps)
-
-
-class DependenciesUnitTest_2(unittest.TestCase):
-
-  def setUp(self):
-    self.missing_deps, self.surplus_deps, self.orphan_sonames = checkpkg.AnalyzeDependencies(
-        d2.DATA_PKGNAME,
-        d2.DATA_DECLARED_DEPENDENCIES,
-        d2.DATA_BINARIES_BY_PKGNAME,
-        d2.DATA_NEEDED_SONAMES_BY_BINARY,
-        d2.DATA_PKGS_BY_FILENAME,
-        d2.DATA_FILENAMES_BY_SONAME,
-        d2.DATA_PKG_BY_ANY_FILENAME,
-    )
-
-  def testSurplusDeps(self):
-    self.assertEquals(set([]), self.surplus_deps)
-
-  def testOrphanSonames(self):
-    self.assertEquals(set([]), self.orphan_sonames)
-
-  def testMissingDeps(self):
-    expected = set([])
-    self.assertEquals(expected, self.missing_deps)
-
-
-class DependenciesUnitTest_3(unittest.TestCase):
-
-  def setUp(self):
-    self.missing_deps, self.surplus_deps, self.orphan_sonames = checkpkg.AnalyzeDependencies(
-        d3.DATA_PKGNAME,
-        d3.DATA_DECLARED_DEPENDENCIES,
-        d3.DATA_BINARIES_BY_PKGNAME,
-        d3.DATA_NEEDED_SONAMES_BY_BINARY,
-        d3.DATA_PKGS_BY_FILENAME,
-        d3.DATA_FILENAMES_BY_SONAME,
-        d3.DATA_PKG_BY_ANY_FILENAME,
-    )
-
-  def testSurplusDeps(self):
-    self.assertEquals(set([u'CSWmysql51client']), self.surplus_deps)
-
-  def testOrphanSonames(self):
-    self.assertEquals(set([]), self.orphan_sonames)
-
-  def testMissingDeps(self):
-    expected = set(['CSWmysql51rt'])
-    self.assertEquals(expected, self.missing_deps)
-
-
-class DependenciesUnitTest_4(unittest.TestCase):
-
-  def setUp(self):
-    self.missing_deps, self.surplus_deps, self.orphan_sonames = checkpkg.AnalyzeDependencies(
-        d4.DATA_PKGNAME,
-        d4.DATA_DECLARED_DEPENDENCIES,
-        d4.DATA_BINARIES_BY_PKGNAME,
-        d4.DATA_NEEDED_SONAMES_BY_BINARY,
-        d4.DATA_PKGS_BY_FILENAME,
-        d4.DATA_FILENAMES_BY_SONAME,
-        d4.DATA_PKG_BY_ANY_FILENAME,
-    )
-
-  def testSurplusDeps(self):
-    self.assertEquals(set([]), self.surplus_deps)
-
-  def testOrphanSonames(self):
-    self.assertEquals(set([]), self.orphan_sonames)
-
-  def testMissingDeps(self):
-    expected = set([])
-    self.assertEquals(expected, self.missing_deps)
-
-
-class DependenciesUnitTest_5(unittest.TestCase):
-
-  def setUp(self):
-    self.missing_deps, self.surplus_deps, self.orphan_sonames = checkpkg.AnalyzeDependencies(
-        d5.DATA_PKGNAME,
-        d5.DATA_DECLARED_DEPENDENCIES,
-        d5.DATA_BINARIES_BY_PKGNAME,
-        d5.DATA_NEEDED_SONAMES_BY_BINARY,
-        d5.DATA_PKGS_BY_FILENAME,
-        d5.DATA_FILENAMES_BY_SONAME,
-        d5.DATA_PKG_BY_ANY_FILENAME,
-    )
-
-  def testSurplusDeps(self):
-    self.assertEquals(set([]), self.surplus_deps)
-
-  def testOrphanSonames(self):
-    self.assertEquals(set([]), self.orphan_sonames)
-
-  def testMissingDeps(self):
-    # This tends to report itself...
-    expected = set([u'SUNWgss'])
-    self.assertEquals(expected, self.missing_deps)
-
-
-class DependenciesUnitTest_6(unittest.TestCase):
-
-  def setUp(self):
-    (self.missing_deps,
-     self.surplus_deps,
-     self.orphan_sonames) = checkpkg.AnalyzeDependencies(
-        d6.DATA_PKGNAME,
-        d6.DATA_DECLARED_DEPENDENCIES,
-        d6.DATA_BINARIES_BY_PKGNAME,
-        d6.DATA_NEEDED_SONAMES_BY_BINARY,
-        d6.DATA_PKGS_BY_FILENAME,
-        d6.DATA_FILENAMES_BY_SONAME,
-        d6.DATA_PKG_BY_ANY_FILENAME,
-    )
-
-  def testSurplusDeps(self):
-    self.assertEquals(set([]), self.surplus_deps)
-
-  def testOrphanSonames(self):
-    self.assertEquals(set([]), self.orphan_sonames)
-
-  def testMissingDeps(self):
-    expected = set([])
-    self.assertEquals(expected, self.missing_deps)
-
-
-class GuessDepsUnitTest(unittest.TestCase):
-
-  def testGuessDepsByFilename1(self):
-    expected = set([u"CSWpython"])
-    pkgname = u"CSWfoo"
-    pkg_by_filename = {
-        "/opt/csw/bin/bar": u"CSWfoo",
-        "/opt/csw/lib/python/site-packages/foo.py": u"CSWfoo",
-    }
-    self.assertEqual(expected,
-                     checkpkg.GuessDepsByFilename(pkgname, pkg_by_filename))
-
-  def testGuessDepsByFilename2(self):
-    expected = set([])
-    pkgname = u"CSWfoo"
-    pkg_by_filename = {
-        "/opt/csw/bin/bar": u"CSWfoo",
-        "/opt/csw/lib/python/site-packages/foo.py": u"CSWbar",
-    }
-    self.assertEqual(expected,
-                     checkpkg.GuessDepsByFilename(pkgname, pkg_by_filename))
-
-  def testGuessDepsByPkgname1(self):
-    expected = set([u"CSWfoo"])
-    pkgname = u"CSWfoo-devel"
-    pkg_by_filename = {
-        "/opt/csw/bin/bar": u"CSWfoo",
-        "/opt/csw/bin/barfoo": u"CSWfoobar",
-        "/opt/csw/lib/python/site-packages/foo.py": u"CSWfoo",
-    }
-    self.assertEqual(expected,
-                     checkpkg.GuessDepsByPkgname(pkgname, pkg_by_filename))
-
-  def testGuessDepsByPkgname2(self):
-    expected = set([])
-    pkgname = u"CSWzfoo-devel"
-    pkg_by_filename = {
-        "/opt/csw/bin/bar": u"CSWfoo",
-        "/opt/csw/bin/barfoo": u"CSWfoobar",
-        "/opt/csw/lib/python/site-packages/foo.py": u"CSWfoo",
-    }
-    self.assertEqual(expected,
-                     checkpkg.GuessDepsByPkgname(pkgname, pkg_by_filename))
-
-  def testGuessDepsByPkgname3(self):
-    self.assertEqual(set([u"CSWmysql51"]),
-                     checkpkg.GuessDepsByPkgname(u"CSWmysql51devel",
-                                                 d4.DATA_PKG_BY_ANY_FILENAME))
-
-  def testGuessDepsByPkgname4(self):
-    data1 = set(['CSWmysql51', 'CSWmysql51rt', 'CSWmysql51test',
-                 'CSWmysql51client', 'CSWmysql51bench', 'CSWmysql51devel'])
-    data2 = dict(((x, x) for x in data1))
-    self.assertEqual(set([u"CSWmysql51"]), checkpkg.GuessDepsByPkgname(u"CSWmysql51devel", data2))
-
-  def testGuessDepsByPkgname4(self):
-    data1 = set(['CSWmysql51', 'CSWmysql51rt', 'CSWmysql51test',
-                 'CSWmysql51client', 'CSWmysql51bench', 'CSWmysql51devel'])
-    data2 = dict(((x, x) for x in data1))
-    self.assertEqual(set([]), checkpkg.GuessDepsByPkgname(u"CSWmysql51rt", data2))
-
-
-class GetLinesBySonameUnitTest(unittest.TestCase):
-
-  class PkgmapStub(object):
-
-    def __init__(self, cache):
-      self.cache = cache
-
-    def GetPkgmapLineByBasename(self, soname):
-      return self.cache[soname]
-
-  def setUp(self):
-    self.pkgmap_mocker = mox.Mox()
-
-  def testExpandRunpath_1(self):
-    isalist = ["foo", "bar"]
-    runpath = "/opt/csw/lib/$ISALIST"
-    expected = ["/opt/csw/lib/foo", "/opt/csw/lib/bar"]
-    self.assertEquals(expected, checkpkg.ExpandRunpath(runpath, isalist))
-
-  def testExpandRunpath_2(self):
-    isalist = ["foo", "bar"]
-    runpath = "/opt/csw/mysql5/lib/$ISALIST/mysql"
-    expected = ["/opt/csw/mysql5/lib/foo/mysql", "/opt/csw/mysql5/lib/bar/mysql"]
-    self.assertEquals(expected, checkpkg.ExpandRunpath(runpath, isalist))
-
-  def testEmulate64BitSymlinks_1(self):
-    runpath_list = ["/opt/csw/mysql5/lib/foo/mysql/64"]
-    expected = "/opt/csw/mysql5/lib/foo/mysql/amd64"
-    self.assertTrue(expected in checkpkg.Emulate64BitSymlinks(runpath_list))
-
-  def testEmulate64BitSymlinks_2(self):
-    runpath_list = ["/opt/csw/mysql5/lib/64/mysql/foo"]
-    expected = "/opt/csw/mysql5/lib/amd64/mysql/foo"
-    result = checkpkg.Emulate64BitSymlinks(runpath_list)
-    self.assertTrue(expected in result, "%s not in %s" % (expected, result))
-
-  def testGetLinesBySoname(self):
-    expected = {'foo.so.1': '/opt/csw/lib/isa-value-1/foo.so.1 foo'}
-    pkgmap = self.pkgmap_mocker.CreateMock(checkpkg.SystemPkgmap)
-    pkgmap.GetPkgmapLineByBasename("foo")
-    lines1 = {"/opt/csw/lib/isa-value-1": "/opt/csw/lib/isa-value-1/foo.so.1 foo",
-              "/usr/lib":                  "/usr/lib/foo.so.1 foo"}
-    # pkgmap.GetPkgmapLineByBasename("foo.so.1").AndReturn(lines1)
-    pkgmap.GetPkgmapLineByBasename("foo.so.1").AndReturn(lines1)
-    self.pkgmap_mocker.ReplayAll()
-    pkgmap.GetPkgmapLineByBasename("foo")
-    needed_sonames = set(["foo.so.1"])
-    runpath_by_needed_soname = {"foo.so.1": ["/opt/csw/lib/$ISALIST", "/usr/lib"]}
-    isalist = ["isa-value-1", "isa-value-2"]
-    result = checkpkg.GetLinesBySoname(pkgmap, needed_sonames, runpath_by_needed_soname, isalist)
-    self.pkgmap_mocker.VerifyAll()
-    self.assertEqual(expected, result)
-
-  def testGetLinesBySoname_3(self):
-    expected = {'foo.so.1': '/opt/csw/lib/isa-value-1/foo.so.1 foo'}
-    pkgmap = self.pkgmap_mocker.CreateMock(checkpkg.SystemPkgmap)
-    pkgmap.GetPkgmapLineByBasename("foo")
-    lines1 = {
-        "/opt/csw/lib/isa-value-1": "/opt/csw/lib/isa-value-1/foo.so.1 foo",
-        "/opt/csw/lib":             "/opt/csw/lib/foo.so.1 foo",
-        "/usr/lib":                 "/usr/lib/foo.so.1 foo"}
-    # pkgmap.GetPkgmapLineByBasename("foo.so.1").AndReturn(lines1)
-    pkgmap.GetPkgmapLineByBasename("foo.so.1").AndReturn(lines1)
-    self.pkgmap_mocker.ReplayAll()
-    pkgmap.GetPkgmapLineByBasename("foo")
-    needed_sonames = set(["foo.so.1"])
-    runpath_by_needed_soname = {
-        "foo.so.1": ["/opt/csw/lib/$ISALIST", "/usr/lib"]}
-    isalist = ["isa-value-1", "isa-value-2"]
-    result = checkpkg.GetLinesBySoname(
-        pkgmap, needed_sonames, runpath_by_needed_soname, isalist)
-    self.pkgmap_mocker.VerifyAll()
-    self.assertEqual(expected, result)
-
-  def testGetLinesBySoname_4(self):
-    """A more complex test, four ISAs."""
-    expected = {'foo.so.1': '/opt/csw/lib/isa-value-1/foo.so.1 foo'}
-    pkgmap = self.pkgmap_mocker.CreateMock(checkpkg.SystemPkgmap)
-    pkgmap.GetPkgmapLineByBasename("foo")
-    lines1 = {
-        "/opt/csw/lib/isa-value-1":
-            "/opt/csw/lib/isa-value-1/foo.so.1 foo",
-        "/opt/csw/mysql5/lib/isa-value-2":
-            "/opt/csw/mysql5/lib/isa-value-2/foo.so.1 foo",
-        "/opt/csw/mysql5/lib/isa-value-1":
-            "/opt/csw/mysql5/lib/isa-value-1/foo.so.1 foo",
-        "/opt/csw/lib":
-            "/opt/csw/lib/foo.so.1 foo",
-        "/usr/lib":
-            "/usr/lib/foo.so.1 foo"}
-    pkgmap.GetPkgmapLineByBasename("foo.so.1").AndReturn(lines1)
-    pkgmap.GetPkgmapLineByBasename("foo.so.1").AndReturn(lines1)
-    self.pkgmap_mocker.ReplayAll()
-    pkgmap.GetPkgmapLineByBasename("foo")
-    needed_sonames = set(["foo.so.1"])
-    runpath_by_needed_soname = {
-        "foo.so.1": ["/opt/csw/mysql5/lib/$ISALIST/mysql",
-                     "/opt/csw/lib/$ISALIST",
-                     "/usr/lib"]}
-    isalist = ["isa-value-1", "isa-value-2"]
-    result = checkpkg.GetLinesBySoname(
-        pkgmap, needed_sonames, runpath_by_needed_soname, isalist)
-    self.pkgmap_mocker.VerifyAll()
-    self.assertEqual(expected, result)
-
-  def testGetLinesBySoname_5(self):
-    """Based on CSWmysql5client on build8x."""
-    soname = u'libm.so.1'
-    expected = {u'libm.so.1': u'/usr/lib/libm.so.1 f none 0755 root bin '
-                              u'99844 3884 1050525375 SUNWlibms\n'}
-
-    pkgmap_stub = self.PkgmapStub(d6.DATA_PKGMAP_CACHE)
-    (needed_sonames,
-     binaries_by_soname,
-     runpath_by_needed_soname) = checkpkg.BuildIndexesBySoname(
-         d6.DATA_NEEDED_SONAMES_BY_BINARY)
-    result = checkpkg.GetLinesBySoname(
-        pkgmap_stub,
-        set([soname]),
-        runpath_by_needed_soname,
-        d6.DATA_ISALIST)
-    self.assertEqual(expected, result)
-
-  def testGetLinesBySoname_6(self):
-    """Based on CSWmysql5client on build8x."""
-    soname = u'libz.so.1'
-    expected = {u'libz.so.1': u'/opt/csw/lib/pentium_pro+mmx/libz.so.1=libz.so.1.2.3 '
-                              u's none CSWzlib\n'}
-    pkgmap_stub = self.PkgmapStub(d6.DATA_PKGMAP_CACHE)
-    (needed_sonames,
-     binaries_by_soname,
-     runpath_by_needed_soname) = checkpkg.BuildIndexesBySoname(
-         d6.DATA_NEEDED_SONAMES_BY_BINARY)
-    result = checkpkg.GetLinesBySoname(
-        pkgmap_stub,
-        set([soname]),
-        runpath_by_needed_soname,
-        d6.DATA_ISALIST)
-    self.assertEqual(expected, result)
-
-  def testGetLinesBySoname_7(self):
-    """A test for 64-bit symlink expansion."""
-    soname = u'libncursesw.so.5'
-    # To test the 64-bit symlink expansion
-    expected = {
-    	  u'libncursesw.so.5':
-    	    u'/opt/csw/lib/amd64/libncursesw.so.5=libncursesw.so.5.7 '
-    	    u's none CSWncurses\n'}
-    pkgmap_stub = self.PkgmapStub(d6.DATA_PKGMAP_CACHE)
-    (needed_sonames,
-     binaries_by_soname,
-     runpath_by_needed_soname) = checkpkg.BuildIndexesBySoname(
-         d6.DATA_NEEDED_SONAMES_BY_BINARY)
-    result = checkpkg.GetLinesBySoname(
-        pkgmap_stub,
-        set([soname]),
-        runpath_by_needed_soname,
-        d6.DATA_ISALIST)
-    self.assertEqual(expected, result)
-
-
-class ParseDumpOutputUnitTest(unittest.TestCase):
-
-  def test_1(self):
-    expected = {
-        'soname': 'libmysqlclient.so.15',
-        'runpath': ['/opt/csw/lib/$ISALIST',
-                    '/opt/csw/lib',
-                    '/opt/csw/mysql5/lib/$ISALIST',
-                    '/opt/csw/mysql5/lib',
-                    '/opt/csw/mysql5/lib/$ISALIST/mysql',
-                    # These four are artificially appended
-                    '/usr/lib/$ISALIST',
-                    '/usr/lib',
-                    '/lib/$ISALIST',
-                    '/lib'],
-        'needed sonames': ['librt.so.1',
-                           'libresolv.so.2',
-                           'libc.so.1',
-                           'libgen.so.1',
-                           'libsocket.so.1',
-                           'libnsl.so.1',
-                           'libm.so.1',
-                           'libz.so.1']}
-    self.assertEqual(expected,
-                     checkpkg.ParseDumpOutput(dump_1.DATA_DUMP_OUTPUT))
-
-  def test_2(self):
-    expected_runpath = ['/usr/lib/$ISALIST', '/usr/lib', '/lib/$ISALIST', '/lib']
-    self.assertEqual(
-        expected_runpath,
-        checkpkg.ParseDumpOutput(dump_2.DATA_DUMP_OUTPUT)["runpath"])
-
-
-if __name__ == '__main__':
-  unittest.main()

Copied: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg_test.py (from rev 7855, csw/mgar/gar/v2-checkpkg/bin/checkpkg.d/checkpkg_test.py)
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg.d/checkpkg_test.py	                        (rev 0)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg_test.py	2010-01-04 10:28:15 UTC (rev 7856)
@@ -0,0 +1,438 @@
+#!/opt/csw/bin/python2.6
+# $Id$
+
+import unittest
+import mox
+import checkpkg
+import testdata.checkpkg_test_data_CSWmysql51rt as d1
+import testdata.checkpkg_test_data_CSWmysql51client as d2
+import testdata.checkpkg_test_data_CSWmysql51 as d3
+import testdata.checkpkg_test_data_CSWmysql51devel as d4
+import testdata.checkpkg_test_data_CSWlibpq_84 as d5
+import testdata.checkpkg_test_data_CSWmysql5client_8x as d6
+import testdata.dump_output_1 as dump_1
+import testdata.dump_output_2 as dump_2
+
+"""A set of unit tests for the library checking code.
+
+A bunch of lines to test in the interactive Python shell.
+
+import sys
+sys.path.append("gar/bin/checkpkg.d")
+import checkpkg
+import testdata.checkpkg_test_data_CSWmysql5client_8x as d6
+
+checkpkg.SharedObjectDependencies("CSWmysql5client",
+d6.DATA_BINARIES_BY_PKGNAME, d6.DATA_NEEDED_SONAMES_BY_BINARY,
+d6.DATA_PKGS_BY_FILENAME, d6.DATA_FILENAMES_BY_SONAME,
+d6.DATA_PKG_BY_ANY_FILENAME)
+
+sqlite3 ~/.checkpkg/var-sadm-install-contents-cache-build8x
+SELECT * FROM systempkgmap WHERE basename = 'libncursesw.so.5';
+"""
+
+class DependenciesUnitTest_1(unittest.TestCase):
+
+  def setUp(self):
+    self.missing_deps, self.surplus_deps, self.orphan_sonames = checkpkg.AnalyzeDependencies(
+        d1.DATA_PKGNAME,
+        d1.DATA_DECLARED_DEPENDENCIES,
+        d1.DATA_BINARIES_BY_PKGNAME,
+        d1.DATA_NEEDED_SONAMES_BY_BINARY,
+        d1.DATA_PKGS_BY_FILENAME,
+        d1.DATA_FILENAMES_BY_SONAME,
+        d1.DATA_PKG_BY_ANY_FILENAME,
+    )
+
+  def testSurplusDeps(self):
+    self.assertEquals(set([]), self.surplus_deps)
+
+  def testOrphanSonames(self):
+    self.assertEquals(set([]), self.orphan_sonames)
+
+  def testMissingDeps(self):
+    expected = set([])
+    self.assertEquals(expected, self.missing_deps)
+
+
+class DependenciesUnitTest_2(unittest.TestCase):
+
+  def setUp(self):
+    self.missing_deps, self.surplus_deps, self.orphan_sonames = checkpkg.AnalyzeDependencies(
+        d2.DATA_PKGNAME,
+        d2.DATA_DECLARED_DEPENDENCIES,
+        d2.DATA_BINARIES_BY_PKGNAME,
+        d2.DATA_NEEDED_SONAMES_BY_BINARY,
+        d2.DATA_PKGS_BY_FILENAME,
+        d2.DATA_FILENAMES_BY_SONAME,
+        d2.DATA_PKG_BY_ANY_FILENAME,
+    )
+
+  def testSurplusDeps(self):
+    self.assertEquals(set([]), self.surplus_deps)
+
+  def testOrphanSonames(self):
+    self.assertEquals(set([]), self.orphan_sonames)
+
+  def testMissingDeps(self):
+    expected = set([])
+    self.assertEquals(expected, self.missing_deps)
+
+
+class DependenciesUnitTest_3(unittest.TestCase):
+
+  def setUp(self):
+    self.missing_deps, self.surplus_deps, self.orphan_sonames = checkpkg.AnalyzeDependencies(
+        d3.DATA_PKGNAME,
+        d3.DATA_DECLARED_DEPENDENCIES,
+        d3.DATA_BINARIES_BY_PKGNAME,
+        d3.DATA_NEEDED_SONAMES_BY_BINARY,
+        d3.DATA_PKGS_BY_FILENAME,
+        d3.DATA_FILENAMES_BY_SONAME,
+        d3.DATA_PKG_BY_ANY_FILENAME,
+    )
+
+  def testSurplusDeps(self):
+    self.assertEquals(set([u'CSWmysql51client']), self.surplus_deps)
+
+  def testOrphanSonames(self):
+    self.assertEquals(set([]), self.orphan_sonames)
+
+  def testMissingDeps(self):
+    expected = set(['CSWmysql51rt'])
+    self.assertEquals(expected, self.missing_deps)
+
+
+class DependenciesUnitTest_4(unittest.TestCase):
+
+  def setUp(self):
+    self.missing_deps, self.surplus_deps, self.orphan_sonames = checkpkg.AnalyzeDependencies(
+        d4.DATA_PKGNAME,
+        d4.DATA_DECLARED_DEPENDENCIES,
+        d4.DATA_BINARIES_BY_PKGNAME,
+        d4.DATA_NEEDED_SONAMES_BY_BINARY,
+        d4.DATA_PKGS_BY_FILENAME,
+        d4.DATA_FILENAMES_BY_SONAME,
+        d4.DATA_PKG_BY_ANY_FILENAME,
+    )
+
+  def testSurplusDeps(self):
+    self.assertEquals(set([]), self.surplus_deps)
+
+  def testOrphanSonames(self):
+    self.assertEquals(set([]), self.orphan_sonames)
+
+  def testMissingDeps(self):
+    expected = set([])
+    self.assertEquals(expected, self.missing_deps)
+
+
+class DependenciesUnitTest_5(unittest.TestCase):
+
+  def setUp(self):
+    self.missing_deps, self.surplus_deps, self.orphan_sonames = checkpkg.AnalyzeDependencies(
+        d5.DATA_PKGNAME,
+        d5.DATA_DECLARED_DEPENDENCIES,
+        d5.DATA_BINARIES_BY_PKGNAME,
+        d5.DATA_NEEDED_SONAMES_BY_BINARY,
+        d5.DATA_PKGS_BY_FILENAME,
+        d5.DATA_FILENAMES_BY_SONAME,
+        d5.DATA_PKG_BY_ANY_FILENAME,
+    )
+
+  def testSurplusDeps(self):
+    self.assertEquals(set([]), self.surplus_deps)
+
+  def testOrphanSonames(self):
+    self.assertEquals(set([]), self.orphan_sonames)
+
+  def testMissingDeps(self):
+    # This tends to report itself...
+    expected = set([u'SUNWgss'])
+    self.assertEquals(expected, self.missing_deps)
+
+
+class DependenciesUnitTest_6(unittest.TestCase):
+
+  def setUp(self):
+    (self.missing_deps,
+     self.surplus_deps,
+     self.orphan_sonames) = checkpkg.AnalyzeDependencies(
+        d6.DATA_PKGNAME,
+        d6.DATA_DECLARED_DEPENDENCIES,
+        d6.DATA_BINARIES_BY_PKGNAME,
+        d6.DATA_NEEDED_SONAMES_BY_BINARY,
+        d6.DATA_PKGS_BY_FILENAME,
+        d6.DATA_FILENAMES_BY_SONAME,
+        d6.DATA_PKG_BY_ANY_FILENAME,
+    )
+
+  def testSurplusDeps(self):
+    self.assertEquals(set([]), self.surplus_deps)
+
+  def testOrphanSonames(self):
+    self.assertEquals(set([]), self.orphan_sonames)
+
+  def testMissingDeps(self):
+    expected = set([])
+    self.assertEquals(expected, self.missing_deps)
+
+
+class GuessDepsUnitTest(unittest.TestCase):
+
+  def testGuessDepsByFilename1(self):
+    expected = set([u"CSWpython"])
+    pkgname = u"CSWfoo"
+    pkg_by_filename = {
+        "/opt/csw/bin/bar": u"CSWfoo",
+        "/opt/csw/lib/python/site-packages/foo.py": u"CSWfoo",
+    }
+    self.assertEqual(expected,
+                     checkpkg.GuessDepsByFilename(pkgname, pkg_by_filename))
+
+  def testGuessDepsByFilename2(self):
+    expected = set([])
+    pkgname = u"CSWfoo"
+    pkg_by_filename = {
+        "/opt/csw/bin/bar": u"CSWfoo",
+        "/opt/csw/lib/python/site-packages/foo.py": u"CSWbar",
+    }
+    self.assertEqual(expected,
+                     checkpkg.GuessDepsByFilename(pkgname, pkg_by_filename))
+
+  def testGuessDepsByPkgname1(self):
+    expected = set([u"CSWfoo"])
+    pkgname = u"CSWfoo-devel"
+    pkg_by_filename = {
+        "/opt/csw/bin/bar": u"CSWfoo",
+        "/opt/csw/bin/barfoo": u"CSWfoobar",
+        "/opt/csw/lib/python/site-packages/foo.py": u"CSWfoo",
+    }
+    self.assertEqual(expected,
+                     checkpkg.GuessDepsByPkgname(pkgname, pkg_by_filename))
+
+  def testGuessDepsByPkgname2(self):
+    expected = set([])
+    pkgname = u"CSWzfoo-devel"
+    pkg_by_filename = {
+        "/opt/csw/bin/bar": u"CSWfoo",
+        "/opt/csw/bin/barfoo": u"CSWfoobar",
+        "/opt/csw/lib/python/site-packages/foo.py": u"CSWfoo",
+    }
+    self.assertEqual(expected,
+                     checkpkg.GuessDepsByPkgname(pkgname, pkg_by_filename))
+
+  def testGuessDepsByPkgname3(self):
+    self.assertEqual(set([u"CSWmysql51"]),
+                     checkpkg.GuessDepsByPkgname(u"CSWmysql51devel",
+                                                 d4.DATA_PKG_BY_ANY_FILENAME))
+
+  def testGuessDepsByPkgname4(self):
+    data1 = set(['CSWmysql51', 'CSWmysql51rt', 'CSWmysql51test',
+                 'CSWmysql51client', 'CSWmysql51bench', 'CSWmysql51devel'])
+    data2 = dict(((x, x) for x in data1))
+    self.assertEqual(set([u"CSWmysql51"]), checkpkg.GuessDepsByPkgname(u"CSWmysql51devel", data2))
+
+  def testGuessDepsByPkgname4(self):
+    data1 = set(['CSWmysql51', 'CSWmysql51rt', 'CSWmysql51test',
+                 'CSWmysql51client', 'CSWmysql51bench', 'CSWmysql51devel'])
+    data2 = dict(((x, x) for x in data1))
+    self.assertEqual(set([]), checkpkg.GuessDepsByPkgname(u"CSWmysql51rt", data2))
+
+
+class GetLinesBySonameUnitTest(unittest.TestCase):
+
+  class PkgmapStub(object):
+
+    def __init__(self, cache):
+      self.cache = cache
+
+    def GetPkgmapLineByBasename(self, soname):
+      return self.cache[soname]
+
+  def setUp(self):
+    self.pkgmap_mocker = mox.Mox()
+
+  def testExpandRunpath_1(self):
+    isalist = ["foo", "bar"]
+    runpath = "/opt/csw/lib/$ISALIST"
+    expected = ["/opt/csw/lib/foo", "/opt/csw/lib/bar"]
+    self.assertEquals(expected, checkpkg.ExpandRunpath(runpath, isalist))
+
+  def testExpandRunpath_2(self):
+    isalist = ["foo", "bar"]
+    runpath = "/opt/csw/mysql5/lib/$ISALIST/mysql"
+    expected = ["/opt/csw/mysql5/lib/foo/mysql", "/opt/csw/mysql5/lib/bar/mysql"]
+    self.assertEquals(expected, checkpkg.ExpandRunpath(runpath, isalist))
+
+  def testEmulate64BitSymlinks_1(self):
+    runpath_list = ["/opt/csw/mysql5/lib/foo/mysql/64"]
+    expected = "/opt/csw/mysql5/lib/foo/mysql/amd64"
+    self.assertTrue(expected in checkpkg.Emulate64BitSymlinks(runpath_list))
+
+  def testEmulate64BitSymlinks_2(self):
+    runpath_list = ["/opt/csw/mysql5/lib/64/mysql/foo"]
+    expected = "/opt/csw/mysql5/lib/amd64/mysql/foo"
+    result = checkpkg.Emulate64BitSymlinks(runpath_list)
+    self.assertTrue(expected in result, "%s not in %s" % (expected, result))
+
+  def testGetLinesBySoname(self):
+    expected = {'foo.so.1': '/opt/csw/lib/isa-value-1/foo.so.1 foo'}
+    pkgmap = self.pkgmap_mocker.CreateMock(checkpkg.SystemPkgmap)
+    pkgmap.GetPkgmapLineByBasename("foo")
+    lines1 = {"/opt/csw/lib/isa-value-1": "/opt/csw/lib/isa-value-1/foo.so.1 foo",
+              "/usr/lib":                  "/usr/lib/foo.so.1 foo"}
+    # pkgmap.GetPkgmapLineByBasename("foo.so.1").AndReturn(lines1)
+    pkgmap.GetPkgmapLineByBasename("foo.so.1").AndReturn(lines1)
+    self.pkgmap_mocker.ReplayAll()
+    pkgmap.GetPkgmapLineByBasename("foo")
+    needed_sonames = set(["foo.so.1"])
+    runpath_by_needed_soname = {"foo.so.1": ["/opt/csw/lib/$ISALIST", "/usr/lib"]}
+    isalist = ["isa-value-1", "isa-value-2"]
+    result = checkpkg.GetLinesBySoname(pkgmap, needed_sonames, runpath_by_needed_soname, isalist)
+    self.pkgmap_mocker.VerifyAll()
+    self.assertEqual(expected, result)
+
+  def testGetLinesBySoname_3(self):
+    expected = {'foo.so.1': '/opt/csw/lib/isa-value-1/foo.so.1 foo'}
+    pkgmap = self.pkgmap_mocker.CreateMock(checkpkg.SystemPkgmap)
+    pkgmap.GetPkgmapLineByBasename("foo")
+    lines1 = {
+        "/opt/csw/lib/isa-value-1": "/opt/csw/lib/isa-value-1/foo.so.1 foo",
+        "/opt/csw/lib":             "/opt/csw/lib/foo.so.1 foo",
+        "/usr/lib":                 "/usr/lib/foo.so.1 foo"}
+    # pkgmap.GetPkgmapLineByBasename("foo.so.1").AndReturn(lines1)
+    pkgmap.GetPkgmapLineByBasename("foo.so.1").AndReturn(lines1)
+    self.pkgmap_mocker.ReplayAll()
+    pkgmap.GetPkgmapLineByBasename("foo")
+    needed_sonames = set(["foo.so.1"])
+    runpath_by_needed_soname = {
+        "foo.so.1": ["/opt/csw/lib/$ISALIST", "/usr/lib"]}
+    isalist = ["isa-value-1", "isa-value-2"]
+    result = checkpkg.GetLinesBySoname(
+        pkgmap, needed_sonames, runpath_by_needed_soname, isalist)
+    self.pkgmap_mocker.VerifyAll()
+    self.assertEqual(expected, result)
+
+  def testGetLinesBySoname_4(self):
+    """A more complex test, four ISAs."""
+    expected = {'foo.so.1': '/opt/csw/lib/isa-value-1/foo.so.1 foo'}
+    pkgmap = self.pkgmap_mocker.CreateMock(checkpkg.SystemPkgmap)
+    pkgmap.GetPkgmapLineByBasename("foo")
+    lines1 = {
+        "/opt/csw/lib/isa-value-1":
+            "/opt/csw/lib/isa-value-1/foo.so.1 foo",
+        "/opt/csw/mysql5/lib/isa-value-2":
+            "/opt/csw/mysql5/lib/isa-value-2/foo.so.1 foo",
+        "/opt/csw/mysql5/lib/isa-value-1":
+            "/opt/csw/mysql5/lib/isa-value-1/foo.so.1 foo",
+        "/opt/csw/lib":
+            "/opt/csw/lib/foo.so.1 foo",
+        "/usr/lib":
+            "/usr/lib/foo.so.1 foo"}
+    pkgmap.GetPkgmapLineByBasename("foo.so.1").AndReturn(lines1)
+    pkgmap.GetPkgmapLineByBasename("foo.so.1").AndReturn(lines1)
+    self.pkgmap_mocker.ReplayAll()
+    pkgmap.GetPkgmapLineByBasename("foo")
+    needed_sonames = set(["foo.so.1"])
+    runpath_by_needed_soname = {
+        "foo.so.1": ["/opt/csw/mysql5/lib/$ISALIST/mysql",
+                     "/opt/csw/lib/$ISALIST",
+                     "/usr/lib"]}
+    isalist = ["isa-value-1", "isa-value-2"]
+    result = checkpkg.GetLinesBySoname(
+        pkgmap, needed_sonames, runpath_by_needed_soname, isalist)
+    self.pkgmap_mocker.VerifyAll()
+    self.assertEqual(expected, result)
+
+  def testGetLinesBySoname_5(self):
+    """Based on CSWmysql5client on build8x."""
+    soname = u'libm.so.1'
+    expected = {u'libm.so.1': u'/usr/lib/libm.so.1 f none 0755 root bin '
+                              u'99844 3884 1050525375 SUNWlibms\n'}
+
+    pkgmap_stub = self.PkgmapStub(d6.DATA_PKGMAP_CACHE)
+    (needed_sonames,
+     binaries_by_soname,
+     runpath_by_needed_soname) = checkpkg.BuildIndexesBySoname(
+         d6.DATA_NEEDED_SONAMES_BY_BINARY)
+    result = checkpkg.GetLinesBySoname(
+        pkgmap_stub,
+        set([soname]),
+        runpath_by_needed_soname,
+        d6.DATA_ISALIST)
+    self.assertEqual(expected, result)
+
+  def testGetLinesBySoname_6(self):
+    """Based on CSWmysql5client on build8x."""
+    soname = u'libz.so.1'
+    expected = {u'libz.so.1': u'/opt/csw/lib/pentium_pro+mmx/libz.so.1=libz.so.1.2.3 '
+                              u's none CSWzlib\n'}
+    pkgmap_stub = self.PkgmapStub(d6.DATA_PKGMAP_CACHE)
+    (needed_sonames,
+     binaries_by_soname,
+     runpath_by_needed_soname) = checkpkg.BuildIndexesBySoname(
+         d6.DATA_NEEDED_SONAMES_BY_BINARY)
+    result = checkpkg.GetLinesBySoname(
+        pkgmap_stub,
+        set([soname]),
+        runpath_by_needed_soname,
+        d6.DATA_ISALIST)
+    self.assertEqual(expected, result)
+
+  def testGetLinesBySoname_7(self):
+    """A test for 64-bit symlink expansion."""
+    soname = u'libncursesw.so.5'
+    # To test the 64-bit symlink expansion
+    expected = {
+    	  u'libncursesw.so.5':
+    	    u'/opt/csw/lib/amd64/libncursesw.so.5=libncursesw.so.5.7 '
+    	    u's none CSWncurses\n'}
+    pkgmap_stub = self.PkgmapStub(d6.DATA_PKGMAP_CACHE)
+    (needed_sonames,
+     binaries_by_soname,
+     runpath_by_needed_soname) = checkpkg.BuildIndexesBySoname(
+         d6.DATA_NEEDED_SONAMES_BY_BINARY)
+    result = checkpkg.GetLinesBySoname(
+        pkgmap_stub,
+        set([soname]),
+        runpath_by_needed_soname,
+        d6.DATA_ISALIST)
+    self.assertEqual(expected, result)
+
+
+class ParseDumpOutputUnitTest(unittest.TestCase):
+
+  def test_1(self):
+    expected = {
+        'soname': 'libmysqlclient.so.15',
+        'runpath': ['/opt/csw/lib/$ISALIST',
+                    '/opt/csw/lib',
+                    '/opt/csw/mysql5/lib/$ISALIST',
+                    '/opt/csw/mysql5/lib',
+                    '/opt/csw/mysql5/lib/$ISALIST/mysql',
+                    # These four are artificially appended
+                    '/usr/lib/$ISALIST',
+                    '/usr/lib',
+                    '/lib/$ISALIST',
+                    '/lib'],
+        'needed sonames': ['librt.so.1',
+                           'libresolv.so.2',
+                           'libc.so.1',
+                           'libgen.so.1',
+                           'libsocket.so.1',
+                           'libnsl.so.1',
+                           'libm.so.1',
+                           'libz.so.1']}
+    self.assertEqual(expected,
+                     checkpkg.ParseDumpOutput(dump_1.DATA_DUMP_OUTPUT))
+
+  def test_2(self):
+    expected_runpath = ['/usr/lib/$ISALIST', '/usr/lib', '/lib/$ISALIST', '/lib']
+    self.assertEqual(
+        expected_runpath,
+        checkpkg.ParseDumpOutput(dump_2.DATA_DUMP_OUTPUT)["runpath"])
+
+
+if __name__ == '__main__':
+  unittest.main()

Deleted: csw/mgar/gar/v2/bin/checkpkg.d/testdata/checkpkg_test_data_CSWlibpq_84.py
===================================================================
--- csw/mgar/gar/v2-checkpkg/bin/checkpkg.d/testdata/checkpkg_test_data_CSWlibpq_84.py	2010-01-04 03:57:34 UTC (rev 7855)
+++ csw/mgar/gar/v2/bin/checkpkg.d/testdata/checkpkg_test_data_CSWlibpq_84.py	2010-01-04 10:28:15 UTC (rev 7856)
@@ -1,10 +0,0 @@
-# Testing data for CSWlibpq-84
-# $Id$
-DATA_PKGNAME = 'CSWlibpq-84'
-DATA_DECLARED_DEPENDENCIES = {'CSWlibxml2': 'CSWlibxml2 libxml2 - XML Parser Library ', 'CSWkrb5lib': 'CSWkrb5lib krb5_lib - MIT Kerberos 5 core libraries ', 'CSWlibxslt': 'CSWlibxslt libxslt - XSLT engine runtime package ', 'CSWcommon': 'CSWcommon common - common files and dirs for CSW packages ', 'CSWisaexec': 'CSWisaexec isaexec - sneaky wrapper around Sun isaexec ', 'CSWzlib': 'CSWzlib zlib - Zlib Data Compression Library ', 'CSWosslrt': 'CSWosslrt openssl_rt - Openssl runtime libraries '}

@@ Diff output truncated at 100000 characters. @@

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.



More information about the devel mailing list