* improved arg parsing for pisi-install

* purge_dir -> clean_dir
* build_work_dir -> pkg_work_dir ve yeni install_dir() fonksiyonu
  etc. install, package spec'i olmadan calisiyor tabii ki
This commit is contained in:
Eray Özkural
2005-06-17 18:48:42 +00:00
parent fd7333c32a
commit 9da5552af9
9 changed files with 64 additions and 55 deletions
+4
View File
@@ -11,6 +11,10 @@ Guidelines
3. Follow python philosophy of 'batteries included' 3. Follow python philosophy of 'batteries included'
4. Don't make the code have runtime dependencies on 4. Don't make the code have runtime dependencies on
a particular distribution (as much as possible) a particular distribution (as much as possible)
5. Don't assume narrow use cases.
6. If you are changing something, check if that change
breaks anything and fix breakage. For instance a
name. Running the tests is not always enough!
Unittests Unittests
--------- ---------
+20 -25
View File
@@ -1,43 +1,38 @@
#! /usr/bin/python #! /usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# sys modules
import sys
from optparse import OptionParser
import pisi.install import pisi.install
import pisi.util import pisi.util
def usage(progname = "pisi-install"): class ArgError(Exception):
print """ pass
Usage:
%s [options] <packagefilename>
""" %(progname)
def main(): def main():
import sys
import getopt
# wrapper for usage(progname) function usage = "usage: %prog [options] <package>"
help = lambda: usage(sys.argv[0]) parser = OptionParser(usage=usage,version="%prog " + pisi.__version__)
parser.add_option("-D", "--destdir", action="store")
parser.add_option("-v", "--verbose", action="store_true",
dest="verbose", default=False,
help="detailed output")
parser.add_option("-d", "--debug", action="store_true", default=True)
parser.add_option("-n", "--dry-run", action="store_true",
default = "do not perform any action, just show what\
would be done")
# getopt magic (options, args) = parser.parse_args()
try:
opts, args = getopt.getopt(sys.argv[1:],"h",["help"])
except getopt.GetoptError:
help()
sys.exit(1)
for opt, arg in opts:
if opt == "-h":
help()
sys.exit(1)
# package filename # package filename
package_fn = "" package_fn = ""
# TODO: We accept only one pspec file (at a time) currently, # TODO: We accept only one package file arg ATM
# but pisi-build may build many packages (pspecs given in order)
# sequentially.
if len(args) != 1: if len(args) != 1:
help() print usage
raise pisi.util.ArgError, "pisi-install expects one (and only one) package file currently" raise ArgError, "pisi-install expects one (and only one) package file currently"
else: else:
package_fn = args[0] package_fn = args[0]
+1 -1
View File
@@ -21,7 +21,7 @@ class ArchiveBase(object):
self.targetDir = targetDir self.targetDir = targetDir
# first we check if we need to clean-up our working env. # first we check if we need to clean-up our working env.
if os.path.exists(self.targetDir): if os.path.exists(self.targetDir):
util.purge_dir(self.targetDir) util.clean_dir(self.targetDir)
else: else:
os.makedirs(self.targetDir) os.makedirs(self.targetDir)
+6 -4
View File
@@ -18,7 +18,9 @@ class PisiBuildError(Exception):
# FIXME: this eventually has to go to ui module # FIXME: this eventually has to go to ui module
# Infact all ui calls has nothing to do with this build process. # Infact all ui calls has nothing to do with this build process.
# There more of them in PisiBuild... # There more of them in PisiBuild...
# And maybe we should consider moving PisiBuild.build() back to pisi-build CLI too. # And maybe we should consider moving PisiBuild.build() back to pisi-build
# CLI too.
# exa: This, like all others, will have a GUI or CLI, interchangeably
def displayProgress(pd): def displayProgress(pd):
out = '\r%-30.30s %3d%% %12.2f %s' % \ out = '\r%-30.30s %3d%% %12.2f %s' % \
(pd['filename'], pd['percent'], pd['rate'], pd['symbol']) (pd['filename'], pd['percent'], pd['rate'], pd['symbol'])
@@ -28,7 +30,7 @@ class PisiBuild:
"""PisiBuild class, provides the package build and creation routines""" """PisiBuild class, provides the package build and creation routines"""
def __init__(self, context): def __init__(self, context):
self.ctx = context self.ctx = context
self.work_dir = self.ctx.build_work_dir() self.work_dir = self.ctx.pkg_work_dir()
self.spec = self.ctx.spec self.spec = self.ctx.spec
@@ -44,7 +46,7 @@ class PisiBuild:
ui.info("Unpacking archive...") ui.info("Unpacking archive...")
self.unpackArchive() self.unpackArchive()
ui.info(" unpacked (%s)\n" % self.ctx.build_work_dir()) ui.info(" unpacked (%s)\n" % self.ctx.pkg_work_dir())
self.applyPatches() self.applyPatches()
@@ -59,7 +61,7 @@ class PisiBuild:
# will create a name-version top-level directory. # will create a name-version top-level directory.
# Archive module should give the exact location. # Archive module should give the exact location.
# (from the assumption is evil dept.) # (from the assumption is evil dept.)
os.chdir(self.ctx.build_work_dir() + "/" + self.spec.source.name + "-" + self.spec.source.version) os.chdir(self.ctx.pkg_work_dir() + "/" + self.spec.source.name + "-" + self.spec.source.version)
locals = globals = {} locals = globals = {}
try: try:
+14 -6
View File
@@ -16,8 +16,8 @@ class Constants:
self.c.tmp_dir_suffix = "/var/tmp/pisi" self.c.tmp_dir_suffix = "/var/tmp/pisi"
# directory suffixes for build # directory suffixes for build
self.c.build_work_dir_suffix = "/work" self.c.work_dir_suffix = "/work"
self.c.build_install_dir_suffix = "/install" self.c.install_dir_suffix = "/install"
# file/directory names # file/directory names
self.c.actions_file = "actions.py" self.c.actions_file = "actions.py"
@@ -53,6 +53,11 @@ class Context(object):
spec.verify() # check pspec integrity spec.verify() # check pspec integrity
self.spec = spec self.spec = spec
# directory accessor functions
# here is how it goes
# x_dir: system wide directory for storing info type x
# pkg_x_dir: per package directory for storing info type x
def lib_dir(self): def lib_dir(self):
return self.destdir + self.const.lib_dir_suffix return self.destdir + self.const.lib_dir_suffix
@@ -65,19 +70,22 @@ class Context(object):
def tmp_dir(self): def tmp_dir(self):
return self.destdir + self.const.tmp_dir_suffix return self.destdir + self.const.tmp_dir_suffix
def build_work_dir(self): def pkg_work_dir(self):
packageDir = self.spec.source.name + '-' \ packageDir = self.spec.source.name + '-' \
+ self.spec.source.version + '-' + self.spec.source.release + self.spec.source.version + '-' + self.spec.source.release
return self.destdir + self.const.tmp_dir_suffix \ return self.destdir + self.const.tmp_dir_suffix \
+ '/' + packageDir + self.const.build_work_dir_suffix + '/' + packageDir + self.const.work_dir_suffix
def build_install_dir(self): def install_dir(self):
return self.tmp_dir() + self.const.install_dir_suffix
def pkg_install_dir(self):
packageDir = self.spec.source.name + '-' \ packageDir = self.spec.source.name + '-' \
+ self.spec.source.version + '-' + self.spec.source.release + self.spec.source.version + '-' + self.spec.source.release
return self.destdir + self.const.tmp_dir_suffix \ return self.destdir + self.const.tmp_dir_suffix \
+ '/' + packageDir + self.const.build_install_dir_suffix + '/' + packageDir + self.const.install_dir_suffix
__instance = __impl() __instance = __impl()
+4 -3
View File
@@ -4,6 +4,7 @@
from specfile import * from specfile import *
from package import Package from package import Package
import util import util
from context import ctx
from ui import ui from ui import ui
import installdb import installdb
import packagedb import packagedb
@@ -17,15 +18,15 @@ def install_package_file(package_fn):
package = Package(package_fn, 'r') package = Package(package_fn, 'r')
# extract control files # extract control files
util.clean_directory(install_dir()) util.clean_dir(ctx.install_dir())
ui.info('extracting files\n') ui.info('extracting files\n')
package.extract_files(install_dir()) package.extract_PISI_files(ctx.install_dir())
# verify package # verify package
# check if we have all required files # check if we have all required files
metadata = MetaData() metadata = MetaData()
metadata.read(install_dir() + '/metadata.xml') metadata.read(ctx.install_dir() + '/metadata.xml')
# check package semantics # check package semantics
if not metadata.verify(): if not metadata.verify():
raise InstallError("MetaData format wrong") raise InstallError("MetaData format wrong")
+8 -8
View File
@@ -9,22 +9,22 @@ class Package:
self.mode = mode # bu gerekli mi? self.mode = mode # bu gerekli mi?
# etc. etc. # etc. etc.
def add_file(fn): def add_file(self, fn):
"""add a file to package""" """add a file to package"""
def extract(outdir): def extract(self, outdir):
"""extract entire package contents to directory""" """extract entire package contents to directory"""
extract_dir('', outdir) # means package root extract_dir('', outdir) # means package root
def extract_file(path, outdir): def extract_file(self, path, outdir):
"""extract file with path to outdir""" """extract file with path to outdir"""
def extract_dir(dir, outdir): def extract_dir(self, dir, outdir):
"""extract directory recursively""" """extract directory recursively"""
def extract_PISI_files(outdir): def extract_PISI_files(self, outdir):
"""extract PISI control files: metadata.xml, files.xml, """extract PISI control files: metadata.xml, files.xml,
action scripts, etc.""" action scripts, etc."""
extract_file('metadata.xml', outdir) self.extract_file('metadata.xml', outdir)
extract_file('files.xml', outdir) self.extract_file('files.xml', outdir)
extract_dir('Config', outdir) self.extract_dir('Config', outdir)
+5 -6
View File
@@ -10,6 +10,9 @@ from ui import ui
class FileError(Exception): class FileError(Exception):
pass pass
class UtilError(Exception):
pass
# shorthand to check if a file exists # shorthand to check if a file exists
def check_file(file, mode = os.F_OK): def check_file(file, mode = os.F_OK):
if not os.access(file, mode): if not os.access(file, mode):
@@ -23,7 +26,7 @@ def check_dir(dir):
if not os.access(dir, os.F_OK): if not os.access(dir, os.F_OK):
os.makedirs(dir) os.makedirs(dir)
def purge_dir(top): def clean_dir(top):
"""Remove all content of a directory (top)""" """Remove all content of a directory (top)"""
for root, dirs, files in os.walk(top, topdown=False): for root, dirs, files in os.walk(top, topdown=False):
for name in files: for name in files:
@@ -31,7 +34,6 @@ def purge_dir(top):
for name in dirs: for name in dirs:
os.rmdir(os.path.join(root, name)) os.rmdir(os.path.join(root, name))
# TODO:
def copy_file(s,d): def copy_file(s,d):
check_file(s) check_file(s)
check_dir(os.path.dirname(d)) check_dir(os.path.dirname(d))
@@ -41,7 +43,7 @@ def copy_file(s,d):
fd.write(l) fd.write(l)
def copy_dir(): def copy_dir():
pass raise UtilError("not implemented")
def md5_file(filename): def md5_file(filename):
m = md5.new() m = md5.new()
@@ -67,6 +69,3 @@ def run_batch(cmd):
# print a list # print a list
def strlist(l): def strlist(l):
return string.join(map(lambda x: str(x) + ' ', l)) return string.join(map(lambda x: str(x) + ' ', l))
class UtilError(Exception):
pass
+2 -2
View File
@@ -15,7 +15,7 @@ class ArchiveFileTestCase(unittest.TestCase):
def testUnpackTar(self): def testUnpackTar(self):
ctx = context.Context("samples/popt/popt.pspec") ctx = context.Context("samples/popt/popt.pspec")
targetDir = ctx.build_work_dir() targetDir = ctx.pkg_work_dir()
achv = archive.Archive(ctx) achv = archive.Archive(ctx)
assert ctx.spec.source.archiveType == "targz" assert ctx.spec.source.archiveType == "targz"
@@ -39,7 +39,7 @@ class ArchiveFileTestCase(unittest.TestCase):
fetch = fetcher.Fetcher(ctx) fetch = fetcher.Fetcher(ctx)
fetch.fetch() fetch.fetch()
targetDir = ctx.build_work_dir() targetDir = ctx.pkg_work_dir()
assert ctx.spec.source.archiveType == "zip" assert ctx.spec.source.archiveType == "zip"