[csw-devel] SF.net SVN: gar:[8650] csw/mgar/gar/v2
wahwah at users.sourceforge.net
wahwah at users.sourceforge.net
Thu Feb 18 14:20:58 CET 2010
Revision: 8650
http://gar.svn.sourceforge.net/gar/?rev=8650&view=rev
Author: wahwah
Date: 2010-02-18 13:20:57 +0000 (Thu, 18 Feb 2010)
Log Message:
-----------
mGAR v2: merging the v2-checkpkg-stats branch back to v2
Modified Paths:
--------------
csw/mgar/gar/v2/bin/checkpkg
csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-actionclasses.py
csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-archall.py
csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-libs.py
csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-license.py
csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-missing-symbols.py
csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-obsolete-deps.py
csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-you-can-write-your-own.py
csw/mgar/gar/v2/bin/update_contents_cache.py
csw/mgar/gar/v2/gar.conf.mk
csw/mgar/gar/v2/lib/python/checkpkg.py
csw/mgar/gar/v2/lib/python/opencsw.py
csw/mgar/gar/v2/tests/overrides_test.py
csw/mgar/gar/v2/tests/run_tests.py
Added Paths:
-----------
csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-basic.py
csw/mgar/gar/v2/bin/checkpkg_collect_stats.py
csw/mgar/gar/v2/bin/checkpkg_collect_stats_test.py
csw/mgar/gar/v2/bin/custom-pkgtrans
csw/mgar/gar/v2/lib/python/package_checks.py
csw/mgar/gar/v2/lib/python/package_checks_test.py
csw/mgar/gar/v2/lib/sh/
csw/mgar/gar/v2/lib/sh/libcheckpkg.sh
Removed Paths:
-------------
csw/mgar/gar/v2/lib/sh/libcheckpkg.sh
Property Changed:
----------------
csw/mgar/gar/v2/
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-checkpkg:7722-7855
/csw/mgar/gar/v2-collapsed-modulations:6895
/csw/mgar/gar/v2-dirpackage:8125-8180
/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-checkpkg-stats:8454-8649
/csw/mgar/gar/v2-collapsed-modulations:6895
/csw/mgar/gar/v2-dirpackage:8125-8180
/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-02-18 13:01:38 UTC (rev 8649)
+++ csw/mgar/gar/v2/bin/checkpkg 2010-02-18 13:20:57 UTC (rev 8650)
@@ -21,10 +21,15 @@
# you know you are tracking the most current version.
#
-
PATH=$PATH:/usr/sbin
readonly NAME_MAX_LENGTH=${NAME_MAX_LENGTH:-20}
+command_basename=`basename $0`
+command_basedir="${0%/${command_basename}}"
+libshdir="${command_basedir}/../lib/sh"
+readonly command_basename command_basedir libshdir
+. "${libshdir}/libcheckpkg.sh"
+
LOCAL_ARCH=`uname -p`
if [[ -z "${CHECKPKG_TMPDIR}" ]]; then
readonly CHECKPKG_TMPDIR="/var/tmp"
@@ -44,9 +49,10 @@
BOLD=""
COLOR_RESET=""
fi
+readonly GREEN RED BOLD COLOR_RESET
readonly selfpath="$0"
-readonly selfargs="$*"
+readonly selfargs="$@"
# always print out a warning message. (to stderr)
# exit script, if quit_on_warn set
@@ -124,8 +130,9 @@
shift
fi
if [[ "$1" == "-h" ]] ; then
- print 'Usage: checkpkg [-e] pkg1 [pkg2 ....]'
- print ' -e = "exit on warnings"'
+ print 'Usage: checkpkg [-d] [-e] pkg1 [pkg2 ....]'
+ print ' -d display debug messages'
+ print ' -e exit on warnings (soon to be obsolete)'
shift
fi
@@ -209,12 +216,6 @@
basedir=`sed -n 's/^BASEDIR=//p' $TMPFILE`
pkgarch=`sed -n 's/^ARCH=//p' $TMPFILE|head -1`
-case $software in
- *[A-Z]*)
- errmsg "$software must be all lowercase"
- ;;
-esac
-
case `basename $f` in
${software}-${version}-*)
# file name looks okay
@@ -337,38 +338,9 @@
# exit 0
#fi
-
-# This function exists, because pkgtrans is BROKEN!!
-# It leaves a directory in /var/tmp/aaXXXXXXX, even after clean quit
-# SO, emulate pkgtrans behaviour, for "pkgtrans src destdir pkgname"
-# Except that we ignore pkgname arg, and just do first one we find.
-# and we are a bit hacky about how we do things.
-pkgtrans(){
- if [[ ! -d $2 ]] ; then
- print ERROR: $2 is not a directory >/dev/fd/2
- return 1
- fi
- hdrblks=`(dd if=$1 skip=1 2>/dev/null| cpio -i -t >/dev/null) 2>&1 |
- nawk '{print $1; exit;}'`
-
- ## print initial hdrblks=$hdrblks
-
- hdrblks=$(($hdrblks + 1))
- mkdir $2/$3 || return 1
-
- dd if=$1 skip=$hdrblks 2>/dev/null | (cd $2/$3 ; cpio -ivdm)
- # on fail, SOMETIMES cpio returns 1, but sometimes it returns 0!!
- if [[ ! -d $2/$3/install ]] ; then
- print retrying extract with different archive offset...
- # no, I cant tell in advance why/when the prev fails
- hdrblks=$(($hdrblks + 1))
- dd if=$1 skip=$hdrblks 2>/dev/null| (cd $2/$3 ; cpio -ivdm)
- fi
-}
-
print ""
print Extracing pkg for examination of files...
-pkgtrans $f $EXTRACTDIR $pkgname
+custom_pkgtrans $f $EXTRACTDIR $pkgname
#############################################################
# We now have the package expanded, in "directory" form, in
@@ -566,33 +538,36 @@
set_variables_for_individual_package_check "$f"
test_suite_ok=1
-checkpkg_scriptname=`basename $0`
-checkpkg_basedir=${0%/${checkpkg_scriptname}}
-plugindir=${checkpkg_basedir}/checkpkg.d
+checkpkg_module_dir=${command_basedir}/checkpkg.d
checkpkg_module_tag="checkpkg-"
+checkpkg_stats_basedir="${HOME}/.checkpkg/stats"
# Cleaning up old *.pyc files which can cause grief. This is because of the
# move of Python libraries.
-for pyc_file in ${plugindir}/opencsw.pyc \
- ${plugindir}/checkpkg.pyc; do
+for pyc_file in ${checkpkg_module_dir}/opencsw.pyc \
+ ${checkpkg_module_dir}/checkpkg.pyc; do
if [ -f "${pyc_file}" ]; then
echo "Removing old pyc file: '${pyc_file}'"
rm "${pyc_file}"
fi
done
-# /var/sadm/install/contents cache update
-${checkpkg_basedir}/update_contents_cache.py
-
if [[ "${DEBUG}" != "" ]]; then
extra_options="--debug"
fi
-debugmsg "plugindir: '$plugindir'"
+
+# /var/sadm/install/contents cache update
+${command_basedir}/update_contents_cache.py
+# Collects package stats to be later analyzed
+${command_basedir}/checkpkg_collect_stats.py ${extra_options} "$@"
+
+debugmsg "checkpkg_module_dir: '$checkpkg_module_dir'"
log_files=""
module_name_format="%-40s"
-if [[ -d "$plugindir" ]]; then
- echo "Running modular tests"
- for plugin in "${plugindir}/${checkpkg_module_tag}"*; do
+md5sums=`gmd5sum "$@" | awk '{print $1}'`
+if [[ -d "${checkpkg_module_dir}" ]]; then
+ echo "Running modular tests in ${checkpkg_module_dir}"
+ for plugin in "${checkpkg_module_dir}/${checkpkg_module_tag}"*; do
if [[ -x "${plugin}" ]]; then
plugin_base_name=`basename ${plugin}`
plugin_log="${EXTRACTDIR}/${plugin_base_name}.log"
@@ -600,12 +575,12 @@
plugin_name="`echo ${plugin} | sed -e 's+.*/checkpkg-++' | sed -e 's+\.py$++'`"
error_tag_file="tags.${plugin_name}"
printf "${BOLD}${module_name_format}${COLOR_RESET} running..." "${plugin_name}"
- debugmsg "Executing: ${plugin} $extra_options -e \"${EXTRACTDIR}\" ${pkgnames}"
+ debugmsg "Executing: ${plugin} $extra_options -b \"${checkpkg_stats_basedir}\" -o \"${EXTRACTDIR}/${error_tag_file}\" ${md5sums}"
${plugin} \
$extra_options \
- -e "${EXTRACTDIR}" \
+ -b "${checkpkg_stats_basedir}" \
-o "${EXTRACTDIR}/${error_tag_file}" \
- ${pkgnames} \
+ ${md5sums} \
> "${plugin_log}" 2>&1
if [[ "$?" -ne 0 ]]; then
printf "\r${module_name_format} ${RED}[ERROR]${COLOR_RESET} \\n" "${plugin_name}"
@@ -618,7 +593,7 @@
fi
done
else
- debugmsg "plugin dir ${plugindir} does not exist"
+ debugmsg "module dir ${checkpkg_module_dir} does not exist"
fi
for log_file in ${log_files}; do
@@ -653,7 +628,7 @@
fi
# Collecting errors and applying the overrides.
-${checkpkg_basedir}/analyze_module_results.py \
+${command_basedir}/analyze_module_results.py \
-e "${EXTRACTDIR}" \
${pkgnames}
if [[ "$?" -ne 0 ]]; then
Modified: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-actionclasses.py
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-actionclasses.py 2010-02-18 13:01:38 UTC (rev 8649)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-actionclasses.py 2010-02-18 13:20:57 UTC (rev 8650)
@@ -22,18 +22,21 @@
import opencsw
-def CheckActionClasses(pkg, debug):
+def CheckActionClasses(pkg_data, debug):
"""Checks the consistency between classes in the prototype and pkginfo."""
errors = []
- pkginfo = pkg.GetParsedPkginfo()
- pkgmap = pkg.GetPkgmap()
+ pkginfo = pkg_data["pkginfo"]
+ pkgmap = pkg_data["pkgmap"]
pkginfo_classes = set(re.split(opencsw.WS_RE, pkginfo["CLASSES"]))
- pkgmap_classes = pkgmap.GetClasses()
+ pkgmap_classes = set()
+ for entry in pkgmap:
+ if entry["class"]: # might be None
+ pkgmap_classes.add(entry["class"])
only_in_pkginfo = pkginfo_classes.difference(pkgmap_classes)
only_in_pkgmap = pkgmap_classes.difference(pkginfo_classes)
for action_class in only_in_pkginfo:
error = checkpkg.CheckpkgTag(
- pkg.pkgname,
+ pkg_data["basic_stats"]["pkgname"],
"action-class-only-in-pkginfo",
action_class,
msg="This shouldn't cause any problems, but it might be not necessary.")
@@ -46,10 +49,16 @@
def main():
options, args = checkpkg.GetOptions()
- pkgnames = args
+ if options.debug:
+ logging.basicConfig(level=logging.DEBUG)
+ else:
+ logging.basicConfig(level=logging.INFO)
+ md5sums = args
+ # CheckpkgManager class abstracts away things such as the collection of
+ # results.
check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
- options.extractdir,
- pkgnames,
+ options.stats_basedir,
+ md5sums,
options.debug)
# Registering functions defined above.
check_manager.RegisterIndividualCheck(CheckActionClasses)
Modified: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-archall.py
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-archall.py 2010-02-18 13:01:38 UTC (rev 8649)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-archall.py 2010-02-18 13:20:57 UTC (rev 8650)
@@ -19,13 +19,14 @@
ARCH_RE = re.compile(r"(sparcv(8|9)|i386|amd64)")
-def CheckArchitectureVsContents(pkg, debug):
+def CheckArchitectureVsContents(pkg_data, debug):
"""Verifies the relationship between package contents and architecture."""
errors = []
- binaries = pkg.ListBinaries()
- pkginfo = pkg.GetParsedPkginfo()
+ binaries = pkg_data["binaries"]
+ pkginfo = pkg_data["pkginfo"]
pkgmap = pkg.GetPkgmap()
arch = pkginfo["ARCH"]
+ pkgname = pkg_data["basic_stats"]["pkgname"]
reasons_to_be_arch_specific = []
for pkgmap_path in pkgmap.entries_by_path:
# print "pkgmap_path", repr(pkgmap_path), type(pkgmap_path)
@@ -41,13 +42,13 @@
"package contains binary %s" % binary))
if arch == "all":
for tag, param, desc in reasons_to_be_arch_specific:
- errors.append(checkpkg.CheckpkgTag(pkg.pkgname, tag, param))
+ errors.append(checkpkg.CheckpkgTag(pkgname, tag, param))
elif not reasons_to_be_arch_specific:
# This is not a clean way of handling messages for the user, but there's
# not better way at the moment.
- print "Package %s does not contain any binaries." % pkg.pkgname
+ print "Package %s does not contain any binaries." % pkgname
print "Consider making it ARCHALL = 1 instead of %s:" % arch
- print "ARCHALL_%s = 1" % pkg.pkgname
+ print "ARCHALL_%s = 1" % pkgname
print ("However, be aware that there might be other reasons "
"to keep it architecture-specific.")
return errors
@@ -55,10 +56,12 @@
def main():
options, args = checkpkg.GetOptions()
- pkgnames = args
+ md5sums = args
+ # CheckpkgManager class abstracts away things such as the collection of
+ # results.
check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
- options.extractdir,
- pkgnames,
+ options.stats_basedir,
+ md5sums,
options.debug)
check_manager.RegisterIndividualCheck(CheckArchitectureVsContents)
Copied: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-basic.py (from rev 8649, csw/mgar/gar/v2-checkpkg-stats/bin/checkpkg.d/checkpkg-basic.py)
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-basic.py (rev 0)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-basic.py 2010-02-18 13:20:57 UTC (rev 8650)
@@ -0,0 +1,44 @@
+#!/opt/csw/bin/python2.6
+# $Id: checkpkg-you-can-write-your-own.py 8571 2010-02-16 09:05:51Z wahwah $
+
+"""This is a dummy module. You can use it as a boilerplate for your own modules.
+
+Copy it and modify.
+"""
+
+import os.path
+import sys
+
+CHECKPKG_MODULE_NAME = "basic checks ported from Korn shell"
+
+# The following bit of code sets the correct path to Python libraries
+# distributed with GAR.
+path_list = [os.path.dirname(__file__),
+ "..", "..", "lib", "python"]
+sys.path.append(os.path.join(*path_list))
+import checkpkg
+import package_checks
+
+def main():
+ options, args = checkpkg.GetOptions()
+ md5sums = args
+ # CheckpkgManager class abstracts away things such as the collection of
+ # results.
+ check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
+ options.stats_basedir,
+ md5sums,
+ options.debug)
+ # Registering functions defined above.
+ check_manager.RegisterIndividualCheck(package_checks.CatalognameLowercase)
+ check_manager.RegisterIndividualCheck(package_checks.FileNameSanity)
+ # Running the checks, reporting and exiting.
+ exit_code, screen_report, tags_report = check_manager.Run()
+ f = open(options.output, "w")
+ f.write(tags_report)
+ f.close()
+ print screen_report.strip()
+ sys.exit(exit_code)
+
+
+if __name__ == '__main__':
+ main()
Modified: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-libs.py
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-libs.py 2010-02-18 13:01:38 UTC (rev 8649)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-libs.py 2010-02-18 13:20:57 UTC (rev 8650)
@@ -28,69 +28,32 @@
import checkpkg
import opencsw
-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 CheckSharedLibraryConsistency(pkgs, debug):
+def CheckSharedLibraryConsistency(pkgs_data, debug):
+ ws_re = re.compile(r"\s+")
result_ok = True
errors = []
binaries = []
binaries_by_pkgname = {}
sonames_by_pkgname = {}
pkg_by_any_filename = {}
- for checker in pkgs:
- 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
+ needed_sonames_by_binary = {}
+ filenames_by_soname = {}
+ for pkg_data in pkgs_data:
+ binaries_base = [os.path.basename(x) for x in pkg_data["binaries"]]
+ pkgname = pkg_data["basic_stats"]["pkgname"]
+ binaries_by_pkgname[pkgname] = binaries_base
+ binaries.extend(pkg_data["binaries"])
+ for filename in pkg_data["all_filenames"]:
+ pkg_by_any_filename[filename] = pkgname
+ for binary_data in pkg_data["binaries_dump_info"]:
+ binary_base_name = os.path.basename(binary_data["base_name"])
+ needed_sonames_by_binary[binary_base_name] = binary_data
+ filenames_by_soname[binary_data[checkpkg.SONAME]] = binary_base_name
+
# Making the binaries unique
binaries = set(binaries)
- ws_re = re.compile(r"\s+")
+ isalist = pkg_data["isalist"]
- # 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.debug("The %s binary doesn't provide a SONAME. "
- "(It might be an executable)",
- 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,
@@ -158,10 +121,9 @@
print
dependent_pkgs = {}
- for checker in pkgs:
- pkgname = checker.pkgname
- dir_format_pkg = opencsw.DirectoryFormatPackage(checker.pkgpath)
- declared_dependencies = dir_format_pkg.GetDependencies()
+ for checker in pkgs_data:
+ pkgname = checker["basic_stats"]["pkgname"]
+ declared_dependencies = checker["depends"]
if debug:
sanitized_pkgname = pkgname.replace("-", "_")
data_file_name = "/var/tmp/checkpkg_test_data_%s.py" % sanitized_pkgname
@@ -191,7 +153,7 @@
filenames_by_soname,
pkg_by_any_filename)
namespace = {
- "pkgname": checker.pkgname,
+ "pkgname": pkgname,
"missing_deps": missing_deps,
"surplus_deps": surplus_deps,
"orphan_sonames": orphan_sonames,
@@ -206,20 +168,22 @@
"orphan-soname",
soname))
for missing_dep in missing_deps:
- errors.append(
- checkpkg.CheckpkgTag(
- pkgname,
- "missing-dependency",
- missing_dep))
+ errors.append(
+ checkpkg.CheckpkgTag(
+ pkgname,
+ "missing-dependency",
+ missing_dep))
return errors
def main():
options, args = checkpkg.GetOptions()
- pkgnames = args
+ md5sums = args
+ # CheckpkgManager class abstracts away things such as the collection of
+ # results.
check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
- options.extractdir,
- pkgnames,
+ options.stats_basedir,
+ md5sums,
options.debug)
check_manager.RegisterSetCheck(CheckSharedLibraryConsistency)
Modified: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-license.py
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-license.py 2010-02-18 13:01:38 UTC (rev 8649)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-license.py 2010-02-18 13:20:57 UTC (rev 8650)
@@ -19,16 +19,17 @@
LICENSE_TMPL = "/opt/csw/share/doc/%s/license"
-def CheckLicenseFile(pkg, debug):
+def CheckLicenseFile(pkg_data, debug):
"""Checks for the presence of the license file."""
errors = []
- pkgmap = pkg.GetPkgmap()
- catalogname = pkg.GetCatalogname()
+ pkgmap = pkg_data["pkgmap"]
+ catalogname = pkg_data["basic_stats"]["catalogname"]
license_path = LICENSE_TMPL % catalogname
- if license_path not in pkgmap.entries_by_path:
+ pkgmap_paths = [x["path"] for x in pkgmap]
+ if license_path not in pkgmap_paths:
errors.append(
checkpkg.CheckpkgTag(
- pkg.pkgname,
+ pkg_data["basic_stats"]["pkgname"],
"license-missing",
msg="See http://sourceforge.net/apps/trac/gar/wiki/CopyRight"))
return errors
@@ -36,10 +37,12 @@
def main():
options, args = checkpkg.GetOptions()
- pkgnames = args
+ md5sums = args
+ # CheckpkgManager class abstracts away things such as the collection of
+ # results.
check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
- options.extractdir,
- pkgnames,
+ options.stats_basedir,
+ md5sums,
options.debug)
# Registering functions defined above.
check_manager.RegisterIndividualCheck(CheckLicenseFile)
Modified: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-missing-symbols.py
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-missing-symbols.py 2010-02-18 13:01:38 UTC (rev 8649)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-missing-symbols.py 2010-02-18 13:20:57 UTC (rev 8650)
@@ -22,39 +22,33 @@
# Defining checking functions.
-def CheckForMissingSymbols(pkg, debug):
+def CheckForMissingSymbols(pkg_data, debug):
"""Looks for "symbol not found" in ldd -r output."""
errors = []
- binaries = pkg.ListBinaries()
+ binaries = pkg_data["binaries"]
symbol_re = re.compile(r"symbol not found:")
for binary in binaries:
- # this could be potentially moved into the DirectoryFormatPackage class.
- args = ["ldd", "-r", binary]
- ldd_proc = subprocess.Popen(
- args,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = ldd_proc.communicate()
- retcode = ldd_proc.wait()
- lines = stdout.splitlines()
+ lines = pkg_data["ldd_dash_r"][binary]
missing_symbols = False
for line in lines:
if re.search(symbol_re, line):
missing_symbols = True
binary_base = os.path.basename(binary)
if missing_symbols:
- errors.append(checkpkg.CheckpkgTag(pkg.pkgname, "symbol-not-found", binary_base))
+ errors.append(checkpkg.CheckpkgTag(
+ pkg_data["basic_stats"]["pkgname"],
+ "symbol-not-found", binary_base))
return errors
def main():
options, args = checkpkg.GetOptions()
- pkgnames = args
+ md5sums = args
# CheckpkgManager class abstracts away things such as the collection of
# results.
check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
- options.extractdir,
- pkgnames,
+ options.stats_basedir,
+ md5sums,
options.debug)
# Registering functions defined above.
check_manager.RegisterIndividualCheck(CheckForMissingSymbols)
Modified: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-obsolete-deps.py
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-obsolete-deps.py 2010-02-18 13:01:38 UTC (rev 8649)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-obsolete-deps.py 2010-02-18 13:20:57 UTC (rev 8650)
@@ -8,6 +8,8 @@
import os.path
import sys
+CHECKPKG_MODULE_NAME = "obsolete dependencies"
+
# The following bit of code sets the correct path to Python libraries
# distributed with GAR.
path_list = [os.path.dirname(__file__),
@@ -26,10 +28,10 @@
},
}
-def CheckObsoleteDeps(pkg, debug):
+def CheckObsoleteDeps(pkg_data, debug):
"""Checks for obsolete dependencies."""
errors = []
- deps = set(pkg.GetDependencies())
+ deps = set(pkg_data["depends"])
obsolete_pkg_deps = deps.intersection(set(OBSOLETE_DEPS))
if obsolete_pkg_deps:
for obsolete_pkg in obsolete_pkg_deps:
@@ -43,17 +45,20 @@
if not msg:
msg = None
errors.append(
- checkpkg.CheckpkgTag(pkg.pkgname, "obsolete-dependency",
- obsolete_pkg, msg=msg))
+ checkpkg.CheckpkgTag(
+ pkg_data["basic_stats"]["pkgname"],
+ "obsolete-dependency", obsolete_pkg, msg=msg))
return errors
def main():
options, args = checkpkg.GetOptions()
- pkgnames = args
- check_manager = checkpkg.CheckpkgManager("obsolete dependencies",
- options.extractdir,
- pkgnames,
+ md5sums = args
+ # CheckpkgManager class abstracts away things such as the collection of
+ # results.
+ check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
+ options.stats_basedir,
+ md5sums,
options.debug)
check_manager.RegisterIndividualCheck(CheckObsoleteDeps)
# Running the checks, reporting and exiting.
Modified: csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-you-can-write-your-own.py
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-you-can-write-your-own.py 2010-02-18 13:01:38 UTC (rev 8649)
+++ csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-you-can-write-your-own.py 2010-02-18 13:20:57 UTC (rev 8650)
@@ -21,7 +21,7 @@
# Defining the checking functions. They come in two flavors: individual
# package checks and set checks.
-def MyCheckForAsinglePackage(pkg, debug):
+def MyCheckForAsinglePackage(pkg_data, debug):
"""Checks an individual package.
Gets a DirctoryFormatPackage as an argument, and returns a list of errors.
@@ -40,11 +40,13 @@
# Here's how to report an error:
something_is_wrong = False
if something_is_wrong:
- errors.append(checkpkg.CheckpkgTag(pkg.pkgname, "example-problem", "thing"))
+ errors.append(checkpkg.CheckpkgTag(
+ pkg_data["basic_stats"]["pkgname"],
+ "example-problem", "thing"))
return errors
-def MyCheckForAsetOfPackages(pkgs, debug):
+def MyCheckForAsetOfPackages(pkgs_data, debug):
"""Checks a set of packages.
Sometimes individual checks aren't enough. If you need to write code which
@@ -59,12 +61,12 @@
def main():
options, args = checkpkg.GetOptions()
- pkgnames = args
+ md5sums = args
# CheckpkgManager class abstracts away things such as the collection of
# results.
check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
- options.extractdir,
- pkgnames,
+ options.stats_basedir,
+ md5sums,
options.debug)
# Registering functions defined above.
check_manager.RegisterIndividualCheck(MyCheckForAsinglePackage)
Copied: csw/mgar/gar/v2/bin/checkpkg_collect_stats.py (from rev 8649, csw/mgar/gar/v2-checkpkg-stats/bin/checkpkg_collect_stats.py)
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg_collect_stats.py (rev 0)
+++ csw/mgar/gar/v2/bin/checkpkg_collect_stats.py 2010-02-18 13:20:57 UTC (rev 8650)
@@ -0,0 +1,42 @@
+#!/opt/csw/bin/python2.6
+#
+# $Id$
+#
+# Collects statistics about a package and saves to a directory, for later use
+# by checkpkg modules.
+
+import logging
+import optparse
+import os
+import os.path
+import subprocess
+import sys
+
+# The following bit of code sets the correct path to Python libraries
+# distributed with GAR.
+path_list = [os.path.dirname(__file__),
+ "..", "lib", "python"]
+sys.path.append(os.path.join(*path_list))
+import checkpkg
+import opencsw
+
+
+def main():
+ parser = optparse.OptionParser()
+ parser.add_option("-d", "--debug", dest="debug",
+ default=False, action="store_true",
+ help="Turn on debugging messages")
+ options, args = parser.parse_args()
+ if options.debug:
+ logging.basicConfig(level=logging.DEBUG)
+ else:
+ logging.basicConfig(level=logging.INFO)
+ logging.info("Collecting statistics about given package files.")
+ logging.debug("calling: %s, please be patient", args)
+ packages = [opencsw.CswSrv4File(x, options.debug) for x in args]
+ stats_list = [checkpkg.PackageStats(pkg) for pkg in packages]
+ for pkg_stats in stats_list:
+ pkg_stats.CollectStats()
+
+if __name__ == '__main__':
+ main()
Copied: csw/mgar/gar/v2/bin/checkpkg_collect_stats_test.py (from rev 8649, csw/mgar/gar/v2-checkpkg-stats/bin/checkpkg_collect_stats_test.py)
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg_collect_stats_test.py (rev 0)
+++ csw/mgar/gar/v2/bin/checkpkg_collect_stats_test.py 2010-02-18 13:20:57 UTC (rev 8650)
@@ -0,0 +1,34 @@
+#!/opt/csw/bin/python2.6
+
+import os
+import sys
+import unittest
+import mox
+import checkpkg_collect_stats as ccs
+
+# The following bit of code sets the correct path to Python libraries
+# distributed with GAR.
+path_list = [os.path.dirname(__file__),
+ "..", "lib", "python"]
+sys.path.append(os.path.join(*path_list))
+import checkpkg
+import opencsw
+
+
+class PackageStatsUnitTest(unittest.TestCase):
+
+ def setUp(self):
+ self.mocker = mox.Mox()
+
+ def testGetStatsPath(self):
+ mock_pkg = self.mocker.CreateMock(opencsw.CswSrv4File)
+ mock_pkg.GetMd5sum().AndReturn("abcdef")
+ self.mocker.ReplayAll()
+ sc = ccs.PackageStats(mock_pkg)
+ expected = "/home/joe/.checkpkg/stats/ab/abcdef"
+ self.assertEqual(expected, sc.GetStatsPath("/home/joe"))
+ self.mocker.VerifyAll()
+
+
+if __name__ == '__main__':
+ unittest.main()
Copied: csw/mgar/gar/v2/bin/custom-pkgtrans (from rev 8649, csw/mgar/gar/v2-checkpkg-stats/bin/custom-pkgtrans)
===================================================================
--- csw/mgar/gar/v2/bin/custom-pkgtrans (rev 0)
+++ csw/mgar/gar/v2/bin/custom-pkgtrans 2010-02-18 13:20:57 UTC (rev 8650)
@@ -0,0 +1,22 @@
+#!/bin/ksh -p
+#
+# $Id$
+#
+# This file exists in order to avoid implementing pipelines in Python. It
+# could be integrated into the package stats collection program.
+
+command_basename=`basename $0`
+command_basedir="${0%/${command_basename}}"
+libshdir="${command_basedir}/../lib/sh"
+readonly command_basename command_basedir libshdir
+. "${libshdir}/libcheckpkg.sh"
+
+if [[ -z "$1" || -z "$2" || -z "$3" ]]; then
+ print >&2 "usage: $0 <file.pkg> <targetdir> <pkgname>"
+ exit 1
+fi
+if [[ "$3" == "all" ]]; then
+ print >&2 "This script can't handle 'all' as the third argument"
+ exit 1
+fi
+custom_pkgtrans "$1" "$2" "$3"
Modified: csw/mgar/gar/v2/bin/update_contents_cache.py
===================================================================
--- csw/mgar/gar/v2/bin/update_contents_cache.py 2010-02-18 13:01:38 UTC (rev 8649)
+++ csw/mgar/gar/v2/bin/update_contents_cache.py 2010-02-18 13:20:57 UTC (rev 8650)
@@ -12,8 +12,7 @@
# The following bit of code sets the correct path to Python libraries
# distributed with GAR.
-path_list = [os.getcwd(),
- os.path.split(sys.argv[0])[0],
+path_list = [os.path.dirname(__file__),
"..", "lib", "python"]
sys.path.append(os.path.join(*path_list))
import checkpkg
Modified: csw/mgar/gar/v2/gar.conf.mk
===================================================================
--- csw/mgar/gar/v2/gar.conf.mk 2010-02-18 13:01:38 UTC (rev 8649)
+++ csw/mgar/gar/v2/gar.conf.mk 2010-02-18 13:20:57 UTC (rev 8650)
@@ -179,6 +179,7 @@
DEF_BASE_PKGS += CSWgsed
DEF_BASE_PKGS += CSWgtar
DEF_BASE_PKGS += CSWpy-cheetah
+DEF_BASE_PKGS += CSWpy-yaml
DEF_BASE_PKGS += CSWpython
DEF_BASE_PKGS += CSWtextutils
DEF_BASE_PKGS += CSWwget
Modified: csw/mgar/gar/v2/lib/python/checkpkg.py
===================================================================
--- csw/mgar/gar/v2/lib/python/checkpkg.py 2010-02-18 13:01:38 UTC (rev 8649)
+++ csw/mgar/gar/v2/lib/python/checkpkg.py 2010-02-18 13:20:57 UTC (rev 8650)
@@ -3,6 +3,9 @@
# This is the checkpkg library, common for all checkpkg tests written in
# Python.
+import copy
+import cPickle
+import errno
import itertools
import logging
import optparse
@@ -12,6 +15,7 @@
import socket
import sqlite3
import subprocess
+import yaml
from Cheetah import Template
import opencsw
@@ -24,21 +28,23 @@
DO_NOT_REPORT_SURPLUS = set([u"CSWcommon", u"CSWcswclassutils", u"CSWisaexec"])
DO_NOT_REPORT_MISSING = set([])
DO_NOT_REPORT_MISSING_RE = [r"SUNW.*", r"\*SUNW.*"]
+DUMP_BIN = "/usr/ccs/bin/dump"
SYSTEM_SYMLINKS = (
- ("/opt/csw/bdb4", ["/opt/csw/bdb42"]),
- ("/64", ["/amd64", "/sparcv9"]),
+ ("/opt/csw/bdb4", ["/opt/csw/bdb42"]),
+ ("/64", ["/amd64", "/sparcv9"]),
("/opt/csw/lib/i386", ["/opt/csw/lib"]),
)
+INSTALL_CONTENTS_AVG_LINE_LENGTH = 102.09710677919261
# 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"])
DEPENDENCY_FILENAME_REGEXES = (
- (r".*\.pl", u"CSWperl"),
- (r".*\.pm", u"CSWperl"),
- (r".*\.py", u"CSWpython"),
- (r".*\.rb", u"CSWruby"),
+ (r".*\.pl$", u"CSWperl"),
+ (r".*\.pm$", u"CSWperl"),
+ (r".*\.py$", u"CSWpython"),
+ (r".*\.rb$", u"CSWruby"),
)
REPORT_TMPL = u"""#if $missing_deps or $surplus_deps or $orphan_sonames
@@ -75,7 +81,7 @@
#end for
#else
#if $debug
-OK: $name found no problems.
+OK: $repr($name) module found no problems.
#end if
#end if
"""
@@ -106,16 +112,19 @@
def GetOptions():
parser = optparse.OptionParser()
- parser.add_option("-e", dest="extractdir",
- help="The directory into which the package has been extracted")
+ parser.add_option("-b", dest="stats_basedir",
+ help=("The base directory with package statistics "
+ "in yaml format, e.g. ~/.checkpkg/stats"))
parser.add_option("-d", "--debug", dest="debug",
default=False, action="store_true",
help="Turn on debugging messages")
parser.add_option("-o", "--output", dest="output",
help="Output error tag file")
(options, args) = parser.parse_args()
- if not options.extractdir:
- raise ConfigurationError("ERROR: -e option is missing.")
+ if not options.stats_basedir:
+ raise ConfigurationError("ERROR: the -b option is missing.")
+ if not options.output:
+ raise ConfigurationError("ERROR: the -o option is missing.")
# Using set() to make the arguments unique.
return options, set(args)
@@ -199,18 +208,21 @@
fgrep -f $EXTRACTDIR/liblist >$EXTRACTDIR/shortcatalog
"""
+ contents_length = os.stat(SYSTEM_PKGMAP).st_size
+ estimated_lines = contents_length / INSTALL_CONTENTS_AVG_LINE_LENGTH
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)
+ print "Processing %s" % 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,
+ print "\r~%3.1f%%" % (100.0 * i / estimated_lines,),
if stop_re.search(line):
continue
fields = re.split(WS_RE, line)
@@ -218,7 +230,7 @@
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 "\rAll lines of %s were processed." % SYSTEM_PKGMAP
print "Creating the main database index."
sql = "CREATE INDEX basename_idx ON systempkgmap(basename);"
c.execute(sql)
@@ -280,17 +292,18 @@
return self.GetFileMtime() <= self.GetDatabaseMtime()
def PurgeDatabase(self):
- logging.info("Purging the cache database")
c = self.conn.cursor()
- sql = "DELETE FROM config;"
- c.execute(sql)
- sql = "DELETE FROM systempkgmap;"
- c.execute(sql)
+ logging.info("Dropping the index.")
sql = "DROP INDEX basename_idx;"
try:
c.execute(sql)
except sqlite3.OperationalError, e:
logging.warn(e)
+ logging.info("Deleting all rows from the cache database")
+ sql = "DELETE FROM config;"
+ c.execute(sql)
+ sql = "DELETE FROM systempkgmap;"
+ c.execute(sql)
def SharedObjectDependencies(pkgname,
binaries_by_pkgname,
@@ -560,11 +573,11 @@
class CheckpkgManager(object):
"""Takes care of calling checking functions"""
- def __init__(self, name, extractdir, pkgname_list, debug=False):
+ def __init__(self, name, stats_basedir, md5sum_list, debug=False):
self.debug = debug
self.name = name
- self.extractdir = extractdir
- self.pkgname_list = pkgname_list
+ self.md5sum_list = md5sum_list
+ self.stats_basedir = stats_basedir
self.errors = []
self.individual_checks = []
self.set_checks = []
@@ -576,23 +589,24 @@
def RegisterSetCheck(self, function):
self.set_checks.append(function)
- def GetDirectoryFormatPackages(self):
- packages = []
- for pkgname in self.pkgname_list:
- pkg_path = os.path.join(self.extractdir, pkgname)
- packages.append(opencsw.DirectoryFormatPackage(pkg_path))
- return packages
+ def GetPackageStatsList(self):
+ stats_list = []
+ for md5sum in self.md5sum_list:
+ stats_list.append(PackageStats(None, self.stats_basedir, md5sum))
+ return stats_list
- def GetAllTags(self, packages):
+ def GetAllTags(self, packages_data):
errors = {}
- for pkg in packages:
+ for pkg_data in packages_data:
for function in self.individual_checks:
- errors_for_pkg = function(pkg, debug=self.debug)
+ all_stats = pkg_data.GetAllStats()
+ errors_for_pkg = function(all_stats, debug=self.debug)
if errors_for_pkg:
- errors[pkg.pkgname] = errors_for_pkg
+ errors[all_stats["basic_stats"]["pkgname"]] = errors_for_pkg
# Set checks
for function in self.set_checks:
- set_errors = function(packages, debug=self.debug)
+ set_errors = function([x.GetAllStats() for x in packages_data],
+ debug=self.debug)
if set_errors:
# These were generated by a set, but are likely to be bound to specific
# packages. We'll try to preserve the package assignments.
@@ -624,8 +638,8 @@
Returns a tuple of an exit code and a report.
"""
- packages = self.GetDirectoryFormatPackages()
- errors = self.GetAllTags(packages)
+ packages_data = self.GetPackageStatsList()
+ errors = self.GetAllTags(packages_data)
screen_report, tags_report = self.FormatReports(errors)
exit_code = 0
return (exit_code, screen_report, tags_report)
@@ -679,7 +693,6 @@
basket_b["tag_info"] = tag.tag_info
basket_a["tag_name"] = self.tag_name
basket_b["tag_name"] = tag.tag_name
- # print "comparing", basket_a, basket_b
return basket_a == basket_b
def ParseOverrideLine(line):
@@ -714,3 +727,234 @@
if not override_applies:
tags_after_overrides.append(tag)
return tags_after_overrides
+
+
+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
+
+
+class PackageStats(object):
+ """Collects stats about a package and saves it."""
+ STATS_VERSION = 1L
+ # This list needs to be synchronized with the CollectStats() method.
+ STAT_FILES = [
+ "all_filenames",
+ "basic_stats",
+ "binaries",
+ "binaries_dump_info",
+ "depends",
+ "isalist",
+ "ldd_dash_r",
+ "overrides",
+ "pkginfo",
+ "pkgmap",
+ ]
+
+ def __init__(self, srv4_pkg, stats_basedir=None, md5sum=None):
+ self.srv4_pkg = srv4_pkg
+ self.md5sum = md5sum
+ self.dir_format_pkg = None
+ self.stats_path = None
+ self.all_stats = {}
+ self.stats_basedir = stats_basedir
+ if not self.stats_basedir:
+ home = os.environ["HOME"]
+ parts = [home, ".checkpkg", "stats"]
+ self.stats_basedir = os.path.join(*parts)
+
+ def GetMd5sum(self):
+ if not self.md5sum:
+ self.md5sum = self.srv4_pkg.GetMd5sum()
+ return self.md5sum
+
+ def GetStatsPath(self):
+ if not self.stats_path:
+ md5sum = self.GetMd5sum()
+ two_chars = md5sum[0:2]
+ parts = [self.stats_basedir, two_chars, md5sum]
+ self.stats_path = os.path.join(*parts)
+ return self.stats_path
+
+ def StatsExist(self):
+ """Checks if statistics of a package exist.
+
+ Returns:
+ bool
+ """
+ if not self.StatsDirExists():
+ return False
+ # More checks can be added in the future.
+ return True
+
+ def StatsDirExists(self):
+ return os.path.isdir(self.GetStatsPath())
+
+ def GetDirFormatPkg(self):
+ if not self.dir_format_pkg:
+ self.dir_format_pkg = self.srv4_pkg.GetDirFormatPkg()
+ return self.dir_format_pkg
+
+ def MakeStatsDir(self):
+ """mkdir -p equivalent.
+
+ http://stackoverflow.com/questions/600268/mkdir-p-functionality-in-python
+ """
+ stats_path = self.GetStatsPath()
+ try:
+ os.makedirs(stats_path)
+ except OSError, e:
+ if e.errno == errno.EEXIST:
+ pass
+ else:
+ raise
+
+ def GetBinaryDumpInfo(self):
+ dir_pkg = self.GetDirFormatPkg()
+ # Binaries. This could be split off to a separate function.
+ # man ld.so.1 for more info on this hack
+ env = copy.copy(os.environ)
+ env["LD_NOAUXFLTR"] = "1"
+ binaries_dump_info = []
+ for binary in dir_pkg.ListBinaries():
+ binary_abs_path = os.path.join(dir_pkg.directory, "root", binary)
+ binary_base_name = os.path.basename(binary)
+ args = [DUMP_BIN, "-Lv", binary_abs_path]
+ dump_proc = subprocess.Popen(args, stdout=subprocess.PIPE, env=env)
+ stdout, stderr = dump_proc.communicate()
+ ret = dump_proc.wait()
+ binary_data = ParseDumpOutput(stdout)
+ binary_data["path"] = binary
+ binary_data["soname_guessed"] = False
+ binary_data["base_name"] = binary_base_name
+ if SONAME not in binary_data:
+ logging.debug("The %s binary doesn't provide a SONAME. "
+ "(It might be an executable)",
+ binary_base_name)
+ # The binary doesn't tell its SONAME. We're guessing it's the
+ # same as the base file name.
+ binary_data[SONAME] = binary_base_name
+ binary_data["soname_guessed"] = True
+ binaries_dump_info.append(binary_data)
+ return binaries_dump_info
+
+ def GetBasicStats(self):
+ dir_pkg = self.GetDirFormatPkg()
+ basic_stats = {}
+ basic_stats["stats_version"] = self.STATS_VERSION
+ basic_stats["pkg_path"] = self.srv4_pkg.pkg_path
+ basic_stats["pkg_basename"] = os.path.basename(self.srv4_pkg.pkg_path)
+ basic_stats["parsed_basename"] = opencsw.ParsePackageFileName(basic_stats["pkg_basename"])
+ basic_stats["pkgname"] = dir_pkg.pkgname
+ basic_stats["catalogname"] = dir_pkg.GetCatalogname()
+ return basic_stats
+
+ def GetOverrides(self):
+ dir_pkg = self.GetDirFormatPkg()
+ overrides = dir_pkg.GetOverrides()
+ def OverrideToDict(override):
+ d = {}
+ d["pkgname"] = override.pkgname
+ d["tag_name"] = override.tag_name
+ d["tag_info"] = override.tag_info
+ return d
+ overrides_simple = [OverrideToDict(x) for x in overrides]
+ return overrides_simple
+
+ def GetLddMinusRlines(self):
+ """Returns ldd -r output."""
+ dir_pkg = self.GetDirFormatPkg()
+ binaries = dir_pkg.ListBinaries()
+ ldd_output = {}
+ for binary in binaries:
+ binary_abspath = os.path.join(dir_pkg.directory, "root", binary)
+ # this could be potentially moved into the DirectoryFormatPackage class.
+ # ldd needs the binary to be executable
+ os.chmod(binary_abspath, 0755)
+ args = ["ldd", "-r", binary_abspath]
+ ldd_proc = subprocess.Popen(
+ args,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ stdout, stderr = ldd_proc.communicate()
+ retcode = ldd_proc.wait()
+ if retcode:
+ logging.error("%s returned an error: %s", args, stderr)
+ lines = stdout.splitlines()
+ ldd_output[binary] = lines
+ return ldd_output
+
+
+ def CollectStats(self):
+ stats_path = self.GetStatsPath()
+ self.MakeStatsDir()
+ dir_pkg = self.GetDirFormatPkg()
+ logging.info("Collecting %s package statistics.", repr(dir_pkg.pkgname))
+ self.DumpObject(dir_pkg.GetAllFilenames(), "all_filenames")
+ self.DumpObject(self.GetBasicStats(), "basic_stats")
+ self.DumpObject(dir_pkg.ListBinaries(), "binaries")
+ self.DumpObject(self.GetBinaryDumpInfo(), "binaries_dump_info")
+ self.DumpObject(dir_pkg.GetDependencies(), "depends")
+ self.DumpObject(GetIsalist(), "isalist")
+ self.DumpObject(self.GetOverrides(), "overrides")
+ self.DumpObject(dir_pkg.GetParsedPkginfo(), "pkginfo")
+ self.DumpObject(dir_pkg.GetPkgmap().entries, "pkgmap")
+ self.DumpObject(self.GetLddMinusRlines(), "ldd_dash_r")
+ logging.debug("Statistics collected.")
+
+ def GetAllStats(self):
+ if self.StatsExist():
+ self.all_stats = self.ReadSavedStats()
+ else:
+ self.CollectStats()
+ return self.all_stats
+
+ def DumpObject(self, obj, name):
+ """Saves an object.
+
+ TODO(maciej): Implement pickling with cPickle.
+ """
+ stats_path = self.GetStatsPath()
+ # yaml
+ out_file_name = os.path.join(stats_path, "%s.yml" % name)
+ logging.debug("DumpObject(): writing %s", repr(out_file_name))
+ f = open(out_file_name, "w")
+ f.write(yaml.safe_dump(obj))
+ f.close()
+ # pickle
+ out_file_name_pickle = os.path.join(stats_path, "%s.pickle" % name)
+ f = open(out_file_name_pickle, "wb")
+ cPickle.dump(obj, f)
+ f.close()
+ self.all_stats[name] = obj
+
+ def ReadObject(self, name):
+ """Reads an object."""
+ stats_path = self.GetStatsPath()
+ in_file_name = os.path.join(stats_path, "%s.yml" % name)
+ in_file_name_pickle = os.path.join(stats_path, "%s.pickle" % name)
+ if os.path.exists(in_file_name_pickle):
+ logging.debug("ReadObject(): reading %s", repr(in_file_name_pickle))
+ f = open(in_file_name_pickle, "r")
+ obj = cPickle.load(f)
+ f.close()
+ logging.debug("ReadObject(): finished reading %s", repr(in_file_name_pickle))
+ else:
+ logging.debug("ReadObject(): reading %s", repr(in_file_name))
+ f = open(in_file_name, "r")
+ obj = yaml.safe_load(f)
+ f.close()
+ logging.debug("ReadObject(): finished reading %s", repr(in_file_name))
+ return obj
+
+ def ReadSavedStats(self):
+ all_stats = {}
+ for name in self.STAT_FILES:
+ all_stats[name] = self.ReadObject(name)
+ return all_stats
Modified: csw/mgar/gar/v2/lib/python/opencsw.py
===================================================================
--- csw/mgar/gar/v2/lib/python/opencsw.py 2010-02-18 13:01:38 UTC (rev 8649)
+++ csw/mgar/gar/v2/lib/python/opencsw.py 2010-02-18 13:20:57 UTC (rev 8650)
@@ -15,6 +15,7 @@
import copy
import datetime
import difflib
+import hashlib
import logging
import os
import os.path
@@ -347,14 +348,13 @@
def ShellCommand(self, args, quiet=False):
logging.debug("Calling: %s", repr(args))
if quiet:
- sub_stdout = subprocess.PIPE
- sub_stderr = subprocess.PIPE
+ process = subprocess.Popen(args,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ stdout, stderr = process.communicate()
+ retcode = process.wait()
else:
- sub_stdout = None
- sub_stderr = None
- retcode = subprocess.call(args,
- stdout=sub_stdout,
- stderr=sub_stderr)
+ retcode = subprocess.call(args)
if retcode:
raise Error("Running %s has failed." % repr(args))
return retcode
@@ -363,13 +363,17 @@
class CswSrv4File(ShellMixin, object):
"""Represents a package in the srv4 format (pkg)."""
- def __init__(self, pkg_path):
+ def __init__(self, pkg_path, debug=False):
self.pkg_path = pkg_path
self.workdir = None
self.gunzipped_path = None
self.transformed = False
self.dir_format_pkg = None
+ self.debug = debug
+ def __repr__(self):
+ return u"CswSrv4File(%s)" % repr(self.pkg_path)
+
def GetWorkDir(self):
if not self.workdir:
self.workdir = tempfile.mkdtemp(prefix="pkg_")
@@ -399,11 +403,49 @@
"%s or %s." % (gzip_suffix, pkg_suffix))
return self.gunzipped_path
+ def Pkgtrans(self, src_file, destdir, pkgname):
+ """A proxy for the pkgtrans command.
+
+ This requires custom-pkgtrans to be available.
+ """
+ if not os.path.isdir(destdir):
+ raise PackageError("%s doesn't exist or is not a directory" % destdir)
+ args = [os.path.join(os.path.dirname(__file__), "custom-pkgtrans"),
+ src_file, destdir, pkgname ]
+ pkgtrans_proc = subprocess.Popen(args)
+ pkgtrans_proc.communicate()
+ ret = pkgtrans_proc.wait()
+ if ret:
+ logging.error("% has failed" % args)
+
+ def GetPkgname(self):
+ """It's necessary to figure out the pkgname from the .pkg file.
+ # nawk 'NR == 2 {print $1; exit;} $f
+ """
+ gunzipped_path = self.GetGunzippedPath()
+ args = ["nawk", "NR == 2 {print $1; exit;}", gunzipped_path]
+ nawk_proc = subprocess.Popen(args, stdout=subprocess.PIPE)
+ stdout, stderr = nawk_proc.communicate()
+ ret_code = nawk_proc.wait()
+ pkgname = stdout.strip()
+ logging.debug("GetPkgname(): %s", repr(pkgname))
+ return pkgname
+
def TransformToDir(self):
+ """Transforms the file to the directory format.
+
+ This uses the Pkgtrans function at the top, because pkgtrans behaves
+ differently on Solaris 8 and 10. Having our own implementation helps
+ achieve consistent behavior.
+ """
if not self.transformed:
- args = ["pkgtrans", "-a", self.GetAdminFilePath(),
- self.GetGunzippedPath(), self.GetWorkDir(), "all"]
- unused_retcode = self.ShellCommand(args, quiet=True)
+ gunzipped_path = self.GetGunzippedPath()
+ pkgname = self.GetPkgname()
+ args = [os.path.join(os.path.dirname(__file__),
+ "..", "..", "bin", "custom-pkgtrans"),
+ gunzipped_path, self.GetWorkDir(), pkgname]
+ logging.info("transforming: %s", args)
+ unused_retcode = self.ShellCommand(args, quiet=(not self.debug))
dirs = self.GetDirs()
if len(dirs) != 1:
raise Error("Need exactly one package in the package stream: "
@@ -428,6 +470,13 @@
dir_format_pkg = self.GetDirFormatPkg()
return dir_format_pkg.GetPkgmap(analyze_permissions, strip)
+ def GetMd5sum(self):
+ fp = open(self.pkg_path)
+ hash = hashlib.md5()
+ hash.update(fp.read())
+ fp.close()
+ return hash.hexdigest()
+
def __del__(self):
if self.workdir:
logging.debug("Removing %s", repr(self.workdir))
@@ -537,12 +586,17 @@
class DirectoryFormatPackage(ShellMixin, object):
+ """Represents a package in the directory format.
+ Allows some read-write operations.
+ """
+
def __init__(self, directory):
self.directory = directory
- self.pkgname = os.path.split(directory)[1]
+ self.pkgname = os.path.basename(directory)
self.pkgpath = self.directory
self.pkginfo_dict = None
+ self.binaries = None
def GetCatalogname(self):
"""Returns the catalog name of the package.
@@ -682,16 +736,23 @@
Returns a list of absolute paths.
"""
- self.CheckPkgpathExists()
- find_tmpl = "find '%s' -print | xargs file | grep ELF | nawk -F: '{print $1}'"
- find_proc = subprocess.Popen(find_tmpl % self.directory,
- 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()
+ if not self.binaries:
+ self.CheckPkgpathExists()
+ files_root = os.path.join(self.directory, "root")
+ find_tmpl = "find '%s' -print | xargs file | grep ELF | nawk -F: '{print $1}'"
+ find_proc = subprocess.Popen(find_tmpl % ".",
+ shell=True,
+ stdout=subprocess.PIPE,
+ cwd=files_root)
+ stdout, stderr = find_proc.communicate()
+ ret = find_proc.wait()
+ if ret:
+ logging.error("The find command returned an error.")
+ dotslash_re = re.compile(r"^./")
+ def StripRe(x, strip_re):
+ return re.sub(strip_re, "", x)
+ self.binaries = [StripRe(x, dotslash_re) for x in stdout.splitlines()]
+ return self.binaries
def GetAllFilenames(self):
self.CheckPkgpathExists()
@@ -710,15 +771,15 @@
# worry about that at this stage.
logging.debug("Trying to open %s", repr(file_path))
if os.path.isfile(file_path):
- return open(file_path, "r")
+ return open(file_path, "r")
else:
- return None
+ return None
def _ParseOverridesStream(self, stream):
overrides = []
for line in stream:
if line.startswith("#"):
- continue
+ continue
overrides.append(checkpkg.ParseOverrideLine(line))
return overrides
@@ -726,9 +787,9 @@
"""Returns overrides, a list of checkpkg.Override instances."""
stream = self._GetOverridesStream()
if stream:
- return self._ParseOverridesStream(stream)
+ return self._ParseOverridesStream(stream)
else:
- return list()
+ return list()
def GetFileContent(self, pkg_file_path):
if pkg_file_path.startswith("/"):
@@ -802,7 +863,7 @@
if line_to_add:
self.paths.add(line_to_add)
entry = {
- "line": line,
+ "line": line.strip(),
"type": line_type,
}
entry["path"] = installed_path
@@ -892,6 +953,7 @@
else:
logging.warn("%s is not a directory.", pkg_path)
+
def Srv4Exists(self, pkg_dir):
pkg = DirectoryFormatPackage(pkg_dir)
srv4_name = pkg.GetSrv4FileName()
Copied: csw/mgar/gar/v2/lib/python/package_checks.py (from rev 8649, csw/mgar/gar/v2-checkpkg-stats/lib/python/package_checks.py)
===================================================================
--- csw/mgar/gar/v2/lib/python/package_checks.py (rev 0)
+++ csw/mgar/gar/v2/lib/python/package_checks.py 2010-02-18 13:20:57 UTC (rev 8650)
@@ -0,0 +1,32 @@
+# Defining the checking functions. They come in two flavors: individual
+# package checks and set checks.
+
+import checkpkg
+import re
+
+def CatalognameLowercase(pkg_data, debug):
+ errors = []
+ # Here's how to report an error:
+ catalogname = pkg_data["basic_stats"]["catalogname"]
+ if catalogname != catalogname.lower():
+ errors.append(checkpkg.CheckpkgTag(
+ pkg_data["basic_stats"]["pkgname"],
+ "catalogname-not-lowercase"))
+ if not re.match(r"^\w+$", catalogname):
+ errors.append(checkpkg.CheckpkgTag(
+ pkg_data["basic_stats"]["pkgname"],
+ "catalogname-is-not-a-simple-word"))
+ return errors
+
+
+def FileNameSanity(pkg_data, debug):
+ errors = []
+ # Here's how to report an error:
+ basic_stats = pkg_data["basic_stats"]
+ revision_info = basic_stats["parsed_basename"]["revision_info"]
+ catalogname = pkg_data["basic_stats"]["catalogname"]
+ if "REV" not in revision_info:
+ errors.append(checkpkg.CheckpkgTag(
+ pkg_data["basic_stats"]["pkgname"],
+ "rev-tag-missing-in-filename"))
+ return errors
Copied: csw/mgar/gar/v2/lib/python/package_checks_test.py (from rev 8649, csw/mgar/gar/v2-checkpkg-stats/lib/python/package_checks_test.py)
===================================================================
--- csw/mgar/gar/v2/lib/python/package_checks_test.py (rev 0)
+++ csw/mgar/gar/v2/lib/python/package_checks_test.py 2010-02-18 13:20:57 UTC (rev 8650)
@@ -0,0 +1,55 @@
+#!/opt/csw/bin/python2.6
+# coding=utf-8
+# $Id$
+
+import unittest
+import package_checks as pc
+
+class PackageChecksUnitTest(unittest.TestCase):
+
+ def setUp(self):
+ self.pkg_data_1 = {
+ "basic_stats": {
+ "pkgname": "CSWfoo"
+ }
+ }
+ self.pkg_data_2 = {
+ 'basic_stats': {
+ 'parsed_basename':
+ {'revision_info': {'REV': '2010.02.15'},
+ 'catalogname': 'python_tk',
+ 'full_version_string': '2.6.4,REV=2010.02.15',
+ 'version': '2.6.4',
+ 'version_info': {
+ 'minor version': '6',
+ 'major version': '2',
+ 'patchlevel': '4'}},
+ 'pkgname': 'CSWpython-tk',
+ 'stats_version': 1,
+ 'pkg_basename': 'python_tk-2.6.4,REV=2010.02.15-SunOS5.8-sparc-CSW.pkg.gz',
+ 'pkg_path': '/tmp/pkg_lL0HDH/python_tk-2.6.4,REV=2010.02.15-SunOS5.8-sparc-CSW.pkg.gz',
+ 'catalogname': 'python_tk'}}
+
+ def testCatalogName_1(self):
+ self.pkg_data_1["basic_stats"]["catalogname"] = "Foo"
+ errors = pc.CatalognameLowercase(self.pkg_data_1, False)
+ self.failUnless(errors)
+
+ def testCatalogName_2(self):
+ self.pkg_data_1["basic_stats"]["catalogname"] = "foo"
+ errors = pc.CatalognameLowercase(self.pkg_data_1, False)
+ self.failIf(errors)
+
+ def testCatalogNameSpecialCharacters(self):
+ self.pkg_data_1["basic_stats"]["catalogname"] = "foo+abc&123"
+ errors = pc.CatalognameLowercase(self.pkg_data_1, False)
+ self.failUnless(errors)
+
+ def testFileNameSanity(self):
+ del(self.pkg_data_2["basic_stats"]["parsed_basename"]["revision_info"]["REV"])
+ errors = pc.FileNameSanity(self.pkg_data_2, False)
+ self.failUnless(errors)
+
+
+if __name__ == '__main__':
+ unittest.main()
Deleted: csw/mgar/gar/v2/lib/sh/libcheckpkg.sh
===================================================================
--- csw/mgar/gar/v2-checkpkg-stats/lib/sh/libcheckpkg.sh 2010-02-18 13:01:38 UTC (rev 8649)
+++ csw/mgar/gar/v2/lib/sh/libcheckpkg.sh 2010-02-18 13:20:57 UTC (rev 8650)
@@ -1,30 +0,0 @@
-#!/bin/ksh -p
-#
-# $Id$
-
-# pkgtrans leaves a directory in /var/tmp/aaXXXXXXX even after clean quit.
-# Emulating pkgtrans behaviour, for "pkgtrans src destdir pkgname". Except
-# that the pkgname arg is ignored, and only the first pkg is processed.
-
-custom_pkgtrans(){
- if [[ ! -d $2 ]] ; then
- print ERROR: $2 is not a directory >/dev/fd/2
- return 1
- fi
- hdrblks=`(dd if=$1 skip=1 2>/dev/null| cpio -i -t >/dev/null) 2>&1 |
- nawk '{print $1; exit;}'`
-
- ## print initial hdrblks=$hdrblks
-
- hdrblks=$(($hdrblks + 1))
- mkdir $2/$3 || return 1
-
- dd if=$1 skip=$hdrblks 2>/dev/null | (cd $2/$3 ; cpio -ivdm)
- # on fail, SOMETIMES cpio returns 1, but sometimes it returns 0!!
- if [[ ! -d $2/$3/install ]] ; then
- print retrying extract with different archive offset...
- # no, I can't tell in advance why/when the prev fails
- hdrblks=$(($hdrblks + 1))
- dd if=$1 skip=$hdrblks 2>/dev/null| (cd $2/$3 ; cpio -ivdm)
- fi
-}
Copied: csw/mgar/gar/v2/lib/sh/libcheckpkg.sh (from rev 8649, csw/mgar/gar/v2-checkpkg-stats/lib/sh/libcheckpkg.sh)
===================================================================
--- csw/mgar/gar/v2/lib/sh/libcheckpkg.sh (rev 0)
+++ csw/mgar/gar/v2/lib/sh/libcheckpkg.sh 2010-02-18 13:20:57 UTC (rev 8650)
@@ -0,0 +1,30 @@
+#!/bin/ksh -p
+#
+# $Id$
+
+# pkgtrans leaves a directory in /var/tmp/aaXXXXXXX even after clean quit.
+# Emulating pkgtrans behaviour, for "pkgtrans src destdir pkgname". Except
+# that the pkgname arg is ignored, and only the first pkg is processed.
+
+custom_pkgtrans(){
+ if [[ ! -d $2 ]] ; then
+ print ERROR: $2 is not a directory >/dev/fd/2
+ return 1
+ fi
+ hdrblks=`(dd if=$1 skip=1 2>/dev/null| cpio -i -t >/dev/null) 2>&1 |
+ nawk '{print $1; exit;}'`
+
+ ## print initial hdrblks=$hdrblks
+
+ hdrblks=$(($hdrblks + 1))
+ mkdir $2/$3 || return 1
+
+ dd if=$1 skip=$hdrblks 2>/dev/null | (cd $2/$3 ; cpio -ivdm)
+ # on fail, SOMETIMES cpio returns 1, but sometimes it returns 0!!
+ if [[ ! -d $2/$3/install ]] ; then
+ print retrying extract with different archive offset...
+ # no, I can't tell in advance why/when the prev fails
+ hdrblks=$(($hdrblks + 1))
+ dd if=$1 skip=$hdrblks 2>/dev/null| (cd $2/$3 ; cpio -ivdm)
+ fi
+}
Property changes on: csw/mgar/gar/v2/pkglib/csw/depend
___________________________________________________________________
Modified: svn:mergeinfo
- /csw/mgar/gar/v2/pkglib/csw/depend:4936-6678
/csw/mgar/gar/v2-checkpkg/pkglib/csw/depend:7722-7855
/csw/mgar/gar/v2-collapsed-modulations/pkglib/csw/depend:6895
/csw/mgar/gar/v2-dirpackage/pkglib/csw/depend:8125-8180
/csw/mgar/gar/v2-skayser/pkglib/csw/depend:6087-6132
+ /csw/mgar/gar/v2/pkglib/csw/depend:4936-6678
/csw/mgar/gar/v2-checkpkg/pkglib/csw/depend:7722-7855
/csw/mgar/gar/v2-checkpkg-stats/pkglib/csw/depend:8454-8649
/csw/mgar/gar/v2-collapsed-modulations/pkglib/csw/depend:6895
/csw/mgar/gar/v2-dirpackage/pkglib/csw/depend:8125-8180
/csw/mgar/gar/v2-skayser/pkglib/csw/depend:6087-6132
Modified: csw/mgar/gar/v2/tests/overrides_test.py
===================================================================
--- csw/mgar/gar/v2/tests/overrides_test.py 2010-02-18 13:01:38 UTC (rev 8649)
+++ csw/mgar/gar/v2/tests/overrides_test.py 2010-02-18 13:20:57 UTC (rev 8650)
@@ -6,7 +6,7 @@
sys.path.append("../lib/python")
import gartest
-class OverridesUnitTest(unittest.TestCase):
+class OverridesUnitTest_1(unittest.TestCase):
"""Tests CHECKPKG_OVERRIDES support."""
def testOneOverride(self):
@@ -15,7 +15,7 @@
mybuild.SetGarVariable("GARNAME", "overrides-test")
mybuild.SetGarVariable("CATALOGNAME", "overrides_test")
mybuild.SetGarVariable("CHECKPKG_OVERRIDES",
- "CSWoverrides-test|example-tag|example-parameter")
+ "example-tag|example-parameter")
mybuild.WriteGarFiles()
self.assertEquals(0, mybuild.Build())
pkg = mybuild.GetFirstBuiltPackage()
@@ -32,8 +32,8 @@
mybuild.SetGarVariable("CATALOGNAME", "overrides_test")
mybuild.SetGarVariable(
"CHECKPKG_OVERRIDES",
- ("CSWoverrides-test|example-tag-1|example-parameter-1 "
- "CSWoverrides-test|example-tag-2|example-parameter-2"))
+ ("example-tag-1|example-parameter-1 "
+ "example-tag-2|example-parameter-2"))
mybuild.WriteGarFiles()
self.assertEquals(0, mybuild.Build())
pkg = mybuild.GetFirstBuiltPackage()
@@ -43,3 +43,39 @@
self.assertEqual(expected, pkg.GetFileContent(overr_file))
overrides = pkg.GetOverrides()
self.assertEqual(2, len(overrides))
+
+# This bit fails, needs more work.
+#
+# class OverridesUnitTest_2(unittest.TestCase):
+# """Tests CHECKPKG_OVERRIDES support."""
+#
+# def testOverridersForTwoPackages(self):
+# """http://sourceforge.net/apps/trac/gar/ticket/17"""
+# overr_file_1 = "/opt/csw/share/checkpkg/overrides/overrides_test_1"
+# mybuild = gartest.DynamicGarBuild()
+# mybuild.SetGarVariable("GARNAME", "overrides-test")
+# mybuild.SetGarVariable("PACKAGES", "CSWoverrides-test-1 "
+# "CSWoverrides-test-2")
+# mybuild.SetGarVariable("CATALOGNAME_CSWoverrides-test-1",
+# "overrides_test_1")
+# mybuild.SetGarVariable("CATALOGNAME_CSWoverrides-test-2",
+# "overrides_test_2")
+# mybuild.SetGarVariable("SPKG_DESC_CSWoverrides-test-1",
+# "Test package 1")
+# mybuild.SetGarVariable("SPKG_DESC_CSWoverrides-test-1",
+# "Test package 2")
+# mybuild.SetGarVariable("PKGFILES_CSWoverrides-test-1",
+# overr_file_1)
+# mybuild.SetGarVariable(
+# "CHECKPKG_OVERRIDESCSWoverrides-test-1",
+# "example-tag-1|example-parameter-1")
+# mybuild.SetGarVariable(
+# "CHECKPKG_OVERRIDESCSWoverrides-test-2",
+# "example-tag-2|example-parameter-2")
+# mybuild.WriteGarFiles()
+# self.assertEquals(0, mybuild.Build())
+# pkg = mybuild.GetFirstBuiltPackage()
+# expected = ('CSWoverrides-test-1: example-tag-1 example-parameter-1\n')
+# self.assertEqual(expected, pkg.GetFileContent(overr_file_1))
+# overrides = pkg.GetOverrides()
+# self.assertEqual(1, len(overrides))
Modified: csw/mgar/gar/v2/tests/run_tests.py
===================================================================
--- csw/mgar/gar/v2/tests/run_tests.py 2010-02-18 13:01:38 UTC (rev 8649)
+++ csw/mgar/gar/v2/tests/run_tests.py 2010-02-18 13:20:57 UTC (rev 8650)
@@ -10,10 +10,11 @@
# To add more test files, create <name>.py file and add a corresponding line
# here:
-from opencsw_test import *
-from checkpkg_test import *
-from example_test import *
-from overrides_test import *
+from checkpkg_test import *
+from example_test import *
+from opencsw_test import *
+from overrides_test import *
+from package_checks_test import *
if __name__ == '__main__':
unittest.main()
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