* 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
from pisi.config import config
import pisi.operations
from pisi.purl import PUrl
from commands import *
# globals
usage_text = """%prog <command> [options] [arguments]
@@ -25,25 +27,6 @@ Use \"%prog help <command>\" for help on a specific subcommand.
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):
p = parser
@@ -63,166 +46,6 @@ def commonopts(parser):
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):
pass
-63
View File
@@ -6,9 +6,6 @@
from constants import const
from config import Config
from specfile import SpecFile
from package import Package
from metadata import MetaData
from files import Files
class BuildContext(object):
"""Build Context Singleton"""
@@ -52,63 +49,3 @@ class BuildContext(object):
def __setattr__(self, 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
# implemantation olduğu için daha rahat anlaşılır bir kod tabanı
# 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:
"PisiInstall class, provides install rutines for pisi packages"
def __init__(self, installcontext):
self.ctx = installcontext
## bu context fikri multi package installation fikriyle
## uyusmuyor ne yazik ki. gitmesi gerek.
#
class Installer:
"Installer class, provides install rutines for pisi packages"
def __init__(self, package_fname):
# Ben buna karşıyım. Multi-package işini kotarmak yalnızca
# install'da değil hemen hemen tüm işlemlerde halletmemiz
# 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
# modülleri kullanarak üst seviye modüller ile çoklu paketler
# işini halletmeliyiz. (baris)
self.metadata = self.ctx.metadata
self.files = self.ctx.files
self.package = self.ctx.package
self.package = Package(package_fname)
self.package.read()
self.metadata = self.package.metadata
self.files = self.package.files
def extractInstall(self):
ui.info('Extracting files\n')
@@ -74,24 +62,23 @@ class PisiInstall:
# put files.xml, metadata.xml, actions.py and COMAR scripts
# 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)
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)
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:
fpath = os.path.join(const.comar_dir, pcomar.script)
# comar prefix is added to the pkg_dir while extracting comar
# script file. so we'll use pkg_dir as destination.
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):
# register COMAR scripts
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)
ret = comariface.registerScript(pcomar.om,
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 config import config
from purl import PUrl
from os.path import join
from metadata import MetaData
from files import Files
class PackageError:
pass
class Package:
"""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_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)