* alpha-light testi multi-install olayini test ediyor, packages

symlinki ister, deneyin isterseniz cok zor degil. once
  ln -s path/to/pisi/repo packages
  tests/alpha-light.sh
  le su anki debug outputunu gorursunuz
* pgraph pisi relation'larini tutan bir graph'tir
* cat-db'yi update et
* specfile'a bos constructor'lar ekle, eksik attribute'lari hallet
  verify'lari elden gecir vs.
* build: build nosunu 0 yap, FIXME de
* metadata:
  - version,release,build yaz
  - packageURI diye bir tag ekle metadata.package'a
  - version ve release'i hem source'a hem package'a yaz, belki de iyi
    bir fikir degil uhuhuhuh
* multi-install algoritmasinin bir kismini yaz
* graph: 
  - graphviz outputu sagla
  - edge data'larini implement et
* daha varsa bilemeyecegim artik
This commit is contained in:
Eray Özkural
2005-07-28 02:28:43 +00:00
parent 6b920f5f26
commit a347263871
11 changed files with 299 additions and 101 deletions
+4
View File
@@ -196,6 +196,10 @@ class PisiBuild:
some additional information."""
metadata = MetaData()
metadata.fromSpec(self.spec.source, package)
# FIXME: MEREEEEEN :)
metadata.package.build = 0 # BOGUS. WRONG.
metadata.package.distribution = config.values.general.distribution
metadata.package.distributionRelease = config.values.general.distribution_release
metadata.package.architecture = "Any"
+39 -7
View File
@@ -1,7 +1,10 @@
# the most simple minded digraph class ever
# for python 2.3 compatibility
from sets import Set as set
import sys
ver = sys.version_info
if ver[0] == 2 and ver[1] == 4:
from sets import Set as set
class CycleError:
pass
@@ -12,7 +15,7 @@ class digraph(object):
self.__v = set()
self.__adj = {}
self.__vdata = {}
#self.__edata = {}
self.__edata = {}
def vertices(self):
"return set of vertex descriptors"
@@ -38,15 +41,21 @@ class digraph(object):
self.__adj[u] = set()
if data:
self.__vdata[u] = data
self.__edata[u] = {}
def add_edge(self, u, v, edata = None):
def add_edge(self, u, v, edata = None, udata = None, vdata = None):
"add edge u -> v"
if not u in self.__v:
self.add_vertex(u)
self.add_vertex(u, udata)
if not v in self.__v:
self.add_vertex(v)
self.add_vertex(v, vdata)
self.__adj[u].add(v)
#if edata != None:
if edata != None:
self.__edata[u][v] = edata
def add_biedge(self, u, v, edata = None):
self.add_edge(u, v, edata)
self.add_edge(v, u, edata)
def set_vertex_data(self, u, data):
self.__vdata[u] = data
@@ -54,6 +63,9 @@ class digraph(object):
def vertex_data(self, u):
return self.__vdata[u]
def edge_data(self, u, v):
return self.__edata[u][v]
def has_vertex(self, u):
return u in self.__v
@@ -105,5 +117,25 @@ class digraph(object):
self.dfs(lambda u: l.append(u))
l.reverse()
return l
def write_graphviz(self, f):
f.write('digraph G {\n')
for u in self.vertices():
f.write(u)
self.write_graphviz_vlabel(f, u)
f.write(';\n')
f.write('\n')
for u in self.vertices():
for v in self.adj(u):
f.write(u + ' -- ' + v)
self.write_graphviz_elabel(f, u, v)
f.write(';\n')
f.write('\n')
f.write('}\n')
def write_graphviz_vlabel(self, f, u):
pass
def write_graphviz_elabel(self, f, u, v):
pass
+5 -2
View File
@@ -50,11 +50,12 @@ class Index(XmlFile):
self.writexml(filename)
self.unlink()
def index(self, repo_dir):
def index(self, repo_uri):
self.repo_dir = repo_uri
import os
from os.path import join, getsize
for root, dirs, files in os.walk(repo_dir):
for root, dirs, files in os.walk(repo_uri):
for fn in files:
if fn.endswith('.pisi'):
ui.info('Adding ' + fn + ' to package index\n')
@@ -73,6 +74,8 @@ class Index(XmlFile):
md = metadata.MetaData()
md.read(config.install_dir() + '/metadata.xml')
# TODO: in the future we'll do all of this with purl/pfile/&helpers
md.package.packageURI = path
# check package semantics
if md.verify():
self.packages.append(md.package)
+26 -6
View File
@@ -17,6 +17,8 @@ class SourceInfo:
self.name = getNodeText(node, "Name")
self.homepage = getNodeText(node, "HomePage")
self.packager = specfile.PackagerInfo(getNode(node, "Packager"))
else:
self.homepage = None
def elt(self, xml):
node = xml.newNode("Source")
@@ -33,24 +35,40 @@ class SourceInfo:
class PackageInfo(specfile.PackageInfo):
def __init__(self, node=None):
def __init__(self, node = None):
if node:
specfile.PackageInfo.__init__(self, node)
self.version = getNodeText(node, "Version")
self.release = getNodeText(node, "Release")
self.build = int(getNodeText(node, "Build"))
self.distribution = getNodeText(node, "Distribution")
self.distributionRelease = getNodeText(node, "DistributionRelease")
self.architecture = getNodeText(node, "Architecture")
self.installedSize = int(getNodeText(node, "InstalledSize"))
self.packageURI = getNodeText(node, "PackageURI")
else:
self.packageURI = None
def elt(self, xml):
node = specfile.PackageInfo.elt(self, xml)
xml.addTextNodeUnder(node, "Version", self.version)
xml.addTextNodeUnder(node, "Release", self.release)
xml.addTextNodeUnder(node, "Build", str(self.build))
xml.addTextNodeUnder(node, "Distribution", self.distribution)
xml.addTextNodeUnder(node, "DistributionRelease", self.distributionRelease)
xml.addTextNodeUnder(node, "Architecture", self.architecture)
xml.addTextNodeUnder(node, "InstalledSize", str(self.installedSize))
if self.packageURI:
xml.addTextNodeUnder(node, "PackageURI", str(self.packageURI))
return node
def verify(self):
return specfile.PackageInfo.verify(self)
ret = specfile.PackageInfo.verify(self) and self.build!=None
ret = ret and self.distribution!=None
ret = ret and self.distributionRelease!=None
ret = ret and self.architecture!=None and self.installedSize!=None
ret = ret and self.packageURI!=None
return ret
def __str__(self):
s = specfile.PackageInfo.__str__(self)
@@ -82,16 +100,18 @@ class MetaData(XmlFile):
self.package.providesComar = pkg.providesComar
self.package.requiresComar = pkg.requiresComar
self.package.additionalFiles = pkg.additionalFiles
# FIXME: right way to do it?
self.source.version = src.version
self.source.release = src.release
self.package.version = src.version
self.package.release = src.release
def read(self, filename):
self.readxml(filename)
self.source = SourceInfo(self.getNode("Source"))
self.package = PackageInfo(self.getNode("Package"))
self.package.version = self.package.history[0].version
self.package.release = self.package.history[0].release
def write(self, filename):
self.newDOM()
self.addChild(self.source.elt(self))
+42
View File
@@ -0,0 +1,42 @@
# PISI package relation graph that represents the state of packagedb
from packagedb import packagedb
from sourcedb import sourcedb
from graph import *
# Cache the results from packagedb queries in a graph
class PGraph(digraph):
def __init__(self):
super(PGraph, self).__init__()
def add_dep(self, pkg, depinfo):
pkg1data = None
if not pkg in self.vertices():
pkg1 = packagedb.get_package(pkg)
pkg2data = None
if not pkg in self.vertices():
pkg2 = packagedb.get_package(depinfo.package)
self.add_edge(pkg, depinfo.package, ('d', depinfo),
(pkg1.version, pkg1.release),
(pkg2.version, pkg2.release) )
def add_conflict(self, pkg, conflinfo):
pkg1data = None
if not pkg in self.vertices():
pkg1 = packagedb.get_package(pkg)
pkg2data = None
if not pkg in self.vertices():
pkg2 = packagedb.get_package(depinfo.package)
self.add_biedge(pkg, conflinfo.package, ('c', conflinfo)
(pkg1.version, pkg1.release),
(pkg2.version, pkg2.release) )
def write_graphviz_vlabel(self, f, u):
(v, r) = self.vertex_data(u)
f.write('[ ' + str(u) + '(' + str(v) + ',' + str(r) + ') ]')
+101 -71
View File
@@ -16,9 +16,10 @@ from xmlfile import XmlFile
from ui import ui
class PackagerInfo:
def __init__(self, node):
self.name = getNodeText(getNode(node, "Name"))
self.email = getNodeText(getNode(node, "Email"))
def __init__(self, node = None):
if node:
self.name = getNodeText(getNode(node, "Name"))
self.email = getNodeText(getNode(node, "Email"))
def elt(self, xml):
node = xml.newNode("Packager")
@@ -32,11 +33,14 @@ class PackagerInfo:
return True
class AdditionalFileInfo:
def __init__(self, node):
self.filename = getNodeText(node)
self.target = getNodeAttribute(node, "target")
self.permission = getNodeAttribute(node, "permission")
self.owner = getNodeAttribute(node, "owner")
def __init__(self, node = None):
if node:
self.filename = getNodeText(node)
self.target = getNodeAttribute(node, "target")
self.permission = getNodeAttribute(node, "permission")
self.owner = getNodeAttribute(node, "owner")
else:
self.permission = self.owner = None
def elt(self, xml):
node = xml.newNode("AdditionalFile")
@@ -53,18 +57,25 @@ class AdditionalFileInfo:
return True
class PatchInfo:
def __init__(self, node):
self.filename = getNodeText(node)
self.compressionType = getNodeAttribute(node, "compressionType")
self.level = getNodeAttribute(node, "level")
def __init__(self, node = None):
if node:
self.filename = getNodeText(node)
self.compressionType = getNodeAttribute(node, "compressionType")
self.level = getNodeAttribute(node, "level")
else:
self.compressionType = None
if not self.level:
self.level = 0
else:
self.level = int(self.level)
def elt(self, xml):
node = xml.newNode("Patch")
xml.addText(node, self.filename)
if self.compressionType:
node.setAttribute("compressionType", self.compressionType)
if self.level:
node.setAttribute("level", self.level)
return node
def verify(self):
@@ -72,10 +83,16 @@ class PatchInfo:
return True
class DepInfo:
def __init__(self, node):
self.package = getNodeText(node).strip()
self.versionFrom = getNodeAttribute(node, "versionFrom")
self.versionTo = getNodeAttribute(node, "versionTo")
def __init__(self, node = None):
if node:
self.package = getNodeText(node).strip()
self.versionFrom = getNodeAttribute(node, "versionFrom")
self.versionTo = getNodeAttribute(node, "versionTo")
self.releaseFrom = getNodeAttribute(node, "releaseFrom")
self.releaseTo = getNodeAttribute(node, "releaseTo")
else:
self.versionFrom = self.versionTo = None
self.releaseFrom = self.releaseFrom = None
def elt(self, xml):
node = xml.newNode("Dependency")
@@ -84,6 +101,10 @@ class DepInfo:
node.setAttribute("versionFrom", self.versionFrom)
if self.versionTo:
node.setAttribute("versionTo", self.versionTo)
if self.releaseFrom:
node.setAttribute("releaseFrom", self.versionFrom)
if self.releaseTo:
node.setAttribute("releaseTo", self.versionTo)
return node
def verify(self):
@@ -91,11 +112,14 @@ class DepInfo:
return True
class UpdateInfo:
def __init__(self, node):
self.date = getNodeText(getNode(node, "Date"))
self.version = getNodeText(getNode(node, "Version"))
self.release = getNodeText(getNode(node, "Release"))
self.type = getNodeText(getNode(node, "Type"))
def __init__(self, node = None):
if node:
self.date = getNodeText(getNode(node, "Date"))
self.version = getNodeText(getNode(node, "Version"))
self.release = getNodeText(getNode(node, "Release"))
self.type = getNodeText(getNode(node, "Type"))
else:
self.type = None
def elt(self, xml):
node = xml.newNode("Update")
@@ -113,9 +137,10 @@ class UpdateInfo:
return True
class PathInfo:
def __init__(self, node):
self.pathname = getNodeText(node)
self.fileType = getNodeAttribute(node, "fileType")
def __init__(self, node = None):
if node:
self.pathname = getNodeText(node)
self.fileType = getNodeAttribute(node, "fileType")
if not self.fileType:
self.fileType = "other"
@@ -130,9 +155,10 @@ class PathInfo:
return True
class ComarProvide:
def __init__(self, node):
self.om = getNodeText(node)
self.script=getNodeAttribute(node, "script")
def __init__(self, node = None):
if node:
self.om = getNodeText(node)
self.script=getNodeAttribute(node, "script")
def elt(self, xml):
node = xml.newNode("COMAR")
@@ -148,27 +174,30 @@ class ComarProvide:
class SourceInfo:
"""A structure to hold source information. Source information is
located under <Source> tag in PSPEC file."""
def __init__(self, node):
self.name = getNodeText(node, "Name")
self.homepage = getNodeText(node, "HomePage")
self.packager = PackagerInfo(getNode(node, "Packager"))
self.summary = getNodeText(node, "Summary")
self.description = getNodeText(node, "Description")
self.license = map(getNodeText, getAllNodes(node, "License"))
self.isa = map(getNodeText, getAllNodes(node, "IsA"))
self.partof = getNodeText(node, "PartOf")
archiveNode = getNode(node, "Archive")
self.archiveUri = getNodeText(archiveNode).strip()
self.archiveName = basename(self.archiveUri)
self.archiveType = getNodeAttribute(archiveNode, "type")
self.archiveSHA1 = getNodeAttribute(archiveNode, "sha1sum")
patchElts = getAllNodes(node, "Patches/Patch")
self.patches = [PatchInfo(p) for p in patchElts]
buildDepElts = getAllNodes(node, "BuildDependencies/Dependency")
self.buildDeps = [DepInfo(d) for d in buildDepElts]
historyElts = getAllNodes(node, "History/Update")
self.history = [UpdateInfo(x) for x in historyElts]
def __init__(self, node = None):
if node:
self.name = getNodeText(node, "Name")
self.homepage = getNodeText(node, "HomePage")
self.packager = PackagerInfo(getNode(node, "Packager"))
self.summary = getNodeText(node, "Summary")
self.description = getNodeText(node, "Description")
self.license = map(getNodeText, getAllNodes(node, "License"))
self.isa = map(getNodeText, getAllNodes(node, "IsA"))
self.partof = getNodeText(node, "PartOf")
archiveNode = getNode(node, "Archive")
self.archiveUri = getNodeText(archiveNode).strip()
self.archiveName = basename(self.archiveUri)
self.archiveType = getNodeAttribute(archiveNode, "type")
self.archiveSHA1 = getNodeAttribute(archiveNode,
"sha1sum")
patchElts = getAllNodes(node, "Patches/Patch")
self.patches = [PatchInfo(p) for p in patchElts]
buildDepElts = getAllNodes(node,
"BuildDependencies/Dependency")
self.buildDeps = [DepInfo(d) for d in buildDepElts]
historyElts = getAllNodes(node, "History/Update")
self.history = [UpdateInfo(x) for x in historyElts]
def elt(self, xml):
node = xml.newNode("Source")
xml.addTextNodeUnder(node, "Name", self.name)
@@ -198,9 +227,8 @@ class SourceInfo:
if not self.description: return False
if not self.packager: return False
if not self.license: return False
if not self.archiveUri or \
not self.archiveType or \
not self.archiveSHA1: return False
if (not self.archiveUri) or (not self.archiveType): return False
if not self.archiveSHA1: return False
if len(self.history) <= 0: return False
if not self.packager.verify(): return False
@@ -217,26 +245,27 @@ class PackageInfo(object):
"""A structure to hold package information. Package information is
located under <Package> tag in PSPEC file. Opposite to Source each
PSPEC file can have more than one Package tag."""
def __init__(self, node):
self.name = getNodeText(node, "Name")
self.summary = getNodeText(node, "Summary")
self.description = getNodeText(node, "Description")
self.isa = map(getNodeText, getAllNodes(node, "IsA"))
self.partof = getNodeText(node, "PartOf")
self.license = map(getNodeText, getAllNodes(node, "License"))
rtDepElts = getAllNodes(node, "RuntimeDependencies/Dependency")
self.runtimeDeps = [DepInfo(x) for x in rtDepElts]
self.paths = [PathInfo(x) for x in getAllNodes(node, "Files/Path")]
historyElts = getAllNodes(node, "History/Update")
self.history = [UpdateInfo(x) for x in historyElts]
conflElts = getAllNodes(node, "Conflicts/Package")
self.conflicts = map(getNodeText, conflElts)
provComarElts = getAllNodes(node, "Provides/COMAR")
self.providesComar = [ComarProvide(x) for x in provComarElts]
reqComarElts = getAllNodes(node, "Requires/COMAR")
self.requiresComar = map(getNodeText, reqComarElts)
aFilesElts = getAllNodes(node, "AdditionalFiles/AdditionalFile")
self.additionalFiles = [AdditionalFileInfo(f) for f in aFilesElts]
def __init__(self, node = None):
if node:
self.name = getNodeText(node, "Name")
self.summary = getNodeText(node, "Summary")
self.description = getNodeText(node, "Description")
self.isa = map(getNodeText, getAllNodes(node, "IsA"))
self.partof = getNodeText(node, "PartOf")
self.license = map(getNodeText, getAllNodes(node, "License"))
rtDepElts = getAllNodes(node, "RuntimeDependencies/Dependency")
self.runtimeDeps = [DepInfo(x) for x in rtDepElts]
self.paths = [PathInfo(x) for x in getAllNodes(node, "Files/Path")]
historyElts = getAllNodes(node, "History/Update")
self.history = [UpdateInfo(x) for x in historyElts]
conflElts = getAllNodes(node, "Conflicts/Package")
self.conflicts = map(getNodeText, conflElts)
provComarElts = getAllNodes(node, "Provides/COMAR")
self.providesComar = [ComarProvide(x) for x in provComarElts]
reqComarElts = getAllNodes(node, "Requires/COMAR")
self.requiresComar = map(getNodeText, reqComarElts)
aFilesElts = getAllNodes(node, "AdditionalFiles/AdditionalFile")
self.additionalFiles = [AdditionalFileInfo(f) for f in aFilesElts]
def elt(self, xml):
node = xml.newNode("Package")
@@ -283,6 +312,7 @@ class PackageInfo(object):
def __str__(self):
s = 'Name: ' + self.name
s += '\nSummary: ' + self.summary
s += '\nDescription: ' + self.description
return s
class SpecFile(XmlFile):
+65 -4
View File
@@ -2,20 +2,81 @@
# a facade to the entire PISI system
import os
import sys
from config import config
from constants import const
from ui import ui
from purl import PUrl
import util
import dependency
import pgraph
import operations
from packagedb import packagedb
def install(packages):
"""install a list of packages (either files, urls, or names)"""
#TODO: this for loop is just a placeholder
"""install a list of packages (either files/urls, or names)"""
# determine if this is a list of files/urls or names
if packages[0].endswith(const.package_prefix): # they all have to!
install_pkg_files(packages)
else:
install_pkg_names(packages)
def install_pkg_files(packages):
"""install a number of pisi package files"""
# read the package information into memory first
# regardless of which distribution they come from
d_t = {}
for x in packages:
operations.install_single(x)
package = Package(x)
package.read()
d_t[package.name] = package.metadata
# for this case, we have to determine the dependencies
# that aren't already satisfied and try to install them
# from the repository.
dep_unsatis = []
for name in d_t.keys():
pkg = d_t[name]
deps = pkg.runtimeDeps
if not dependency.satisfiesDep(pkg, deps):
dep_unsatis.append(deps)
# now determine if these unsatisfied dependencies could
# be satisfied by installing packages from the repo
# if so, then invoke install_pkg_names
install_pkg_names([x.package for x in dep_unsatis])
def install_pkg_names(A):
"""This is the real thing. It installs packages from
the repository, trying to perform a minimum number of
installs"""
# try to construct a pisi graph of packages to
# install / reinstall
G_f = pgraph.PGraph() # construct G_f
# find the "install closure" graph of G_f by package
# set A using packagedb
B = A
state = {}
while len(B) > 0:
Bp = set()
for x in B:
pkg = packagedb.get_package(x)
#print pkg
for dep in pkg.runtimeDeps:
# we don't deal with satisfied dependencies
if not dependency.satisfiesDep(pkg, dep):
if not dep.package in G_f.vertices():
Bp.add(str(dep.package))
G_f.add_dep(x, dep)
B = Bp
G_f.write_graphviz(sys.stdout)
def remove(packages):
#TODO: this for loop is just a placeholder
+1 -1
View File
@@ -166,7 +166,7 @@ def dir_size(dir):
yield sum([getsize(join(root, name)) for name in files if not islink(join(root,name))])
return sum( sizes() )
def copy_file(src, dest):
def copy_file(src,dest):
"""copy source file to destination file"""
check_file(src)
check_dir(os.path.dirname(dest))
+5 -4
View File
@@ -2,9 +2,10 @@
pwd
PATH=$PATH:.
pisi-cli build packages/s/star*/pspec.xml
set -x
pisi-cli build packages/z/zip/pspec.xml packages/u/unzip/pspec.xml
pisi-cli index .
pisi-cli updatedb pisi-index.xml
pisi-cli install start*pisi
echo database contents
find tmp -iname '*.bdb' | xargs ./cat-db.py
# database contents
find tmp -iname '*.bdb' | xargs tools/cat-db.py
pisi-cli install zip
+7 -6
View File
@@ -1,10 +1,11 @@
#!/bin/sh
pwd
rm -rf tmp
./pisi-build samples/*/pspec.xml
./pisi-index .
./pisi-updatedb pisi-index.xml
./pisi-install start*pisi
./pisi-install popt*pisi
#rm -rf tmp
pisi-cli build packages/*/*/pspec.xml
pisi-cli -index .
pisi-cli -updatedb pisi-index.xml
pisi-cli -install start*pisi
pisi-cli -install popt*pisi
find tmp -iname '*.bdb' | xargs ./cat-db.py
+4
View File
@@ -5,6 +5,10 @@
import sys
import bsddb.dbshelve as shelve
sys.path.append('.')
import pisi
d = shelve.open( sys.argv[1] )
for (k, data) in d.iteritems():