diff --git a/pisi.e3p b/pisi.e3p
index 1bf5c07d..f72ff3c2 100644
--- a/pisi.e3p
+++ b/pisi.e3p
@@ -1,15 +1,16 @@
-
-
+
+
Python
Qt
The package management software of Pardus distribution.
+
PiSi Development Team
-
+ pisi@uludag.org.tr
tools
@@ -372,6 +373,14 @@
tests
xmlexttests.py
+
+ tests
+ specfileoldtests.py
+
+
+ pisi
+ specfileold.py
+
@@ -409,10 +418,10 @@
{'standardLayout': 1}
-
+
-
+
diff --git a/pisi/build.py b/pisi/build.py
index 220824ac..baf80ebb 100644
--- a/pisi/build.py
+++ b/pisi/build.py
@@ -50,8 +50,8 @@ def get_file_type(path, pinfoList):
ftype = ""
path = "/"+path # we need a real path.
for pinfo in pinfoList:
- if util.subpath(pinfo.pathname, path):
- length = len(pinfo.pathname)
+ if util.subpath(pinfo.path, path):
+ length = len(pinfo.path)
if depth < length:
depth = length
ftype = pinfo.fileType
@@ -62,20 +62,20 @@ def check_path_collision(package, pkgList):
the paths of packages in pkgList. The return value will be the
list containing the paths that collide."""
collisions = []
- for pinfo in package.paths:
+ for pinfo in package.files:
for pkg in pkgList:
if pkg is package:
continue
- for path in pkg.paths:
- # if pinfo.pathname is a subpath of path.pathname like
- # the example below. path.patname is marked as a
+ for path in pkg.files:
+ # if pinfo.path is a subpath of path.path like
+ # the example below. path.path is marked as a
# collide. Exp:
- # pinfo.pathname: /usr/share
- # path.pathname: /usr/share/doc
- if util.subpath(pinfo.pathname, path.pathname):
- collisions.append(path.pathname)
+ # pinfo.path: /usr/share
+ # path.path: /usr/share/doc
+ if util.subpath(pinfo.path, path.path):
+ collisions.append(path.path)
ctx.ui.error(_('Path %s belongs in multiple packages') %
- path.pathname)
+ path.path)
return collisions
# a dynamic build context
@@ -191,10 +191,10 @@ class Builder:
ctx.ui.info(_("CCache detected..."))
def fetch_source_archive(self):
- ctx.ui.info(_("Fetching source from: %s") % self.spec.source.archiveUri)
+ ctx.ui.info(_("Fetching source from: %s") % self.spec.source.archive.uri)
self.sourceArchive.fetch()
ctx.ui.info(_("Source archive is stored: %s/%s")
- %(ctx.config.archives_dir(), self.spec.source.archiveName))
+ %(ctx.config.archives_dir(), self.spec.source.archive.name))
def unpack_source_archive(self):
ctx.ui.info(_("Unpacking archive..."))
@@ -274,7 +274,7 @@ class Builder:
# find out the build dependencies that are not satisfied...
dep_unsatis = []
- for dep in self.spec.source.buildDeps:
+ for dep in self.spec.source.buildDependencies:
if not dependency.installed_satisfies_dep(dep):
dep_unsatis.append(dep)
@@ -340,8 +340,8 @@ class Builder:
size, d = 0, self.bctx.pkg_install_dir()
- for path in package.paths:
- size += util.dir_size(util.join_path(d, path.pathname))
+ for path in package.files:
+ size += util.dir_size(util.join_path(d, path.path))
metadata.package.installedSize = str(size)
@@ -377,15 +377,15 @@ class Builder:
# add the files under material path
for fpath, fhash in util.get_file_hashes(path, collisions, install_dir):
frpath = util.removepathprefix(install_dir, fpath) # relative path
- ftype = get_file_type(frpath, package.paths)
+ ftype = get_file_type(frpath, package.files)
try: # broken links and empty dirs can cause problem
fsize = str(os.path.getsize(fpath))
except OSError:
fsize = None
d[frpath] = FileInfo(frpath, ftype, fsize, fhash)
- for pinfo in package.paths:
- wildcard_path = util.join_path(install_dir, pinfo.pathname)
+ for pinfo in package.files:
+ wildcard_path = util.join_path(install_dir, pinfo.path)
for path in glob.glob(wildcard_path):
add_path(path)
diff --git a/pisi/metadata.py b/pisi/metadata.py
index 2c6eb517..813afbee 100644
--- a/pisi/metadata.py
+++ b/pisi/metadata.py
@@ -39,9 +39,10 @@ class Source:
class Package:
__metaclass__ = xmlfile.autoxml
+ # FIXME: copied attributes
t_Name = [ xmlfile.String, xmlfile.mandatory ]
- t_Summary = [ xmlfile.String, xmlfile.mandatory ]
- t_Description = [ xmlfile.String, xmlfile.mandatory ]
+ t_Summary = [ xmlfile.LocalText, xmlfile.optional ]
+ t_Description = [ xmlfile.LocalText, xmlfile.optional ]
t_IsA = [ [xmlfile.String], xmlfile.optional]
t_PartOf = [xmlfile.String, xmlfile.optional]
t_License = [ [xmlfile.String], xmlfile.optional]
@@ -53,6 +54,7 @@ class Package:
#t_RequiresComar = [ [xmlfile.String], xmlfile.mandatory, "Requires/COMAR"]
t_AdditionalFiles = [ [specfile.AdditionalFile], xmlfile.optional]
t_History = [ [specfile.Update], xmlfile.optional]
+
t_Build = [ xmlfile.Integer, xmlfile.optional]
t_Distribution = [ xmlfile.String, xmlfile.mandatory]
t_DistributionRelease = [ xmlfile.String, xmlfile.mandatory]
@@ -81,25 +83,23 @@ class MetaData(xmlfile.XmlFile):
#t_History = [ [Update], xmlfile.mandatory]
def from_spec(self, src, pkg):
- self.source = SourceInfo()
self.source.name = src.name
self.source.homepage = src.homepage
self.source.packager = src.packager
- self.package = PackageInfo()
self.package.name = pkg.name
self.package.summary = pkg.summary
self.package.description = pkg.description
self.package.icon = pkg.icon
- self.package.isa = pkg.isa
- self.package.partof = pkg.partof
+ self.package.isA = pkg.isA
+ self.package.partOf = pkg.partOf
self.package.license = pkg.license
- self.package.runtimeDeps = pkg.runtimeDeps
- self.package.paths = pkg.paths
+ self.package.runtimeDependencies = pkg.runtimeDependencies
+ self.package.files = pkg.files
# FIXME: no need to copy full history with comments
self.package.history = src.history
self.package.conflicts = pkg.conflicts
self.package.providesComar = pkg.providesComar
- self.package.requiresComar = pkg.requiresComar
+ #self.package.requiresComar = pkg.requiresComar
self.package.additionalFiles = pkg.additionalFiles
# FIXME: right way to do it?
diff --git a/pisi/sourcearchive.py b/pisi/sourcearchive.py
index 8c6d9556..61ef5409 100644
--- a/pisi/sourcearchive.py
+++ b/pisi/sourcearchive.py
@@ -36,11 +36,9 @@ class SourceArchive:
"""source archive. this is a class responsible for fetching
and unpacking a source archive"""
def __init__(self, bctx):
- self.url = URI(bctx.spec.source.archiveUri)
+ self.url = URI(bctx.spec.source.archive.uri)
self.archiveFile = join(ctx.config.archives_dir(), self.url.filename())
- self.archiveName = bctx.spec.source.archiveName
- self.archiveType = bctx.spec.source.archiveType
- self.archiveSHA1 = bctx.spec.source.archiveSHA1
+ self.archive = bctx.spec.source.archive
self.bctx = bctx
def fetch(self, interactive=True):
@@ -55,18 +53,18 @@ class SourceArchive:
return False
# check hash
- if util.check_file_hash(self.archiveFile, self.archiveSHA1):
+ if util.check_file_hash(self.archiveFile, self.archive.sha1sum):
if interactive:
- ctx.ui.info(_('%s [cached]') % self.archiveName)
+ ctx.ui.info(_('%s [cached]') % self.archive.name)
return True
return False
- def unpack(self, cleanDir=True):
+ def unpack(self, clean_dir=True):
# check archive file's integrity
- if not util.check_file_hash(self.archiveFile, self.archiveSHA1):
+ if not util.check_file_hash(self.archiveFile, self.archive.sha1sum):
raise Error, _("unpack: check_file_hash failed")
- archive = Archive(self.archiveFile, self.archiveType)
- archive.unpack(self.bctx.pkg_work_dir(), cleanDir)
+ archive = Archive(self.archiveFile, self.archive.type)
+ archive.unpack(self.bctx.pkg_work_dir(), clean_dir)
diff --git a/pisi/specfile.py b/pisi/specfile.py
new file mode 100644
index 00000000..6de03fc7
--- /dev/null
+++ b/pisi/specfile.py
@@ -0,0 +1,246 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2005, TUBITAK/UEKAE
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your option)
+# any later version.
+#
+# Please read the COPYING file.
+#
+# Authors: Eray Ozkural
+# Baris Metin
+
+"""
+ Specfile module is our handler for PSPEC files. PSPEC (PISI SPEC)
+ files are specification files for PISI source packages. This module
+ provides read and write routines for PSPEC files.
+"""
+
+import gettext
+__trans = gettext.translation('pisi', fallback=True)
+_ = __trans.ugettext
+
+# standard python modules
+from os.path import basename
+
+# pisi modules
+from pisi.xmlext import *
+import pisi.xmlfile as xmlfile
+from pisi.xmlfile import XmlFile
+import pisi.context as ctx
+from pisi.dependency import DepInfo
+from pisi.util import Checks
+
+class Error(pisi.Error):
+ pass
+
+__metaclass__ = xmlfile.autoxml
+
+class Packager:
+
+ t_Name = [xmlfile.Text, xmlfile.mandatory]
+ t_Email = [xmlfile.String, xmlfile.mandatory]
+ def __str__(self):
+ s = "%s <%s>" % (self.name, self.email)
+ return s
+
+
+class AdditionalFile:
+
+ s_Filename = [xmlfile.String, xmlfile.mandatory]
+ a_Target = [xmlfile.String, xmlfile.mandatory]
+ a_Permission = [xmlfile.String, xmlfile.optional]
+
+ def __str__(self):
+ s = "%s -> %s " % (self.filename, self.target)
+ if self.permission:
+ s += '(%s)' % self.permission
+ return s
+
+
+class Patch:
+
+ s_Filename = [xmlfile.String, xmlfile.mandatory]
+ a_compressionType = [xmlfile.String, xmlfile.optional]
+ a_level = [xmlfile.String, xmlfile.optional]
+ a_target = [xmlfile.String, xmlfile.optional]
+
+ def __str__(self):
+ s = self.filename
+ if self.compressionType:
+ s += ' (' + self.compressionType + ')'
+ if self.level:
+ s += ' level:' + self.level
+ if self.target:
+ s += ' target:' + self.target
+ return s
+
+
+class Update:
+
+ a_release = [xmlfile.String, xmlfile.mandatory]
+ t_Date = [xmlfile.String, xmlfile.mandatory]
+ t_Version = [xmlfile.String, xmlfile.mandatory]
+ t_Type = [xmlfile.String, xmlfile.optional]
+
+ def __str__(self):
+ s = self.date
+ s += ", ver=" + self.version
+ s += ", rel=" + self.release
+ if self.type:
+ s += ", type=" + self.type
+ return s
+
+
+class Path:
+
+ s_Path = [xmlfile.String, xmlfile.mandatory]
+ a_fileType = [xmlfile.String, xmlfile.optional]
+
+ def __str__(self):
+ s = self.path
+ s += ", type=" + self.fileType
+ return s
+
+class Dependency:
+
+ s_Package = [xmlfile.String, xmlfile.mandatory]
+ a_versionFrom = [xmlfile.String, xmlfile.optional]
+ a_versionTo = [xmlfile.String, xmlfile.optional]
+ a_releaseFrom = [xmlfile.String, xmlfile.optional]
+ a_releaseTo = [xmlfile.String, xmlfile.optional]
+
+ def __str__(self):
+ s = self.package
+ if self.versionFrom:
+ s += 'ver >= ' + self.versionFrom
+ if self.versionTo:
+ s += 'ver <= ' + self.versionTo
+ if self.releaseFrom:
+ s += 'rel >= ' + self.releaseFrom
+ if self.releaseTo:
+ s += 'rel <= ' + self.releaseTo
+ return s
+
+class ComarProvide:
+
+ s_om = [xmlfile.String, xmlfile.mandatory]
+ a_script = [xmlfile.String, xmlfile.mandatory]
+
+ def __str__(self):
+ # FIXME: descriptive enough?
+ s = self.script
+ s += ' (' + self.om + ')'
+ return s
+
+
+class Archive:
+
+ s_uri = [ xmlfile.String, xmlfile.mandatory ]
+ a_type =[ xmlfile.String, xmlfile.mandatory ]
+ a_sha1sum =[ xmlfile.String, xmlfile.mandatory ]
+
+ def decode_post(self):
+ self.name = basename(self.uri)
+
+
+class Source:
+
+ t_Name = [xmlfile.String, xmlfile.mandatory]
+ t_Homepage = [xmlfile.String, xmlfile.mandatory]
+ t_Packager = [Packager, xmlfile.mandatory]
+ t_Summary = [xmlfile.String, xmlfile.mandatory]
+ t_Description = [xmlfile.String, xmlfile.mandatory]
+ t_IsA = [ [xmlfile.String], xmlfile.mandatory]
+ t_PartOf = [xmlfile.String, xmlfile.mandatory]
+ t_Icon = [ xmlfile.String, xmlfile.optional]
+ t_License = [ [xmlfile.String], xmlfile.mandatory]
+ t_Archive = [Archive, xmlfile.mandatory ]
+ t_Patches = [ [Patch], xmlfile.optional]
+ t_BuildDependencies = [ [Dependency], xmlfile.optional]
+ t_Version = [ xmlfile.String, xmlfile.optional]
+ t_Release = [ xmlfile.String, xmlfile.optional]
+
+
+class Package:
+
+ t_Name = [ xmlfile.String, xmlfile.mandatory ]
+ t_Summary = [ xmlfile.String, xmlfile.mandatory ]
+ t_Description = [ xmlfile.String, xmlfile.mandatory ]
+ t_IsA = [ [xmlfile.String], xmlfile.optional]
+ t_PartOf = [xmlfile.String, xmlfile.optional]
+ t_License = [ [xmlfile.String], xmlfile.optional]
+ t_Icon = [ xmlfile.String, xmlfile.optional]
+ t_RuntimeDependencies = [ [Dependency], xmlfile.optional]
+ t_Files = [ [Path], xmlfile.optional]
+ t_Conflicts = [ [xmlfile.String], xmlfile.optional, "Conflicts/Package"]
+ t_ProvidesComar = [ [ComarProvide], xmlfile.optional, "Provides/COMAR"]
+ #t_RequiresComar = [ [xmlfile.String], xmlfile.mandatory, "Requires/COMAR"]
+ t_AdditionalFiles = [ [AdditionalFile], xmlfile.optional]
+ t_History = [ [Update], xmlfile.optional]
+
+
+class SpecFile(XmlFile):
+ __metaclass__ = xmlfile.autoxml #needed when we specify a superclass
+
+ tag = "PISI"
+
+ t_Source = [ Source, xmlfile.mandatory]
+ t_Packages = [ [Package], xmlfile.mandatory, "Package"]
+ t_History = [ [Update], xmlfile.mandatory]
+
+ #we're not doing this with the init hook right now
+ #def init(self, tag = "PISI"):
+ #ignore tag
+ #XmlFile.__init__(self, tag)
+
+ def read_hook(self, errs):
+ """Read PSPEC file"""
+ self.merge_tags()
+ self.override_tags()
+
+ def merge_tags(self):
+ """Merge tags from Source in Packages. Some tags in Packages merged
+ with the tags from Source. There is a more detailed
+ description in documents."""
+
+ # FIXME: copy only needed information
+ # no need to keep full history with comments in metadata.xml
+ self.source.history = self.history
+
+ # To avoid tag duplication in PSPEC we need to get
+ # the last version and release information
+ # from the most recent History/Update.
+ if not self.source.version:
+ self.source.version = self.history[0].version
+ if not self.source.release:
+ self.source.release = self.history[0].release
+
+ tmp = []
+ for pkg in self.packages:
+ pkg.isA.extend(self.source.isA)
+ pkg.history = self.history
+ tmp.append(pkg)
+ self.packages = tmp
+
+ def override_tags(self):
+ """Override tags from Source in Packages. Some tags in Packages
+ overrides the tags from Source. There is a more detailed
+ description in documents."""
+
+ tmp = []
+ for pkg in self.packages:
+ if not pkg.summary:
+ pkg.summary = self.source.summary
+ if not pkg.description:
+ pkg.description = self.source.description
+ if not pkg.partOf:
+ pkg.partOf = self.source.partOf
+ if not pkg.license:
+ pkg.license = self.source.license
+ if not pkg.icon:
+ pkg.icon = self.source.icon
+ tmp.append(pkg)
+ self.packages = tmp
diff --git a/pisi/util.py b/pisi/util.py
index fab564ca..05069743 100644
--- a/pisi/util.py
+++ b/pisi/util.py
@@ -395,20 +395,22 @@ def uncompress(patchFile, compressType="gz", targetDir=None):
return filePath
-def do_patch(sourceDir, patchFile, level, target = ''):
+def do_patch(sourceDir, patchFile, level = 0, target = ''):
"""simple function to apply patches.."""
cwd = os.getcwd()
os.chdir(sourceDir)
+
+ if level == None:
+ level = 0
+ if target == None:
+ target = ''
check_file(patchFile)
- level = int(level)
- cmd = "patch -p%d %s< %s" % (level, target, patchFile)
- p = os.popen(cmd)
- o = p.readlines()
- retval = p.close()
- if retval:
+ (successful, lines) = run_batch("patch -p%d %s< %s" %
+ (level, target, patchFile))
+ if not successful:
raise Error(_("ERROR: patch (%s) failed: %s") % (patchFile,
- strlist (o)))
+ strlist (lines)))
os.chdir(cwd)
diff --git a/pisi/xmlfile.py b/pisi/xmlfile.py
index 4d5e2adc..b7e3914c 100644
--- a/pisi/xmlfile.py
+++ b/pisi/xmlfile.py
@@ -84,14 +84,14 @@ class LocalText(dict):
nodes = getAllNodes(node, self.tag)
if not nodes:
if self.req == mandatory:
- errs.append(where + _("LocalText '%s' should have at least one '%s' tag\n") %
- self.tag)
+ errs.append(where + _(" At least one '%s' tag should have local text") %
+ self.tag )
else:
for node in nodes:
lang = getNodeAttribute(node, "xml:lang")
c = getNodeText(node)
if not c:
- errs.append(where + _("'%s' language of tag '%s' should have some text data\n") %
+ errs.append(where + _("'%s' language of tag '%s' is empty") %
(lang, self.tag))
# FIXME: check for dups and 'en'
if not lang: