summaryrefslogtreecommitdiffstats
path: root/devshell
diff options
context:
space:
mode:
Diffstat (limited to 'devshell')
-rw-r--r--devshell/base/factories.py72
-rw-r--r--devshell/base/module.py10
-rw-r--r--devshell/base/util.py8
-rw-r--r--devshell/modules/autotools.py9
-rw-r--r--devshell/modules/build.py5
-rw-r--r--devshell/modules/buildsystem.py3
-rw-r--r--devshell/modules/cabal.py1
-rw-r--r--devshell/modules/darcs.py5
-rw-r--r--devshell/modules/directory.py91
-rw-r--r--devshell/modules/git.py8
-rw-r--r--devshell/modules/mock.py3
-rw-r--r--devshell/modules/package.py5
-rw-r--r--devshell/modules/packagesource.py5
-rw-r--r--devshell/modules/port.py3
-rw-r--r--devshell/modules/profile.py5
-rw-r--r--devshell/modules/revisioncontrol.py3
-rw-r--r--devshell/modules/rpmcvspackage.py4
-rw-r--r--devshell/modules/source.py1
-rw-r--r--devshell/modules/sourceball.py5
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']