[csw-devel] SF.net SVN: gar:[8698] csw/mgar/gar/v2-git
wahwah at users.sourceforge.net
wahwah at users.sourceforge.net
Sat Feb 20 12:24:30 CET 2010
Revision: 8698
http://gar.svn.sourceforge.net/gar/?rev=8698&view=rev
Author: wahwah
Date: 2010-02-20 11:24:28 +0000 (Sat, 20 Feb 2010)
Log Message:
-----------
mGAR v2-git: Merged changes from the v2 branch.
Modified Paths:
--------------
csw/mgar/gar/v2-git/Makefile
csw/mgar/gar/v2-git/bin/checkpkg
csw/mgar/gar/v2-git/bin/checkpkg.d/README
csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-actionclasses.py
csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-libs.py
csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-obsolete-deps.py
csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-you-can-write-your-own.py
csw/mgar/gar/v2-git/bin/fixlibtool
csw/mgar/gar/v2-git/bin/update-commondirs
csw/mgar/gar/v2-git/categories/cpan/category.mk
csw/mgar/gar/v2-git/categories/x11/category.mk
csw/mgar/gar/v2-git/etc/commondirs-i386
csw/mgar/gar/v2-git/etc/commondirs-sparc
csw/mgar/gar/v2-git/gar.conf.mk
csw/mgar/gar/v2-git/gar.lib.mk
csw/mgar/gar/v2-git/gar.mk
csw/mgar/gar/v2-git/gar.pkg.mk
csw/mgar/gar/v2-git/lib/python/checkpkg.py
csw/mgar/gar/v2-git/lib/python/checkpkg_test.py
csw/mgar/gar/v2-git/lib/python/opencsw.py
csw/mgar/gar/v2-git/tests/run_tests.py
Added Paths:
-----------
csw/mgar/gar/v2-git/bin/analyze_module_results.py
csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-archall.py
csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-basic.py
csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-license.py
csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-missing-symbols.py
csw/mgar/gar/v2-git/bin/checkpkg_collect_stats.py
csw/mgar/gar/v2-git/bin/checkpkg_collect_stats_test.py
csw/mgar/gar/v2-git/bin/custom-pkgtrans
csw/mgar/gar/v2-git/bin/submitpkg
csw/mgar/gar/v2-git/bin/update_contents_cache.py
csw/mgar/gar/v2-git/lib/python/package_checks.py
csw/mgar/gar/v2-git/lib/python/package_checks_test.py
csw/mgar/gar/v2-git/lib/python/submit_to_newpkgs.py
csw/mgar/gar/v2-git/lib/python/testdata/example-1-pkginfo.yml
csw/mgar/gar/v2-git/lib/python/testdata/example-1-pkgmap.yml
csw/mgar/gar/v2-git/lib/sh/
csw/mgar/gar/v2-git/lib/sh/libcheckpkg.sh
csw/mgar/gar/v2-git/tests/overrides_test.py
Removed Paths:
-------------
csw/mgar/gar/v2-git/lib/sh/libcheckpkg.sh
Property Changed:
----------------
csw/mgar/gar/v2-git/
csw/mgar/gar/v2-git/lib/python/opencsw.py
csw/mgar/gar/v2-git/pkglib/csw/depend
Property changes on: csw/mgar/gar/v2-git
___________________________________________________________________
Modified: svn:mergeinfo
- /csw/mgar/gar/v2:4936-6678,6915-8229
/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,6915-8697
/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-git/Makefile
===================================================================
--- csw/mgar/gar/v2-git/Makefile 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/Makefile 2010-02-20 11:24:28 UTC (rev 8698)
@@ -1,3 +1,7 @@
+
+stoptheunwary:
+ $(error "*** You are in the GAR directory and probably didn't mean to call make")
+
FILTER_DIRS = CVS/ bin/ meta/
# top-level Makefile for the entire tree.
%:
Copied: csw/mgar/gar/v2-git/bin/analyze_module_results.py (from rev 8697, csw/mgar/gar/v2/bin/analyze_module_results.py)
===================================================================
--- csw/mgar/gar/v2-git/bin/analyze_module_results.py (rev 0)
+++ csw/mgar/gar/v2-git/bin/analyze_module_results.py 2010-02-20 11:24:28 UTC (rev 8698)
@@ -0,0 +1,53 @@
+#!/opt/csw/bin/python2.6
+# $Id$
+
+import optparse
+import os
+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("-e", "--extract-dir", dest="extractdir",
+ help="Directory with extracted packages")
+ options, args = parser.parse_args()
+ pkgnames = args
+ packages = [opencsw.DirectoryFormatPackage(
+ os.path.join(options.extractdir, pkgname))
+ for pkgname in pkgnames]
+ overrides_list = [pkg.GetOverrides() for pkg in packages]
+ files = os.listdir(options.extractdir)
+ error_tags = []
+ for file_name in files:
+ if file_name.startswith("tags."):
+ fd = open(os.path.join(options.extractdir, file_name))
+ for line in fd:
+ if line.startswith("#"):
+ continue
+ pkgname, tag_name, tag_info = checkpkg.ParseTagLine(line)
+ error_tags.append(checkpkg.CheckpkgTag(pkgname, tag_name, tag_info))
+ overrides = reduce(lambda x, y: x + y, overrides_list)
+ tags_after_overrides = checkpkg.ApplyOverrides(error_tags, overrides)
+ exit_code = bool(tags_after_overrides)
+ if tags_after_overrides:
+ print "There were errors reported."
+ print "If you know they are false positives, you can override them:"
+ for tag in tags_after_overrides:
+ if tag.tag_info:
+ tag_postfix = "|%s" % tag.tag_info.replace(" ", "|")
+ else:
+ tag_postfix = ""
+ print ("CHECKPKG_OVERRIDES_%s += %s%s"
+ % (tag.pkgname, tag.tag_name, tag_postfix))
+ sys.exit(exit_code)
+
+
+if __name__ == '__main__':
+ main()
Modified: csw/mgar/gar/v2-git/bin/checkpkg
===================================================================
--- csw/mgar/gar/v2-git/bin/checkpkg 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/bin/checkpkg 2010-02-20 11:24:28 UTC (rev 8698)
@@ -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"
@@ -36,15 +41,18 @@
if [[ -t 1 ]]; then
GREEN="\\033[0;32;40m"
RED="\\033[1;31;40m"
+ BOLD="\\033[1m"
COLOR_RESET="\\033[00m"
else
GREEN=""
RED=""
+ 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
@@ -122,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
@@ -207,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
@@ -263,8 +266,12 @@
print basedir="'$basedir'"
fi
-if [[ ${#software} -gt ${NAME_MAX_LENGTH} ]] ; then errmsg $f: software name greater than 20 chars ; fi
-if [[ ${#pkgname} -gt ${NAME_MAX_LENGTH} ]] ; then errmsg $f: pkg name greater than 20 chars; fi
+if [[ ${#software} -gt ${NAME_MAX_LENGTH} ]] ; then
+ errmsg "$f: software name longer than ${NAME_MAX_LENGTH} chars"
+fi
+if [[ ${#pkgname} -gt ${NAME_MAX_LENGTH} ]] ; then
+ errmsg "$f: pkg name longer than ${NAME_MAX_LENGTH} chars"
+fi
if [ "$software" = "" ] ; then errmsg $f: software field not set properly in NAME ; fi
if [ "$pkgname" = "" ] ; then errmsg $f: pkgname field blank ; fi
@@ -331,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
@@ -506,7 +484,7 @@
| sort | uniq -c | awk '{print $1}' | sort | uniq | wc -l)"
if [[ "$repeated_depends" -gt 1 ]]; then
cat $EXTRACTDIR/$pkgname/install/depend
- errmsg "$pkgname has multiple depends"
+ errmsg "$pkgname lists a dependency more than once, see above"
fi
#to retain a record of all packages currently being examined from $@
@@ -520,8 +498,8 @@
if [[ $? -ne 0 ]]; then
#if we've already looked at the package named $dep,
#it'll be in the file.
- awk "\$1 == \"$dep\" {print}" $SETDEPS | /usr/bin/grep $dep >/dev/null
- if [[ $? -ne 0 ]]; then #we haven't yet seen this package in our set
+ awk "\$1 == \"$dep\" {print}" $SETDEPS | /usr/bin/grep $dep >/dev/null
+ if [[ $? -ne 0 ]]; then #we haven't yet seen this package in our set
echo "Can't validate dependence on $dep. Storing for delayed validation."
#store for validation at the end.
echo "$dep $pkgname" >> $SETDEPS.missing
@@ -560,71 +538,105 @@
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
-${plugindir}/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=""
-if [[ -d "$plugindir" ]]; then
- echo "Running modular tests"
- # echo plugin dir exists
- for plugin in "${plugindir}"/checkpkg-*; do
+module_name_format="%-40s"
+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
- 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
+ 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 -b \"${checkpkg_stats_basedir}\" -o \"${EXTRACTDIR}/${error_tag_file}\" ${md5sums}"
+ ${plugin} \
+ $extra_options \
+ -b "${checkpkg_stats_basedir}" \
+ -o "${EXTRACTDIR}/${error_tag_file}" \
+ ${md5sums} \
+ > "${plugin_log}" 2>&1
if [[ "$?" -ne 0 ]]; then
- printf "\rTEST: ${plugin} ${RED}[FAIL]${COLOR_RESET} \\n"
+ printf "\r${module_name_format} ${RED}[ERROR]${COLOR_RESET} \\n" "${plugin_name}"
test_suite_ok=0
else
- printf "\rTEST: ${plugin} ${GREEN}[OK]${COLOR_RESET} \\n"
+ printf "\r${module_name_format} [Done] \\n" "${plugin_name}"
fi
else
debugmsg "'${plugin}' is not executable"
fi
done
else
- debugmsg "plugin dir does not exist"
+ debugmsg "module dir ${checkpkg_module_dir} does not exist"
fi
-echo
for log_file in ${log_files}; do
- if [[ -s "${log_file}" ]]; then
+ if [[ `gwc -c "${log_file}" | awk '{print $1}'` -gt 1 ]]; then
debugmsg ">> LOG START: ${log_file}"
cat "${log_file}"
debugmsg "<< LOG END: ${log_file}"
- else
- debugmsg "-- LOG ${log_file} is empty"
+ else
+ debugmsg "-- LOG ${log_file} is empty"
fi
done
-echo
if [[ ${test_suite_ok} -ne 1 ]]; then
- errmsg "One or more modular tests have failed."
+ errmsg "One or more modular tests have finished with an error."
else
- print "All modular tests were successful."
+ print "All modular tests completed. Analyzing the reports."
fi
+if [[ "${DEBUG}" != "" ]]; then
+ override_info_printed=0
+ for tagfile in ${EXTRACTDIR}/tags.*; do
+ if [[ -s "${tagfile}" ]]; then
+ if [[ "${override_info_printed}" -ne 1 ]]; then
+ echo "# You can use the following lines to create overrides"
+ echo "# See http://wiki.opencsw.org/checkpkg"
+ override_info_printed=1
+ fi
+ echo "# ${tagfile}:"
+ cat "${tagfile}"
+ fi
+ done
+fi
+
+# Collecting errors and applying the overrides.
+${command_basedir}/analyze_module_results.py \
+ -e "${EXTRACTDIR}" \
+ ${pkgnames}
+if [[ "$?" -ne 0 ]]; then
+ errmsg "${RED}Modular checks are reporting errors.${COLOR_RESET}"
+else
+ print "${GREEN}All modular tests were successful.${COLOR_RESET}"
+fi
+
print ""
# Cleaning up after all packages
Modified: csw/mgar/gar/v2-git/bin/checkpkg.d/README
===================================================================
--- csw/mgar/gar/v2-git/bin/checkpkg.d/README 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/bin/checkpkg.d/README 2010-02-20 11:24:28 UTC (rev 8698)
@@ -2,10 +2,12 @@
This directory contains modular checks. Each check is an executable file,
written in any language, accepting specific command line options and returning
-the result as a status exit code.
+the result by writing to a text file.
To see the required flags, issue:
-./checkpkg-dummy.py -h
+./checkpkg-you-can-write-your-own.py -h
Each test's file name must begin with "checkpkg-".
+
+See http://wiki.opencsw.org/checkpkg for more information.
Modified: csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-actionclasses.py
===================================================================
--- csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-actionclasses.py 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-actionclasses.py 2010-02-20 11:24:28 UTC (rev 8698)
@@ -11,6 +11,8 @@
import sys
import re
+CHECKPKG_MODULE_NAME = "class action scripts / prototype integrity"
+
# The following bit of code sets the correct path to Python libraries
# distributed with GAR.
path_list = [os.path.dirname(__file__),
@@ -20,38 +22,52 @@
import opencsw
-def CheckActionClasses(pkg):
+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 cls in only_in_pkginfo:
- print "Class %s of %s is only in pkginfo" % (repr(cls), pkg.pkgname)
- print "This shouldn't cause any problems, but it might be not necessary."
- for cls in only_in_pkgmap:
+ for action_class in only_in_pkginfo:
+ error = checkpkg.CheckpkgTag(
+ 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.")
+ errors.append(error)
+ for action_class in only_in_pkgmap:
errors.append(
- opencsw.PackageError("Class %s is only in pkgmap" % repr(cls)))
- if only_in_pkginfo or only_in_pkgmap:
- print ("pkginfo_classes: %s, pkgmap classes: %s"
- % (pkginfo_classes, pkgmap_classes))
+ checkpkg.CheckpkgTag(pkg.pkgname, "action-class-only-in-pkgmap", action_class))
return errors
def main():
options, args = checkpkg.GetOptions()
- pkgnames = args
- check_manager = checkpkg.CheckpkgManager(
- "class action scripts / prototype integrity",
- options.extractdir,
- pkgnames,
- options.debug)
+ 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.stats_basedir,
+ md5sums,
+ options.debug)
+ # Registering functions defined above.
check_manager.RegisterIndividualCheck(CheckActionClasses)
- exit_code, report = check_manager.Run()
- print report.strip()
+ # 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)
Copied: csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-archall.py (from rev 8697, csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-archall.py)
===================================================================
--- csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-archall.py (rev 0)
+++ csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-archall.py 2010-02-20 11:24:28 UTC (rev 8698)
@@ -0,0 +1,44 @@
+#!/opt/csw/bin/python2.6
+#
+# $Id$
+
+"""Verifies the architecture of the package."""
+
+import os.path
+import re
+import sys
+
+CHECKPKG_MODULE_NAME = "architecture check"
+
+# 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)
+
+ check_manager.RegisterIndividualCheck(
+ package_checks.CheckArchitectureVsContents)
+ 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()
+
+# vim:set sw=2 ts=2 sts=2 expandtab:
Copied: csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-basic.py (from rev 8697, csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-basic.py)
===================================================================
--- csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-basic.py (rev 0)
+++ csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-basic.py 2010-02-20 11:24:28 UTC (rev 8698)
@@ -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-git/bin/checkpkg.d/checkpkg-libs.py
===================================================================
--- csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-libs.py 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-libs.py 2010-02-20 11:24:28 UTC (rev 8698)
@@ -1,13 +1,13 @@
#!/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.
+"""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 os
import os.path
import copy
@@ -16,7 +16,10 @@
import logging
import sys
import textwrap
+from Cheetah import Template
+CHECKPKG_MODULE_NAME = "shared library linking consistency"
+
# The following bit of code sets the correct path to Python libraries
# distributed with GAR.
path_list = [os.path.dirname(__file__),
@@ -25,79 +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 main():
+def CheckSharedLibraryConsistency(pkgs_data, debug):
+ ws_re = re.compile(r"\s+")
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
+ 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,
@@ -128,7 +84,7 @@
# same bit of code with do checking and reporting.
#
# TODO: Rewrite this using cheetah templates
- if options.debug and needed_sonames:
+ if debug and needed_sonames:
print "Analysis of sonames needed by the package set:"
binaries_with_missing_sonames = set([])
for soname in needed_sonames:
@@ -150,10 +106,13 @@
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])))
+ pass
+ # The error checking needs to be unified: done in one place only.
+ # errors.append(
+ # checkpkg.CheckpkgTag(
+ # "%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))
@@ -162,11 +121,10 @@
print
dependent_pkgs = {}
- for checker in checkers:
- pkgname = checker.pkgname
- dir_format_pkg = opencsw.DirectoryFormatPackage(checker.pkgpath)
- declared_dependencies = dir_format_pkg.GetDependencies()
- if options.debug:
+ 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
logging.warn("Saving test data to %s." % repr(data_file_name))
@@ -194,22 +152,50 @@
pkgs_by_filename,
filenames_by_soname,
pkg_by_any_filename)
- print checker.FormatDepsReport(missing_deps,
- surplus_deps,
- orphan_sonames)
+ namespace = {
+ "pkgname": pkgname,
+ "missing_deps": missing_deps,
+ "surplus_deps": surplus_deps,
+ "orphan_sonames": orphan_sonames,
+ }
+ t = Template.Template(checkpkg.REPORT_TMPL, searchList=[namespace])
+ print unicode(t)
for soname in orphan_sonames:
- errors.append(checkpkg.Error("The following soname does't belong to "
- "any package: %s" % soname))
+ errors.append(
+ checkpkg.CheckpkgTag(
+ pkgname,
+ "orphan-soname",
+ soname))
+ for missing_dep in missing_deps:
+ errors.append(
+ checkpkg.CheckpkgTag(
+ pkgname,
+ "missing-dependency",
+ missing_dep))
+ return errors
- if errors:
- for error in errors:
- logging.error(error)
- sys.exit(1)
- else:
- sys.exit(0)
+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)
+ check_manager.RegisterSetCheck(CheckSharedLibraryConsistency)
+
+ 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()
Copied: csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-license.py (from rev 8697, csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-license.py)
===================================================================
--- csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-license.py (rev 0)
+++ csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-license.py 2010-02-20 11:24:28 UTC (rev 8698)
@@ -0,0 +1,59 @@
+#!/opt/csw/bin/python2.6
+# $Id$
+
+"""Checks for the existence of the license file."""
+
+import logging
+import os.path
+import sys
+
+CHECKPKG_MODULE_NAME = "license presence"
+
+# 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
+
+LICENSE_TMPL = "/opt/csw/share/doc/%s/license"
+
+def CheckLicenseFile(pkg_data, debug):
+ """Checks for the presence of the license file."""
+ errors = []
+ pkgmap = pkg_data["pkgmap"]
+ catalogname = pkg_data["basic_stats"]["catalogname"]
+ license_path = LICENSE_TMPL % catalogname
+ pkgmap_paths = [x["path"] for x in pkgmap]
+ if license_path not in pkgmap_paths:
+ errors.append(
+ checkpkg.CheckpkgTag(
+ pkg_data["basic_stats"]["pkgname"],
+ "license-missing",
+ msg="See http://sourceforge.net/apps/trac/gar/wiki/CopyRight"))
+ return errors
+
+
+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(CheckLicenseFile)
+ # 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()
Copied: csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-missing-symbols.py (from rev 8697, csw/mgar/gar/v2/bin/checkpkg.d/checkpkg-missing-symbols.py)
===================================================================
--- csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-missing-symbols.py (rev 0)
+++ csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-missing-symbols.py 2010-02-20 11:24:28 UTC (rev 8698)
@@ -0,0 +1,65 @@
+#!/opt/csw/bin/python2.6
+# $Id$
+
+"""Check for missing symbols in binaries.
+
+http://sourceforge.net/tracker/?func=detail&aid=2939416&group_id=229205&atid=1075770
+"""
+
+import os.path
+import re
+import sys
+import subprocess
+
+CHECKPKG_MODULE_NAME = "missing symbols"
+
+# 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
+
+# Defining checking functions.
+
+def CheckForMissingSymbols(pkg_data, debug):
+ """Looks for "symbol not found" in ldd -r output."""
+ errors = []
+ binaries = pkg_data["binaries"]
+ symbol_re = re.compile(r"symbol not found:")
+ for binary in binaries:
+ 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_data["basic_stats"]["pkgname"],
+ "symbol-not-found", binary_base))
+ return errors
+
+
+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(CheckForMissingSymbols)
+ # 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-git/bin/checkpkg.d/checkpkg-obsolete-deps.py
===================================================================
--- csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-obsolete-deps.py 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-obsolete-deps.py 2010-02-20 11:24:28 UTC (rev 8698)
@@ -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,36 +28,45 @@
},
}
-def CheckObsoleteDeps(pkg):
+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:
- errors.append(
- checkpkg.PackageError(
- "Package %s should not depend on %s."
- % (pkg.pkgname, obsolete_pkg)))
+ msg = ""
if "hint" in OBSOLETE_DEPS[obsolete_pkg]:
- errors.append(
- checkpkg.PackageError("Hint: %s" % OBSOLETE_DEPS[obsolete_pkg]["hint"]))
+ msg += "Hint: %s" % OBSOLETE_DEPS[obsolete_pkg]["hint"]
if "url" in OBSOLETE_DEPS[obsolete_pkg]:
- errors.append(
- checkpkg.PackageError("URL: %s" % OBSOLETE_DEPS[obsolete_pkg]["url"]))
+ if msg:
+ msg += ", "
+ msg += "URL: %s" % OBSOLETE_DEPS[obsolete_pkg]["url"]
+ if not msg:
+ msg = None
+ errors.append(
+ 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)
- exit_code, report = check_manager.Run()
- print report.strip()
+ # 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)
Modified: csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-you-can-write-your-own.py
===================================================================
--- csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-you-can-write-your-own.py 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/bin/checkpkg.d/checkpkg-you-can-write-your-own.py 2010-02-20 11:24:28 UTC (rev 8698)
@@ -9,6 +9,8 @@
import os.path
import sys
+CHECKPKG_MODULE_NAME = "a template of a checkpkg module"
+
# The following bit of code sets the correct path to Python libraries
# distributed with GAR.
path_list = [os.path.dirname(__file__),
@@ -16,16 +18,19 @@
sys.path.append(os.path.join(*path_list))
import checkpkg
-# Defining checking functions.
+# Defining the checking functions. They come in two flavors: individual
+# package checks and set checks.
-def MyCheckForAsinglePackage(pkg):
+def MyCheckForAsinglePackage(pkg_data, debug):
"""Checks an individual package.
Gets a DirctoryFormatPackage as an argument, and returns a list of errors.
- Errors should be a list of checkpkg.PackageError objects:
+ Errors should be a list of checkpkg.CheckpkgTag objects:
+ errors.append(checkpkg.CheckpkgTag(pkg.pkgname, "tag-name"))
- errors.append(checkpkg.PackageError("There's something wrong."))
+ You can also add a parameter:
+ errors.append(checkpkg.CheckpkgTag(pkg.pkgname, "tag-name", "/opt/csw/bin/problem"))
"""
errors = []
# Checking code for an individual package goes here. See the
@@ -35,11 +40,13 @@
# Here's how to report an error:
something_is_wrong = False
if something_is_wrong:
- errors.append(checkpkg.PackageError("There's something wrong."))
+ errors.append(checkpkg.CheckpkgTag(
+ pkg_data["basic_stats"]["pkgname"],
+ "example-problem", "thing"))
return errors
-def MyCheckForAsetOfPackages(pkgs):
+def MyCheckForAsetOfPackages(pkgs_data, debug):
"""Checks a set of packages.
Sometimes individual checks aren't enough. If you need to write code which
@@ -54,19 +61,22 @@
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("a template of a checkpkg module",
- options.extractdir,
- pkgnames,
+ check_manager = checkpkg.CheckpkgManager(CHECKPKG_MODULE_NAME,
+ options.stats_basedir,
+ md5sums,
options.debug)
# Registering functions defined above.
check_manager.RegisterIndividualCheck(MyCheckForAsinglePackage)
check_manager.RegisterSetCheck(MyCheckForAsetOfPackages)
# Running the checks, reporting and exiting.
- exit_code, report = check_manager.Run()
- print report.strip()
+ 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)
Copied: csw/mgar/gar/v2-git/bin/checkpkg_collect_stats.py (from rev 8697, csw/mgar/gar/v2/bin/checkpkg_collect_stats.py)
===================================================================
--- csw/mgar/gar/v2-git/bin/checkpkg_collect_stats.py (rev 0)
+++ csw/mgar/gar/v2-git/bin/checkpkg_collect_stats.py 2010-02-20 11:24:28 UTC (rev 8698)
@@ -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-git/bin/checkpkg_collect_stats_test.py (from rev 8697, csw/mgar/gar/v2/bin/checkpkg_collect_stats_test.py)
===================================================================
--- csw/mgar/gar/v2-git/bin/checkpkg_collect_stats_test.py (rev 0)
+++ csw/mgar/gar/v2-git/bin/checkpkg_collect_stats_test.py 2010-02-20 11:24:28 UTC (rev 8698)
@@ -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-git/bin/custom-pkgtrans (from rev 8697, csw/mgar/gar/v2/bin/custom-pkgtrans)
===================================================================
--- csw/mgar/gar/v2-git/bin/custom-pkgtrans (rev 0)
+++ csw/mgar/gar/v2-git/bin/custom-pkgtrans 2010-02-20 11:24:28 UTC (rev 8698)
@@ -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-git/bin/fixlibtool
===================================================================
--- csw/mgar/gar/v2-git/bin/fixlibtool 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/bin/fixlibtool 2010-02-20 11:24:28 UTC (rev 8698)
@@ -21,7 +21,6 @@
# @$(MAKECOOKIE)
#
####################################################
-
umask 0022
PATH=/opt/csw/bin
@@ -34,7 +33,8 @@
## Fix Makefiles
for mk in $(gfind ${BASEPATH} -name Makefile -print); do
gcp ${mk} ${mk}.orig
- LT_FILES=$(for lib in $(ggrep '/opt/csw.*/lib/.*\.la' ${mk}); do \
+ LT_FILES=$(for lib in $(gegrep -v '^#|^$' ${mk} | \
+ ggrep '/opt/csw.*/lib/.*\.la'); do \
echo $lib |gsed -ne '/\/opt.*\.la/p'; done)
for file in ${LT_FILES}; do
LIB_NAME=$(ggrep 'dlname=' ${file} | \
@@ -44,7 +44,7 @@
fixpath=$(gecho $file |gsed 's/\//\\\//g')
gsed "s/${fixpath}/-l${LIB_NAME}/g" ${mk} >${mk}.new
LIB_DIR=$(ggrep 'libdir=' ${file} | gsed -e "s/.*'\(.*\)'/\1/")
- gsed "s,\(LDFLAGS =.*\),\1 -R${LIB_DIR} -L${LIB_DIR}," ${mk}.new >${mk}
+ perl -pe 's,(LDFLAGS =[^\\]*)(\\)?\n,$1 -R'${LIB_DIR}' -L'${LIB_DIR}' $2\n,' ${mk}.new >${mk}
gchmod +x ${mk}
done
done
Copied: csw/mgar/gar/v2-git/bin/submitpkg (from rev 8697, csw/mgar/gar/v2/bin/submitpkg)
===================================================================
--- csw/mgar/gar/v2-git/bin/submitpkg (rev 0)
+++ csw/mgar/gar/v2-git/bin/submitpkg 2010-02-20 11:24:28 UTC (rev 8698)
@@ -0,0 +1 @@
+link ../lib/python/submit_to_newpkgs.py
\ No newline at end of file
Modified: csw/mgar/gar/v2-git/bin/update-commondirs
===================================================================
--- csw/mgar/gar/v2-git/bin/update-commondirs 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/bin/update-commondirs 2010-02-20 11:24:28 UTC (rev 8698)
@@ -29,7 +29,10 @@
print ($l[3] =~ /([^=]*)/);
print "\n";
}
- ' $TMPDIR/CSWcommon/pkgmap; echo "/var"; echo "/var/run") > ../etc/commondirs-$1
+ ' $TMPDIR/CSWcommon/pkgmap
+ echo "/var"; echo "/var/run"
+ echo "/usr"; echo "/usr/sadm"; echo "/usr/sadm/install"; echo "/usr/sadm/install/scripts"
+ ) > ../etc/commondirs-$1
rm -rf $TMPDIR
}
Copied: csw/mgar/gar/v2-git/bin/update_contents_cache.py (from rev 8697, csw/mgar/gar/v2/bin/update_contents_cache.py)
===================================================================
--- csw/mgar/gar/v2-git/bin/update_contents_cache.py (rev 0)
+++ csw/mgar/gar/v2-git/bin/update_contents_cache.py 2010-02-20 11:24:28 UTC (rev 8698)
@@ -0,0 +1,27 @@
+#!/opt/csw/bin/python2.6
+#
+# $Id$
+#
+# This file only creates an instance of SystemPkgmap in order to update the
+# package cache (if necessary), and display the information about the update.
+
+import os
+import os.path
+import sys
+import logging
+
+# 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
+
+def main():
+ print "Checking if the package cache is up to date."
+ logging.basicConfig(level=logging.INFO)
+ test_pkgmap = checkpkg.SystemPkgmap()
+
+
+if __name__ == '__main__':
+ main()
Modified: csw/mgar/gar/v2-git/categories/cpan/category.mk
===================================================================
--- csw/mgar/gar/v2-git/categories/cpan/category.mk 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/categories/cpan/category.mk 2010-02-20 11:24:28 UTC (rev 8698)
@@ -62,10 +62,11 @@
INSTALL_ENV += PERL5LIB=$(PERL5LIB)
# Configure a target using Makefile.PL
+_CATEGORY_LD_OPTIONS ?= -L$(libdir) -lperl
PERL_CONFIGURE_ARGS ?= INSTALLDIRS=vendor $(EXTRA_PERL_CONFIGURE_ARGS)
configure-%/Makefile.PL:
@echo " ==> Running Makefile.PL in $*"
- @( cd $* ; \
+ ( cd $* ; \
$(CONFIGURE_ENV) perl Makefile.PL \
$(CONFIGURE_ARGS) $(PERL_CONFIGURE_ARGS) )
@$(MAKECOOKIE)
@@ -73,14 +74,14 @@
PERLBUILD_CONFIGURE_ARGS ?= installdirs=vendor $(EXTRA_PERLBUILD_CONFIGURE_ARGS)
configure-%/Build.PL:
@echo " ==> Running Build.PL in $*"
- @( cd $* ; \
+ ( cd $* ; \
$(CONFIGURE_ENV) perl Build.PL \
$(PERLBUILD_CONFIGURE_ARGS) $(CONFIGURE_ARGS) )
@$(MAKECOOKIE)
build-%/Build:
@echo " ==> Running Build in $*"
- @( cd $* ; $(BUILD_ENV) ./Build )
+ ( cd $* ; $(BUILD_ENV) ./Build )
@$(MAKECOOKIE)
test-%/Build:
Modified: csw/mgar/gar/v2-git/categories/x11/category.mk
===================================================================
--- csw/mgar/gar/v2-git/categories/x11/category.mk 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/categories/x11/category.mk 2010-02-20 11:24:28 UTC (rev 8698)
@@ -1,7 +1,7 @@
# X11
# Version of X11
-X11_RELEASE_VERSION = X11R7.4
+X11_RELEASE_VERSION = X11R7.5
# Definition of the URL to access sources
X11_PROTO_MASTER_SITE = http://xorg.freedesktop.org/releases/$(X11_RELEASE_VERSION)/src/proto/
Modified: csw/mgar/gar/v2-git/etc/commondirs-i386
===================================================================
--- csw/mgar/gar/v2-git/etc/commondirs-i386 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/etc/commondirs-i386 2010-02-20 11:24:28 UTC (rev 8698)
@@ -156,3 +156,7 @@
/var/opt/csw/pkg-hooks
/var
/var/run
+/usr
+/usr/sadm
+/usr/sadm/install
+/usr/sadm/install/scripts
Modified: csw/mgar/gar/v2-git/etc/commondirs-sparc
===================================================================
--- csw/mgar/gar/v2-git/etc/commondirs-sparc 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/etc/commondirs-sparc 2010-02-20 11:24:28 UTC (rev 8698)
@@ -160,3 +160,7 @@
/var/opt/csw/pkg-hooks
/var
/var/run
+/usr
+/usr/sadm
+/usr/sadm/install
+/usr/sadm/install/scripts
Modified: csw/mgar/gar/v2-git/gar.conf.mk
===================================================================
--- csw/mgar/gar/v2-git/gar.conf.mk 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/gar.conf.mk 2010-02-20 11:24:28 UTC (rev 8698)
@@ -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
@@ -497,10 +498,10 @@
# may not be a subdirectory for the 32-bit standard case (this would normally
# be a symlink of the form lib/sparcv8 -> . and lib/i386 -> .). This is most likely
# the case for libraries in $(EXTRA_LIB) for which no links generated in CSWcommon.
-RUNPATH_DIRS ?= $(libpath_install) $(filter-out $(libpath_install),$(libdir_install)) $(EXTRA_LIB) $(EXTRA_RUNPATH_DIRS)
+RUNPATH_DIRS ?= $(EXTRA_RUNPATH_DIRS) $(EXTRA_LIB) $(filter-out $(libpath_install),$(libdir_install)) $(libpath_install)
ifndef NOISALIST
-RUNPATH_ISALIST ?= $(libpath_install) $(filter-out $(libpath_install),$(libdir_install)) $(EXTRA_LIB) $(EXTRA_RUNPATH_ISALIST)
+RUNPATH_ISALIST ?= $(EXTRA_RUNPATH_DIRS) $(EXTRA_LIB) $(filter-out $(libpath_install),$(libdir_install)) $(libpath_install)
endif
# Iterate over all directories in RUNPATH_DIRS, prefix each directory with one
@@ -508,7 +509,7 @@
RUNPATH_LINKER_FLAGS ?= $(foreach D,$(RUNPATH_DIRS),$(addprefix -R,$(addsuffix /\$$ISALIST,$(filter $D,$(RUNPATH_ISALIST))) $(abspath $D/$(MM_LIBDIR)))) $(addprefix -R,$(filter-out $(RUNPATH_DIRS),$(RUNPATH_ISALIST))) $(EXTRA_RUNPATH_LINKER_FLAGS)
endif
-LINKER_FLAGS ?= $(foreach ELIB,$(libpath_install) $(filter-out $(libpath_install),$(libdir_install)) $(EXTRA_LIB),-L$(abspath $(ELIB)/$(MM_LIBDIR))) $(EXTRA_LINKER_FLAGS)
+LINKER_FLAGS ?= $(foreach ELIB,$(EXTRA_LIB) $(filter-out $(libpath_install),$(libdir_install)) $(libpath_install),-L$(abspath $(ELIB)/$(MM_LIBDIR))) $(EXTRA_LINKER_FLAGS)
CC_HOME = $($(GARCOMPILER)_CC_HOME)
CC = $($(GARCOMPILER)_CC)
@@ -525,7 +526,7 @@
SOS11_LD_OPTIONS = $(EXTRA_SOS11_LD_OPTIONS) $(EXTRA_SOS_LD_OPTIONS)
SOS12_LD_OPTIONS = $(EXTRA_SOS12_LD_OPTIONS) $(EXTRA_SOS_LD_OPTIONS)
-LD_OPTIONS ?= $(strip $($(GARCOMPILER)_LD_OPTIONS) $(RUNPATH_LINKER_FLAGS) $(EXTRA_LD_OPTIONS))
+LD_OPTIONS ?= $(strip $($(GARCOMPILER)_LD_OPTIONS) $(RUNPATH_LINKER_FLAGS) $(EXTRA_LD_OPTIONS) $(_CATEGORY_LD_OPTIONS))
# 1. Make sure everything works fine for SOS12
# 2. Allow us to use programs we just built. This is a bit complicated,
Modified: csw/mgar/gar/v2-git/gar.lib.mk
===================================================================
--- csw/mgar/gar/v2-git/gar.lib.mk 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/gar.lib.mk 2010-02-20 11:24:28 UTC (rev 8698)
@@ -196,6 +196,8 @@
# echo ""; \
# echo "Please consider updating your package. Documentation is available from this link : http://www.opencsw.org" ; \
# echo ""; \
+# echo "Questions, problem report or help should be sent to mailto:maintainers at lists.opencsw.org"; \
+# echo ""; \
# echo "--"; \
# echo "Kindest regards"; \
# echo "upstream notification job"; } | $(GARBIN)/mail2maintainer -s '[svn] $(GARNAME) upstream update notification' $(GARNAME); \
@@ -222,6 +224,8 @@
echo " $(UPSTREAM_MASTER_SITES)"; \
echo ""; \
echo "Please consider updating your package." ; \
+ echo ""; \
+ echo "Questions, problem report or help should be sent to mailto:maintainers at lists.opencsw.org"; \
echo ""; \
echo "--"; \
echo "Kindest regards"; \
Modified: csw/mgar/gar/v2-git/gar.mk
===================================================================
--- csw/mgar/gar/v2-git/gar.mk 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/gar.mk 2010-02-20 11:24:28 UTC (rev 8698)
@@ -295,7 +295,7 @@
@echo "[===== NOW BUILDING: $(DISTNAME) MODULATION $(MODULATION): $(foreach M,$(MODULATORS),$M=$($M)) =====]"
# prerequisite - Make sure that the system is in a sane state for building the package
-PREREQUISITE_TARGETS = $(addprefix prerequisitepkg-,$(PREREQUISITE_BASE_PKGS) $(BUILD_DEP_PKGS)) $(addprefix prerequisite-,$(PREREQUISITE_SCRIPTS))
+PREREQUISITE_TARGETS = $(addprefix prerequisitepkg-,$(PREREQUISITE_BASE_PKGS) $(BUILD_DEP_PKGS) $(DEP_PKGS) $(foreach S,$(_PKG_SPECS),$(DEP_PKGS_$S))) $(addprefix prerequisite-,$(PREREQUISITE_SCRIPTS))
# Force to be called in global modulation
prerequisite: $(if $(filter global,$(MODULATION)),announce pre-everything $(COOKIEDIR) $(DOWNLOADDIR) $(PARTIALDIR) $(addprefix dep-$(GARDIR)/,$(FETCHDEPS)) pre-prerequisite $(PREREQUISITE_TARGETS) post-prerequisite)
@@ -650,24 +650,10 @@
# These directories get relocated into their ISA subdirectories
MERGE_DIRS ?= $(MERGE_DIRS_$(MODULATION))
-# The files in ISAEXEC get relocated and will be replaced by the isaexec-wrapper
-_ISAEXEC_EXCLUDE_FILES = $(bindir)/%-config $(bindir)/%/%-config
-_ISAEXEC_FILES = $(filter-out $(foreach F,$(_ISAEXEC_EXCLUDE_FILES) $(ISAEXEC_EXCLUDE_FILES),$(PKGROOT)$(F)), \
- $(wildcard $(foreach D,$(ISAEXEC_DIRS),$(PKGROOT)$(D)/* )) \
- )
-ISAEXEC_FILES ?= $(if $(_ISAEXEC_FILES),$(patsubst $(PKGROOT)%,%, \
- $(shell for F in $(_ISAEXEC_FILES); do \
- if test -f "$$F" -a \! -h "$$F"; then echo $$F; fi; \
- done)),)
-
ifneq ($(COMMON_PKG_DEPENDS),)
_EXTRA_GAR_PKGS += $(COMMON_PKG_DEPENDS)
endif
-ifneq ($(ISAEXEC_FILES),)
-_EXTRA_GAR_PKGS += CSWisaexec
-endif
-
# These merge-rules are actually processed for the current modulation
MERGE_TARGETS ?= $(addprefix merge-,$(MERGE_SCRIPTS_$(MODULATION))) $(EXTRA_MERGE_TARGETS)
@@ -749,7 +735,7 @@
# The basic merge merges the compiles for all ISAs on the current architecture
-merge: checksum pre-merge merge-do merge-license merge-classutils $(if $(COMPILE_ELISP),compile-elisp) $(if $(NOSOURCEPACKAGE),,merge-src) post-merge
+merge: checksum pre-merge merge-do merge-license merge-classutils merge-checkpkgoverrides merge-alternatives $(if $(COMPILE_ELISP),compile-elisp) $(if $(NOSOURCEPACKAGE),,merge-src) post-merge
@$(DONADA)
merge-do: $(if $(PARALLELMODULATIONS),merge-parallel,merge-sequential)
@@ -825,7 +811,7 @@
.PHONY: remerge reset-merge reset-merge-modulated
remerge: reset-merge merge
-reset-merge: reset-package $(addprefix reset-merge-,$(MODULATIONS)) reset-merge-license reset-merge-classutils reset-merge-src
+reset-merge: reset-package $(addprefix reset-merge-,$(MODULATIONS)) reset-merge-license reset-merge-classutils reset-merge-checkpkgoverrides reset-merge-alternatives reset-merge-src
@rm -f $(COOKIEDIR)/pre-merge $(foreach M,$(MODULATIONS),$(COOKIEDIR)/merge-$M) $(COOKIEDIR)/merge $(COOKIEDIR)/post-merge
@rm -rf $(PKGROOT)
@$(DONADA)
Modified: csw/mgar/gar/v2-git/gar.pkg.mk
===================================================================
--- csw/mgar/gar/v2-git/gar.pkg.mk 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/gar.pkg.mk 2010-02-20 11:24:28 UTC (rev 8698)
@@ -32,10 +32,12 @@
ifeq ($(origin PACKAGES), undefined)
PACKAGES = $(if $(filter %.gspec,$(DISTFILES)),,CSW$(GARNAME))
+CATALOGNAME = $(if $(filter %.gspec,$(DISTFILES)),,$(GARNAME))
SRCPACKAGE_BASE = $(firstword $(basename $(filter %.gspec,$(DISTFILES))) $(PACKAGES))
SRCPACKAGE ?= $(SRCPACKAGE_BASE)-src
SPKG_SPECS ?= $(basename $(filter %.gspec,$(DISTFILES))) $(PACKAGES) $(if $(NOSOURCEPACKAGE),,$(SRCPACKAGE))
else
+CATALOGNAME ?= $(if $(filter-out $(firstword $(PACKAGES)),$(PACKAGES)),,$(patsubst CSW%,%,$(PACKAGES)))
SRCPACKAGE_BASE = $(firstword $(PACKAGES))
SRCPACKAGE ?= $(SRCPACKAGE_BASE)-src
SPKG_SPECS ?= $(sort $(basename $(filter %.gspec,$(DISTFILES))) $(PACKAGES) $(if $(NOSOURCEPACKAGE),,$(SRCPACKAGE)))
@@ -67,6 +69,13 @@
GARPKG_v2 = CSWgar-v2
RUNTIME_DEP_PKGS_$(SRCPACKAGE) ?= $(or $(GARPKG_$(GARSYSTEMVERSION)),$(error GAR version $(GARSYSTEMVERSION) unknown))
+# Sanity checks for r8335
+$(if $(NO_ISAEXEC),$(error The deprecated variable 'NO_ISAEXEC' is defined, please replace it with NOISAEXEC))
+$(if $(PREREQUISITE_PKGS),$(error The deprecated variable 'PREREQUISITE_PKGS' is defined, please replace it with BUILD_DEP_PKGS))
+$(foreach P,$(SPKG_SPECS),$(if $(PREREQUISITE_PKGS_$P),$(error The deprecated variable 'PREREQUISITE_PKGS_$P' is defined, please replace it with BUILD_DEP_PKGS_$P)))
+$(if $(REQUIRED_PKGS),$(error The deprecated variable 'REQUIRED_PKGS' is defined, please replace it with RUNTIME_DEP_PKGS))
+$(foreach P,$(SPKG_SPECS),$(if $(REQUIRED_PKGS_$P),$(error The deprecated variable 'REQUIRED_PACKAGES_$P' is defined, please replace it with RUNTIME_DEP_PKGS_$P)))
+
_PKG_SPECS = $(filter-out $(NOPACKAGE),$(SPKG_SPECS))
# pkgname - Get the name of a package from a gspec-name or package-name
@@ -205,6 +214,7 @@
_CSWCLASSES += cswinetd
_CSWCLASSES += cswinitsmf
_CSWCLASSES += cswtexinfo
+_CSWCLASSES += cswpostmsg
# Make sure the configuration files always have a .CSW suffix and rename the
# configuration files to this if necessary during merge.
@@ -344,7 +354,7 @@
_PROTOTYPE_MODIFIERS = | perl -ane '\
$(foreach M,$(PROTOTYPE_MODIFIERS),\
- $(if $(PROTOTYPE_FILES_$M),if( $$F[2] =~ m(^$(PROTOTYPE_FILES_$M)$$) ) {)\
+ $(if $(PROTOTYPE_FILES_$M),if( $$F[2] =~ m(^$(shell echo $(PROTOTYPE_FILES_$M) | /usr/bin/tr " " "|")$$) ) {)\
$(if $(PROTOTYPE_FTYPE_$M),$$F[0] = "$(PROTOTYPE_FTYPE_$M)";)\
$(if $(PROTOTYPE_CLASS_$M),$$F[1] = "$(PROTOTYPE_CLASS_$M)";)\
$(if $(PROTOTYPE_PERMS_$M),$$F[3] = "$(PROTOTYPE_PERMS_$M)";)\
@@ -352,6 +362,8 @@
$(if $(PROTOTYPE_GROUP_$M),$$F[5] = "$(PROTOTYPE_GROUP_$M)";)\
$(if $(PROTOTYPE_FILES_$M),})\
)\
+ $(foreach F,$(POSTMSG),$$F[1] = "cswpostmsg" if( $$F[2] eq "$F" );)\
+ $$F[1] = "cswalternatives" if( $$F[2] =~ m,^/opt/csw/share/alternatives/[^/]+$$, );\
print join(" ", at F),"\n";'
@@ -382,8 +394,18 @@
-n "$(_PKGFILES_EXCLUDE)" -o \
-n "$(ISAEXEC_FILES_$*)" -o \
-n "$(ISAEXEC_FILES)" ]; then \
- (pathfilter $(if $(or $(_PKGFILES_EXCLUDE),$(_PKGFILES_INCLUDE)),-I $(call licensedir,$*)/license -I /etc/opt/csw/pkg/$*/cswmigrateconf) \
- $(foreach S,$(filter-out $*,$(SPKG_SPECS)),-X $(call licensedir,$S)/license -X /etc/opt/csw/pkg/$S/cswmigrateconf) \
+ (pathfilter $(if $(or $(_PKGFILES_EXCLUDE),$(_PKGFILES_INCLUDE)),\
+ -I $(call licensedir,$*)/license \
+ -I /etc/opt/csw/pkg/$*/cswmigrateconf \
+ -I /opt/csw/share/alternatives/$(call catalogname,$*) \
+ -I /opt/csw/share/checkpkg/overrides/$(call catalogname,$*) \
+ )\
+ $(foreach S,$(filter-out $*,$(SPKG_SPECS)),\
+ -X $(call licensedir,$S)/license \
+ -X /etc/opt/csw/pkg/$S/cswmigrateconf \
+ -X /opt/csw/share/alternatives/$(call catalogname,$S) \
+ -X /opt/csw/share/checkpkg/overrides/$(call catalogname,$S) \
+ ) \
$(foreach I,$(EXTRA_PKGFILES_INCLUDED) $(EXTRA_PKGFILES_INCLUDED_$*),-i '$I') \
$(foreach X,$(EXTRA_PKGFILES_EXCLUDED) $(EXTRA_PKGFILES_EXCLUDED_$*),-x '$X') \
$(foreach FILE,$(_PKGFILES_INCLUDE),-i '$(FILE)') \
@@ -422,14 +444,15 @@
# The dependencies to CSWcswclassutils and CSWtexinfo are only added if there are files
# actually matching the _TEXINFO_FILTER. This is done at the prototype-level.
$(WORKDIR)/%.depend: $(WORKDIR)/$*.prototype
+$(WORKDIR)/%.depend: _EXTRA_GAR_PKGS += $(if $(strip $(shell cat $(WORKDIR)/$*.prototype | perl -ane 'print "yes" if( $$F[1] eq "cswalternatives")')),CSWalternatives)
$(WORKDIR)/%.depend: _EXTRA_GAR_PKGS += $(if $(strip $(shell cat $(WORKDIR)/$*.prototype | perl -ane '$(foreach C,$(_CSWCLASSES),print "$C\n" if( $$F[1] eq "$C");)')),CSWcswclassutils)
$(WORKDIR)/%.depend: $(WORKDIR)
- $(_DBG)$(if $(_EXTRA_GAR_PKGS)$(RUNTIME_DEP_PKGS_$*)$(RUNTIME_DEP_PKGS)$(INCOMPATIBLE_PKGS)$(INCOMPATIBLE_PKGS_$*), \
+ $(_DBG)$(if $(_EXTRA_GAR_PKGS)$(RUNTIME_DEP_PKGS_$*)$(RUNTIME_DEP_PKGS)$(DEP_PKGS)$(DEP_PKGS_$*)$(INCOMPATIBLE_PKGS)$(INCOMPATIBLE_PKGS_$*), \
($(foreach PKG,$(INCOMPATIBLE_PKGS_$*) $(INCOMPATIBLE_PKGS),\
echo "I $(PKG)";\
)\
- $(foreach PKG,$(sort $(_EXTRA_GAR_PKGS)) $(RUNTIME_DEP_PKGS_$*) $(RUNTIME_DEP_PKGS),\
+ $(foreach PKG,$(sort $(_EXTRA_GAR_PKGS)) $(or $(RUNTIME_DEP_PKGS_$*),$(RUNTIME_DEP_PKGS),$(DEP_PKGS_$*),$(DEP_PKGS)),\
$(if $(SPKG_DESC_$(PKG)), \
echo "P $(PKG) $(call catalogname,$(PKG)) - $(SPKG_DESC_$(PKG))";, \
echo "$(shell (/usr/bin/pkginfo $(PKG) || echo "P $(PKG) - ") | $(GAWK) '{ $$1 = "P"; print } ')"; \
@@ -527,6 +550,7 @@
# The texinfo filter has been taken out of the normal filters as TEXINFO has a default.
$(WORKDIR)/%.pkginfo: $(WORKDIR)/%.prototype
+$(WORKDIR)/%.pkginfo: SPKG_CLASSES += $(if $(strip $(shell cat $(WORKDIR)/$*.prototype | perl -ane 'print "yes" if( $$F[1] eq "cswalternatives")')),cswalternatives)
$(WORKDIR)/%.pkginfo: SPKG_CLASSES += $(shell cat $(WORKDIR)/$*.prototype | perl -e 'while(<>){@F=split;$$c{$$F[1]}++};$(foreach C,$(_CSWCLASSES),print "$C\n" if( $$c{$C});)')
$(WORKDIR)/%.pkginfo: $(WORKDIR)
@@ -540,8 +564,9 @@
echo "PSTAMP=$(LOGNAME)@$(shell hostname)-$(shell date '+%Y%m%d%H%M%S')"; \
echo "CLASSES=$(call pkgvar,SPKG_CLASSES,$*)"; \
echo "HOTLINE=http://www.opencsw.org/bugtrack/"; \
+ echo "OPENCSW_CATALOGNAME=$(call catalogname,$*)"; \
+ echo "OPENCSW_MODE64=$(call mode64,$*)"; \
echo "OPENCSW_REPOSITORY=$(call _URL)@$(call _REVISION)"; \
- echo "OPENCSW_MODE64=$(call mode64,$*)"; \
) >$@
@@ -600,8 +625,8 @@
@echo "X: $(MIGRATE_FILES_$*) Y: $(MIGRATE_FILES)"
$(_DBG)ginstall -d $(PKGROOT)/etc/opt/csw/pkg/$*
$(_DBG)(echo "MIGRATE_FILES=\"$(or $(MIGRATE_FILES_$*),$(MIGRATE_FILES))\"";\
- $(if $(MIGRATE_SOURCE_DIR_$*),echo "SOURCE_DIR___default__=\"$(MIGRATE_SOURCE_DIR_$*)\"";)\
- $(if $(MIGRATE_DEST_DIR_$*),echo "DEST_DIR___default__=\"$(MIGRATE_DEST_DIR_$*)\"";)\
+ $(if $(or $(MIGRATE_SOURCE_DIR_$*),$(MIGRATE_SOURCE_DIR)),echo "SOURCE_DIR___default__=\"$(or $(MIGRATE_SOURCE_DIR_$*),$(MIGRATE_SOURCE_DIR))\"";)\
+ $(if $(or $(MIGRATE_DEST_DIR_$*),$(MIGRATE_DEST_DIR)),echo "DEST_DIR___default__=\"$(or $(MIGRATE_DEST_DIR_$*),$(MIGRATE_DEST_DIR))\"";)\
$(foreach F,$(or $(MIGRATE_FILES_$*),$(MIGRATE_FILES)),\
$(if $(MIGRATE_SOURCE_DIR_$F),echo "SOURCE_DIR_$(subst .,_,$F)=\"$(MIGRATE_SOURCE_DIR_$F)\"";)\
$(if $(MIGRATE_DEST_DIR_$F),echo "DEST_DIR_$(subst .,_,$F)=\"$(MIGRATE_DEST_DIR_$F)\"";)\
@@ -649,6 +674,31 @@
reset-merge-etcservices:
@rm -f $(COOKIEDIR)/merge-etcservices $(foreach SPEC,$(_PKG_SPECS),$(COOKIEDIR)/merge-etcservices-$(SPEC))
+merge-checkpkgoverrides-%:
+ @echo "[ Generating checkpkg override for package $* ]"
+ $(_DBG)ginstall -d $(PKGROOT)/opt/csw/share/checkpkg/overrides
+ $(_DBG)($(foreach O,$(or $(CHECKPKG_OVERRIDES_$*),$(CHECKPKG_OVERRIDES)),echo "$O";)) | \
+ perl -F'\|' -ane 'unshift @F,"$*"; $$F[0].=":"; print join(" ", at F );' \
+ > $(PKGROOT)/opt/csw/share/checkpkg/overrides/$(call catalogname,$*)
+ @$(MAKECOOKIE)
+
+merge-checkpkgoverrides: $(foreach S,$(SPKG_SPECS),$(if $(or $(CHECKPKG_OVERRIDES_$S),$(CHECKPKG_OVERRIDES)),merge-checkpkgoverrides-$S))
+
+reset-merge-checkpkgoverrides:
+ @rm -f $(COOKIEDIR)/merge-checkpkgoverrides $(foreach SPEC,$(_PKG_SPECS),$(COOKIEDIR)/merge-checkpkgoverrides-$(SPEC))
+
+merge-alternatives-%:
+ @echo "[ Generating alternatives for package $* ]"
+ $(_DBG)ginstall -d $(PKGROOT)/opt/csw/share/alternatives
+ $(_DBG)($(foreach A,$(or $(ALTERNATIVES_$*),$(ALTERNATIVES)),echo "$(ALTERNATIVE_$A)";)) \
+ > $(PKGROOT)/opt/csw/share/alternatives/$(call catalogname,$*)
+ @$(MAKECOOKIE)
+
+merge-alternatives: $(foreach S,$(SPKG_SPECS),$(if $(or $(ALTERNATIVES_$S),$(ALTERNATIVES)),merge-alternatives-$S))
+
+reset-merge-alternatives:
+ @rm -f $(COOKIEDIR)/merge-alternatives $(foreach SPEC,$(_PKG_SPECS),$(COOKIEDIR)/merge-alternatives-$(SPEC))
+
merge-src: _SRCDIR=$(PKGROOT)$(sourcedir)/$(call catalogname,$(SRCPACKAGE_BASE))
merge-src: fetch
$(_DBG)mkdir -p $(_SRCDIR)/files
@@ -694,7 +744,22 @@
# unpacked to global/ for packaging. E. g. 'merge' depends only on the specific
# modulations and does not fill global/.
ENABLE_CHECK ?= 1
-_package: validateplatform extract-global merge $(SPKG_DESTDIRS) pre-package $(PACKAGE_TARGETS) post-package $(if $(ENABLE_CHECK),pkgcheck)
+
+# The files in ISAEXEC get relocated and will be replaced by the isaexec-wrapper.
+# The trick is to delay the calculcation of the variable values until that time
+# when PKGROOT has already been populated.
+_ISAEXEC_EXCLUDE_FILES = $(bindir)/%-config $(bindir)/%/%-config
+_buildpackage: _ISAEXEC_FILES=$(filter-out $(foreach F,$(_ISAEXEC_EXCLUDE_FILES) $(ISAEXEC_EXCLUDE_FILES),$(PKGROOT)$(F)), \
+ $(wildcard $(foreach D,$(ISAEXEC_DIRS),$(PKGROOT)$(D)/* )) \
+ )
+_buildpackage: ISAEXEC_FILES ?= $(if $(_ISAEXEC_FILES),$(patsubst $(PKGROOT)%,%, \
+ $(shell for F in $(_ISAEXEC_FILES); do \
+ if test -f "$$F" -a \! -h "$$F"; then echo $$F; fi; \
+ done)),)
+_buildpackage: _EXTRA_GAR_PKGS += $(if $(ISAEXEC_FILES),CSWisaexec)
+_buildpackage: pre-package $(PACKAGE_TARGETS) post-package $(if $(ENABLE_CHECK),pkgcheck)
+
+_package: validateplatform extract-global merge $(SPKG_DESTDIRS) _buildpackage
@$(MAKECOOKIE)
package: _package
@@ -770,8 +835,9 @@
# This rule automatically logs into every host where a package for this software should
# be built. It is especially suited for automated build bots.
+platforms: _PACKAGING_PLATFORMS=$(if $(ARCHALL),$(firstword $(PACKAGING_PLATFORMS)),$(PACKAGING_PLATFORMS))
platforms:
- $(foreach P,$(PACKAGING_PLATFORMS),\
+ $(foreach P,$(_PACKAGING_PLATFORMS),\
$(if $(PACKAGING_HOST_$P),\
$(if $(filter $(THISHOST),$(PACKAGING_HOST_$P)),\
$(MAKE) PLATFORM=$P _package && ,\
@@ -783,8 +849,9 @@
@echo
@echo "The following packages have been built during this invocation:"
@echo
- @$(foreach P,$(PACKAGING_PLATFORMS),\
+ @$(foreach P,$(_PACKAGING_PLATFORMS),\
echo "* Platform $P\c";\
+ $(if $(ARCHALL),echo " (suitable for all architectures)\c";) \
$(if $(filter $(THISHOST),$(PACKAGING_HOST_$P)),\
echo " (built on this host)";\
$(MAKE) -s PLATFORM=$P _pkgshow;echo;,\
@@ -794,11 +861,12 @@
)
@$(MAKECOOKIE)
+platforms-%: _PACKAGING_PLATFORMS=$(if $(ARCHALL),$(firstword $(PACKAGING_PLATFORMS)),$(PACKAGING_PLATFORMS))
platforms-%:
- $(foreach P,$(PACKAGING_PLATFORMS),\
+ $(foreach P,$(_PACKAGING_PLATFORMS),\
$(if $(PACKAGING_HOST_$P),\
$(if $(filter $(THISHOST),$(PACKAGING_HOST_$P)),\
- $(MAKE) PLATFORM=$P $* && ,\
+ $(MAKE) -s PLATFORM=$P $* && ,\
$(SSH) -t $(PACKAGING_HOST_$P) "PATH=$$PATH:/opt/csw/bin $(MAKE) -C $(CURDIR) PLATFORM=$P $*" && \
),\
$(error *** No host has been defined for platform $P)\
Modified: csw/mgar/gar/v2-git/lib/python/checkpkg.py
===================================================================
--- csw/mgar/gar/v2-git/lib/python/checkpkg.py 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/lib/python/checkpkg.py 2010-02-20 11:24:28 UTC (rev 8698)
@@ -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
@@ -22,26 +26,30 @@
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",
- u"SUNWcslx"])
+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"""# $pkgname:
+REPORT_TMPL = u"""#if $missing_deps or $surplus_deps or $orphan_sonames
+# $pkgname:
+#end if
#if $missing_deps
# SUGGESTION: you may want to add some or all of the following as depends:
# (Feel free to ignore SUNW or SPRO packages)
@@ -61,12 +69,9 @@
# ! $soname
#end for
#end if
-#if not $missing_deps and not $surplus_deps and not $orphan_sonames
-# + Dependencies of $pkgname look good.
-#end if
"""
-ERROR_REPORT_TMPL = u"""#if $errors
+SCREEN_ERROR_REPORT_TMPL = u"""#if $errors and $debug
ERROR: One or more errors have been found by $name.
#for $pkgname in $errors
$pkgname:
@@ -76,11 +81,23 @@
#end for
#else
#if $debug
-OK: $name found no problems.
+OK: $repr($name) module found no problems.
#end if
#end if
"""
+# http://www.cheetahtemplate.org/docs/users_guide_html_multipage/language.directives.closures.html
+TAG_REPORT_TMPL = u"""#if $errors
+# Tags reported by $name module
+#for $pkgname in $errors
+#for $tag in $errors[$pkgname]
+$pkgname: ${tag.tag_name}#if $tag.tag_info# $tag.tag_info#end if#
+#end for
+#end for
+#end if
+"""
+
+
class Error(Exception):
pass
@@ -95,79 +112,35 @@
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)
-class CheckpkgBase(object):
- """This class has functionality overlapping with DirectoryFormatPackage
- from the opencsw.py library. The classes should be merged.
- """
+def FormatDepsReport(pkgname, missing_deps, surplus_deps, orphan_sonames):
+ """To be removed."""
+ namespace = {
+ "pkgname": pkgname,
+ "missing_deps": missing_deps,
+ "surplus_deps": surplus_deps,
+ "orphan_sonames": orphan_sonames,
+ }
+ t = Template.Template(REPORT_TMPL, searchList=[namespace])
+ return unicode(t)
- 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 FormatDepsReport(self, missing_deps, surplus_deps, orphan_sonames):
- """To be removed."""
- namespace = {
- "pkgname": self.pkgname,
- "missing_deps": missing_deps,
- "surplus_deps": surplus_deps,
- "orphan_sonames": orphan_sonames,
- }
- t = Template.Template(REPORT_TMPL, searchList=[namespace])
- return unicode(t)
-
-
class SystemPkgmap(object):
"""A class to hold and manipulate the /var/sadm/install/contents file.
@@ -235,26 +208,31 @@
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
+ if line.startswith("#"):
+ 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 "\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)
@@ -316,17 +294,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,
@@ -441,6 +420,11 @@
# 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))
+ for re_str in DO_NOT_REPORT_MISSING_RE:
+ padded_re = "^%s$" % re_str
+ missing_deps = filter(lambda x: not re.match(padded_re, x),
+ missing_deps)
+ missing_deps = set(missing_deps)
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)
@@ -573,14 +557,29 @@
return binary_data
+class CheckpkgTag(object):
+ """Represents a tag to be written to the checkpkg tag file."""
+
+ def __init__(self, pkgname, tag_name, tag_info=None, severity=None, msg=None):
+ self.pkgname = pkgname
+ self.tag_name = tag_name
+ self.tag_info = tag_info
+ self.severity = severity
+ self.msg = msg
+
+ def __repr__(self):
+ return (u"CheckpkgTag(%s, %s, %s, ...)"
+ % (repr(self.pkgname), repr(self.tag_name), repr(self.tag_info)))
+
+
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 = []
@@ -592,31 +591,372 @@
def RegisterSetCheck(self, function):
self.set_checks.append(function)
- def Run(self):
- """Runs all the checks
+ def GetPackageStatsList(self):
+ stats_list = []
+ for md5sum in self.md5sum_list:
+ stats_list.append(PackageStats(None, self.stats_basedir, md5sum))
+ return stats_list
- Returns a tuple of an exit code and a report.
- """
- packages = []
+ def GetAllTags(self, packages_data):
errors = {}
- for pkgname in self.pkgname_list:
- pkg_path = os.path.join(self.extractdir, pkgname)
- packages.append(opencsw.DirectoryFormatPackage(pkg_path))
- for pkg in packages:
+ for pkg_data in packages_data:
for function in self.individual_checks:
- errors_for_pkg = function(pkg)
+ 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)
+ set_errors = function([x.GetAllStats() for x in packages_data],
+ debug=self.debug)
if set_errors:
- errors["The package set"] = 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.
+ for tag in set_errors:
+ if tag.pkgname:
+ if not tag.pkgname in errors:
+ errors[tag.pkgname] = []
+ errors[tag.pkgname].append(tag)
+ else:
+ if "package-set" not in errors:
+ errors["package-set"] = []
+ errors["package-set"].append(error)
+ return errors
+
+ def FormatReports(self, errors):
namespace = {
"name": self.name,
"errors": errors,
"debug": self.debug,
}
- t = Template.Template(ERROR_REPORT_TMPL, searchList=[namespace])
- exit_code = bool(errors)
- return (exit_code, unicode(t))
+ screen_t = Template.Template(SCREEN_ERROR_REPORT_TMPL, searchList=[namespace])
+ tags_report_t = Template.Template(TAG_REPORT_TMPL, searchList=[namespace])
+ screen_report = unicode(screen_t)
+ tags_report = unicode(tags_report_t)
+ return screen_report, tags_report
+
+ def Run(self):
+ """Runs all the checks
+
+ Returns a tuple of an exit code and a report.
+ """
+ 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)
+
+
+def ParseTagLine(line):
+ """Parses a line from the tag.${module} file.
+
+ Returns a triplet of pkgname, tagname, tag_info.
+ """
+ level_1 = line.strip().split(":")
+ if len(level_1) > 1:
+ data_1 = level_1[1]
+ pkgname = level_1[0]
+ else:
+ data_1 = level_1[0]
+ pkgname = None
+ level_2 = re.split(WS_RE, data_1.strip())
+ tag_name = level_2[0]
+ if len(level_2) > 1:
+ tag_info = " ".join(level_2[1:])
+ else:
+ tag_info = None
+ return (pkgname, tag_name, tag_info)
+
+
+class Override(object):
+ """Represents an override of a certain checkpkg tag.
+
+ It's similar to checkpkg.CheckpkgTag, but serves a different purpose.
+ """
+
+ def __init__(self, pkgname, tag_name, tag_info):
+ self.pkgname = pkgname
+ self.tag_name = tag_name
+ self.tag_info = tag_info
+
+ def __repr__(self):
+ return (u"Override(%s, %s, %s)"
+ % (self.pkgname, self.tag_name, self.tag_info))
+
+ def DoesApply(self, tag):
+ """Figures out if this override applies to the given tag."""
+ basket_a = {}
+ basket_b = {}
+ if self.pkgname:
+ basket_a["pkgname"] = self.pkgname
+ basket_b["pkgname"] = tag.pkgname
+ if self.tag_info:
+ basket_a["tag_info"] = self.tag_info
+ basket_b["tag_info"] = tag.tag_info
+ basket_a["tag_name"] = self.tag_name
+ basket_b["tag_name"] = tag.tag_name
+ return basket_a == basket_b
+
+def ParseOverrideLine(line):
+ level_1 = line.split(":")
+ if len(level_1) > 1:
+ pkgname = level_1[0]
+ data_1 = level_1[1]
+ else:
+ pkgname = None
+ data_1 = level_1[0]
+ level_2 = re.split(WS_RE, data_1.strip())
+ if len(level_2) > 1:
+ tag_name = level_2[0]
+ tag_info = " ".join(level_2[1:])
+ else:
+ tag_name = level_2[0]
+ tag_info = None
+ return Override(pkgname, tag_name, tag_info)
+
+
+def ApplyOverrides(error_tags, overrides):
+ """Filters out all the error tags that overrides apply to.
+
+ O(N * M), but N and M are always small.
+ """
+ tags_after_overrides = []
+ for tag in error_tags:
+ override_applies = False
+ for override in overrides:
+ if override.DoesApply(tag):
+ override_applies = True
+ 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-git/lib/python/checkpkg_test.py
===================================================================
--- csw/mgar/gar/v2-git/lib/python/checkpkg_test.py 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/lib/python/checkpkg_test.py 2010-02-20 11:24:28 UTC (rev 8698)
@@ -5,6 +5,7 @@
import mox
import difflib
import checkpkg
+import opencsw
import testdata.checkpkg_test_data_CSWmysql51rt as d1
import testdata.checkpkg_test_data_CSWmysql51client as d2
import testdata.checkpkg_test_data_CSWmysql51 as d3
@@ -150,7 +151,7 @@
def testMissingDeps(self):
# This tends to report itself...
- expected = set([u'SUNWgss'])
+ expected = set([])
self.assertEquals(expected, self.missing_deps)
@@ -556,8 +557,8 @@
missing_deps = set([u'SUNWgss', u'*SUNWlxsl'])
surplus_deps = set(['CSWsudo', 'CSWlibxslt'])
orphan_sonames = set([u'libm.so.2'])
- testdata = (missing_deps, surplus_deps, orphan_sonames)
- checker = checkpkg.CheckpkgBase("/tmp/nonexistent", "CSWfoo")
+ testdata = ("CSWfoo", missing_deps, surplus_deps, orphan_sonames)
+ checker = opencsw.DirectoryFormatPackage("/tmp/nonexistent/CSWfoo")
expected = u"""# CSWfoo:
# SUGGESTION: you may want to add some or all of the following as depends:
# (Feel free to ignore SUNW or SPRO packages)
@@ -569,21 +570,151 @@
# The following required sonames would not be found at runtime:
# ! libm.so.2
"""
- result = checker.FormatDepsReport(*testdata)
+ result = checkpkg.FormatDepsReport(*testdata)
self.AssertTextEqual(result, expected)
def testNone(self):
missing_deps = set([])
surplus_deps = set([])
orphan_sonames = set([])
- testdata = (missing_deps, surplus_deps, orphan_sonames)
- checker = checkpkg.CheckpkgBase("/tmp/nonexistent", "CSWfoo")
- expected = u"""# CSWfoo:
-# + Dependencies of CSWfoo look good.
-"""
- result = checker.FormatDepsReport(*testdata)
+ testdata = ("CSWfoo", missing_deps, surplus_deps, orphan_sonames)
+ checker = opencsw.DirectoryFormatPackage("/tmp/nonexistent/CSWfoo")
+ expected = u""
+ result = checkpkg.FormatDepsReport(*testdata)
self.AssertTextEqual(result, expected)
+class CheckpkgTagsUnitTest(unittest.TestCase):
+
+ def test_1(self):
+ m = checkpkg.CheckpkgManager("testname", "/tmp", ["CSWfoo"])
+ tags = {
+ "CSWfoo": [
+ checkpkg.CheckpkgTag("CSWfoo", "foo-tag", "foo-info"),
+ ],
+ }
+ screen_report, tags_report = m.FormatReports(tags)
+ expected = u'# Tags reported by testname module\nCSWfoo: foo-tag foo-info\n'
+ self.assertEqual(expected, tags_report)
+
+ def test_2(self):
+ m = checkpkg.CheckpkgManager("testname", "/tmp", ["CSWfoo"])
+ tags = {
+ "CSWfoo": [
+ checkpkg.CheckpkgTag("CSWfoo", "foo-tag", "foo-info"),
+ checkpkg.CheckpkgTag("CSWfoo", "bar-tag", "bar-info"),
+ checkpkg.CheckpkgTag("CSWfoo", "baz-tag"),
+ ],
+ }
+ screen_report, tags_report = m.FormatReports(tags)
+ expected = (u'# Tags reported by testname module\n'
+ u'CSWfoo: foo-tag foo-info\n'
+ u'CSWfoo: bar-tag bar-info\n'
+ u'CSWfoo: baz-tag\n')
+ self.assertEqual(expected, tags_report)
+
+ def testParseTagLine1(self):
+ line = "foo-tag"
+ self.assertEquals((None, "foo-tag", None), checkpkg.ParseTagLine(line))
+
+ def testParseTagLine2(self):
+ line = "CSWfoo: foo-tag"
+ self.assertEquals(("CSWfoo", "foo-tag", None), checkpkg.ParseTagLine(line))
+
+ def testParseTagLine3(self):
+ line = "CSWfoo: foo-tag foo-info"
+ self.assertEquals(("CSWfoo", "foo-tag", "foo-info"), checkpkg.ParseTagLine(line))
+
+ def testParseTagLine4(self):
+ line = "CSWfoo: foo-tag foo-info1 foo-info2"
+ self.assertEquals(("CSWfoo", "foo-tag", "foo-info1 foo-info2"), checkpkg.ParseTagLine(line))
+
+
+class ParseOverrideLineUnitTest(unittest.TestCase):
+
+ def setUp(self):
+ line1 = "CSWfoo: foo-override"
+ line2 = "CSWfoo: foo-override foo-info"
+ line3 = "CSWfoo: foo-override foo-info-1 foo-info-2"
+ self.o1 = checkpkg.ParseOverrideLine(line1)
+ self.o2 = checkpkg.ParseOverrideLine(line2)
+ self.o3 = checkpkg.ParseOverrideLine(line3)
+
+ def test_ParseOverridesLine1(self):
+ self.assertEqual("CSWfoo", self.o1.pkgname)
+
+ def test_ParseOverridesLine2(self):
+ self.assertEqual("foo-override", self.o1.tag_name)
+
+ def test_ParseOverridesLine3(self):
+ self.assertEqual(None, self.o1.tag_info)
+
+ def test_ParseOverridesLine4(self):
+ self.assertEqual("foo-info", self.o2.tag_info)
+
+ def test_ParseOverridesLine5(self):
+ self.assertEqual("CSWfoo", self.o3.pkgname)
+
+ def test_ParseOverridesLine6(self):
+ self.assertEqual("foo-override", self.o3.tag_name)
+
+ def test_ParseOverridesLine7(self):
+ self.assertEqual("foo-info-1 foo-info-2", self.o3.tag_info)
+
+
+class ApplyOverridesUnitTest(unittest.TestCase):
+
+ # This would be better, more terse. But requires metaclasses.
+ DATA_1 = (
+ (None, 'tag1', 'info1', None, 'tag1', 'info1', None),
+ )
+
+ def test_1a(self):
+ """One tag, no overrides."""
+ tags = [checkpkg.CheckpkgTag("CSWfoo", "foo-tag")]
+ overrides = []
+ self.assertEqual(tags, checkpkg.ApplyOverrides(tags, overrides))
+
+ def test_1b(self):
+ """One override, matching by tag name only."""
+ tags = [checkpkg.CheckpkgTag("CSWfoo", "foo-tag")]
+ overrides = [checkpkg.Override(None, "foo-tag", None)]
+ self.assertEqual([], checkpkg.ApplyOverrides(tags, overrides))
+
+ def test_1c(self):
+ """One override, matching by tag name only, no pkgname."""
+ tags = [checkpkg.CheckpkgTag("CSWfoo", "foo-tag")]
+ overrides = [checkpkg.Override(None, "foo-tag", None)]
+ self.assertEqual([], checkpkg.ApplyOverrides(tags, overrides))
+
+ def test_2(self):
+ """One override, matching by tag name and tag info, no pkgname."""
+ tags = [checkpkg.CheckpkgTag("CSWfoo", "foo-tag")]
+ overrides = [checkpkg.Override(None, "foo-tag", None)]
+ self.assertEqual([], checkpkg.ApplyOverrides(tags, overrides))
+
+ def test_3(self):
+ """One override, matching by tag name, mismatching tag info, no pkgname."""
+ tags = [checkpkg.CheckpkgTag("CSWfoo", "foo-tag", "tag-info-1")]
+ overrides = [checkpkg.Override(None, "foo-tag", "tag-info-2")]
+ self.assertEqual(tags, checkpkg.ApplyOverrides(tags, overrides))
+
+ def test_4(self):
+ tags = [checkpkg.CheckpkgTag("CSWfoo", "foo-tag", "tag-info-1")]
+ overrides = [checkpkg.Override(None, "foo-tag", "tag-info-1")]
+ self.assertEqual([], checkpkg.ApplyOverrides(tags, overrides))
+
+ def test_5(self):
+ tags = [checkpkg.CheckpkgTag("CSWfoo", "foo-tag", "tag-info-1")]
+ overrides = [checkpkg.Override("CSWfoo", "foo-tag", "tag-info-1")]
+ self.assertEqual([], checkpkg.ApplyOverrides(tags, overrides))
+
+ def test_5(self):
+ """Pkgname mismatch."""
+ tags = [checkpkg.CheckpkgTag("CSWfoo", "foo-tag", "tag-info-1")]
+ overrides = [checkpkg.Override("CSWbar", "foo-tag", "tag-info-1")]
+ self.assertEqual(tags, checkpkg.ApplyOverrides(tags, overrides))
+
+
if __name__ == '__main__':
unittest.main()
Modified: csw/mgar/gar/v2-git/lib/python/opencsw.py
===================================================================
--- csw/mgar/gar/v2-git/lib/python/opencsw.py 2010-02-20 08:31:40 UTC (rev 8697)
+++ csw/mgar/gar/v2-git/lib/python/opencsw.py 2010-02-20 11:24:28 UTC (rev 8698)
@@ -15,6 +15,7 @@
import copy
import datetime
import difflib
+import hashlib
import logging
import os
import os.path
@@ -23,6 +24,7 @@
import subprocess
import tempfile
import urllib2
+import checkpkg
ARCHITECTURES = ["i386", "sparc", "all"]
MAJOR_VERSION = "major version"
@@ -57,14 +59,13 @@
EMAIL_TMPL = """From: %(from)s
To: %(to)s
-Cc: %(cc)s
-Date: %(date)s
+%(optional_cc)sDate: %(date)s
Subject: newpkgs %(pkgnames)s
%(body)s
--
-$Id$
+Generated by submitpkg, $Rev$.
"""
@@ -209,7 +210,7 @@
for line in catalog_source:
# Working around the GPG signature
if line.startswith("#"): continue
- if "BEGIN PGP SIGNED MESSAGE" in line: continue
+ if "BEGIN PGP SIGNED MESSAGE" in line: continue
if line.startswith("Hash:"): continue
if len(line.strip()) <= 0: continue
if "BEGIN PGP SIGNATURE" in line: break
@@ -272,7 +273,9 @@
self.pkgnames = pkgnames
self.paths = paths
self.release_mgr = u"%s <%s>" % (release_mgr_name, release_mgr_email)
- self.release_cc = u"%s" % release_cc
+ self.release_cc = release_cc
+ if self.release_cc:
+ self.release_cc = unicode(release_cc)
def FormatMail(self):
body_list = ["The following package files are ready to be released:"]
@@ -317,14 +320,17 @@
body_list.extend(msg)
body_list.append("")
body = "\n".join(body_list)
+ # TODO: This needs to be rewritten using Cheetah
d = {
'from': self.sender,
'to': self.release_mgr,
- 'cc': self.release_cc,
+ 'optional_cc': '',
'pkgnames': ", ".join(self.pkgnames),
'body': body,
'date': datetime.datetime.now(),
}
+ if self.release_cc:
+ d['optional_cc'] = "cc: %s\n" % self.release_cc
mail_text = EMAIL_TMPL % d
return mail_text
@@ -342,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
@@ -358,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_")
@@ -394,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.
+ """
@@ 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