[csw-devel] SF.net SVN: gar:[8164] csw/mgar
wahwah at users.sourceforge.net
wahwah at users.sourceforge.net
Mon Jan 25 12:26:35 CET 2010
Revision: 8164
http://gar.svn.sourceforge.net/gar/?rev=8164&view=rev
Author: wahwah
Date: 2010-01-25 11:26:34 +0000 (Mon, 25 Jan 2010)
Log Message:
-----------
mGAR v2-dirpackage: Static build tests.
Added Paths:
-----------
csw/mgar/gar/v2-dirpackage/lib/
csw/mgar/gar/v2-dirpackage/lib/python/
csw/mgar/gar/v2-dirpackage/lib/python/opencsw.py
csw/mgar/gar/v2-dirpackage/tests/
csw/mgar/gar/v2-dirpackage/tests/gartest.py
csw/mgar/gar/v2-dirpackage/tests/run_tests.py
csw/mgar/gar/v2-dirpackage/tests/static/
csw/mgar/gar/v2-dirpackage/tests/static/example/
csw/mgar/gar/v2-dirpackage/tests/static/example/Makefile
csw/mgar/gar/v2-dirpackage/tests/static/example/checksums
csw/mgar/gar/v2-dirpackage/tests/static/example/gar
Removed Paths:
-------------
csw/mgar/gar/v2-dirpackage/tests/gartest.py
csw/mgar/pkg/tests/gartest.py
csw/mgar/pkg/tests/run_tests.py
Added: csw/mgar/gar/v2-dirpackage/lib/python/opencsw.py
===================================================================
--- csw/mgar/gar/v2-dirpackage/lib/python/opencsw.py (rev 0)
+++ csw/mgar/gar/v2-dirpackage/lib/python/opencsw.py 2010-01-25 11:26:34 UTC (rev 8164)
@@ -0,0 +1,718 @@
+#!/opt/csw/bin/python2.6
+# coding=utf-8
+#
+# $Id$
+#
+# vim:set sw=2 ts=2 sts=2 expandtab:
+#
+# Copyright (c) 2009 OpenCSW
+# Author: Maciej Bliziński
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License version 2 as published by the
+# Free Software Foundation.
+
+import copy
+import datetime
+import difflib
+import logging
+import os
+import os.path
+import re
+import shutil
+import subprocess
+import tempfile
+import urllib2
+
+ARCHITECTURES = ["i386", "sparc", "all"]
+MAJOR_VERSION = "major version"
+MINOR_VERSION = "minor version"
+PATCHLEVEL = "patchlevel"
+REVISION = "revision"
+OTHER_VERSION_INFO = "other version info"
+NEW_PACKAGE = "new package"
+NO_VERSION_CHANGE = "no version change"
+REVISION_ADDED = "revision number added"
+PKG_URL_TMPL = "http://www.opencsw.org/packages/%s"
+CATALOG_URL = "http://mirror.opencsw.org/opencsw/current/i386/5.10/catalog"
+ADMIN_FILE_CONTENT = """
+basedir=default
+runlevel=nocheck
+conflict=nocheck
+setuid=nocheck
+action=nocheck
+partial=nocheck
+instance=unique
+idepend=quit
+rdepend=quit
+space=quit
+authentication=nocheck
+networktimeout=10
+networkretries=5
+keystore=/var/sadm/security
+proxy=
+"""
+EMAIL_TMPL = """From: %(from)s
+To: %(to)s
+Cc: %(cc)s
+Date: %(date)s
+Subject: newpkgs %(pkgnames)s
+
+%(body)s
+
+--
+$Id$
+"""
+
+
+class Error(Exception):
+ pass
+
+
+class PackageError(Error):
+ pass
+
+
+def ParsePackageFileName(p):
+ bits = p.split("-")
+ catalogname = bits[0]
+ version, version_info, revision_info = ParseVersionString(bits[1])
+ data = {
+ 'catalogname': catalogname,
+ 'full_version_string': bits[1],
+ 'version': version,
+ 'version_info': version_info,
+ 'revision_info': revision_info,
+ }
+ return data
+
+def ParseVersionString(s):
+ version_bits = re.split("_|,", s)
+ version_str = version_bits[0]
+ revision_bits = version_bits[1:]
+ revision_info = {}
+ version_info = {}
+ version_number_bits = version_str.split(".")
+ version_info[MAJOR_VERSION] = version_number_bits[0]
+ if len(version_number_bits) >= 2:
+ version_info[MINOR_VERSION] = version_number_bits[1]
+ if len(version_number_bits) >= 3:
+ version_info[PATCHLEVEL] = version_number_bits[2]
+ for version_bit in revision_bits:
+ if "=" in version_bit:
+ (var_name, var_value) = version_bit.split("=")
+ revision_info[var_name] = var_value
+ else:
+ if not "extra_strings" in revision_info:
+ revision_info["extra_strings"] = []
+ revision_info["extra_strings"].append(version_bit)
+ return version_str, version_info, revision_info
+
+
+class CatalogBasedOpencswPackage(object):
+
+ catalog_downloaded = False
+
+ def __init__(self, catalogname):
+ self.catalogname = catalogname
+
+ def IsOnTheWeb(self):
+ url = PKG_URL_TMPL % self.catalogname
+ logging.debug("Opening %s", repr(url))
+ package_page = urllib2.urlopen(url)
+ html = package_page.read()
+ # Since beautifulsoup is not installed on the buildfarm yet, a quirk in
+ # package page display is going to be used.
+ package_not_in_mantis_pattern = u"cannot find maintainer"
+ return html.find(package_not_in_mantis_pattern) >= 0
+
+ def IsNew(self):
+ return not self.IsOnTheWeb()
+
+ def UpgradeType(self, new_version_string):
+ """What kind of upgrade would it be if the new version was X.
+
+ This function contains ugly logic. It has many unit tests to prove that it
+ does the right thing.
+
+ Args:
+ New (candidate) version string
+
+ Returns:
+ Revision type, message, (old_data, new_data)
+ """
+ (new_version,
+ new_version_info,
+ new_revision_info) = ParseVersionString(new_version_string)
+ catalog_data = self.GetCatalogPkgData()
+ if not catalog_data:
+ return (NEW_PACKAGE,
+ "/dev/null -> %s" % new_version_string,
+ (None, new_version_string))
+ cat_version_info = catalog_data["version_info"]
+ levels = (MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL)
+ for level in levels:
+ if level in cat_version_info and level in new_version_info:
+ if (cat_version_info[level] != new_version_info[level]):
+ versions = (catalog_data["full_version_string"], new_version_string)
+ msg = "%s --> %s" % versions
+ return level, msg, versions
+ cat_rev_info = catalog_data["revision_info"]
+ for rev_kw in new_revision_info:
+ if rev_kw in cat_rev_info:
+ if cat_rev_info[rev_kw] != new_revision_info[rev_kw]:
+ msg = "%s: %s --> %s" % (rev_kw,
+ cat_rev_info[rev_kw],
+ new_revision_info[rev_kw])
+ versions = cat_rev_info[rev_kw], new_revision_info[rev_kw]
+ return REVISION, msg, versions
+ else:
+ # This revision info is missing from the old package
+ msg = "new tag %s: %s" % (repr(rev_kw),
+ new_revision_info[rev_kw])
+ return REVISION_ADDED, msg, (None, new_revision_info[rev_kw])
+ if (catalog_data["version"] == new_version
+ and
+ catalog_data["revision_info"] == new_revision_info):
+ return NO_VERSION_CHANGE, "no", (new_version, new_version)
+ return OTHER_VERSION_INFO, "other", (None, None)
+
+ @classmethod
+ def LazyDownloadCatalogData(cls, catalog_source=None):
+ if not cls.catalog_downloaded:
+ cls.DownloadCatalogData(catalog_source)
+ cls.catalog_downloaded = True
+
+ @classmethod
+ def DownloadCatalogData(cls, catalog_source):
+ """Downloads catalog data."""
+ logging.debug("Downloading catalog data from %s.", repr(CATALOG_URL))
+ if not catalog_source:
+ catalog_source = urllib2.urlopen(CATALOG_URL)
+ cls.catalog = {}
+ for line in catalog_source:
+ # Working around the GPG signature
+ if line.startswith("#"): 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
+ fields = re.split(r"\s+", line)
+ try:
+ cls.catalog[fields[0]] = ParsePackageFileName(fields[3])
+ except IndexError, e:
+ print repr(line)
+ print fields
+ print e
+ raise
+
+ @classmethod
+ def _GetCatalogPkgData(cls, catalogname):
+ cls.LazyDownloadCatalogData()
+ if catalogname in cls.catalog:
+ return cls.catalog[catalogname]
+ else:
+ return None
+
+ def GetCatalogPkgData(self):
+ """A wrapper for the classmethod _GetCatalogPkgData, supplying the catalogname."""
+ return self._GetCatalogPkgData(self.catalogname)
+
+
+class StagingDir(object):
+ """Represents a staging directory."""
+
+ def __init__(self, dir_path):
+ self.dir_path = dir_path
+
+ def GetLatest(self, software, architectures=ARCHITECTURES):
+ files = os.listdir(self.dir_path)
+ package_files = []
+ for a in architectures:
+ relevant_pkgs = sorted(shutil.fnmatch.filter(files,
+ "*-%s-*.pkg.gz" % a))
+ relevant_pkgs = sorted(shutil.fnmatch.filter(relevant_pkgs,
+ "%s-*.pkg.gz" % software))
+ if relevant_pkgs:
+ package_files.append(relevant_pkgs[-1])
+ if not package_files:
+ raise PackageError("Could not find %s in %s" % (software, self.dir_path))
+ logging.debug("The latest packages %s in %s are %s",
+ repr(software),
+ repr(self.dir_path),
+ repr(package_files))
+ return [os.path.join(self.dir_path, x) for x in package_files]
+
+
+class NewpkgMailer(object):
+
+ def __init__(self, pkgnames, paths,
+ release_mgr_name,
+ release_mgr_email,
+ sender_name,
+ sender_email,
+ release_cc):
+ self.sender = u"%s <%s>" % (sender_name, sender_email)
+ 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
+
+ def FormatMail(self):
+ body_list = ["The following package files are ready to be released:"]
+ body_list.append("")
+ # Gathering package information, grouping packages that are upgraded
+ # together.
+ pkgs_data = {}
+ for p in self.paths:
+ base_file_name = os.path.split(p)[1]
+ catalogname = base_file_name.split("-")[0]
+ pkg = CatalogBasedOpencswPackage(catalogname)
+ new_data = ParsePackageFileName(base_file_name)
+ new_version_str = new_data["full_version_string"]
+ catalog_data = pkg.GetCatalogPkgData()
+ if catalog_data:
+ catalog_version_str = catalog_data["full_version_string"]
+ else:
+ catalog_version_str = "package not in the catalog"
+ upgrade_type, upgrade_msg, versions = pkg.UpgradeType(new_version_str)
+ pkgs_data_key = (upgrade_type, upgrade_msg, versions)
+ if pkgs_data_key not in pkgs_data:
+ pkgs_data[pkgs_data_key] = []
+ pkg.srv4path = p
+ pkg.cat_version_str = catalog_version_str
+ pkg.new_version_str = new_version_str
+ pkgs_data[pkgs_data_key].append(pkg)
+ # Formatting grouped packages:
+ for upgrade_type, upgrade_msg, versions in pkgs_data:
+ msg = []
+ pkgs = pkgs_data[(upgrade_type, upgrade_msg, versions)]
+ group_name = CatalogNameGroupName([pkg.catalogname for pkg in pkgs])
+ if upgrade_type == NEW_PACKAGE:
+ msg.append("* %s: %s" % (upgrade_type, group_name))
+ elif upgrade_type == NO_VERSION_CHANGE:
+ msg.append("* WARNING: no version change of %s" % group_name)
+ else:
+ msg.append("* %s: %s upgrade" % (group_name, upgrade_type))
+ msg.append(" - from: %s" % versions[0])
+ msg.append(" - to: %s" % versions[1])
+ for pkg in pkgs:
+ msg.append(" + %s" % os.path.split(pkg.srv4path)[1])
+ body_list.extend(msg)
+ body_list.append("")
+ body = "\n".join(body_list)
+ d = {
+ 'from': self.sender,
+ 'to': self.release_mgr,
+ 'cc': self.release_cc,
+ 'pkgnames': ", ".join(self.pkgnames),
+ 'body': body,
+ 'date': datetime.datetime.now(),
+ }
+ mail_text = EMAIL_TMPL % d
+ return mail_text
+
+ def GetEditorName(self, env):
+ editor = "/opt/csw/bin/vim"
+ if "EDITOR" in env:
+ editor = env["EDITOR"]
+ if "VISUAL" in env:
+ editor = env["VISUAL"]
+ return editor
+
+
+class ShellMixin(object):
+
+ def ShellCommand(self, args, quiet=False):
+ logging.debug("Calling: %s", repr(args))
+ if quiet:
+ sub_stdout = subprocess.PIPE
+ sub_stderr = subprocess.PIPE
+ else:
+ sub_stdout = None
+ sub_stderr = None
+ retcode = subprocess.call(args,
+ stdout=sub_stdout,
+ stderr=sub_stderr)
+ if retcode:
+ raise Error("Running %s has failed." % repr(args))
+ return retcode
+
+
+class CswSrv4File(ShellMixin, object):
+ """Represents a package in the srv4 format (pkg)."""
+
+ def __init__(self, pkg_path):
+ self.pkg_path = pkg_path
+ self.workdir = None
+ self.gunzipped_path = None
+ self.transformed = False
+ self.dir_format_pkg = None
+
+ def GetWorkDir(self):
+ if not self.workdir:
+ self.workdir = tempfile.mkdtemp(prefix="pkg_")
+ fd = open(os.path.join(self.workdir, "admin"), "w")
+ fd.write(ADMIN_FILE_CONTENT)
+ fd.close()
+ return self.workdir
+
+ def GetAdminFilePath(self):
+ return os.path.join(self.GetWorkDir(), "admin")
+
+ def GetGunzippedPath(self):
+ gzip_suffix = ".gz"
+ pkg_suffix = ".pkg"
+ if not self.gunzipped_path:
+ if self.pkg_path.endswith("%s%s" % (pkg_suffix, gzip_suffix)):
+ base_name_gz = os.path.split(self.pkg_path)[1]
+ shutil.copy(self.pkg_path, self.GetWorkDir())
+ self.pkg_path = os.path.join(self.GetWorkDir(), base_name_gz)
+ args = ["gunzip", "-f", self.pkg_path]
+ retcode = self.ShellCommand(args)
+ self.gunzipped_path = self.pkg_path[:(-len(gzip_suffix))]
+ elif self.pkg_path.endswith(pkg_suffix):
+ self.gunzipped_path = self.pkg_path
+ else:
+ raise Error("The file name should end in either "
+ "%s or %s." % (gzip_suffix, pkg_suffix))
+ return self.gunzipped_path
+
+ def TransformToDir(self):
+ if not self.transformed:
+ args = ["pkgtrans", "-a", self.GetAdminFilePath(),
+ self.GetGunzippedPath(), self.GetWorkDir(), "all"]
+ retcode = self.ShellCommand(args, quiet=True)
+ dirs = self.GetDirs()
+ if len(dirs) != 1:
+ raise Error("Need exactly one package in the package stream: "
+ "%s." % (dirs))
+ self.dir_format_pkg = DirectoryFormatPackage(dirs[0])
+ self.transformed = True
+
+ def GetDirFormatPkg(self):
+ self.TransformToDir(self)
+ return self.dir_format_pkg
+
+ def GetDirs(self):
+ paths = os.listdir(self.GetWorkDir())
+ dirs = []
+ for p in paths:
+ abspath = os.path.join(self.GetWorkDir(), p)
+ if os.path.isdir(abspath):
+ dirs.append(abspath)
+ return dirs
+
+ def GetPkgmap(self, analyze_permissions, strip=None):
+ dir_format_pkg = self.GetDirFormatPkg()
+ return dir_format_pkg.GetPkgmap(analyze_permissions, strip)
+
+ def __del__(self):
+ if self.workdir:
+ logging.debug("Removing %s", repr(self.workdir))
+ shutil.rmtree(self.workdir)
+
+
+def ParsePkginfo(lines):
+ """Parses a pkginfo data."""
+ d = {}
+ for line in lines:
+ try:
+ # Can't use split, because there might be multiple '=' characters.
+ line = line.strip()
+ # Skip empty and commented lines
+ if not line: continue
+ if line.startswith("#"): continue
+ var_name, var_value = line.split("=", 1)
+ d[var_name] = var_value
+ except ValueError, e:
+ raise PackageError("Can't parse %s: %s" % (repr(line), e))
+ return d
+
+
+def PkgnameToCatName(pkgname):
+ """Creates a catalog name based on the pkgname.
+
+ SUNWbash --> sunw_bash
+ SUNWbashS --> sunw_bash_s
+ SUNWPython --> sunw_python
+
+ Incomprehensible, but unit tested!
+ """
+ known_prefixes = ["SUNW", "FJSV", "CSW"]
+ for prefix in known_prefixes:
+ if pkgname.startswith(prefix):
+ unused, tmp_prefix, the_rest = pkgname.partition(prefix)
+ pkgname = tmp_prefix + "_" + the_rest
+ return "_".join(SplitByCase(pkgname))
+
+
+def SplitByCase(s):
+ def CharType(c):
+ if c.isalnum():
+ if c.isupper():
+ return 1
+ else:
+ return 2
+ else:
+ return 3
+ chartype_list = [CharType(x) for x in s]
+ neighbors = zip(chartype_list, chartype_list[1:])
+ casechange = [False] + [x != y for x, y in neighbors]
+ str_list = [(cc * "_") + l.lower() for l, cc in zip(s, casechange)]
+ s2 = "".join(str_list)
+ return re.findall(r"[a-z]+", s2)
+
+
+def CatalogNameGroupName(catalogname_list):
+ """Uses heuristics to guess the common name of a group of packages."""
+ catalogname_list = copy.copy(catalogname_list)
+ if len(catalogname_list) == 1:
+ return catalogname_list[0]
+ current_substring = catalogname_list.pop()
+ while catalogname_list and current_substring:
+ substring_set = LongestCommonSubstring(current_substring,
+ catalogname_list.pop())
+ if substring_set:
+ current_substring = list(substring_set)[0]
+ if len(current_substring) >= 2:
+ return current_substring
+ return "various packages"
+
+
+def LongestCommonSubstring(S, T):
+ """Stolen from Wikibooks
+
+ http://en.wikibooks.org/wiki/Algorithm_Implementation/Strings/Longest_common_substring#Python"""
+ m = len(S); n = len(T)
+ L = [[0] * (n+1) for i in xrange(m+1)]
+ LCS = set()
+ longest = 0
+ for i in xrange(m):
+ for j in xrange(n):
+ if S[i] == T[j]:
+ v = L[i][j] + 1
+ L[i+1][j+1] = v
+ if v > longest:
+ longest = v
+ LCS = set()
+ if v == longest:
+ LCS.add(S[i-v+1:i+1])
+ return LCS
+
+
+def PkginfoToSrv4Name(pkginfo_dict):
+ SRV4_FN_TMPL = "%(catalog_name)s-%(version)s-%(osver)s-%(arch)s-%(tag)s.pkg"
+ fn_data = {}
+ fn_data["catalog_name"] = PkgnameToCatName(pkginfo_dict["PKG"])
+ fn_data["version"] = pkginfo_dict["VERSION"]
+ # os_version = pkginfo_dict["SUNW_PRODVERS"].split("/", 1)[0]
+ # fn_data["osver"] = pkginfo_dict["SUNW_PRODNAME"] + os_version
+ fn_data["osver"] = "SunOS5.10" # Hardcoded, because the original data contains
+ # trash.
+ fn_data["arch"] = pkginfo_dict["ARCH"]
+ fn_data["tag"] = "SUNW"
+ return SRV4_FN_TMPL % fn_data
+
+
+class DirectoryFormatPackage(ShellMixin, object):
+
+ def __init__(self, directory):
+ self.directory = directory
+ self.pkginfo_dict = None
+
+ def GetParsedPkginfo(self):
+ if not self.pkginfo_dict:
+ pkginfo_fd = open(self.GetPkginfoFilename(), "r")
+ self.pkginfo_dict = ParsePkginfo(pkginfo_fd)
+ pkginfo_fd.close()
+ return self.pkginfo_dict
+
+ def GetSrv4FileName(self):
+ """Guesses the Srv4FileName based on the package directory contents."""
+ return PkginfoToSrv4Name(self.GetParsedPkginfo())
+
+ def ToSrv4(self, target_dir):
+ target_file_name = self.GetSrv4FileName()
+ target_path = os.path.join(target_dir, target_file_name)
+ if os.path.exists(target_path):
+ return target_path
+ pkg_container_dir, pkg_dir = os.path.split(self.directory)
+ if not os.path.isdir(target_dir):
+ os.makedirs(target_dir)
+ args = ["pkgtrans", "-s", pkg_container_dir, target_path, pkg_dir]
+ self.ShellCommand(args, quiet=True)
+ args = ["gzip", "-f", target_path]
+ self.ShellCommand(args, quiet=True)
+ return target_path
+
+ def GetPkgmap(self, analyze_permissions=False, strip=None):
+ fd = open(os.path.join(self.directory, "pkgmap"), "r")
+ return Pkgmap(fd, analyze_permissions, strip)
+
+ def SetPkginfoEntry(self, key, value):
+ pkginfo = self.GetParsedPkginfo()
+ logging.debug("Setting %s to %s", repr(key), repr(value))
+ pkginfo[key] = value
+ self.WritePkginfo(pkginfo)
+ pkgmap_path = os.path.join(self.directory, "pkgmap")
+ pkgmap_fd = open(pkgmap_path, "r")
+ new_pkgmap_lines = []
+ pkginfo_re = re.compile("1 i pkginfo")
+ ws_re = re.compile(r"\s+")
+ for line in pkgmap_fd:
+ if pkginfo_re.search(line):
+ fields = ws_re.split(line)
+ # 3: size
+ # 4: sum
+ pkginfo_path = os.path.join(self.directory, "pkginfo")
+ args = ["cksum", pkginfo_path]
+ cksum_process = subprocess.Popen(args, stdout=subprocess.PIPE)
+ stdout, stderr = cksum_process.communicate()
+ cksum_process.wait()
+ size = ws_re.split(stdout)[1]
+ args = ["sum", pkginfo_path]
+ sum_process = subprocess.Popen(args, stdout=subprocess.PIPE)
+ stdout, stderr = sum_process.communicate()
+ sum_process.wait()
+ sum = ws_re.split(stdout)[0]
+ fields[3] = size
+ fields[4] = sum
+ logging.debug("New pkgmap line: %s", fields)
+ line = " ".join(fields)
+ new_pkgmap_lines.append(line.strip())
+ pkgmap_fd.close()
+ # Write that back
+ pkgmap_path_new = pkgmap_path + ".new"
+ logging.debug("Writing back to %s", pkgmap_path_new)
+ pkgmap_fd = open(pkgmap_path_new, "w")
+ pkgmap_fd.write("\n".join(new_pkgmap_lines))
+ pkgmap_fd.close()
+ shutil.move(pkgmap_path_new, pkgmap_path)
+
+ # TODO(maciej): Need to update the relevant line on pkgmap too
+
+ def GetPkginfoFilename(self):
+ return os.path.join(self.directory, "pkginfo")
+
+ def WritePkginfo(self, pkginfo_dict):
+ # Some packages extract read-only. To be sure, change them to be
+ # user-writable.
+ args = ["chmod", "-R", "u+w", self.directory]
+ self.ShellCommand(args)
+ pkginfo_filename = self.GetPkginfoFilename()
+ os.chmod(pkginfo_filename, 0644)
+ pkginfo_fd = open(pkginfo_filename, "w")
+ pkginfo_dict = self.GetParsedPkginfo()
+ for k, v in pkginfo_dict.items():
+ pkginfo_fd.write("%s=%s\n" % (k, pkginfo_dict[k]))
+ pkginfo_fd.close()
+
+ def ResetNameProperty(self):
+ """Sometimes, NAME= contains useless data. This method resets them."""
+ pkginfo_dict = self.GetParsedPkginfo()
+ catalog_name = PkgnameToCatName(pkginfo_dict["PKG"])
+ description = pkginfo_dict["DESC"]
+ pkginfo_name = "%s - %s" % (catalog_name, description)
+ self.SetPkginfoEntry("NAME", pkginfo_name)
+
+class Pkgmap(object):
+
+ def __init__(self, input, permissions=False,
+ strip=None):
+ self.paths = set()
+ self.analyze_permissions = permissions
+ for line in input:
+ fields = re.split(r'\s+', line)
+ if strip:
+ strip_re = re.compile(r"^%s" % strip)
+ fields = [re.sub(strip_re, "", x) for x in fields]
+ logging.debug(fields)
+ line_to_add = None
+ if len(fields) < 2:
+ continue
+ elif fields[1] in ('f', 'd'):
+ line_to_add = fields[3]
+ if self.analyze_permissions:
+ line_to_add += " %s" % fields[4]
+ elif fields[1] in ('s', 'l'):
+ link_from, link_to = fields[3].split("=")
+ line_to_add = "%s --> %s" % (link_from, link_to)
+ if line_to_add:
+ self.paths.add(line_to_add)
+
+
+class PackageComparator(object):
+
+ def __init__(self, file_name_a, file_name_b,
+ permissions=False,
+ strip_a=None,
+ strip_b=None):
+ self.analyze_permissions = permissions
+ self.pkg_a = CswSrv4File(file_name_a)
+ self.pkg_b = CswSrv4File(file_name_b)
+ self.strip_a = strip_a
+ self.strip_b = strip_b
+
+ def Run(self):
+ pkgmap_a = self.pkg_a.GetPkgmap(self.analyze_permissions, strip=self.strip_a)
+ pkgmap_b = self.pkg_b.GetPkgmap(self.analyze_permissions, strip=self.strip_b)
+ diff_ab = difflib.unified_diff(sorted(pkgmap_a.paths),
+ sorted(pkgmap_b.paths),
+ fromfile=self.pkg_a.pkg_path,
+ tofile=self.pkg_b.pkg_path)
+ diff_text = "\n".join(diff_ab)
+ if diff_text:
+ less_proc = subprocess.Popen(["less"], stdin=subprocess.PIPE)
+ less_stdout, less_stderr = less_proc.communicate(input=diff_text)
+ less_proc.wait()
+ else:
+ print "No differences found."
+
+
+class OpencswCatalogBuilder(object):
+
+ def __init__(self, product_dir, catalog_dir):
+ self.product_dir = product_dir
+ self.catalog_dir = catalog_dir
+
+ def Run(self):
+ pkg_dirs = os.listdir(self.product_dir)
+ for pkg_dir in pkg_dirs:
+ pkg_path = os.path.join(self.product_dir, pkg_dir)
+ pkginfo_path = os.path.join(pkg_path, "pkginfo")
+ if (os.path.isdir(pkg_path)
+ and
+ os.path.exists(pkginfo_path)):
+ if not self.Srv4Exists(pkg_path):
+ pkg = None
+ tmpdir = None
+ try:
+ tmpdir = tempfile.mkdtemp(prefix="sunw-pkg-")
+ logging.debug("Copying %s to %s", repr(pkg_path), repr(tmpdir))
+ tmp_pkg_dir = os.path.join(tmpdir, pkg_dir)
+ shutil.copytree(pkg_path, tmp_pkg_dir, symlinks=True)
+ pkg = DirectoryFormatPackage(tmp_pkg_dir)
+ # Replacing NAME= in the pkginfo, setting it to the catalog name.
+ pkg.ResetNameProperty()
+ pkg.ToSrv4(self.catalog_dir)
+ except IOError, e:
+ logging.warn("%s has failed: %s", pkg_path, e)
+ finally:
+ if pkg:
+ del(pkg)
+ if os.path.exists(tmpdir):
+ shutil.rmtree(tmpdir)
+ else:
+ logging.warn("srv4 file for %s already exists, skipping", pkg_path)
+ else:
+ logging.warn("%s is not a directory.", pkg_path)
+
+ def Srv4Exists(self, pkg_dir):
+ pkg = DirectoryFormatPackage(pkg_dir)
+ srv4_name = pkg.GetSrv4FileName()
+ srv4_name += ".gz"
+ srv4_path = os.path.join(self.catalog_dir, srv4_name)
+ result = os.path.exists(srv4_path)
+ logging.debug("Srv4Exists(%s) => %s, %s", pkg_dir, repr(srv4_path), result)
+ return result
Property changes on: csw/mgar/gar/v2-dirpackage/lib/python/opencsw.py
___________________________________________________________________
Added: svn:keywords
+ Id
Deleted: csw/mgar/gar/v2-dirpackage/tests/gartest.py
===================================================================
--- csw/mgar/pkg/tests/gartest.py 2010-01-24 01:31:18 UTC (rev 8133)
+++ csw/mgar/gar/v2-dirpackage/tests/gartest.py 2010-01-25 11:26:34 UTC (rev 8164)
@@ -1,168 +0,0 @@
-# $Id$
-
-import Cheetah.Template
-import shutil
-import tempfile
-import unittest
-import os
-import os.path
-import subprocess
-import opencsw
-
-"""A module used to do end-to-end testing of GAR."""
-
-MAKEFILE_TMPL = """# GAR Makefile generated by $test_id
-#
-GARNAME = $garname
-GARVERSION = $garversion
-CATEGORIES = $profile
-DESCRIPTION = $description
-#if $blurb
-define BLURB
- blurb
-endef
-#end if
-#if $upstream_url
-SPKG_SOURCEURL = $upstream_url
-#end if
-#if $master_sites
-MASTER_SITES = $master_sites
-#end if
-## PATCHFILES =
-## DISTFILES = $(GARNAME)-$(GARVERSION).tar.gz
-## UFILES_REGEX = $(GARNAME)-(\d+(?:\.\d+)*).tar.gz
-## CATALOGNAME =
-## ARCHALL = 0
-## PACKAGES =
-CONFIGURE_SCRIPTS =
-BUILD_SCRIPTS =
-INSTALL_SCRIPTS =
-TEST_SCRIPTS =
-#if $configure_args
-CONFIGURE_ARGS = $configure_args
-#end if
-## BUILD64 =
-include gar/category.mk
-#if $install_files
-post-install-modulated:
-#for filedir_name, directory, file_name, content in $install_files
-\tginstall -m 755 -d \$(DESTDIR)$directory
-\tginstall -m 644 $tmpdir/\$(FILEDIR)/$filedir_name \$(DESTDIR)$directory/$file_name
-#end for
-#end if
-# GAR recipe ends here.
-"""
-TMPDIR_PREFIX = "garpkg"
-DIR_PKG_OUT_DIR = "/home/maciej/spool.5.8-sparc"
-
-class Error(Exception):
- pass
-
-class GarBuild(object):
- """Represents a GAR build.
-
- Can create a GAR build and execute it.
- """
- def __init__(self):
- self.tmpdir = tempfile.mkdtemp(prefix=TMPDIR_PREFIX)
- self.filedir = os.path.join(self.tmpdir, "files")
- self.makefile_filename = os.path.join(self.tmpdir, "Makefile")
- os.mkdir(self.filedir)
- self.install_files = []
- self.built = False
- self.tmpldata = {
- "garname": "testbuild",
- "garsrc": "/home/maciej/src/opencsw/gar/v2-dirpackage",
- "blurb": None,
- "description": u"A test package from %s" % self,
- "profile": "lib",
- "configure_args": "$(DIRPATHS)",
- "upstream_url": "http://www.opencsw.org/",
- "master_sites": None,
- "install_files": self.install_files,
- "garversion": "0.0.1",
- "tmpdir": self.tmpdir,
- "test_id": "$Id$",
- }
- os.symlink(self.tmpldata["garsrc"], os.path.join(self.tmpdir, "gar"))
-
- def WriteGarFiles(self):
- # print "The tmpdir is", self.tmpdir
- for filedir_name, directory, filename, content in self.install_files:
- file_path = os.path.join(self.filedir, filedir_name)
- print "Writing to %s" % file_path
- fp = open(file_path, "w")
- fp.write(content)
- fp.close()
- searchlist = [self.tmpldata]
- t = Cheetah.Template.Template(MAKEFILE_TMPL, searchlist)
- print t
- fp = open(self.makefile_filename, "w")
- fp.write(str(t))
- fp.close()
-
- def Build(self):
- if self.built:
- return 0
- args = ["gmake", "dirpackage"]
- gar_proc = subprocess.Popen(args, cwd=self.tmpdir,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = gar_proc.communicate()
- ret = gar_proc.wait()
- if ret:
- print "ERROR: GAR run has failed."
- self.built = False
- else:
- self.built = True
- return ret
-
- def GetBuiltPackages(self):
- if not self.built:
- raise Error("The packages have not been built yet.")
- args = ["gmake", "pkglist"]
- gar_proc = subprocess.Popen(args, cwd=self.tmpdir, stdout=subprocess.PIPE)
- stdout, stderr = gar_proc.communicate()
- ret = gar_proc.wait()
- pkglist = []
- for line in stdout.splitlines():
- # directory, catalogname, pkgname
- pkglist.append(tuple(line.split("\t")))
- packages = [opencsw.DirectoryFormatPackage(os.path.join(DIR_PKG_OUT_DIR, z)) for x, y, z in pkglist]
- return packages
-
- def AddInstallFile(self, file_path, content):
- filedir_name = file_path.replace("/", "-")
- directory, file_name = os.path.split(file_path)
- self.install_files.append((filedir_name, directory,
- file_name, content))
-
- def __del__(self):
- shutil.rmtree(self.tmpdir)
-
-
-class FooUnitTest(unittest.TestCase):
- """This is the docstring for the FooUnitTest."""
-
- def testSomething(self):
- """This is a doc string for the test method.
-
- You can write more text here.
- """
- mybuild = GarBuild()
- mybuild.tmpldata["garname"] = "blah"
- mybuild.AddInstallFile("/opt/csw/share/foo", "bar!\n")
- mybuild.WriteGarFiles()
- self.assertEquals(0, mybuild.Build())
- packages = mybuild.GetBuiltPackages()
- for pkg in packages:
- print pkg
- print pkg.GetParsedPkginfo()
- # package = mybuild.GetFirstDirFormatPackage()
- # self.assertEqual("blah", package.catalogname)
-
-
-if __name__ == '__main__':
- unittest.main()
-
-# vim:set ts=2 sts=2 sw=2 expandtab:
Copied: csw/mgar/gar/v2-dirpackage/tests/gartest.py (from rev 8134, csw/mgar/pkg/tests/gartest.py)
===================================================================
--- csw/mgar/gar/v2-dirpackage/tests/gartest.py (rev 0)
+++ csw/mgar/gar/v2-dirpackage/tests/gartest.py 2010-01-25 11:26:34 UTC (rev 8164)
@@ -0,0 +1,176 @@
+# $Id$
+
+import Cheetah.Template
+import shutil
+import tempfile
+import unittest
+import os
+import os.path
+import subprocess
+import opencsw
+
+"""A module used to do end-to-end testing of GAR."""
+
+MAKEFILE_TMPL = """# GAR Makefile generated by $test_id
+#for varname in $sorted($garvars)
+$varname = $garvars[$varname]
+#end for
+#if $blurb
+define BLURB
+ blurb
+endef
+#end if
+include gar/category.mk
+#if $install_files
+post-install-modulated:
+#for filedir_name, directory, file_name, content in $install_files
+\tginstall -m 755 -d \$(DESTDIR)$directory
+\tginstall -m 644 \$(FILEDIR)/$filedir_name \$(DESTDIR)$directory/$file_name
+#end for
+#end if
+# GAR recipe ends here.
+"""
+TMPDIR_PREFIX = "gartest-"
+# FIXME: This information should be pulled out from GAR
+DIR_PKG_OUT_DIR = os.path.join(os.environ["HOME"], "spool.5.8-sparc")
+
+class Error(Exception):
+ pass
+
+
+class GarBuild(object):
+
+ def __init__(self):
+ self.built = False
+ self.packages = None
+ self.cleanup = True
+
+ def GetDebugHelp(self):
+ """To be overriden in subclasses."""
+ return ""
+
+ def Build(self):
+ if self.built:
+ return 0
+ args = ["gmake", "dirpackage"]
+ gar_proc = subprocess.Popen(args, cwd=self.tmpdir,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ stdout, stderr = gar_proc.communicate()
+ ret = gar_proc.wait()
+ if ret:
+ print "ERROR: GAR run has failed."
+ print stdout
+ print stderr
+ self.built = False
+ # To allow debugging
+ self.cleanup = False
+ print self.GetDebugHelp()
+ else:
+ self.built = True
+ return ret
+
+ def GetBuiltPackages(self):
+ if not self.built:
+ raise Error("The packages have not been built yet.")
+ args = ["gmake", "pkglist"]
+ gar_proc = subprocess.Popen(args, cwd=self.tmpdir, stdout=subprocess.PIPE)
+ stdout, stderr = gar_proc.communicate()
+ ret = gar_proc.wait()
+ pkglist = []
+ for line in stdout.splitlines():
+ # directory, catalogname, pkgname
+ pkglist.append(tuple(line.split("\t")))
+ self.packages = [
+ opencsw.DirectoryFormatPackage(
+ os.path.join(DIR_PKG_OUT_DIR, z))
+ for x, y, z in pkglist]
+ return self.packages
+
+ def GetFirstBuiltPackage(self):
+ """Returns only the first package. Easy to use."""
+ packages = self.GetBuiltPackages()
+ if packages:
+ return packages[0]
+
+
+class DynamicGarBuild(GarBuild):
+ """Represents a GAR build.
+
+ Can create a GAR build and execute it.
+ """
+ def __init__(self):
+ super(DynamicGarBuild, self).__init__()
+ self.tmpdir = tempfile.mkdtemp(prefix=TMPDIR_PREFIX)
+ self.filedir = os.path.join(self.tmpdir, "files")
+ self.makefile_filename = os.path.join(self.tmpdir, "Makefile")
+ os.mkdir(self.filedir)
+ self.install_files = []
+ self.garvars = {
+ "GARNAME": "testbuild",
+ "DESCRIPTION": u"A test package from %s" % self,
+ "CATEGORIES": "lib",
+ "CONFIGURE_ARGS": "$(DIRPATHS)",
+ "SPKG_SOURCEURL": "http://www.opencsw.org/",
+ "MASTER_SITES": "",
+ "GARVERSION": "0.0.1",
+ "CONFIGURE_SCRIPTS": "",
+ "BUILD_SCRIPTS": "",
+ "TEST_SCRIPTS": "",
+ "INSTALL_SCRIPTS": "",
+ }
+ self.tmpldata = {
+ "garvars": self.garvars,
+ "garsrc": os.path.join(os.getcwd(), ".."),
+ "blurb": None,
+ "install_files": self.install_files,
+ "tmpdir": self.tmpdir,
+ "test_id": "$Id$",
+ }
+ os.symlink(self.tmpldata["garsrc"], os.path.join(self.tmpdir, "gar"))
+
+ def SetGarVariable(self, varname, value):
+ self.garvars[varname] = value
+
+ def WriteGarFiles(self):
+ # print "The tmpdir is", self.tmpdir
+ for filedir_name, directory, filename, content in self.install_files:
+ file_path = os.path.join(self.filedir, filedir_name)
+ print "Writing to %s" % file_path
+ fp = open(file_path, "w")
+ fp.write(content)
+ fp.close()
+ searchlist = [self.tmpldata]
+ t = Cheetah.Template.Template(MAKEFILE_TMPL, searchlist)
+ # For easy debugging, but only until we find a better solution, because it
+ # clutters the screen.
+ print t
+ fp = open(self.makefile_filename, "w")
+ fp.write(str(t))
+ fp.close()
+
+ def AddInstallFile(self, file_path, content):
+ """Creates a file in the package, with the given path and content."""
+ filedir_name = file_path.replace("/", "-")
+ directory, file_name = os.path.split(file_path)
+ self.install_files.append((filedir_name, directory,
+ file_name, content))
+
+ def GetDebugHelp(self):
+ return ("Please look into %s.\n"
+ "Remember to remove it when you're done debugging."
+ % repr(self.tmpdir))
+
+ def __del__(self):
+ if self.cleanup:
+ shutil.rmtree(self.tmpdir)
+
+
+class StaticGarBuild(GarBuild):
+
+ def __init__(self, build_dir):
+ super(StaticGarBuild, self).__init__()
+ self.build_dir = build_dir
+ self.tmpdir = build_dir
+
+# vim:set ts=2 sts=2 sw=2 expandtab:
Copied: csw/mgar/gar/v2-dirpackage/tests/run_tests.py (from rev 8135, csw/mgar/pkg/tests/run_tests.py)
===================================================================
--- csw/mgar/gar/v2-dirpackage/tests/run_tests.py (rev 0)
+++ csw/mgar/gar/v2-dirpackage/tests/run_tests.py 2010-01-25 11:26:34 UTC (rev 8164)
@@ -0,0 +1,44 @@
+#!/opt/csw/bin/python2.6
+# $Id$
+
+import unittest
+import sys
+sys.path.append("../lib/python")
+import gartest
+
+class ExampleEndToEndTest(unittest.TestCase):
+ """An example end-to-end test of GAR."""
+
+ def testPkginfoName(self):
+ """Checks that the GARNAME makes it to the NAME in pkginfo."""
+ mybuild = gartest.DynamicGarBuild()
+ mybuild.SetGarVariable("GARNAME", "foo")
+ mybuild.AddInstallFile("/opt/csw/share/foo", "bar!\n")
+ mybuild.WriteGarFiles()
+ self.assertEquals(0, mybuild.Build())
+ pkg = mybuild.GetFirstBuiltPackage()
+ pkginfo = pkg.GetParsedPkginfo()
+ # By default, the garname should be used to create the catalog name, which
+ # in turn ends up in the NAME field in pkginfo.
+ self.assertTrue(pkginfo["NAME"].startswith("foo"))
+
+
+class StaticBuildTestExample(unittest.TestCase):
+ """An example of a static build.
+
+ This uses a static directory where GAR can be called.
+ """
+
+ def testLooseFiles(self):
+ mybuild = gartest.StaticGarBuild("static/example")
+ mybuild.Build()
+ pkg = mybuild.GetFirstBuiltPackage()
+ pkginfo = pkg.GetParsedPkginfo()
+ # This part would often use "self.assertEqual(<expected>, <actual>)"
+ self.assertTrue(pkginfo["NAME"].startswith("loose"))
+
+
+if __name__ == '__main__':
+ unittest.main()
+
+# vim:set ts=2 sts=2 sw=2 expandtab:
Property changes on: csw/mgar/gar/v2-dirpackage/tests/static/example
___________________________________________________________________
Added: svn:ignore
+ work
gar
Added: csw/mgar/gar/v2-dirpackage/tests/static/example/Makefile
===================================================================
--- csw/mgar/gar/v2-dirpackage/tests/static/example/Makefile (rev 0)
+++ csw/mgar/gar/v2-dirpackage/tests/static/example/Makefile 2010-01-25 11:26:34 UTC (rev 8164)
@@ -0,0 +1,39 @@
+# Copyright 2009 OpenCSW
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+GARNAME = loose-files
+GARVERSION = 1.0
+CATEGORIES = utils
+DESCRIPTION = An example of a package created from loose files.
+define BLURB
+endef
+SPKG_SOURCEURL = http://gar.sf.net
+
+PACKAGES = CSWloosefilesexa
+CATALOGNAME = loose_files_example
+
+# The directory where all the sources are kept. The slash at the end is
+# necessary.
+LOCAL_SRC = /usr/xpg4/
+
+# The list of files to include, relative to LOCAL_SRC
+FILES = bin/grep
+FILES += include/curses.h
+
+MASTER_SITES = $(sort $(addprefix file://$(LOCAL_SRC),$(dir $(FILES))))
+DISTFILES = $(notdir $(FILES))
+
+CONFIGURE_SCRIPTS =
+BUILD_SCRIPTS =
+INSTALL_SCRIPTS = custom
+TEST_SCRIPTS =
+
+include gar/category.mk
+
+install-custom:
+ $(foreach F,$(FILES),ginstall \
+ -d $(DESTDIR)$(prefix)/$(dir $F) \
+ && ginstall $(WORKDIR)/$(notdir $F) \
+ $(DESTDIR)$(prefix)/$(dir $F);)
+ @$(MAKECOOKIE)
Property changes on: csw/mgar/gar/v2-dirpackage/tests/static/example/Makefile
___________________________________________________________________
Added: svn:keywords
+ Id
Added: csw/mgar/gar/v2-dirpackage/tests/static/example/checksums
===================================================================
--- csw/mgar/gar/v2-dirpackage/tests/static/example/checksums (rev 0)
+++ csw/mgar/gar/v2-dirpackage/tests/static/example/checksums 2010-01-25 11:26:34 UTC (rev 8164)
@@ -0,0 +1,2 @@
+d388c5613c830fb4571d0457f53580a0 curses.h
+492eba390abe4fe74c185d0d343c2b81 grep
Added: csw/mgar/gar/v2-dirpackage/tests/static/example/gar
===================================================================
--- csw/mgar/gar/v2-dirpackage/tests/static/example/gar (rev 0)
+++ csw/mgar/gar/v2-dirpackage/tests/static/example/gar 2010-01-25 11:26:34 UTC (rev 8164)
@@ -0,0 +1 @@
+link ../../..
\ No newline at end of file
Property changes on: csw/mgar/gar/v2-dirpackage/tests/static/example/gar
___________________________________________________________________
Added: svn:special
+ *
Deleted: csw/mgar/pkg/tests/gartest.py
===================================================================
--- csw/mgar/pkg/tests/gartest.py 2010-01-25 10:30:29 UTC (rev 8163)
+++ csw/mgar/pkg/tests/gartest.py 2010-01-25 11:26:34 UTC (rev 8164)
@@ -1,144 +0,0 @@
-# $Id$
-
-import Cheetah.Template
-import shutil
-import tempfile
-import unittest
-import os
-import os.path
-import subprocess
-import opencsw
-
-"""A module used to do end-to-end testing of GAR."""
-
-MAKEFILE_TMPL = """# GAR Makefile generated by $test_id
-#for varname in $garvars
-$varname = $garvars[$varname]
-#end for
-#if $blurb
-define BLURB
- blurb
-endef
-#end if
-include gar/category.mk
-#if $install_files
-post-install-modulated:
-#for filedir_name, directory, file_name, content in $install_files
-\tginstall -m 755 -d \$(DESTDIR)$directory
-\tginstall -m 644 $tmpdir/\$(FILEDIR)/$filedir_name \$(DESTDIR)$directory/$file_name
-#end for
-#end if
-# GAR recipe ends here.
-"""
-TMPDIR_PREFIX = "garpkg"
-DIR_PKG_OUT_DIR = "/home/maciej/spool.5.8-sparc"
-
-class Error(Exception):
- pass
-
-class GarBuild(object):
- """Represents a GAR build.
-
- Can create a GAR build and execute it.
- """
- def __init__(self):
- self.packages = None
- self.tmpdir = tempfile.mkdtemp(prefix=TMPDIR_PREFIX)
- self.filedir = os.path.join(self.tmpdir, "files")
- self.makefile_filename = os.path.join(self.tmpdir, "Makefile")
- os.mkdir(self.filedir)
- self.install_files = []
- self.built = False
- self.garvars = {
- "GARNAME": "testbuild",
- "DESCRIPTION": u"A test package from %s" % self,
- "CATEGORIES": "lib",
- "CONFIGURE_ARGS": "$(DIRPATHS)",
- "SPKG_SOURCEURL": "http://www.opencsw.org/",
- "MASTER_SITES": "",
- "GARVERSION": "0.0.1",
- "CONFIGURE_SCRIPTS": "",
- "BUILD_SCRIPTS": "",
- "TEST_SCRIPTS": "",
- "INSTALL_SCRIPTS": "",
- }
- self.tmpldata = {
- "garvars": self.garvars,
- "garsrc": "/home/maciej/src/opencsw/gar/v2-dirpackage",
- "blurb": None,
- "install_files": self.install_files,
- "tmpdir": self.tmpdir,
- "test_id": "$Id$",
- }
- os.symlink(self.tmpldata["garsrc"], os.path.join(self.tmpdir, "gar"))
-
- def SetGarVariable(self, varname, value):
- self.garvars[varname] = value
-
- def WriteGarFiles(self):
- # print "The tmpdir is", self.tmpdir
- for filedir_name, directory, filename, content in self.install_files:
- file_path = os.path.join(self.filedir, filedir_name)
- print "Writing to %s" % file_path
- fp = open(file_path, "w")
- fp.write(content)
- fp.close()
- searchlist = [self.tmpldata]
- t = Cheetah.Template.Template(MAKEFILE_TMPL, searchlist)
- print t
- fp = open(self.makefile_filename, "w")
- fp.write(str(t))
- fp.close()
-
- def Build(self):
- if self.built:
- return 0
- args = ["gmake", "dirpackage"]
- gar_proc = subprocess.Popen(args, cwd=self.tmpdir,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = gar_proc.communicate()
- ret = gar_proc.wait()
- if ret:
- print "ERROR: GAR run has failed."
- print stdout
- print stderr
- self.built = False
- else:
- self.built = True
- return ret
-
- def GetBuiltPackages(self):
- if not self.built:
- raise Error("The packages have not been built yet.")
- args = ["gmake", "pkglist"]
- gar_proc = subprocess.Popen(args, cwd=self.tmpdir, stdout=subprocess.PIPE)
- stdout, stderr = gar_proc.communicate()
- ret = gar_proc.wait()
- pkglist = []
- for line in stdout.splitlines():
- # directory, catalogname, pkgname
- pkglist.append(tuple(line.split("\t")))
- self.packages = [
- opencsw.DirectoryFormatPackage(
- os.path.join(DIR_PKG_OUT_DIR, z))
- for x, y, z in pkglist]
- return self.packages
-
- def GetFirstBuiltPackage(self):
- """Returns only the first package. Easy to use."""
- packages = self.GetBuiltPackages()
- if packages:
- return packages[0]
-
- def AddInstallFile(self, file_path, content):
- """Creates a file in the package, with the given path and content."""
- filedir_name = file_path.replace("/", "-")
- directory, file_name = os.path.split(file_path)
- self.install_files.append((filedir_name, directory,
- file_name, content))
-
- def __del__(self):
- shutil.rmtree(self.tmpdir)
-
-# vim:set ts=2 sts=2 sw=2 expandtab:
Deleted: csw/mgar/pkg/tests/run_tests.py
===================================================================
--- csw/mgar/pkg/tests/run_tests.py 2010-01-25 10:30:29 UTC (rev 8163)
+++ csw/mgar/pkg/tests/run_tests.py 2010-01-25 11:26:34 UTC (rev 8164)
@@ -1,27 +0,0 @@
-#!/opt/csw/bin/python2.6
-# $Id$
-
-import unittest
-import gartest
-
-class ExampleEndToEndTest(unittest.TestCase):
- """An example end-to-end test of GAR."""
-
- def testPkginfoName(self):
- """Checks that the GARNAME makes it to the NAME in pkginfo."""
- mybuild = gartest.GarBuild()
- mybuild.SetGarVariable("GARNAME", "foo")
- mybuild.AddInstallFile("/opt/csw/share/foo", "bar!\n")
- mybuild.WriteGarFiles()
- self.assertEquals(0, mybuild.Build())
- pkg = mybuild.GetFirstBuiltPackage()
- pkginfo = pkg.GetParsedPkginfo()
- # By default, the garname should be used to create the catalog name, which
- # in turn ends up in the NAME field in pkginfo.
- self.assertTrue(pkginfo["NAME"].startswith("foo"))
-
-
-if __name__ == '__main__':
- unittest.main()
-
-# vim:set ts=2 sts=2 sw=2 expandtab:
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