diff options
Diffstat (limited to 'devshell')
| -rw-r--r-- | devshell/base/factories.py | 72 | ||||
| -rw-r--r-- | devshell/base/module.py | 10 | ||||
| -rw-r--r-- | devshell/base/util.py | 8 | ||||
| -rw-r--r-- | devshell/modules/autotools.py | 9 | ||||
| -rw-r--r-- | devshell/modules/build.py | 5 | ||||
| -rw-r--r-- | devshell/modules/buildsystem.py | 3 | ||||
| -rw-r--r-- | devshell/modules/cabal.py | 1 | ||||
| -rw-r--r-- | devshell/modules/darcs.py | 5 | ||||
| -rw-r--r-- | devshell/modules/directory.py | 91 | ||||
| -rw-r--r-- | devshell/modules/git.py | 8 | ||||
| -rw-r--r-- | devshell/modules/mock.py | 3 | ||||
| -rw-r--r-- | devshell/modules/package.py | 5 | ||||
| -rw-r--r-- | devshell/modules/packagesource.py | 5 | ||||
| -rw-r--r-- | devshell/modules/port.py | 3 | ||||
| -rw-r--r-- | devshell/modules/profile.py | 5 | ||||
| -rw-r--r-- | devshell/modules/revisioncontrol.py | 3 | ||||
| -rw-r--r-- | devshell/modules/rpmcvspackage.py | 4 | ||||
| -rw-r--r-- | devshell/modules/source.py | 1 | ||||
| -rw-r--r-- | devshell/modules/sourceball.py | 5 |
19 files changed, 140 insertions, 106 deletions
diff --git a/devshell/base/factories.py b/devshell/base/factories.py index 742939e..9c035d0 100644 --- a/devshell/base/factories.py +++ b/devshell/base/factories.py @@ -15,21 +15,38 @@ # # Authors: Yaakov M. Nemoy <[email protected]> # - from __future__ import with_statement -from configobj import ConfigObj -from os import getcwd -from os.path import abspath, exists - -from devshell.base.util import pwd, log from devshell.base.exceptions import ExecutionException -directory_type = dict() +class Factory(object): + def __init__(self, name, type_of=None): + self.name = name + self.classes = dict() + if type_of: + self.type_of = type_of + + def register(self, cls): + cls_name = cls.__name__.lower() + self.classes[cls_name] = cls + cls._type = cls_name + return cls + + def lookup(self, type): + try: + return self.classes[type] + except KeyError, e: + raise ExecutionException(e, 'the %s type %s is not supported by this installation of fedora-devshell' % (self.name, type)) + + def type_of(self, *args, **keys): + raise NotImplementedError + + def __call__(self, *args, **keys): + type_of = self.type_of(*args, **keys) + new_cls = self.lookup(type_of) + new_cls.__new__(new_cls, *args, **keys) + new_cls.__init__(*args, **keys) -def register_directory(cls, name): - global directory_type - directory_type[name] = cls buildsystem_type = dict() @@ -43,39 +60,6 @@ class BuildSystemFactory(object): foo = new_cls.__new__(new_cls, *args) foo.__init__(*args) return foo - -class DirFactory(object): - '''creates a new object of type defined by a directory's .devshell file''' - def __new__(cls, name=None): - if not name: - log.debug('no name with dirfactory') - cwd = getcwd() - type = whatis_sysdir(cwd) - else: - log.debug('dirfactory.new with name ' + name) - cwd = abspath(name) - if not exists(cwd): - type = 'directory' - else: - type = whatis_sysdir(cwd) - try: - new_cls = directory_type[type] - except KeyError, e: - raise ExecutionException(e, 'the directory type %s is not supported by this installation of fedora-deveshell' % type.capitalize()) - foo = new_cls.__new__(new_cls, name) - foo.__init__(name) - return foo - -def whatis_sysdir(dir): - ''' given a dir, determine it's type''' - with pwd(dir): - cfg = ConfigObj('.devshell') - try: - type = cfg['type'] - log.debug('is type ' + type) - return type - except KeyError, e: - return 'directory' -__all__ = ['DirFactory', 'BuildSystemFactory', 'register_directory', 'register_buildsystem'] +__all__ = ['Factory', 'BuildSystemFactory', 'register_directory', 'register_buildsystem'] diff --git a/devshell/base/module.py b/devshell/base/module.py index 898d49c..8cb0450 100644 --- a/devshell/base/module.py +++ b/devshell/base/module.py @@ -19,6 +19,16 @@ class Module(object): """ Our parent class for all command modules """ + def __init__(self, *args, **keys): + args, keys = self.massage(*args, **keys) + self.init(*args, **keys) + + def massage(self, *args, **keys): + return args, keys + + def init(self, *args, **keys): + return + def close(self): raise NotImplementedError diff --git a/devshell/base/util.py b/devshell/base/util.py index 2407714..f9f695e 100644 --- a/devshell/base/util.py +++ b/devshell/base/util.py @@ -22,7 +22,7 @@ from contextlib import contextmanager from datetime import datetime from os import chdir, getcwd, remove from os import symlink as sym -from os.path import abspath, lexists, isdir, islink, isfile +from os.path import abspath, lexists, isdir, islink, isfile, sep from shutil import copyfileobj, rmtree from shutil import move as mv from shutil import copytree as cpthree @@ -136,6 +136,10 @@ def flip(f): return flipped +def strip_slash(path): + return a[:-1] if a.endswith(sep) else a + + __all__ = ['pwd', 'copy', 'with_sudo', 'with_su', 'symlink', 'move', 'log_file', 'one', 'remove_all', 'flatten', 'base_dir', - 'close_later', 'close_all', 'flip'] + 'close_later', 'close_all', 'flip', 'strip_slash'] diff --git a/devshell/modules/autotools.py b/devshell/modules/autotools.py index cd95296..a61b819 100644 --- a/devshell/modules/autotools.py +++ b/devshell/modules/autotools.py @@ -38,15 +38,6 @@ class Autotools(BuildSystem): This provides a useful api for other modules around the autotools build system ''' - def __init__(self, name): - '''creates a new autotools module - - this api is deprecated, because it should be more autodetecting - - name is a Package (Directory) that uses autotools for its build system - ''' - super(Autotools, self).__init__(name) - def prepare(self, install=False, force=False, *args): with self.logged() as autotools_out: with self.pkg_src.in_src_dir(): diff --git a/devshell/modules/build.py b/devshell/modules/build.py index bb609b1..422e20e 100644 --- a/devshell/modules/build.py +++ b/devshell/modules/build.py @@ -24,14 +24,13 @@ from os import listdir, getcwd, walk from subprocess import Popen from devshell.base.base import log -from devshell.base.factories import DirFactory from devshell.base.exceptions import ExecutionException from devshell.base.module import Module from devshell.base.profiles import dir_defines, join_defines, dist_defines, Profile from devshell.base.util import pwd, copy, symlink, move, log_file from devshell.base.vars import FEDORA_DIR -from devshell.modules.directory import Directory +from devshell.modules.directory import Directory, DirFactory from devshell.modules.package import Package from devshell.modules.profile import Profile @@ -148,4 +147,6 @@ class Build(Directory): source = pkg.cfg['source'] move(join('BUILD', source), join(pkg.dir, 'results')) +DirFactory.register(Build) + __all__ = ['Build'] diff --git a/devshell/modules/buildsystem.py b/devshell/modules/buildsystem.py index 9e5e996..5ec1658 100644 --- a/devshell/modules/buildsystem.py +++ b/devshell/modules/buildsystem.py @@ -22,10 +22,11 @@ from contextlib import contextmanager import devshell.base.factories as factories -from devshell.base.factories import DirFactory from devshell.base.module import Module from devshell.base.util import log_file, rm, log +from devshell.modules.directory import DirFactory + class MetaBuildSystem(type): def __init__(cls, name, bases, attrs): t = name.lower() diff --git a/devshell/modules/cabal.py b/devshell/modules/cabal.py index 36748da..b366aa8 100644 --- a/devshell/modules/cabal.py +++ b/devshell/modules/cabal.py @@ -45,6 +45,7 @@ class Cabal(BuildSystem): name is a Package (Directory) that uses cabal for its build system ''' + #TODO: make me massageable super(Cabal, self).__init__(name) self.compiler = haskell_compiler diff --git a/devshell/modules/darcs.py b/devshell/modules/darcs.py index 3d08452..07286ad 100644 --- a/devshell/modules/darcs.py +++ b/devshell/modules/darcs.py @@ -27,6 +27,8 @@ from os.path import join, basename, exists from subprocess import Popen, PIPE from devshell.base.util import pwd, log, rm, log_file, copy, move + +from devshell.modules.directory import DirFactory from devshell.modules.revisioncontrol import RevisionControl hash_re = re.compile(r'hash=\'(\w|-|.*?)\'', re.MULTILINE) @@ -36,6 +38,7 @@ class Darcs(RevisionControl): '''manages single source packages where the primary source is darcs ''' def __init__(self, name=None, url=None, *args): + #TODO: make me massageable if url: #split chokes on URLs that end in a / url = url[:-1] if url.endswith('/') else url @@ -187,4 +190,6 @@ class Darcs(RevisionControl): move(join(self.source_dir, sourceball), sourceball) self.cfg['sourceball'] = sourceball +Darcs = DirFactory.register(Darcs) + __all__ = ['Darcs'] diff --git a/devshell/modules/directory.py b/devshell/modules/directory.py index 435f149..be9b0cb 100644 --- a/devshell/modules/directory.py +++ b/devshell/modules/directory.py @@ -19,66 +19,74 @@ from __future__ import with_statement - from configobj import ConfigObj from os import makedirs, getcwd, listdir from os.path import abspath, join, split, splitext, basename, exists, dirname from contextlib import contextmanager -from devshell.base.base import log import devshell.base.factories as factories -from devshell.base.factories import DirFactory + +from devshell.base.base import log +from devshell.base.factories import Factory from devshell.base.module import Module -from devshell.base.util import pwd, copytree, close_all +from devshell.base.util import pwd, copytree, close_all, strip_slash -class MetaDirectory(type): - def __init__(cls, name, bases, attrs): - t = name.lower() - cls._type = t - factories.register_directory(cls, t) class Directory(Module): '''a generic base class for any module that has to maintain state on the file system in a directory ''' - __metaclass__ = MetaDirectory - def __init__(self, name=None): - ''' initializer - - name is a path to the directory we are loading, if not given - name is gleaned by assuming the current directory is the - package desired - ''' +# __metaclass__ = MetaDirectory + @classmethod + def massage(cls, name=None): if not name: cwd = getcwd() - if self.is_sysdir_dir(cwd): - self.load_dir(cwd) - else: - self.make_dir(cwd) + name = basename(strip_slash(cwd)) else: - dir = abspath(name) - if not exists(dir): - makedirs(dir) - if self.is_sysdir_dir(dir): - self.load_dir(dir) - else: - self.make_dir(dir) + cwd = abspath(name) + if not exists(cwd): + makedirs(dir) + return (name, cwd), dict() + + def init(self, name, cwd): + cfg = self._get_config(cwd) + if self.is_cfg_type(cfg, self._type): + self.load_dir(cwd) + else: + self.make_dir(cwd) - def is_sysdir_dir(self, dir): - '''given a directory, determine if the system directory is - already a directory or not''' + @classmethod + def type_of(cls, name=None): + (name, cwd), d = cls.massage(name) + cfg = cls._get_config(cwd) + return cls.whatis_cfg_type(cfg) + + @staticmethod + def _get_config(dir): with pwd(dir): - cfg = ConfigObj('.devshell') - try: - if self._type in cfg['type']: - return True - else: - return False - except KeyError, e: + return ConfigObj('.devshell') + + @staticmethod + def is_cfg_type(self, cfg, type): + try: + if self._type in cfg['type']: + return True + else: return False + except KeyError, e: + return False + + @staticmethod + def whatis_cfg_type(cfg): + try: + type = cfg['type'] + log.debug('is type ' + type) + return type + except KeyError, e: + return 'directory' def load_dir(self, dir): - '''presuming dir is a directory, load it's state''' + '''presuming dir is a directory, load it's state''' with pwd(dir): parent, name = split(getcwd()) self.parent = parent @@ -155,4 +163,7 @@ class Directory(Module): new_dir = DirFactory(new_loc) return new_dir -__all__ = ['Directory'] +DirFactory = Factory('directory', Directory.type_of) +Directory = DirFactory.register(Directory) + +__all__ = ['Directory', 'DirFactory'] diff --git a/devshell/modules/git.py b/devshell/modules/git.py index ea31e0d..f93f48a 100644 --- a/devshell/modules/git.py +++ b/devshell/modules/git.py @@ -30,15 +30,17 @@ from os.path import join, basename, exists from subprocess import Popen, PIPE from devshell.base.util import pwd, log, rm, log_file, copy, move + +from devshell.modules.directory import DirFactory from devshell.modules.revisioncontrol import RevisionControl from devshell.modules.packagesource import PackageSource -# hash_re = re.compile(r'hash=\'(\w|-|.*?)\'', re.MULTILINE) -# date_re = re.compile(r'date=\'(\d*?)\'', re.MULTILINE) + class Git(RevisionControl): '''manages single source packages where the primary source is git ''' def __init__(self, name=None, url=None, *args): + #TODO: make me massageable if url: #split chokes on URLs that end in a / url = url[:-1] if url.endswith('/') else url @@ -226,4 +228,6 @@ class Git(RevisionControl): self.cfg['full_name'] = full_name +Git = DirFactory.register(Git) + __all__ = ['Git'] diff --git a/devshell/modules/mock.py b/devshell/modules/mock.py index 63a9ba4..a2c4395 100644 --- a/devshell/modules/mock.py +++ b/devshell/modules/mock.py @@ -20,11 +20,11 @@ from __future__ import with_statement from subprocess import Popen from devshell.base.base import log -from devshell.base.factories import DirFactory from devshell.base.module import Module from devshell.base.util import pwd, log_file from devshell.modules.build import Build +from devshell.modules.directory import DirFactory from devshell.modules.package import Package from devshell.modules.profile import Profile @@ -34,6 +34,7 @@ class Builder(Module): class Mock(Builder): '''wrapper around mock for integrating with profiles and packages''' def __init__(self, profile, build): + #TODO: make me massageable '''initializer profile is a path to a profile directory diff --git a/devshell/modules/package.py b/devshell/modules/package.py index c3c1d7a..f4eaa0e 100644 --- a/devshell/modules/package.py +++ b/devshell/modules/package.py @@ -22,12 +22,11 @@ from os.path import basename, abspath, join from contextlib import contextmanager from devshell.base.base import log -from devshell.base.factories import DirFactory from devshell.base.exceptions import ExecutionException from devshell.base.util import pwd, copy, move, symlink, rm from devshell.base.rpm_utils import RPMSpec -from devshell.modules.directory import Directory +from devshell.modules.directory import Directory, DirFactory class Package(Directory): # These two methods are here as examples. @@ -212,4 +211,6 @@ class Package(Directory): with self.in_dir(): symlink(file_name, self.spec_file) +Package = DirFactory.register(Package) + __all__ = ['Package'] diff --git a/devshell/modules/packagesource.py b/devshell/modules/packagesource.py index 096db46..0692fbf 100644 --- a/devshell/modules/packagesource.py +++ b/devshell/modules/packagesource.py @@ -24,7 +24,7 @@ from os.path import join from devshell.base.factories import BuildSystemFactory from devshell.base.util import pwd -from devshell.modules.directory import Directory +from devshell.modules.directory import Directory, DirFactory class PackageSource(Directory): def make_dir(self, dir): @@ -145,4 +145,7 @@ class PackageSource(Directory): def builder(self): return BuildSystemFactory(self.buildsystem, self) + +PackageSource = DirFactory.register(PackageSource) + __all__ = ['PackageSource'] diff --git a/devshell/modules/port.py b/devshell/modules/port.py index b89dcf6..a01885b 100644 --- a/devshell/modules/port.py +++ b/devshell/modules/port.py @@ -25,18 +25,19 @@ from contextlib import contextmanager from devshell.base.base import log from devshell.base.exceptions import ExecutionException -from devshell.base.factories import DirFactory from devshell.base.util import pwd, close_later, close_all, rm from devshell.base.module import Module from devshell.modules.sourceball import SourceBall from devshell.modules.build import Build +from devshell.modules.directory import DirFactory from devshell.modules.profile import Profile from devshell.modules.mock import Mock class Port(Module): def __init__(self, package=None): + #TODO: make me massageable if not package: package = getcwd() self.pkg = DirFactory(package) diff --git a/devshell/modules/profile.py b/devshell/modules/profile.py index 83a8253..42157ff 100644 --- a/devshell/modules/profile.py +++ b/devshell/modules/profile.py @@ -24,7 +24,7 @@ from devshell.base.profiles import dist_defines, get_mock_cfg, distro, TARGET, D from devshell.base.util import pwd, copytree from devshell.base.vars import MOCK_CFG_DIR -from devshell.modules.directory import Directory +from devshell.modules.directory import Directory, DirFactory class Profile(Directory): '''a profile module to resemble various architectures, branches, build targets, etc...''' @@ -90,4 +90,7 @@ class Profile(Directory): with pwd(self.dir): copytree(MOCK_CFG_DIR, self.mock_cfg_dir) + +Profile = DirFactory.register(Profile) + __all__ = ['Profile'] diff --git a/devshell/modules/revisioncontrol.py b/devshell/modules/revisioncontrol.py index 2acf3b2..ebea84b 100644 --- a/devshell/modules/revisioncontrol.py +++ b/devshell/modules/revisioncontrol.py @@ -16,10 +16,13 @@ # Authors: Yaakov M. Nemoy <[email protected]> # +from devshell.modules.directory import DirFactory from devshell.modules.packagesource import PackageSource class RevisionControl(PackageSource): '''base class for any module that implements a VCS system and wraps it for getting source for packages''' pass +RevisionControl = DirFactory.register(RevisionControl) + __all__ = ['RevisionControl'] diff --git a/devshell/modules/rpmcvspackage.py b/devshell/modules/rpmcvspackage.py index debadc0..7021e1a 100644 --- a/devshell/modules/rpmcvspackage.py +++ b/devshell/modules/rpmcvspackage.py @@ -30,12 +30,14 @@ from tempfile import mkdtemp from devshell.base.base import log from devshell.base.util import pwd, log_file, copytree +from devshell.modules.directory import DirFactory from devshell.modules.package import Package CVSROOT = ':pserver:[email protected]:/cvs/pkgs' class RpmCvsPackage(Package): def __init__(self, name=None, fedora_name=None): + #TODO: make me massageable if fedora_name: if not name: name = fedora_name @@ -97,4 +99,6 @@ class RpmCvsPackage(Package): if branch not in self.branches: self.cfg['branches'].append(branch) +RpmCvsPackage = DirFactory.register(RpmCvsPackage) + __all__ = ['RpmCvsPackage'] diff --git a/devshell/modules/source.py b/devshell/modules/source.py index 9e4dd68..3c0b76e 100644 --- a/devshell/modules/source.py +++ b/devshell/modules/source.py @@ -49,6 +49,7 @@ class SCM(object): class Source(Module): def __init__(self, name, branch='devel'): + #TODO: make me massageable self.name = name self.branch = branch self.scm = None diff --git a/devshell/modules/sourceball.py b/devshell/modules/sourceball.py index efa8b3b..69dd2c3 100644 --- a/devshell/modules/sourceball.py +++ b/devshell/modules/sourceball.py @@ -31,6 +31,7 @@ from devshell.base.exceptions import ExecutionException from devshell.base.util import pwd, copy, move, base_dir, log_file, rm from devshell.base.vars import DIFF_EXCLUDES_FILE +from devshell.modules.directory import DirFactory from devshell.modules.packagesource import PackageSource # 4's what git uses @@ -42,6 +43,7 @@ patch_num_len = 4 class SourceBall(PackageSource): '''a type of package that is a single sourceball, a spec file, and some patches''' def __init__(self, name=None, tarball=''): + #TODO: make me massageable if tarball: tmp_dir = mkdtemp() with pwd(tmp_dir): @@ -203,4 +205,7 @@ class SourceBall(PackageSource): log.info('Verified clean patches: ' + str(clean)) return clean + +SourceBall = DirFactory.register(SourceBall) + __all__ = ['SourceBall'] |

