diff --git a/src/pisi/context.py b/src/pisi/context.py index 50e7c645..d3db9a2d 100644 --- a/src/pisi/context.py +++ b/src/pisi/context.py @@ -2,27 +2,12 @@ # PISI configuration (static and dynamic) from specfile import SpecFile +import oo class Constants: - """Pisi constants""" - class __const: - """Constant members implementation""" - class ConstError(TypeError): - pass + "Pisi constants" - def __setattr__(self, name, value): - if self.__dict__.has_key(name): - raise self.ConstError, "Can't rebind constant: %s" % name - # Binding an attribute once to a const is available - self.__dict__[name] = value - - def __delattr__(self, name): - if self.__dict__.has_key(name): - raise self.ConstError, "Can't unbind constant: %s" % name - # we don't have an attribute by this name - raise NameError, name - - c = __const() + c = oo.const() def __init__(self): self.c.lib_dir_suffix = "/var/lib/pisi" @@ -58,50 +43,54 @@ class Context(object): def __init__(self): self.const = Constants() # self.c.destdir = '' # install default to root by default - self.const.destdir = './tmp' # only for ALPHA + self.destdir = './tmp' # only for ALPHA # the idea is that destdir can be set with --destdir=... - def _specFile(self, pspecfile): + def setSpecFile(self, pspecfile): self.pspecfile = pspecfile spec = SpecFile() spec.read(pspecfile) spec.verify() # check pspec integrity - self.spec = spec def lib_dir(self): - return self.const.destdir + self.const.lib_dir_suffix + return self.destdir + self.const.lib_dir_suffix def db_dir(self): - return self.const.destdir + self.const.db_dir_suffix + return self.destdir + self.const.db_dir_suffix def archives_dir(self): - return self.const.destdir + self.const.archives_dir_suffix + return self.destdir + self.const.archives_dir_suffix def tmp_dir(self): - return self.const.destdir + self.const.tmp_dir_suffix + return self.destdir + self.const.tmp_dir_suffix def build_work_dir(self): packageDir = self.spec.source.name + '-' \ + self.spec.source.version + '-' + self.spec.source.release - return self.const.destdir + self.const.tmp_dir_suffix \ + return self.destdir + self.const.tmp_dir_suffix \ + '/' + packageDir + self.const.build_work_dir_suffix def build_install_dir(self): packageDir = self.spec.source.name + '-' \ + self.spec.source.version + '-' + self.spec.source.release - return self.const.destdir + self.const.tmp_dir_suffix \ + return self.destdir + self.const.tmp_dir_suffix \ + '/' + packageDir + self.const.build_install_dir_suffix __instance = __impl() - def __init__(self, pspecfile): - self.__instance._specFile(pspecfile) + def __init__(self, pspecfile = None): + if pspecfile != None: + self.__instance.setSpecFile(pspecfile) def __getattr__(self, attr): return getattr(self.__instance, attr) def __setattr__(self, attr, value): return setattr(self.__instance, attr, value) + + +# create a default context WITH NO PSPEC +ctx = Context() diff --git a/src/pisi/installdb.py b/src/pisi/installdb.py index aa970489..674af9b6 100644 --- a/src/pisi/installdb.py +++ b/src/pisi/installdb.py @@ -2,41 +2,51 @@ # installation database # maintainer: eray and caglar -from context import Context -import util +import os import bsddb.dbshelve as shelve -util.check_dir(Context.db_dir()) -d = shelve.open(Context.db_dir() + '/install.bdb') -files_dir = Context.archives_dir() + "/files" +from context import ctx +import util + +util.check_dir(ctx.db_dir()) +d = shelve.open(ctx.db_dir() + '/install.bdb') +files_dir = ctx.archives_dir() + "/files" class InstallDBError(Exception): pass def files_name(name, version, release): - return files + '/' + name + '-' + version + '-' + release + return files_dir + '/' + name + '-' + version + '-' + release + +def files(n, v, r): + return file(files_name(n,v,r)) def is_recorded(name, version, release): - key = (name, version, release) + key = name + version + release return d.has_key(key) def is_installed(name, version, release): - key = (name, version, release) - return is_recorded(key) and d[key]=='i' + key = name + version + release + return is_recorded(name,version,release) and d[key]=='i' + +def is_removed(name, version, release): + key = name + version + release + return is_recorded(name,version,release) and d[key]=='r' def install(name, version, release, files_xml): - key = (name, version, release) - if isInstalled(key): + key = name + version + release + if is_installed(name, version, release): raise InstallDBError("already installed") d[key] = 'i' util.copy_file(files_xml, files_name(name, version, release)) def remove(name, version, release): - key = (name, version, release) + key = name + version + release d[key] = 'r' def purge(name, version, release): - util.remove_file(files_name(name, version, release)) + os.unlink(files_name(name, version, release)) + key = name + version + release del d[key] diff --git a/src/pisi/oo.py b/src/pisi/oo.py new file mode 100644 index 00000000..4cbbd866 --- /dev/null +++ b/src/pisi/oo.py @@ -0,0 +1,20 @@ +# OO extensions +# thes are really cool, you can't do this in C++ :) + +class const: + "Constant members implementation" + class ConstError(TypeError): + pass + + def __setattr__(self, name, value): + if self.__dict__.has_key(name): + raise self.ConstError, "Can't rebind constant: %s" % name + # Binding an attribute once to a const is available + self.__dict__[name] = value + + def __delattr__(self, name): + if self.__dict__.has_key(name): + raise self.ConstError, "Can't unbind constant: %s" % name + # we don't have an attribute by this name + raise NameError, name + diff --git a/src/pisi/util.py b/src/pisi/util.py index 3f16d2a6..7c4e55bd 100644 --- a/src/pisi/util.py +++ b/src/pisi/util.py @@ -6,6 +6,14 @@ import os import sys import md5 +class FileError(Exception): + pass + +# shorthand to check if a file exists +def check_file(file, mode = os.F_OK): + if not os.access(file, mode): + raise FileError("File " + file + " not found") + # check if directory exists, and create if it doesn't # works recursively # FIXME: could have a better name @@ -31,12 +39,13 @@ def purge_dir(top): os.rmdir(os.path.join(root, name)) # TODO: -def copy_file(): - pass - -def remove_file(): - # unlink file - pass +def copy_file(s,d): + check_file(s) + check_dir(os.path.dirname(d)) + fs = file(s, 'rb') + fd = file(d, 'wb') + for l in fs: + fd.write(l) def copy_dir(): pass diff --git a/src/unittests/installdbtests.py b/src/unittests/installdbtests.py new file mode 100644 index 00000000..abc9ad94 --- /dev/null +++ b/src/unittests/installdbtests.py @@ -0,0 +1,35 @@ + +import unittest +import os + +from pisi import installdb +from pisi import util +from pisi import context + +class InstallDBTestCase(unittest.TestCase): + def setUp(self): + self.ctx = context.Context() + pass + + def testRemoveDummy(self): + installdb.remove('installtest', '0.1', '2') + self.assert_(not installdb.is_installed('installtest', '0.1', '2')) + + def testInstall(self): + installdb.remove('installtest', '0.1', '2') + installdb.install('installtest', '0.1', '2', './unittests/sandbox/files.xml') + f = installdb.files('installtest', '0.1', '2') + a = f.readlines() + self.assertEqual(a[0], 'placeholder\n') + self.assert_(installdb.is_installed('installtest', '0.1', '2')) + + def testRemovePurge(self): + installdb.install('installtest', '0.1', '2', './unittests/sandbox/files.xml') + self.assert_(installdb.is_installed('installtest', '0.1', '2')) + installdb.remove('installtest', '0.1', '2') + self.assert_(installdb.is_removed('installtest', '0.1', '2')) + installdb.purge('installtest', '0.1', '2') + self.assert_(not installdb.is_recorded('installtest', '0.1', '2')) + self.assert_(not os.access(installdb.files_name('installtest', '0.1', '2'), os.F_OK)) + +suite = unittest.makeSuite(InstallDBTestCase) diff --git a/src/unittests/run.py b/src/unittests/run.py index be068c4e..d8e4038b 100755 --- a/src/unittests/run.py +++ b/src/unittests/run.py @@ -11,12 +11,14 @@ def run_all(): import contexttests import fetchertests import archivetests + import installdbtests alltests = unittest.TestSuite(( specfiletests.suite, contexttests.suite, fetchertests.suite, - archivetests.suite + archivetests.suite, + installdbtests.suite )) runTestSuite(alltests) @@ -26,10 +28,10 @@ if __name__ == "__main__": if len(args) > 1: # run modules given from the command line tests = sys.argv[1:] for test in tests: - module = __import__(test) + module = __import__(test + 'tests') print "\nRunning tests in '%s'...\n" % (test) runTestSuite(module.suite) else: # run all tests - print "\nRunning all test in an order...\n" + print "\nRunning all tests in order...\n" run_all()