* implement pisi.api.list_upgradable
* improve autoxml stuff a bit - start complex types: class, list - refactor a bit
This commit is contained in:
+21
-1
@@ -57,6 +57,7 @@ def init(database = True, options = None, ui = None ):
|
|||||||
# import pisi.sourcedb
|
# import pisi.sourcedb
|
||||||
# pisi.sourcedb.init()
|
# pisi.sourcedb.init()
|
||||||
|
|
||||||
|
|
||||||
def install(packages):
|
def install(packages):
|
||||||
"""install a list of packages (either files/urls, or names)"""
|
"""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
|
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 = []
|
Ap = []
|
||||||
for x in A:
|
for x in A:
|
||||||
if not ctx.installdb.is_installed(x):
|
if not ctx.installdb.is_installed(x):
|
||||||
@@ -305,6 +306,25 @@ def upgrade_pkg_names(A):
|
|||||||
|
|
||||||
return True # everything went OK :)
|
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):
|
def remove(A):
|
||||||
"""remove set A of packages from system (A is a list of package names)"""
|
"""remove set A of packages from system (A is a list of package names)"""
|
||||||
|
|
||||||
|
|||||||
+21
-16
@@ -9,14 +9,15 @@
|
|||||||
#
|
#
|
||||||
# Please read the COPYING file.
|
# 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>
|
# Authors: Eray Ozkural <eray@uludag.org.tr>
|
||||||
# Baris Metin <baris@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
|
# standard python modules
|
||||||
from os.path import basename
|
from os.path import basename
|
||||||
|
|
||||||
@@ -28,17 +29,18 @@ from pisi.ui import ui
|
|||||||
from pisi.dependency import DepInfo
|
from pisi.dependency import DepInfo
|
||||||
from pisi.util import Checks
|
from pisi.util import Checks
|
||||||
|
|
||||||
|
__metaclass__ = xmlfile.autoxml
|
||||||
|
|
||||||
|
|
||||||
class Packager:
|
class Packager:
|
||||||
__metaclass__ = xmlfile.autoxml
|
|
||||||
t_Name = [types.StringType, xmlfile.mandatory]
|
t_Name = [types.StringType, xmlfile.mandatory]
|
||||||
t_Email = [types.StringType, xmlfile.mandatory]
|
t_Email = [types.StringType, xmlfile.mandatory]
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
s = "%s <%s>" % (self.name, self.email)
|
s = "%s <%s>" % (self.name, self.email)
|
||||||
return s
|
return s
|
||||||
class AdditionalFileInfo:
|
|
||||||
__metaclass__ = xmlfile.autoxml
|
|
||||||
|
|
||||||
|
|
||||||
|
class AdditionalFileInfo:
|
||||||
s_Filename = xmlfile.mandatory
|
s_Filename = xmlfile.mandatory
|
||||||
a_Target = [types.StringType, xmlfile.mandatory]
|
a_Target = [types.StringType, xmlfile.mandatory]
|
||||||
a_Permission = [types.StringType, xmlfile.optional]
|
a_Permission = [types.StringType, xmlfile.optional]
|
||||||
@@ -49,9 +51,8 @@ class AdditionalFileInfo:
|
|||||||
s += '(%s)' % self.permission
|
s += '(%s)' % self.permission
|
||||||
return s
|
return s
|
||||||
|
|
||||||
class Patch:
|
|
||||||
__metaclass__ = xmlfile.autoxml
|
|
||||||
|
|
||||||
|
class Patch:
|
||||||
s_Filename = xmlfile.mandatory
|
s_Filename = xmlfile.mandatory
|
||||||
a_compressionType = [types.StringType, xmlfile.optional]
|
a_compressionType = [types.StringType, xmlfile.optional]
|
||||||
a_level = [types.StringType, xmlfile.optional]
|
a_level = [types.StringType, xmlfile.optional]
|
||||||
@@ -67,8 +68,8 @@ class Patch:
|
|||||||
s += ' target:' + self.target
|
s += ' target:' + self.target
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
class Update:
|
class Update:
|
||||||
__metaclass__ = xmlfile.autoxml
|
|
||||||
|
|
||||||
t_Date = [types.StringType, xmlfile.mandatory]
|
t_Date = [types.StringType, xmlfile.mandatory]
|
||||||
t_Version = [types.StringType, xmlfile.mandatory]
|
t_Version = [types.StringType, xmlfile.mandatory]
|
||||||
@@ -83,10 +84,12 @@ class Update:
|
|||||||
s += ", type=" + self.type
|
s += ", type=" + self.type
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
class Path:
|
class Path:
|
||||||
__metaclass__ = xmlfile.autoxml
|
|
||||||
s_Path = xmlfile.mandatory
|
s_Path = xmlfile.mandatory
|
||||||
a_fileType = [types.StringType, xmlfile.optional]
|
a_fileType = [types.StringType, xmlfile.optional]
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
s = self.pathname
|
s = self.pathname
|
||||||
s += ", type=" + self.fileType
|
s += ", type=" + self.fileType
|
||||||
@@ -94,17 +97,19 @@ class Path:
|
|||||||
|
|
||||||
|
|
||||||
class ComarProvide:
|
class ComarProvide:
|
||||||
__metaclass__ = xmlfile.autoxml
|
|
||||||
s_om = [types.StringType, xmlfile.mandatory]
|
s_om = [types.StringType, xmlfile.mandatory]
|
||||||
a_script = [types.StringType, xmlfile.mandatory]
|
a_script = [types.StringType, xmlfile.mandatory]
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
# FIXME: descriptive enough?
|
# FIXME: descriptive enough?
|
||||||
s = self.script
|
s = self.script
|
||||||
s += ' (' + self.om + ')'
|
s += ' (' + self.om + ')'
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
class Archive:
|
class Archive:
|
||||||
__metaclass__ = xmlfile.autoxml
|
|
||||||
s_uri = [ types.StringType, xmlfile.mandatory ]
|
s_uri = [ types.StringType, xmlfile.mandatory ]
|
||||||
a_type =[ types.StringType, xmlfile.mandatory ]
|
a_type =[ types.StringType, xmlfile.mandatory ]
|
||||||
a_sha1sum =[ types.StringType, xmlfile.mandatory ]
|
a_sha1sum =[ types.StringType, xmlfile.mandatory ]
|
||||||
@@ -114,7 +119,7 @@ class Archive:
|
|||||||
|
|
||||||
|
|
||||||
class Source:
|
class Source:
|
||||||
__metaclass__ = xmlfile.autoxml
|
|
||||||
t_Name = [types.StringType, xmlfile.mandatory]
|
t_Name = [types.StringType, xmlfile.mandatory]
|
||||||
t_HomePage = [types.StringType, xmlfile.mandatory]
|
t_HomePage = [types.StringType, xmlfile.mandatory]
|
||||||
t_Packager = [Packager, xmlfile.mandatory]
|
t_Packager = [Packager, xmlfile.mandatory]
|
||||||
@@ -130,7 +135,7 @@ class Source:
|
|||||||
|
|
||||||
|
|
||||||
class Package:
|
class Package:
|
||||||
__metaclass__ = xmlfile.autoxml
|
|
||||||
t_Name = [ types.StringType, xmlfile.mandatory ]
|
t_Name = [ types.StringType, xmlfile.mandatory ]
|
||||||
t_Summary = [ types.StringType, xmlfile.mandatory ]
|
t_Summary = [ types.StringType, xmlfile.mandatory ]
|
||||||
t_Description = [ types.StringType, xmlfile.mandatory ]
|
t_Description = [ types.StringType, xmlfile.mandatory ]
|
||||||
|
|||||||
+111
-27
@@ -11,7 +11,8 @@
|
|||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Authors: Eray Ozkural <eray@uludag.org.tr>
|
# 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 :( )
|
in xml.dom :( )
|
||||||
|
|
||||||
autoxml is a metaclass for automatic XML translation, using
|
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,
|
Method names are mixedCase for compatibility with minidom,
|
||||||
an old library
|
an old library.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# System
|
# System
|
||||||
@@ -45,7 +46,43 @@ class Error(pisi.Error):
|
|||||||
|
|
||||||
import types
|
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):
|
class autoxml(type):
|
||||||
@@ -70,7 +107,7 @@ class autoxml(type):
|
|||||||
root_tag = cls.tag
|
root_tag = cls.tag
|
||||||
|
|
||||||
# generate helper routines
|
# generate helper routines
|
||||||
initializers = []
|
inits = []
|
||||||
decoders = []
|
decoders = []
|
||||||
encoders = []
|
encoders = []
|
||||||
formatters = []
|
formatters = []
|
||||||
@@ -78,27 +115,20 @@ class autoxml(type):
|
|||||||
if var.startswith('t_') or var.startswith('a_'):
|
if var.startswith('t_') or var.startswith('a_'):
|
||||||
name = var[2:]
|
name = var[2:]
|
||||||
#print 'name', name
|
#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_'):
|
if var.startswith('t_'):
|
||||||
x = autoxml.gen_tag(cls, name)
|
x = autoxml.gen_tag(cls, name)
|
||||||
elif var.startswith('a_'):
|
elif var.startswith('a_'):
|
||||||
x = autoxml.gen_attr(cls, name)
|
x = autoxml.gen_attr(cls, name)
|
||||||
(decoder, encoder, formatter) = x
|
(init, decoder, encoder, formatter) = x
|
||||||
|
inits.append(init)
|
||||||
decoders.append(decoder)
|
decoders.append(decoder)
|
||||||
encoders.append(encoder)
|
encoders.append(encoder)
|
||||||
formatters.append(formatter)
|
formatters.append(formatter)
|
||||||
|
|
||||||
#print initializers
|
setattr(cls, 'initializers', inits)
|
||||||
|
|
||||||
setattr(cls, 'initializers', initializers)
|
|
||||||
def initialize(self):
|
def initialize(self):
|
||||||
for initializer in self.__class__.initializers:
|
for init in self.__class__.initializers:
|
||||||
initializer(self)
|
init(self)
|
||||||
setattr(cls, '__init__', initialize)
|
setattr(cls, '__init__', initialize)
|
||||||
|
|
||||||
setattr(cls, 'decoders', decoders)
|
setattr(cls, 'decoders', decoders)
|
||||||
@@ -125,20 +155,20 @@ class autoxml(type):
|
|||||||
return self.format()
|
return self.format()
|
||||||
setattr(cls, '__str__', string)
|
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):
|
def gen_tag(cls, tag):
|
||||||
# generate readers and writers for the tag
|
# generate readers and writers for the tag
|
||||||
val = getattr(cls, 't_' + tag)
|
val = getattr(cls, 't_' + tag)
|
||||||
tag_type = val[0]
|
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
|
# basic types
|
||||||
return autoxml.gen_basic_tag(cls, tag, val)
|
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):
|
def gen_attr(cls, tag):
|
||||||
"generate readers and writers for an attribute"
|
"generate readers and writers for an attribute"
|
||||||
@@ -158,6 +188,10 @@ class autoxml(type):
|
|||||||
token_type = val[0]
|
token_type = val[0]
|
||||||
req = val[1]
|
req = val[1]
|
||||||
|
|
||||||
|
def initialize(self):
|
||||||
|
#print 'init:', name
|
||||||
|
setattr(self, name, None)
|
||||||
|
|
||||||
def decode(self, node):
|
def decode(self, node):
|
||||||
text = readtext(node, token)
|
text = readtext(node, token)
|
||||||
if text:
|
if text:
|
||||||
@@ -181,7 +215,7 @@ class autoxml(type):
|
|||||||
if req == mandatory:
|
if req == mandatory:
|
||||||
return ['Mandatory argument not available']
|
return ['Mandatory argument not available']
|
||||||
|
|
||||||
def formatter(self):
|
def format(self):
|
||||||
#print 'format:', name
|
#print 'format:', name
|
||||||
if hasattr(self, name):
|
if hasattr(self, name):
|
||||||
return '%s: %s\n' % (token, str(getattr(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)
|
raise Error('Mandatory variable %s not available' % name)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
return decode, encode, formatter
|
return initialize, decode, encode, format
|
||||||
|
|
||||||
def gen_basic_attr(cls, attr, val):
|
def gen_basic_attr(cls, attr, val):
|
||||||
"""generate an attribute with a basic datatype"""
|
"""generate an attribute with a basic datatype"""
|
||||||
@@ -208,6 +242,56 @@ class autoxml(type):
|
|||||||
xml.addTextNodeUnder(node, tag, value)
|
xml.addTextNodeUnder(node, tag, value)
|
||||||
return autoxml.gen_basic(cls, tag, val, readtext, writetext)
|
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 = {
|
basic_cons_map = {
|
||||||
types.StringType : str,
|
types.StringType : str,
|
||||||
types.IntType : int
|
types.IntType : int
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import sys
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
sys.path.append('.')
|
sys.path.append('.')
|
||||||
|
sys.path.append('..')
|
||||||
|
|
||||||
runTestSuite = lambda(x): unittest.TextTestRunner(verbosity=2).run(x)
|
runTestSuite = lambda(x): unittest.TextTestRunner(verbosity=2).run(x)
|
||||||
|
|
||||||
|
|||||||
@@ -2,4 +2,8 @@
|
|||||||
<A href="http://www.cs.bilkent.edu.tr/~erayo">
|
<A href="http://www.cs.bilkent.edu.tr/~erayo">
|
||||||
<Name>Eray Ozkural</Name>
|
<Name>Eray Ozkural</Name>
|
||||||
<Number>868</Number>
|
<Number>868</Number>
|
||||||
|
<Projects>
|
||||||
|
<Project>pisi</Project>
|
||||||
|
<Project>noatun</Project>
|
||||||
|
</Projects>
|
||||||
</A>
|
</A>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class XmlFileTestCase(unittest.TestCase):
|
|||||||
a_href = [types.StringType, xmlfile.mandatory]
|
a_href = [types.StringType, xmlfile.mandatory]
|
||||||
#t_Projects = [ [types.StringType], xmlfile.mandatory]
|
#t_Projects = [ [types.StringType], xmlfile.mandatory]
|
||||||
a = A()
|
a = A()
|
||||||
#print a
|
print a
|
||||||
self.assertEqual(a.href, None)
|
self.assertEqual(a.href, None)
|
||||||
dom = mdom.parse('tests/sandbox/a.xml')
|
dom = mdom.parse('tests/sandbox/a.xml')
|
||||||
node = getNode(dom, 'A')
|
node = getNode(dom, 'A')
|
||||||
|
|||||||
Reference in New Issue
Block a user