* 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"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Project SYSTEM "Project-3.8.dtd"> <!DOCTYPE Project SYSTEM "Project-3.8.dtd">
<!-- Project file for project pisi --> <!-- Project file for project pisi -->
<!-- Saved: 2005-11-02, 20:32:59 --> <!-- Saved: 2005-11-03, 02:14:40 -->
<!-- Copyright (C) 2005 PiSi Development Team, --> <!-- Copyright (C) 2005 PiSi Development Team, pisi@uludag.org.tr -->
<Project version="3.8"> <Project version="3.8">
<ProgLanguage mixed="0">Python</ProgLanguage> <ProgLanguage mixed="0">Python</ProgLanguage>
<UIType>Qt</UIType> <UIType>Qt</UIType>
<Description>The package management software of Pardus distribution. <Description>The package management software of Pardus distribution.
</Description> </Description>
<Version></Version>
<Author>PiSi Development Team</Author> <Author>PiSi Development Team</Author>
<Email></Email> <Email>pisi@uludag.org.tr</Email>
<Sources> <Sources>
<Source> <Source>
<Dir>tools</Dir> <Dir>tools</Dir>
@@ -372,6 +373,14 @@
<Dir>tests</Dir> <Dir>tests</Dir>
<Name>xmlexttests.py</Name> <Name>xmlexttests.py</Name>
</Source> </Source>
<Source>
<Dir>tests</Dir>
<Name>specfileoldtests.py</Name>
</Source>
<Source>
<Dir>pisi</Dir>
<Name>specfileold.py</Name>
</Source>
</Sources> </Sources>
<Forms> <Forms>
</Forms> </Forms>
@@ -409,10 +418,10 @@
<VcsOtherData>{'standardLayout': 1}</VcsOtherData> <VcsOtherData>{'standardLayout': 1}</VcsOtherData>
</Vcs> </Vcs>
<FiletypeAssociations> <FiletypeAssociations>
<FiletypeAssociation pattern="*.py" type="SOURCES" />
<FiletypeAssociation pattern="*.ui.h" type="FORMS" /> <FiletypeAssociation pattern="*.ui.h" type="FORMS" />
<FiletypeAssociation pattern="*.ptl" type="SOURCES" />
<FiletypeAssociation pattern="*.idl" type="INTERFACES" /> <FiletypeAssociation pattern="*.idl" type="INTERFACES" />
<FiletypeAssociation pattern="*.ui" type="FORMS" /> <FiletypeAssociation pattern="*.ui" type="FORMS" />
<FiletypeAssociation pattern="*.ptl" type="SOURCES" /> <FiletypeAssociation pattern="*.py" type="SOURCES" />
</FiletypeAssociations> </FiletypeAssociations>
</Project> </Project>
+19 -19
View File
@@ -50,8 +50,8 @@ def get_file_type(path, pinfoList):
ftype = "" ftype = ""
path = "/"+path # we need a real path. path = "/"+path # we need a real path.
for pinfo in pinfoList: for pinfo in pinfoList:
if util.subpath(pinfo.pathname, path): if util.subpath(pinfo.path, path):
length = len(pinfo.pathname) length = len(pinfo.path)
if depth < length: if depth < length:
depth = length depth = length
ftype = pinfo.fileType 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 the paths of packages in pkgList. The return value will be the
list containing the paths that collide.""" list containing the paths that collide."""
collisions = [] collisions = []
for pinfo in package.paths: for pinfo in package.files:
for pkg in pkgList: for pkg in pkgList:
if pkg is package: if pkg is package:
continue continue
for path in pkg.paths: for path in pkg.files:
# if pinfo.pathname is a subpath of path.pathname like # if pinfo.path is a subpath of path.path like
# the example below. path.patname is marked as a # the example below. path.path is marked as a
# collide. Exp: # collide. Exp:
# pinfo.pathname: /usr/share # pinfo.path: /usr/share
# path.pathname: /usr/share/doc # path.path: /usr/share/doc
if util.subpath(pinfo.pathname, path.pathname): if util.subpath(pinfo.path, path.path):
collisions.append(path.pathname) collisions.append(path.path)
ctx.ui.error(_('Path %s belongs in multiple packages') % ctx.ui.error(_('Path %s belongs in multiple packages') %
path.pathname) path.path)
return collisions return collisions
# a dynamic build context # a dynamic build context
@@ -191,10 +191,10 @@ class Builder:
ctx.ui.info(_("CCache detected...")) ctx.ui.info(_("CCache detected..."))
def fetch_source_archive(self): 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() self.sourceArchive.fetch()
ctx.ui.info(_("Source archive is stored: %s/%s") 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): def unpack_source_archive(self):
ctx.ui.info(_("Unpacking archive...")) ctx.ui.info(_("Unpacking archive..."))
@@ -274,7 +274,7 @@ class Builder:
# find out the build dependencies that are not satisfied... # find out the build dependencies that are not satisfied...
dep_unsatis = [] dep_unsatis = []
for dep in self.spec.source.buildDeps: for dep in self.spec.source.buildDependencies:
if not dependency.installed_satisfies_dep(dep): if not dependency.installed_satisfies_dep(dep):
dep_unsatis.append(dep) dep_unsatis.append(dep)
@@ -340,8 +340,8 @@ class Builder:
size, d = 0, self.bctx.pkg_install_dir() size, d = 0, self.bctx.pkg_install_dir()
for path in package.paths: for path in package.files:
size += util.dir_size(util.join_path(d, path.pathname)) size += util.dir_size(util.join_path(d, path.path))
metadata.package.installedSize = str(size) metadata.package.installedSize = str(size)
@@ -377,15 +377,15 @@ class Builder:
# add the files under material path # add the files under material path
for fpath, fhash in util.get_file_hashes(path, collisions, install_dir): for fpath, fhash in util.get_file_hashes(path, collisions, install_dir):
frpath = util.removepathprefix(install_dir, fpath) # relative path 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 try: # broken links and empty dirs can cause problem
fsize = str(os.path.getsize(fpath)) fsize = str(os.path.getsize(fpath))
except OSError: except OSError:
fsize = None fsize = None
d[frpath] = FileInfo(frpath, ftype, fsize, fhash) d[frpath] = FileInfo(frpath, ftype, fsize, fhash)
for pinfo in package.paths: for pinfo in package.files:
wildcard_path = util.join_path(install_dir, pinfo.pathname) wildcard_path = util.join_path(install_dir, pinfo.path)
for path in glob.glob(wildcard_path): for path in glob.glob(wildcard_path):
add_path(path) add_path(path)
+9 -9
View File
@@ -39,9 +39,10 @@ class Source:
class Package: class Package:
__metaclass__ = xmlfile.autoxml __metaclass__ = xmlfile.autoxml
# FIXME: copied attributes
t_Name = [ xmlfile.String, xmlfile.mandatory ] t_Name = [ xmlfile.String, xmlfile.mandatory ]
t_Summary = [ xmlfile.String, xmlfile.mandatory ] t_Summary = [ xmlfile.LocalText, xmlfile.optional ]
t_Description = [ xmlfile.String, xmlfile.mandatory ] t_Description = [ xmlfile.LocalText, xmlfile.optional ]
t_IsA = [ [xmlfile.String], xmlfile.optional] t_IsA = [ [xmlfile.String], xmlfile.optional]
t_PartOf = [xmlfile.String, xmlfile.optional] t_PartOf = [xmlfile.String, xmlfile.optional]
t_License = [ [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_RequiresComar = [ [xmlfile.String], xmlfile.mandatory, "Requires/COMAR"]
t_AdditionalFiles = [ [specfile.AdditionalFile], xmlfile.optional] t_AdditionalFiles = [ [specfile.AdditionalFile], xmlfile.optional]
t_History = [ [specfile.Update], xmlfile.optional] t_History = [ [specfile.Update], xmlfile.optional]
t_Build = [ xmlfile.Integer, xmlfile.optional] t_Build = [ xmlfile.Integer, xmlfile.optional]
t_Distribution = [ xmlfile.String, xmlfile.mandatory] t_Distribution = [ xmlfile.String, xmlfile.mandatory]
t_DistributionRelease = [ xmlfile.String, xmlfile.mandatory] t_DistributionRelease = [ xmlfile.String, xmlfile.mandatory]
@@ -81,25 +83,23 @@ class MetaData(xmlfile.XmlFile):
#t_History = [ [Update], xmlfile.mandatory] #t_History = [ [Update], xmlfile.mandatory]
def from_spec(self, src, pkg): def from_spec(self, src, pkg):
self.source = SourceInfo()
self.source.name = src.name self.source.name = src.name
self.source.homepage = src.homepage self.source.homepage = src.homepage
self.source.packager = src.packager self.source.packager = src.packager
self.package = PackageInfo()
self.package.name = pkg.name self.package.name = pkg.name
self.package.summary = pkg.summary self.package.summary = pkg.summary
self.package.description = pkg.description self.package.description = pkg.description
self.package.icon = pkg.icon self.package.icon = pkg.icon
self.package.isa = pkg.isa self.package.isA = pkg.isA
self.package.partof = pkg.partof self.package.partOf = pkg.partOf
self.package.license = pkg.license self.package.license = pkg.license
self.package.runtimeDeps = pkg.runtimeDeps self.package.runtimeDependencies = pkg.runtimeDependencies
self.package.paths = pkg.paths self.package.files = pkg.files
# FIXME: no need to copy full history with comments # FIXME: no need to copy full history with comments
self.package.history = src.history self.package.history = src.history
self.package.conflicts = pkg.conflicts self.package.conflicts = pkg.conflicts
self.package.providesComar = pkg.providesComar self.package.providesComar = pkg.providesComar
self.package.requiresComar = pkg.requiresComar #self.package.requiresComar = pkg.requiresComar
self.package.additionalFiles = pkg.additionalFiles self.package.additionalFiles = pkg.additionalFiles
# FIXME: right way to do it? # 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 """source archive. this is a class responsible for fetching
and unpacking a source archive""" and unpacking a source archive"""
def __init__(self, bctx): 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.archiveFile = join(ctx.config.archives_dir(), self.url.filename())
self.archiveName = bctx.spec.source.archiveName self.archive = bctx.spec.source.archive
self.archiveType = bctx.spec.source.archiveType
self.archiveSHA1 = bctx.spec.source.archiveSHA1
self.bctx = bctx self.bctx = bctx
def fetch(self, interactive=True): def fetch(self, interactive=True):
@@ -55,18 +53,18 @@ class SourceArchive:
return False return False
# check hash # check hash
if util.check_file_hash(self.archiveFile, self.archiveSHA1): if util.check_file_hash(self.archiveFile, self.archive.sha1sum):
if interactive: if interactive:
ctx.ui.info(_('%s [cached]') % self.archiveName) ctx.ui.info(_('%s [cached]') % self.archive.name)
return True return True
return False return False
def unpack(self, cleanDir=True): def unpack(self, clean_dir=True):
# check archive file's integrity # 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") raise Error, _("unpack: check_file_hash failed")
archive = Archive(self.archiveFile, self.archiveType) archive = Archive(self.archiveFile, self.archive.type)
archive.unpack(self.bctx.pkg_work_dir(), cleanDir) 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 return filePath
def do_patch(sourceDir, patchFile, level, target = ''): def do_patch(sourceDir, patchFile, level = 0, target = ''):
"""simple function to apply patches..""" """simple function to apply patches.."""
cwd = os.getcwd() cwd = os.getcwd()
os.chdir(sourceDir) os.chdir(sourceDir)
if level == None:
level = 0
if target == None:
target = ''
check_file(patchFile) check_file(patchFile)
level = int(level) (successful, lines) = run_batch("patch -p%d %s< %s" %
cmd = "patch -p%d %s< %s" % (level, target, patchFile) (level, target, patchFile))
p = os.popen(cmd) if not successful:
o = p.readlines()
retval = p.close()
if retval:
raise Error(_("ERROR: patch (%s) failed: %s") % (patchFile, raise Error(_("ERROR: patch (%s) failed: %s") % (patchFile,
strlist (o))) strlist (lines)))
os.chdir(cwd) os.chdir(cwd)
+2 -2
View File
@@ -84,14 +84,14 @@ class LocalText(dict):
nodes = getAllNodes(node, self.tag) nodes = getAllNodes(node, self.tag)
if not nodes: if not nodes:
if self.req == mandatory: if self.req == mandatory:
errs.append(where + _("LocalText '%s' should have at least one '%s' tag\n") % errs.append(where + _(" At least one '%s' tag should have local text") %
self.tag ) self.tag )
else: else:
for node in nodes: for node in nodes:
lang = getNodeAttribute(node, "xml:lang") lang = getNodeAttribute(node, "xml:lang")
c = getNodeText(node) c = getNodeText(node)
if not c: 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)) (lang, self.tag))
# FIXME: check for dups and 'en' # FIXME: check for dups and 'en'
if not lang: if not lang: