* operations diye module baslat, bu butun operation'lara bir facade

olacak diye dusunuyorum ama hayirlisi artik :)
* pisicli -> commands'i disari factor et
* InstallContext erir, global variable diye birsey kalmaz orada
* PisiInstall'a daha basit Installer adini veriyorum.
* Package'a InstallContext'teki bir iki sirin fonksiyonu ekliyoruz
  code kaybimiz yok
* Diger yerleri bu degisiklige gore duzenle.
This commit is contained in:
Eray Özkural
2005-07-18 10:24:24 +00:00
parent 860f285471
commit ea085f4926
7 changed files with 247 additions and 281 deletions
+185
View File
@@ -0,0 +1,185 @@
# helper functions
def cmdObject(cmd, fail=False):
commands = {"help": Help,
"build": Build,
"info": Info,
"install": Install,
"remove": Remove,
"index": Index,
"updatedb": UpdateDB}
if commands.has_key(cmd):
obj = commands[cmd]()
return obj
if fail:
print "Unrecognized command: ", cmd
sys.exit(1)
else:
return None
class Command(object):
"""generic help string for any command"""
def __init__(self):
# now for the real parser
self.parser = OptionParser(usage=usage_text,
version="%prog " + pisi.__version__)
self.options()
self.parser = commonopts(self.parser)
(self.options, args) = self.parser.parse_args()
self.args = args[1:]
self.checkAuthInfo()
def options(self):
"""This is a fall back function. If the implementer module provides an
options function it will be called"""
pass
def checkAuthInfo(self):
username = self.options.username
password = self.options.password
if not username and not password:
if config.username and config.password:
self.authInfo = (config.username, config.password)
return
elif username and password:
self.authInfo = (username, password)
return
if username and self.options.getpass:
from getpass import getpass
password = getpass("Password: ")
self.authInfo = (username, password)
else:
self.authInfo = None
def help(self):
print getattr(self, "__doc__")
class Help(Command):
"""prints usage"""
def __init__(self):
super(Help, self).__init__()
def run(self):
if not self.args:
print usage_text
print self.parser.format_option_help()
return
for arg in self.args:
obj = cmdObject(arg, True)
obj.help()
# print "\n",self.parser.format_option_help()
class Build(Command):
"""build: compile PISI package using a pspec.xml file"""
def __init__(self):
super(Build, self).__init__()
def run(self):
if not self.args:
self.help()
return
from pisi.cli import buildhelper
for arg in self.args:
buildhelper.build(arg, self.authInfo)
class Install(Command):
"""install: install PISI packages"""
def __init__(self):
super(Install, self).__init__()
def options(self):
self.parser.add_option("", "--test", action="store_true",
default=True, help="xxxx")
def run(self):
if not self.args:
self.help()
return
from pisi.cli import installhelper
for arg in self.args:
url = PUrl(packagefile)
if url.isRemoteFile():
pass # bunu simdilik bosverelim, once bir calissin :)
pi = Installer(url.uri)
pi.install()
class Remove(Command):
"""remove: remove PISI packages"""
def __init__(self):
super(Remove, self).__init__()
def options(self):
self.parser.add_option("", "--test", action="store_true",
default=True, help="xxxx")
def run(self):
if not self.args:
self.help()
return
for arg in self.args:
pisi.install.remove(arg)
class Info(Command):
"""info: display information about a package
usage: info <package> ..."""
def __init__(self):
super(Info, self).__init__()
def run(self):
if not self.args:
self.help()
return
for arg in self.args:
self.printinfo(arg)
def printinfo(self, arg):
import os.path
if os.path.exists(arg):
metadata, files = pisi.install.get_pkg_info(arg)
print metadata.package
class Index(Command):
"""index: Index PISI files in a given directory"""
def __init__(self):
super(Index, self).__init__()
def run(self):
if not self.args:
self.help()
return
from pisi.cli import indexhelper
if len(self.args)==1:
indexhelper.index(self.args[0])
elif len(self.args)==0:
indexhelper.index()
else:
print 'Indexing only a single directory supported'
return
class UpdateDB(Command):
"""updatedb: update source and package databases"""
def __init__(self):
super(UpdateDB, self).__init__()
def run(self):
if len(self.args) != 1:
self.help()
return
from pisi.cli import indexhelper
indexfile = self.args[0]
indexhelper.updatedb(indexfile)
-14
View File
@@ -1,14 +0,0 @@
from pisi.install import PisiInstall
from pisi.context import InstallContext
from pisi.purl import PUrl
def install(packagefile):
url = PUrl(packagefile)
if url.isRemoteFile():
pass # bunu simdilik bosverelim, once bir calissin :)
else:
ctx = InstallContext(url.uri)
pi = PisiInstall(ctx)
pi.install()
+3 -180
View File
@@ -5,7 +5,9 @@ from optparse import OptionParser
import pisi import pisi
from pisi.config import config from pisi.config import config
import pisi.operations
from pisi.purl import PUrl
from commands import *
# globals # globals
usage_text = """%prog <command> [options] [arguments] usage_text = """%prog <command> [options] [arguments]
@@ -25,25 +27,6 @@ Use \"%prog help <command>\" for help on a specific subcommand.
PISI Package Manager PISI Package Manager
""" """
# helper functions
def cmdObject(cmd, fail=False):
commands = {"help": Help,
"build": Build,
"info": Info,
"install": Install,
"remove": Remove,
"index": Index,
"updatedb": UpdateDB}
if commands.has_key(cmd):
obj = commands[cmd]()
return obj
if fail:
print "Unrecognized command: ", cmd
sys.exit(1)
else:
return None
def commonopts(parser): def commonopts(parser):
p = parser p = parser
@@ -63,166 +46,6 @@ def commonopts(parser):
return p return p
######## start commands #########
class Command(object):
"""generic help string for any command"""
def __init__(self):
# now for the real parser THIS IS ABSOLUTELY NECESSARY
self.parser = OptionParser(usage=usage_text,
version="%prog " + pisi.__version__)
#self.parser.allow_interspersed_args = False
self.options()
self.parser = commonopts(self.parser)
(self.options, args) = self.parser.parse_args()
self.args = args[1:]
self.checkAuthInfo()
def options(self):
"""This is a fall back function. If the implementer module provides an
options function it will be called"""
pass
def checkAuthInfo(self):
username = self.options.username
password = self.options.password
if not username and not password:
if config.username and config.password:
self.authInfo = (config.username, config.password)
return
elif username and password:
self.authInfo = (username, password)
return
if username and self.options.getpass:
from getpass import getpass
password = getpass("Password: ")
self.authInfo = (username, password)
else:
self.authInfo = None
def help(self):
print getattr(self, "__doc__")
class Help(Command):
"""prints usage"""
def __init__(self):
super(Help, self).__init__()
def run(self):
if not self.args:
print usage_text
print self.parser.format_option_help()
return
for arg in self.args:
obj = cmdObject(arg, True)
obj.help()
# print "\n",self.parser.format_option_help()
class Build(Command):
"""build: compile PISI package using a pspec.xml file"""
def __init__(self):
super(Build, self).__init__()
def run(self):
if not self.args:
self.help()
return
from pisi.cli import buildhelper
for arg in self.args:
buildhelper.build(arg, self.authInfo)
class Install(Command):
"""install: install PISI packages"""
def __init__(self):
super(Install, self).__init__()
def options(self):
self.parser.add_option("", "--test", action="store_true",
default=True, help="xxxx")
def run(self):
if not self.args:
self.help()
return
from pisi.cli import installhelper
for arg in self.args:
installhelper.install(arg)
class Remove(Command):
"""remove: remove PISI packages"""
def __init__(self):
super(Remove, self).__init__()
def options(self):
self.parser.add_option("", "--test", action="store_true",
default=True, help="xxxx")
def run(self):
if not self.args:
self.help()
return
for arg in self.args:
pisi.install.remove(arg)
class Info(Command):
"""info: display information about a package
usage: info <package> ..."""
def __init__(self):
super(Info, self).__init__()
def run(self):
if not self.args:
self.help()
return
for arg in self.args:
self.printinfo(arg)
def printinfo(self, arg):
import os.path
if os.path.exists(arg):
metadata, files = pisi.install.get_pkg_info(arg)
print metadata.package
class Index(Command):
"""index: Index PISI files in a given directory"""
def __init__(self):
super(Index, self).__init__()
def run(self):
if not self.args:
self.help()
return
from pisi.cli import indexhelper
if len(self.args)==1:
indexhelper.index(self.args[0])
elif len(self.args)==0:
indexhelper.index()
else:
print 'Indexing only a single directory supported'
return
class UpdateDB(Command):
"""updatedb: update source and package databases"""
def __init__(self):
super(UpdateDB, self).__init__()
def run(self):
if len(self.args) != 1:
self.help()
return
from pisi.cli import indexhelper
indexfile = self.args[0]
indexhelper.updatedb(indexfile)
######## end commands #########
class ParserError(Exception): class ParserError(Exception):
pass pass
-63
View File
@@ -6,9 +6,6 @@
from constants import const from constants import const
from config import Config from config import Config
from specfile import SpecFile from specfile import SpecFile
from package import Package
from metadata import MetaData
from files import Files
class BuildContext(object): class BuildContext(object):
"""Build Context Singleton""" """Build Context Singleton"""
@@ -52,63 +49,3 @@ class BuildContext(object):
def __setattr__(self, attr, value): def __setattr__(self, attr, value):
return setattr(self.__instance, attr, value) return setattr(self.__instance, attr, value)
class InstallContext(object):
"""Build Context Singleton"""
class ctximpl(Config.configimpl): # singleton implementation
def __init(self):
super(ctximpl, self).__init__()
def setPackage(self, packagefile):
self.packagefile = packagefile
self.package = Package(packagefile, 'r')
tmpdir = self.tmp_dir()
# extract control files
self.package.extract_PISI_files(tmpdir)
# read files.xml and metadata.xml
mdxml = tmpdir + '/' + const.metadata_xml
self.setMetadataXML(mdxml)
filesxml = tmpdir + '/' + const.files_xml
self.setFilesXML(filesxml)
def setMetadataXML(self, metadataxml):
self.metadataxml = metadataxml
metadata = MetaData()
metadata.read(metadataxml)
if not metadata.verify():
raise InstallError("MetaData format wrong")
self.metadata = metadata
def setFilesXML(self, filesxml):
self.filesxml = filesxml
files = Files()
files.read(filesxml)
self.files = files
def pkg_dir(self):
packageDir = self.metadata.package.name + '-' \
+ self.metadata.package.version + '-' \
+ self.metadata.package.release
return self.lib_dir() + '/' + packageDir
def comar_dir(self):
return self.pkg_dir() + const.comar_dir_suffix
__instance = ctximpl() # singleton implementation
def __init__(self, packagefile):
self.__instance.setPackage(packagefile)
def __getattr__(self, attr):
return getattr(self.__instance, attr)
def __setattr__(self, attr, value):
return setattr(self.__instance, attr, value)
+11 -24
View File
@@ -35,24 +35,11 @@ class InstallError(Exception):
# gönderilmesi gereksiz bence. Dahası bu PisiBuild ile de uyumlu bir # gönderilmesi gereksiz bence. Dahası bu PisiBuild ile de uyumlu bir
# implemantation olduğu için daha rahat anlaşılır bir kod tabanı # implemantation olduğu için daha rahat anlaşılır bir kod tabanı
# oluşturuyor. (baris) # oluşturuyor. (baris)
def remove(package_name):
"""Remove a goddamn package"""
ui.info('Removing package ' + package_name)
if not installdb.is_installed(package_name):
raise InstallError('Trying to remove nonexistent package '
+ package_name)
for fileinfo in installdb.files(package_name):
os.unlink(fileinfo.path)
installdb.remove(package_name)
class PisiInstall: class Installer:
"PisiInstall class, provides install rutines for pisi packages" "Installer class, provides install rutines for pisi packages"
def __init__(self, installcontext): def __init__(self, package_fname):
self.ctx = installcontext
## bu context fikri multi package installation fikriyle
## uyusmuyor ne yazik ki. gitmesi gerek.
#
# Ben buna karşıyım. Multi-package işini kotarmak yalnızca # Ben buna karşıyım. Multi-package işini kotarmak yalnızca
# install'da değil hemen hemen tüm işlemlerde halletmemiz # install'da değil hemen hemen tüm işlemlerde halletmemiz
# gereken bir iş. Build, install, remove, upgrade, vs. hemen # gereken bir iş. Build, install, remove, upgrade, vs. hemen
@@ -62,9 +49,10 @@ class PisiInstall:
# tek pspec.xml dosyasından peket derlediği gibi. Biz bu # tek pspec.xml dosyasından peket derlediği gibi. Biz bu
# modülleri kullanarak üst seviye modüller ile çoklu paketler # modülleri kullanarak üst seviye modüller ile çoklu paketler
# işini halletmeliyiz. (baris) # işini halletmeliyiz. (baris)
self.metadata = self.ctx.metadata self.package = Package(package_fname)
self.files = self.ctx.files self.package.read()
self.package = self.ctx.package self.metadata = self.package.metadata
self.files = self.package.files
def extractInstall(self): def extractInstall(self):
ui.info('Extracting files\n') ui.info('Extracting files\n')
@@ -74,24 +62,23 @@ class PisiInstall:
# put files.xml, metadata.xml, actions.py and COMAR scripts # put files.xml, metadata.xml, actions.py and COMAR scripts
# somewhere in the file system. We'll need these in future... # somewhere in the file system. We'll need these in future...
#BUG: these look like they ought to be part of Package class
ui.info('Storing %s\n' % const.files_xml) ui.info('Storing %s\n' % const.files_xml)
self.package.extract_file(const.files_xml, self.ctx.pkg_dir()) self.package.extract_file(const.files_xml, self.package.pkg_dir())
ui.info('Storing %s\n' % const.metadata_xml) ui.info('Storing %s\n' % const.metadata_xml)
self.package.extract_file(const.metadata_xml, self.ctx.pkg_dir()) self.package.extract_file(const.metadata_xml, self.package.pkg_dir())
for pcomar in self.metadata.package.providesComar: for pcomar in self.metadata.package.providesComar:
fpath = os.path.join(const.comar_dir, pcomar.script) fpath = os.path.join(const.comar_dir, pcomar.script)
# comar prefix is added to the pkg_dir while extracting comar # comar prefix is added to the pkg_dir while extracting comar
# script file. so we'll use pkg_dir as destination. # script file. so we'll use pkg_dir as destination.
ui.info('Storing %s\n' % fpath) ui.info('Storing %s\n' % fpath)
self.package.extract_file(fpath, self.ctx.pkg_dir()) self.package.extract_file(fpath, self.package.pkg_dir())
def registerCOMARScripts(self): def registerCOMARScripts(self):
# register COMAR scripts # register COMAR scripts
for pcomar in self.metadata.package.providesComar: for pcomar in self.metadata.package.providesComar:
scriptPath = os.path.join(self.ctx.comar_dir(),pcomar.script) scriptPath = os.path.join(self.package.comar_dir(),pcomar.script)
ui.info("Registering COMAR script %s\n" % pcomar.script) ui.info("Registering COMAR script %s\n" % pcomar.script)
ret = comariface.registerScript(pcomar.om, ret = comariface.registerScript(pcomar.om,
self.metadata.package.name, self.metadata.package.name,
+17
View File
@@ -0,0 +1,17 @@
# all package operation interfaces are here
def remove(package_name):
"""Remove a goddamn package"""
ui.info('Removing package ' + package_name)
if not installdb.is_installed(package_name):
raise InstallError('Trying to remove nonexistent package '
+ package_name)
for fileinfo in installdb.files(package_name):
os.unlink(fileinfo.path)
installdb.remove(package_name)
from install import Installer
def install(package_name):
Installer
+31
View File
@@ -6,6 +6,12 @@ import archive
from constants import const from constants import const
from config import config from config import config
from purl import PUrl from purl import PUrl
from os.path import join
from metadata import MetaData
from files import Files
class PackageError:
pass
class Package: class Package:
"""PISI Package Class provides access to a pisi package (.pisi """PISI Package Class provides access to a pisi package (.pisi
@@ -62,3 +68,28 @@ class Package:
self.extract_files([const.metadata_xml, const.files_xml], outdir) self.extract_files([const.metadata_xml, const.files_xml], outdir)
self.extract_dir('config', outdir) self.extract_dir('config', outdir)
def read_info(self, outdir = None):
if not outdir:
outdir = config.tmp_dir()
# extract control files
self.package.extract_PISI_files(tmpdir)
filesxml =
self.metadata = MetaData()
self.metadata.read( join(tmpdir, config.metadata_xml) )
if not metadata.verify():
raise PackageError("MetaData format wrong")
self.files = Files()
self.files.read( join(tmpdir, const.files_xml) )
def pkg_dir(self):
packageDir = self.metadata.package.name + '-' \
+ self.metadata.package.version + '-' \
+ self.metadata.package.release
return join( config.lib_dir(), packageDir)
def comar_dir(self):
return join( self.pkg_dir(), const.comar_dir_suffix)