* finish implementation of sourcedb

- hook it to update-repo
 - new command: list-sources
* start implementing emerge
* reorganize a bit for the upcoming changes
This commit is contained in:
Eray Özkural
2006-03-08 01:21:34 +00:00
parent 4edcb6954c
commit 67938150e3
9 changed files with 248 additions and 19 deletions
+2 -2
View File
@@ -12,9 +12,9 @@
# PiSi version
__version__ = "1.0.3"
__version__ = "1.0.4"
__dbversion__ = "1.0.2"
__dbversion__ = "1.0.4"
__all__ = [ 'api', 'config', 'packagedb', 'installdb', 'search' ]
+5 -4
View File
@@ -37,9 +37,9 @@ import pisi.sourcedb
import pisi.component as component
from pisi.index import Index
import pisi.cli
from pisi.operations import install, remove, upgrade
from pisi.build import build, build_until
from pisi.atomicoperations import resurrect_package
from pisi.operations import install, remove, upgrade, emerge
from pisi.build import build_until
from pisi.atomicoperations import resurrect_package, build
from pisi.metadata import MetaData
from pisi.files import Files
import pisi.search
@@ -73,13 +73,14 @@ def init(database = True, options = None, ui = None, comar = True):
ctx.filesdb = pisi.files.FilesDB()
ctx.componentdb = pisi.component.ComponentDB()
packagedb.init_db()
pisi.sourcedb.init()
ctx.sourcedb = pisi.sourcedb.init()
pisi.search.init(['summary', 'description'], ['en', 'tr'])
else:
ctx.repodb = None
ctx.installdb = None
ctx.filesdb = None
ctx.componentdb = None
ctx.sourcedb = None
ctx.ui.debug('PISI API initialized')
ctx.initialized = True
+8
View File
@@ -429,6 +429,14 @@ class Remove(AtomicOperation):
def remove_single(package_name):
Remove(package_name).run()
def build(package, authinfo=None):
# wrapper for build op`
if package.endswith('.xml'):
import pisi.build
pisi.build.build(package, authinfo)
#else:
# ...
def __is_virtual_upgrade(metadata):
pkg = metadata.package
+1 -1
View File
@@ -43,7 +43,7 @@ import pisi.component as component
class Error(pisi.Error):
pass
# Helper Functions
def get_file_type(path, pinfo_list, install_dir):
"""Return the file type of a path according to the given PathInfo
+43 -3
View File
@@ -320,10 +320,14 @@ def ignoredep_opt(self):
class Build(Command):
"""Build a PISI package using a pspec.xml file
Usage: build <pspec.xml>
Usage: build [<pspec.xml> | <sourcename>] ...
You can give a URI of the pspec.xml file. PISI will
fetch all necessary files and build the package for you.
Alternatively, you can give the name of a source package
to be downloaded from a repository containing sources.
"""
__metaclass__ = autocommand
@@ -350,8 +354,8 @@ fetch all necessary files and build the package for you.
self.init(database = True)
ctx.ui.info(_('Output directory: %s') % ctx.config.options.output_dir)
for arg in self.args:
pisi.api.build(arg, self.authInfo)
for x in self.args:
pisi.api.build(x, self.authInfo)
self.finalize()
@@ -935,6 +939,42 @@ Gives a brief list of PiSi components published in the repositories.
self.finalize()
class ListSources(Command):
"""List available sources
Usage: list-sources
Gives a brief list of sources published in the repositories.
"""
__metaclass__ = autocommand
def __init__(self):
super(ListSources, self).__init__()
name = ("list-sources", "ls")
def options(self):
self.parser.add_option("-l", "--long", action="store_true",
default=False, help=_("show in long format"))
def run(self):
self.init(True)
list = ctx.sourcedb.list()
list.sort()
for p in list:
source = ctx.sourcedb.get_source(p)
if self.options.long:
ctx.ui.info(unicode(component))
else:
lenp = len(p)
#if p in installed_list:
# p = colorize(p, 'cyan')
p = p + ' ' * max(0, 15 - lenp)
ctx.ui.info('%s - %s ' % (source.name, unicode(source.summary)))
self.finalize()
class ListUpgrades(Command):
"""List packages to be upgraded
+3
View File
@@ -26,6 +26,7 @@ import pisi.context as ctx
import pisi.specfile as specfile
import pisi.metadata as metadata
import pisi.packagedb as packagedb
import pisi.sourcedb as sourcedb
import pisi.util as util
from pisi.package import Package
from pisi.pxml.xmlfile import XmlFile
@@ -85,6 +86,8 @@ class Index(XmlFile):
ctx.componentdb.update_component(comp)
for pkg in self.packages:
pkgdb.add_package(pkg)
for src in self.sources:
ctx.sourcedb.add_source(src, repo)
def add_package(self, path, repo_uri):
package = Package(path, 'r')
+145
View File
@@ -41,6 +41,7 @@ class Error(pisi.Error):
pass
# high level operations
def install(packages, reinstall = False):
"""install a list of packages (either files/urls, or names)"""
@@ -495,3 +496,147 @@ def plan_remove(A):
G_f.write_graphviz(sys.stdout)
order = G_f.topological_sort()
return G_f, order
def expand_src_components(A):
Ap = set()
for x in A:
if ctx.componentdb.has_component(x):
Ap = Ap.union(ctx.componentdb.get_component(x).sources)
else:
Ap.add(x)
return Ap
##def build_names(A, rebuild = true):
##
## # A was a list, remove duplicates and expand components
## A_0 = A = expand_src_components(set(A))
## ctx.ui.debug('A = %s' % str(A))
##
## # filter packages that are already installed
## if not rebuild:
## Ap = set(filter(lambda x: not ctx.installdb.is_installed(x), A))
## d = A - Ap
## if len(d) > 0:
## ctx.ui.warning(_('Not re-building the following packages: ') +
## util.strlist(d))
## A = Ap
##
## if len(A)==0:
## ctx.ui.info(_('No packages to build.'))
## return
##
## if not ctx.config.get_option('ignore_dependency'):
## G_f, order_inst = plan_build_pkg_names(A)
## else:
## G_f = None
## order_inst = []
##
## ctx.ui.info(_("""The following minimal list of packages will be installed
##in the respective order to satisfy dependencies:
##""") + util.strlist(order))
##
## if ctx.get_option('dry_run'):
## return
##
## if len(order) > len(A_0):
## if not ctx.ui.confirm(_('There are extra packages due to dependencies. Do you want to continue?')):
## return False
##
## ctx.ui.notify(ui.packagestogo, order = order)
##
## for x in order:
## atomicoperations.install_single_name(x)
##
##def plan_build_names(A):
## # try to construct a pisi graph of packages to
## # install / reinstall
##
## G_f = pgraph.PGraph(packagedb) # construct G_f
##
## # find the "install closure" graph of G_f by package
## # set A using packagedb
## for x in A:
## G_f.add_package(x)
## B = A
##
## while len(B) > 0:
## Bp = set()
## for x in B:
## pkg = packagedb.get_package(x)
## for dep in pkg.runtimeDependencies():
## ctx.ui.debug('checking %s' % str(dep))
## # we don't deal with already *satisfied* dependencies
## if not dependency.installed_satisfies_dep(dep):
## if not dep.package in G_f.vertices():
## Bp.add(str(dep.package))
## G_f.add_dep(x, dep)
## B = Bp
## if ctx.config.get_option('debug'):
## G_f.write_graphviz(sys.stdout)
## order = G_f.topological_sort()
## order.reverse()
## check_conflicts(order)
## return G_f, order
def emerge(A):
# A was a list, remove duplicates and expand components
A_0 = A = expand_src_components(set(A))
ctx.ui.debug('A = %s' % str(A))
if len(A)==0:
ctx.ui.info(_('No packages to build.'))
return
if not ctx.config.get_option('ignore_dependency'):
G_f, order = plan_emerge(A)
else:
G_f = None
order_inst = []
ctx.ui.info(_("""The following minimal list of packages will be built and
installed in the respective order to satisfy dependencies:
""") + util.strlist(order))
if ctx.get_option('dry_run'):
return
if len(order) > len(A_0):
if not ctx.ui.confirm(_('There are extra packages due to dependencies. Do you want to continue?')):
return False
ctx.ui.notify(ui.packagestogo, order = order)
for x in order:
atomicoperations.install_single_name(x)
def plan_emerge(A):
# try to construct a pisi graph of packages to
# install / reinstall
G_f = pgraph.PGraph(packagedb) # construct G_f
# find the "install closure" graph of G_f by package
# set A using packagedb
for x in A:
G_f.add_package(x)
B = A
while len(B) > 0:
Bp = set()
for x in B:
pkg = packagedb.get_package(x)
for dep in pkg.runtimeDependencies():
ctx.ui.debug('checking %s' % str(dep))
# we don't deal with already *satisfied* dependencies
if not dependency.installed_satisfies_dep(dep):
if not dep.package in G_f.vertices():
Bp.add(str(dep.package))
G_f.add_dep(x, dep)
B = Bp
if ctx.config.get_option('debug'):
G_f.write_graphviz(sys.stdout)
order = G_f.topological_sort()
order.reverse()
check_conflicts(order)
return G_f, order
+1 -1
View File
@@ -51,7 +51,7 @@ class RepoDB(object):
# initialize package/source dbs
for x in self.list():
packagedb.add_db(x)
def close(self):
self.d.close()
+40 -8
View File
@@ -16,6 +16,9 @@ package source database
interface for update/query to local package repository
we basically store everything in sourceinfo class
yes, we are cheap
to handle multiple repositories, for sources, we
store a set of repositories in which the source appears.
the actual guy to take is determined from the repo order.
"""
import os
@@ -28,31 +31,60 @@ _ = __trans.ugettext
import pisi.util as util
import pisi.context as ctx
import pisi.lockeddbshelve as shelve
import pisi.repodb
class SourceDB(object):
def __init__(self, id = 'repo'):
self.d = shelve.LockedDBShelf('source-%s' % id)
def __init__(self):
self.d = shelve.LockedDBShelf('source')
def close(self):
self.d.close()
def list(self):
list = []
for (pkg, x) in self.d.items():
list.append(pkg) # for some reason we couldn't return self.d.items()!! --exa
return list
def has_source(self, name):
name = str(name)
return self.d.has_key(name)
def get_source(self, name):
name = str(name)
return self.d[name]
s = self.d[name]
order = ctx.repodb.list()
for repo in order:
if s.has_key(repo):
return s[repo]
return None
def add_source(self, source_info):
def add_source(self, source_info, repo, txn = None):
assert not source_info.errors()
name = str(source_info.name)
self.d[name] = source_info
def remove_source(self, name):
repo = str(repo)
def proc(txn):
if not self.d.has_key(name):
s = dict()
else:
s = self.d[name]
s[repo] = source_info
self.d[name] = s
self.d.txn_proc(proc, txn)
def remove_source(self, name, repo):
name = str(name)
del self.d[name]
repo = str(repo)
def proc(txn):
#assert self.has_source(name)
s = self.d[name]
s.remove(repo)
if (len(s)==0):
del self.d[name]
else:
self.d[name] = s
self.d.txn_proc(proc, txn)
sourcedb = None