* implement pisi.api.list_upgradable

* improve autoxml stuff a bit
  - start complex types: class, list
  - refactor a bit
This commit is contained in:
Eray Özkural
2005-09-02 13:44:23 +00:00
parent 39d33df32c
commit 6dc402e523
6 changed files with 160 additions and 46 deletions
+21 -1
View File
@@ -57,6 +57,7 @@ def init(database = True, options = None, ui = None ):
# import pisi.sourcedb
# pisi.sourcedb.init()
def install(packages):
"""install a list of packages (either files/urls, or names)"""
@@ -235,7 +236,7 @@ def upgrade_pkg_names(A):
ignore_build = ctx.config.options and ctx.config.options.ignore_build_no
# filter packages that are not installed
# filter packages that are not upgradable
Ap = []
for x in A:
if not ctx.installdb.is_installed(x):
@@ -305,6 +306,25 @@ def upgrade_pkg_names(A):
return True # everything went OK :)
def list_upgradable():
A = ctx.installdb.list_installed()
# filter packages that are not upgradable
Ap = []
for x in A:
if not ctx.installdb.is_installed(x):
continue
(version, release, build) = ctx.installdb.get_version(x)
pkg = packagedb.get_package(x)
if ignore_build or (not build):
if release < pkg.release:
Ap.append(x)
elif build < pkg.build:
Ap.append(x)
else:
pass
#ctx.ui.info('Package %s cannot be upgraded. ' % x)
return Ap
def remove(A):
"""remove set A of packages from system (A is a list of package names)"""
+21 -16
View File
@@ -9,14 +9,15 @@
#
# Please read the COPYING file.
#
# 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 access to PSPEC files.
# 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.
"""
# standard python modules
from os.path import basename
@@ -28,17 +29,18 @@ from pisi.ui import ui
from pisi.dependency import DepInfo
from pisi.util import Checks
__metaclass__ = xmlfile.autoxml
class Packager:
__metaclass__ = xmlfile.autoxml
t_Name = [types.StringType, xmlfile.mandatory]
t_Email = [types.StringType, xmlfile.mandatory]
def __str__(self):
s = "%s <%s>" % (self.name, self.email)
return s
class AdditionalFileInfo:
__metaclass__ = xmlfile.autoxml
s_Filename = xmlfile.mandatory
a_Target = [types.StringType, xmlfile.mandatory]
a_Permission = [types.StringType, xmlfile.optional]
@@ -49,9 +51,8 @@ class AdditionalFileInfo:
s += '(%s)' % self.permission
return s
class Patch:
__metaclass__ = xmlfile.autoxml
s_Filename = xmlfile.mandatory
a_compressionType = [types.StringType, xmlfile.optional]
a_level = [types.StringType, xmlfile.optional]
@@ -67,8 +68,8 @@ class Patch:
s += ' target:' + self.target
return s
class Update:
__metaclass__ = xmlfile.autoxml
t_Date = [types.StringType, xmlfile.mandatory]
t_Version = [types.StringType, xmlfile.mandatory]
@@ -83,10 +84,12 @@ class Update:
s += ", type=" + self.type
return s
class Path:
__metaclass__ = xmlfile.autoxml
s_Path = xmlfile.mandatory
a_fileType = [types.StringType, xmlfile.optional]
def __str__(self):
s = self.pathname
s += ", type=" + self.fileType
@@ -94,17 +97,19 @@ class Path:
class ComarProvide:
__metaclass__ = xmlfile.autoxml
s_om = [types.StringType, xmlfile.mandatory]
a_script = [types.StringType, xmlfile.mandatory]
def __str__(self):
# FIXME: descriptive enough?
s = self.script
s += ' (' + self.om + ')'
return s
class Archive:
__metaclass__ = xmlfile.autoxml
s_uri = [ types.StringType, xmlfile.mandatory ]
a_type =[ types.StringType, xmlfile.mandatory ]
a_sha1sum =[ types.StringType, xmlfile.mandatory ]
@@ -114,7 +119,7 @@ class Archive:
class Source:
__metaclass__ = xmlfile.autoxml
t_Name = [types.StringType, xmlfile.mandatory]
t_HomePage = [types.StringType, xmlfile.mandatory]
t_Packager = [Packager, xmlfile.mandatory]
@@ -130,7 +135,7 @@ class Source:
class Package:
__metaclass__ = xmlfile.autoxml
t_Name = [ types.StringType, xmlfile.mandatory ]
t_Summary = [ types.StringType, xmlfile.mandatory ]
t_Description = [ types.StringType, xmlfile.mandatory ]
+112 -28
View File
@@ -11,7 +11,8 @@
#
#
# Authors: Eray Ozkural <eray@uludag.org.tr>
# Baris Metin <baris@uludag.org.tr
# Gurer Ozen <gurer@uludag.org.tr>
# Baris Metin <baris@uludag.org.tr>
"""
@@ -23,10 +24,10 @@
in xml.dom :( )
autoxml is a metaclass for automatic XML translation, using
a miniature type system
a miniature type system. (w00t!)
Method names are mixedCase for compatibility with minidom,
an old library
an old library.
"""
# System
@@ -45,9 +46,45 @@ class Error(pisi.Error):
import types
mandatory, optional = range(2)
mandatory, optional = range(2) # poor man's enum
# basic types
Text = types.StringType
Integer = types.IntType
class LocalText:
"handle tags with localized text"
def __init__():
locs = {}
def decode(nodes, req):
# flags, tag name, instance attribute
if not nodes:
if req == mandatory:
pass
#errs.append("Tag '%s' should have at least one '%s' tag\n" % (parent.tagName, d[2]))
else:
for node in nodes:
lang = getAttribute(node, "xml:lang")
c = getText(node)
if not c:
#errs.append("Tag '%s' should have some text data\n" % node.tagName)
break
# FIXME: check for dups and 'en'
if not lang:
lang = 'en'
self.locs[lang] = c
# FIXME: return full list too
L = language
if not locs.has_key(L):
L = 'en'
if not locs.has_key(L):
errs.append("Tag '%s' should have an English version\n" % d[2])
return ""
return locs[L]
class autoxml(type):
"high-level automatic XML transformation interface for xmlfile"
@@ -70,7 +107,7 @@ class autoxml(type):
root_tag = cls.tag
# generate helper routines
initializers = []
inits = []
decoders = []
encoders = []
formatters = []
@@ -78,27 +115,20 @@ class autoxml(type):
if var.startswith('t_') or var.startswith('a_'):
name = var[2:]
#print 'name', name
# possible python bug, binds var only to t_Email here!
## def initializer(self):
## print 'got', name
## setattr(self, name, None)
## initializers.append(initializer)
initializers.append(autoxml.gen_init(cls, name))
if var.startswith('t_'):
x = autoxml.gen_tag(cls, name)
elif var.startswith('a_'):
x = autoxml.gen_attr(cls, name)
(decoder, encoder, formatter) = x
(init, decoder, encoder, formatter) = x
inits.append(init)
decoders.append(decoder)
encoders.append(encoder)
formatters.append(formatter)
#print initializers
setattr(cls, 'initializers', initializers)
setattr(cls, 'initializers', inits)
def initialize(self):
for initializer in self.__class__.initializers:
initializer(self)
for init in self.__class__.initializers:
init(self)
setattr(cls, '__init__', initialize)
setattr(cls, 'decoders', decoders)
@@ -125,21 +155,21 @@ class autoxml(type):
return self.format()
setattr(cls, '__str__', string)
def gen_init(cls, name):
def initializer(self):
varname = cls.mixed_case(name)
#print 'init:', varname
setattr(self, varname, None)
return initializer
def gen_tag(cls, tag):
# generate readers and writers for the tag
val = getattr(cls, 't_' + tag)
tag_type = val[0]
if type(tag_type) == type(type):
return autoxml.gen_tag_aux(cls, tag, tag_type, val)
def gen_tag_aux(cls, tag, tag_type, val):
if type(tag_type) == types.TypeType:
# basic types
return autoxml.gen_basic_tag(cls, tag, val)
elif type(tag_type) == types.ClassType:
return autoxml.gen_class_tag(cls, tag, val)
elif type(tag_type) == types.ListType:
return autoxml.gen_list_tag(cls, tag, val)
def gen_attr(cls, tag):
"generate readers and writers for an attribute"
#print 'attr:', tag
@@ -157,6 +187,10 @@ class autoxml(type):
name = cls.mixed_case(token)
token_type = val[0]
req = val[1]
def initialize(self):
#print 'init:', name
setattr(self, name, None)
def decode(self, node):
text = readtext(node, token)
@@ -181,7 +215,7 @@ class autoxml(type):
if req == mandatory:
return ['Mandatory argument not available']
def formatter(self):
def format(self):
#print 'format:', name
if hasattr(self, name):
return '%s: %s\n' % (token, str(getattr(self, name)))
@@ -190,7 +224,7 @@ class autoxml(type):
raise Error('Mandatory variable %s not available' % name)
return ""
return decode, encode, formatter
return initialize, decode, encode, format
def gen_basic_attr(cls, attr, val):
"""generate an attribute with a basic datatype"""
@@ -208,6 +242,56 @@ class autoxml(type):
xml.addTextNodeUnder(node, tag, value)
return autoxml.gen_basic(cls, tag, val, readtext, writetext)
def gen_class_tag(cls, tag, val):
pass
def gen_list_tag(cls, tag, val):
name = cls.mixed_case(token)
token_type = val[0]
req = val[1]
if len(val)>=3:
path = val[2]
else:
path = tag
if len(token_type!=1):
raise Error('List type must contain one element')
x = autoxml.gen_tag_aux(cls, tag, tag_type, val)
(x_init, x_decoder, x_encoder, x_formatter) = x
def init(self):
varname = cls.mixed_case(name)
setattr(self, varname, [])
def decode(self, node):
nodes = getAllNodes(node)
if len(nodes) is 0 and req is mandatory:
pass
#FIXME: add error here
for node in nodes:
x_decoder(self, node)
pass
def encode(self, xml):
node = xml.newNode(cls.tag)
if hasattr(self, name):
writetext(xml, node, token, str(getattr(self, name)))
else:
if req == mandatory:
return ['Mandatory argument not available']
def format(self):
#print 'format:', name
if hasattr(self, name):
return '%s: %s\n' % (token, str(getattr(self, name)))
else:
if req == mandatory:
raise Error('Mandatory variable %s not available' % name)
return ""
return (init, decode, encode, format)
basic_cons_map = {
types.StringType : str,
types.IntType : int
+1
View File
@@ -15,6 +15,7 @@ import sys
import os
sys.path.append('.')
sys.path.append('..')
runTestSuite = lambda(x): unittest.TextTestRunner(verbosity=2).run(x)
+4
View File
@@ -2,4 +2,8 @@
<A href="http://www.cs.bilkent.edu.tr/~erayo">
<Name>Eray Ozkural</Name>
<Number>868</Number>
<Projects>
<Project>pisi</Project>
<Project>noatun</Project>
</Projects>
</A>
+1 -1
View File
@@ -33,7 +33,7 @@ class XmlFileTestCase(unittest.TestCase):
a_href = [types.StringType, xmlfile.mandatory]
#t_Projects = [ [types.StringType], xmlfile.mandatory]
a = A()
#print a
print a
self.assertEqual(a.href, None)
dom = mdom.parse('tests/sandbox/a.xml')
node = getNode(dom, 'A')