* fix: update build code path for new specfile. many small fixes wohooo :)

* apply patch: handle None as defaul params
* fix: use run_batch. no need to duplicate code!
* fix: xmlfile, error msg, and param
* move specfile into correct place
* update metadata
This commit is contained in:
Eray Özkural
2005-11-03 00:20:01 +00:00
parent 115e68aec1
commit 38cdc8a7c2
7 changed files with 309 additions and 54 deletions
+14 -5
View File
@@ -1,15 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Project SYSTEM "Project-3.8.dtd">
<!-- Project file for project pisi -->
<!-- Saved: 2005-11-02, 20:32:59 -->
<!-- Copyright (C) 2005 PiSi Development Team, -->
<!-- Saved: 2005-11-03, 02:14:40 -->
<!-- Copyright (C) 2005 PiSi Development Team, pisi@uludag.org.tr -->
<Project version="3.8">
<ProgLanguage mixed="0">Python</ProgLanguage>
<UIType>Qt</UIType>
<Description>The package management software of Pardus distribution.
</Description>
<Version></Version>
<Author>PiSi Development Team</Author>
<Email></Email>
<Email>pisi@uludag.org.tr</Email>
<Sources>
<Source>
<Dir>tools</Dir>
@@ -372,6 +373,14 @@
<Dir>tests</Dir>
<Name>xmlexttests.py</Name>
</Source>
<Source>
<Dir>tests</Dir>
<Name>specfileoldtests.py</Name>
</Source>
<Source>
<Dir>pisi</Dir>
<Name>specfileold.py</Name>
</Source>
</Sources>
<Forms>
</Forms>
@@ -409,10 +418,10 @@
<VcsOtherData>{'standardLayout': 1}</VcsOtherData>
</Vcs>
<FiletypeAssociations>
<FiletypeAssociation pattern="*.py" type="SOURCES" />
<FiletypeAssociation pattern="*.ui.h" type="FORMS" />
<FiletypeAssociation pattern="*.ptl" type="SOURCES" />
<FiletypeAssociation pattern="*.idl" type="INTERFACES" />
<FiletypeAssociation pattern="*.ui" type="FORMS" />
<FiletypeAssociation pattern="*.ptl" type="SOURCES" />
<FiletypeAssociation pattern="*.py" type="SOURCES" />
</FiletypeAssociations>
</Project>
+19 -19
View File
@@ -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)
+9 -9
View File
@@ -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?
+8 -10
View File
@@ -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)
+246
View File
@@ -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 <eray@uludag.org.tr>
# Baris Metin <baris@uludag.org.tr>
"""
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
+10 -8
View File
@@ -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)
+3 -3
View File
@@ -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: