summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYaakov M. Nemoy <loupgaroublond@gmail.com>2008-12-29 23:11:55 -0500
committerYaakov M. Nemoy <loupgaroublond@gmail.com>2008-12-29 23:11:55 -0500
commit0cb6e545b308e79a5d4aa6c36b7366f2b0fc30fd (patch)
tree8c30624c6191a3d7a138b8229ef829a8406b9aa0
parent3d02771f3e2376cd459e9a4d0edf2ff0c0f22b2c (diff)
downloadfedora-devshell-0cb6e545b308e79a5d4aa6c36b7366f2b0fc30fd.tar.gz
fedora-devshell-0cb6e545b308e79a5d4aa6c36b7366f2b0fc30fd.tar.xz
fedora-devshell-0cb6e545b308e79a5d4aa6c36b7366f2b0fc30fd.zip
Mass commit, i should be cleaner in the future.
-rw-r--r--base/profiles.py110
-rw-r--r--base/rpm_utils.py33
-rw-r--r--modules/cabal.py132
-rw-r--r--modules/mock.py46
-rw-r--r--modules/package.py111
-rw-r--r--modules/profile.py11
6 files changed, 413 insertions, 30 deletions
diff --git a/base/profiles.py b/base/profiles.py
new file mode 100644
index 0000000..2490b3f
--- /dev/null
+++ b/base/profiles.py
@@ -0,0 +1,110 @@
+
+from os.path import join
+from subprocess import Popen, PIPE
+
+from vars import FEDORA_DIR
+
+TARGET = 0
+DIST = 1
+DISTVAR = 2
+DISTVAL = 3
+
+def distdef(dist):
+ return dist.replace('.', '')
+
+def define(key, value):
+ return '--define "%s %s"' % (key, value)
+
+def join_defines(*defines):
+ return " ".join(defines)
+
+def dist_defines(dist, distvar, distval):
+ dist = define('dist', dist)
+ distvar = define(distvar, distval)
+ distdef = define(distdef(dist), 1)
+ return join_defines([dist, distvar, distdef])
+
+head_branch = 'devel'
+
+def get_mock_cfg(distvar, distval, buildarch):
+ if distvar == 'fedora' and distval in [4, 5, 6]:
+ return '%s-%s-%s-core' % (distvar, distval, buildarch)
+ else:
+ return '%s-%s-%s' % (distvar, distval, buildarch)
+
+def dir_defines(some_dir):
+ defs = list()
+ defs.append(define('_sourcedir', join(some_dir, 'SOURCES')))
+ defs.append(define('_specdir', join(some_dir, 'SPECS')))
+ defs.append(define('_builddir', join(some_dir, 'BUILD')))
+ defs.append(define('_srcrpmdir', join(some_dir, 'SRPMS')))
+ defs.append(define('_rpmdir', join(some_dir, 'RPMS')))
+ return join_defines(defs)
+
+def ver_rel(spec_file, defines):
+ rpm_p = Popen('rpm %s -q --qf "%%{VERSION} %%{RELEASE}\n" --specfile %s' % \
+ (defines, spec_file), stdout=PIPE, shell=True)
+ verrels = rpm_p.communicate()[0]
+ verrel = verrels.split('\n')[0]
+ return verrel.split(' ')
+
+#taken from CVS for now
+distro = [{'RHL-7':('rhl7','.rhl7','rhl','7'),
+ 'RHL-8':('rhl8','.rhl8','rhl','8'),
+ 'RHL-9':('rhl9','.rhl9','rhl','9'),
+ 'OLPC-2':('dist-olpc2','.olpc2','olpc','2'),
+ 'OLPC-3':('dist-olpc3','.olpc3','olpc','3'),
+ 'EL-4':('el4','.el4','epel','4'),
+ 'EL-5':('el5','.el5','epel','5'),
+ 'FC-1':('fc1','.fc1','fedora','1'),
+ 'FC-2':('fc2','.fc2','fedora','2'),
+ 'FC-3':('fc3','.fc3','fedora','3'),
+ 'FC-4':('fc4','.fc4','fedora','4'),
+ 'FC-5':('fc5','.fc5','fedora','5'),
+ 'FC-6':('fc6','.fc6','fedora','6'),
+ 'F-7':('dist-fc7','.fc7','fedora','7'),
+ 'F-8':('dist-f8','.fc8','fedora','8'),
+ 'F-9':('dist-f9','.fc9','fedora','9'),
+ 'F-10':('dist-f10','.fc10','fedora','10'),
+ 'F-11':('dist-f11','.fc11','fedora','11'),
+ 'devel':('dist-devel','.devel','fedora','10')}]
+
+# this class is temporary, it's only for mimickng CVS for now
+# later we'll come up with a better way to do custom profiles
+class Profile(object):
+ def __init__(self, branch):
+ self.branch = branch
+ self.distro = distro[branch]
+
+ @property
+ def dist_defines(self):
+ d = self.distro
+ return dist_defines(d[DIST], d[DISTVAR], d[DISTVAL])
+
+ @property
+ def mock_cfg(self):
+ d = self.distro
+ # TODO: buildarchs need to be handled somehow
+ # yes i'm lame and i did this i386 only for now
+ return get_mock_cfg(d[DISTVAR], d[DISTVAL], 'i386')
+
+ @property
+ def config_dir(self):
+ return '/etc/mock'
+
+ @property
+ def result_dir(self):
+ return FEDORA_DIR
+
+
+def main():
+ print distdef('.fc9')
+ print ver_rel('ghc-X11.spec', '')
+
+if __name__ == '__main__':
+ main()
+
+__all__ = ['TARGET', 'DISTVAR', 'distdef', 'DISTVAL', 'head_branch',
+ 'DIST', 'join_defines', 'ver_rel', 'define',
+ 'dir_defines', 'get_mock_cfg', 'dist_defines',
+ 'Profile'] \ No newline at end of file
diff --git a/base/rpm_utils.py b/base/rpm_utils.py
new file mode 100644
index 0000000..bfdae46
--- /dev/null
+++ b/base/rpm_utils.py
@@ -0,0 +1,33 @@
+from __future__ import with_statement
+
+import re
+import rpm
+
+from contextlib import contextmanager
+from base import log
+
+class RPMSpec(object):
+ def __init__(self, spec_file):
+ self.contents = [x for x in file(spec_file)]
+
+ def version(self):
+ ver_line = [x for x in self.contents if x.startswith('Version:')][0]
+ ver_re = re.search(r'Version: (.*)', ver_line)
+ return ver_re.groups()[0]
+
+ def rel(self):
+ rel_line = [x for x in self.contents if x.startswith('Release:')][0]
+ rel_re = re.search(r'Release: (.*)', rel_line)
+ return rel_re.groups()[0]
+
+@contextmanager
+def rpm_macros(**keys):
+ for key, value in keys.iteritems():
+ log.debug('setting...')
+ log.debug(key + ' ' + value)
+ rpm.addMacro(key, value)
+ yield
+ for key, value in keys.iteritems():
+ rpm.delMacro(key)
+
+__all__ = ['rpm_macros', 'RPMSpec'] \ No newline at end of file
diff --git a/modules/cabal.py b/modules/cabal.py
new file mode 100644
index 0000000..81f4b68
--- /dev/null
+++ b/modules/cabal.py
@@ -0,0 +1,132 @@
+from __future__ import with_statement
+
+from os import listdir, getcwd
+from os.path import expanduser, expandvars, abspath
+
+from re import compile, DOTALL
+
+from subprocess import Popen
+
+from urllib import urlopen, urlretrieve
+
+from base.base import log
+from base.module import Module
+from base.exceptions import ExecutionException
+from base.util import pwd, one
+from base.vars import orig_src_dir, haskell_compiler
+
+from modules.package import Package
+
+class Cabal(Module):
+ def __init__(self, name, root='~/haskell'):
+ self.name = name
+ self.root = expanduser(root)
+ with pwd(self.root):
+ self.package = Package(name)
+ self.original = orig_src_dir
+ self.compiler = haskell_compiler
+
+ def copy_in(self, tarball):
+ tarball = abspath(tarball)
+ with pwd(self.root):
+ self.package.add_sourceball(tarball)
+
+ def find_setup(self, original=False):
+ setup_re = compile("Setup\.l?hs")
+ with pwd(self.source_dir(original)):
+ setup_f = one(listdir(getcwd()), setup_re.search)
+ log.debug(setup_f)
+ return setup_f
+
+ def compile_setup(self, original=False):
+ with pwd(self.pkg.code_dir):
+ with file('ghc.log', 'a') as ghc_out:
+ with pwd(self.source_dir(original)):
+ setup_f = self.find_setup(original)
+ p = Popen([self.compiler, '--make', setup_f],
+ stdout = ghc_out, stderr = ghc_out)
+ log.info('Building %s, please wait...' % setup_f)
+ p.wait()
+
+ def configure(self, target='home', original=False):
+ user = True if target == 'home' else False
+ self.compile_setup(original)
+ with pwd(self.pkg.code_dir):
+ with file('cabal.log', 'a') as cabal_out:
+ with pwd(self.source_dir(original)):
+ args = [abspath('Setup'), 'configure'] + \
+ (['--user', '--prefix=' + expanduser('~')] if user else [])
+ p = Popen(args, stdout=cabal_out, stderr=cabal_out)
+ log.info('Configuring %s, please wait...' % self.name)
+ p.wait()
+
+ def build(self, original=False):
+ '''This is not safe to run on an unconfigured source dir'''
+ self.compile_setup(original)
+ with pwd(self.pkg.code_dir):
+ with file('cabal.log', 'a') as cabal_out:
+ with pwd(self.source_dir(original)):
+ args = [abspath('Setup'), 'build']
+ p = Popen(args, stdout=cabal_out, stderr=cabal_out)
+ log.info('Building %s, please wait...' % self.name)
+ p.wait()
+
+ def install(self, original=False):
+ '''This is not safe to run on an unconfigured source dir'''
+ self.compile_setup(original)
+ with pwd(self.pkg.code_dir):
+ with file('cabal.log', 'a') as cabal_out:
+ with pwd(self.source_dir(original)):
+ args = [abspath('Setup'), 'install']
+ p = Popen(args, stdout=cabal_out, stderr=cabal_out)
+ log.info('Building %s, please wait...' % self.name)
+ p.wait()
+
+ def install_source(self, target='home', original=False):
+ self.configure(target, original)
+ self.build(original)
+ self.install(original)
+
+ def install_sourceball(self, tarball, target='home'):
+ self.copy_in(tarball)
+ self.install_source(target, False)
+
+ def get_from_hackage(self, pkg, ver):
+ sb_file = self.hackage_url(pkg, ver)
+ self.copy_in(sb_file)
+
+ def get_latest(self, pkg):
+ ver = self.latest_version(pkg)
+ self.get_from_hackage(pkg, ver)
+
+ def install_from_hackage(self, pkg, ver, target='home'):
+ self.get_from_hackage(pkg, ver)
+ self.install_source(target, False)
+
+ def install_latest(self, pkg, target='home'):
+ self.get_latest(pkg)
+ self.install_source(target, False)
+
+ def source_dir(self, original=False):
+ with pwd(self.package.code_dir):
+ return abspath(self.package.cfg['source'] + (self.orig_src_dir if original else ""))
+
+ def latest_version(self, pkg):
+ hackage_title = compile(r'<title.*?>HackageDB: (.*)-(.*)</title.*?>', DOTALL)
+ site = 'http://hackage.haskell.org/cgi-bin/hackage-scripts/package/' + pkg
+ u = urlopen(site)
+ page = u.read()
+ match = hackage_title.search(page)
+ groups = match.groups()
+ print groups
+ if pkg = groups[0]:
+ return groups[1]
+ else:
+ raise ExecutionException("package does not match package name, can't determine version, sorry")
+
+ def hackage_url(self, pkg, ver):
+ return 'http://hackage.haskell.org/packages/archive/' + \
+ pkg + '/' + ver + '/' + pkg + '-' + ver + '.tar.gz'
+
+ def close(self):
+ self.package.close()
diff --git a/modules/mock.py b/modules/mock.py
new file mode 100644
index 0000000..3655c37
--- /dev/null
+++ b/modules/mock.py
@@ -0,0 +1,46 @@
+from __future__ import with_statement
+
+from base.module import Module
+from base.vars import FEDORA_DIR
+from base.profiles import ver_rel, Profile
+from modules.build import Build
+from modules.package import Package
+
+class Mock(Module):
+ def __init__(self, target_dir, name, profile):
+ self.target_dir = target_dir
+ self.name = name
+ self.pkg = Package(name)
+ self.build = Build(name, target_dir)
+ # for now we're using the old profile form, namely a branch
+ # TODO: fix real profiles
+ self.profile = Profile(profile)
+
+ def build_rpm(self, target_dir=None):
+ if not target_dir:
+ if self.target_dir:
+ target_dir = self.target_dir
+ else:
+ raise ExecutionException(None, 'no Target Dir specified')
+
+ self.build.build_source_rpm(target_dir, self.profile)
+ self.build.fetch_rpms(target_dir)
+
+ srpm_name = self.pkg.get_srpm_name(self.profile)
+ mock_cfg = self.profile.mock_cfg
+ result_dir = self.profile.result_dir
+ config_dir = self.profile.config_dir
+ with pwd(self.pkg.code_dir):
+ with file('mock.log', 'w') as mock_out:
+ with pwd(FEDORA_DIR):
+ p = Popen(['/usr/bin/mock',
+ '-r %s' % mock_cfg,
+ '--configdir=%s' % config_dir,
+ '--resultdir=%s' % result_dir,
+ srpm_name],
+ stdout=mock_out, stderr=mock_out)
+ log.info('quick compiling %s... please wait' % srpm_name)
+ p.wait()
+
+
+__all__ = ['Mock'] \ No newline at end of file
diff --git a/modules/package.py b/modules/package.py
index 8072938..18e4dde 100644
--- a/modules/package.py
+++ b/modules/package.py
@@ -1,43 +1,75 @@
from __future__ import with_statement
import tarfile
-from os import makedirs, getcwd, chdir
+from os import makedirs, getcwd, chdir, listdir
from shutil import copyfileobj, copytree
-from os.path import abspath, join, split, splitext, basename
+from os.path import abspath, join, split, splitext, basename, exists
from configobj import ConfigObj
-
+from subprocess import Popen, PIPE
+from urllib import urlretrieve
from base.module import Module
from base.base import log
from base.exceptions import ExecutionException
from base.util import pwd, copy
+from base.profiles import ver_rel
#TODO: Find universal library for parsing URLs and PATHs alike
class Package(Module):
def __init__(self, name=None):
if not name:
- log.debug(split(getcwd()))
+ log.debug('no name with package')
+ cwd = getcwd()
+ log.debug(split(cwd))
+ if self.is_dir_pkg(cwd):
+ self.load_pkg(cwd)
+ else:
+ self.make_pkg(cwd)
name = split(getcwd())[1]
+
self.code_dir = getcwd()
#detect name somehow
else:
+ log.debug('package.init with name ' + name)
+ dir = abspath(name)
+ if not exists(dir):
+ makedirs(dir)
+ if self.is_dir_pkg(dir):
+ self.load_pkg(dir)
+ else:
+ self.make_pkg(dir)
+
+ def is_dir_pkg(self, dir):
+ with pwd(dir):
+ cfg = ConfigObj('.devshell')
try:
- cfg = ConfigObj('.devshell')
if cfg['type'] == 'package':
- self.code_dir = getcwd()
- except:
- self.code_dir = abspath(name)
- with pwd(self.code_dir):
- self.pkg_cfg = ConfigObj('.devshell')
- if not self.pkg_cfg['type'] == 'package':
- raise ExecutionException('invalid package directory')
- self.name = name
-
- def create(self, name):
- if not self.name:
- makedirs(join(getcwd(), name))
-
+ log.debug('is type package')
+ return True
+ else:
+ return False
+ except KeyError, e:
+ return False
+
+ def load_pkg(self, dir):
+ log.debug('package.load_pkg')
+ with pwd(dir):
+ self.cfg = ConfigObj('.devshell')
+ self.name = self.cfg['name']
+ self.code_dir = self.cfg['code_dir']
+
+ def make_pkg(self, dir):
+ log.debug('package.make_pkg')
+ with pwd(dir):
+ code_dir = dir
+ name = split(getcwd())[1]
+ self.cfg = ConfigObj('.devshell')
+ self.cfg['type'] = 'package'
+ self.cfg['name'] = self.name = name
+ self.cfg['code_dir'] = self.code_dir = code_dir
+ self.cfg.write()
+
def add_spec(self, spec_file):
log.debug('spec_file is %s' % spec_file)
log.debug('spec_file_name is %s' % self.name + '.spec')
@@ -47,21 +79,28 @@ class Package(Module):
except IOError, e:
log.error(str(e))
raise ExecutionException(e, 'spec-file could not be added')
-
+
+ def orig_dir(self, dir):
+ return dir + '_orig'
+
def add_sourceball(self, sourceball_name, extract_dir=None):
+ log.debug('addincg sourceball with code_dir ' + self.code_dir)
with pwd(self.code_dir):
try:
- copy(sourceball_name, split(sourceball_name)[1])
- sourceball_name = split(sourceball_name)[1]
-
- self.pkg_cfg['sourceball'] = sourceball_name
+ sourceball_name = urlretrieve(sourceball_name,
+ split(sourceball_name)[1])[0]
+
+ self.cfg['sourceball'] = sourceball_name
sourceball = tarfile.open(sourceball_name)
if not extract_dir:
extract_dir = min([(x.name, x) for x in sourceball])[0]
extract_dir = basename(abspath(extract_dir))
- log.debug('extract_dir is %s' % extract_dir)
- self.pkg_cfg['source'] = extract_dir
- orig_extract_dir = extract_dir + '_orig'
+ log.debug('extract_dir is %s' % extract_dir)
+ log.debug('config is of ' + str(self.cfg))
+ self.cfg['source'] = extract_dir
+ log.debug('cfg[\'source\'] is ' + self.cfg['source'])
+ log.debug('set source')
+ orig_extract_dir = self.orig_dir(extract_dir)
sourceball.extractall()
copytree(abspath(extract_dir), abspath(orig_extract_dir))
except OSError, e:
@@ -69,8 +108,20 @@ class Package(Module):
#Chances are the _orig dir already exists
raise ExecutionException(e, 'something went wrong')
#TODO: figure out what exceptions TarFile will throw
-
+
def close(self):
- self.pkg_cfg.write()
-
-__all__ = ['Package'] \ No newline at end of file
+ log.debug('writing self.cfg for package')
+ with pwd(self.code_dir):
+ self.cfg.write()
+
+ @property
+ def spec_file(self):
+ return self.name + '.spec'
+
+ def get_srpm_name(self, profile):
+ with pwd(self.code_dir):
+ ver, rel = ver_rel(self.spec_file, profile.dist_defines())
+ return '%s-%s-%s.src.rpm' % (self.name, ver, rel)
+
+
+__all__ = ['Package']
diff --git a/modules/profile.py b/modules/profile.py
new file mode 100644
index 0000000..bac1553
--- /dev/null
+++ b/modules/profile.py
@@ -0,0 +1,11 @@
+from base.module import Module
+from base.exceptions import ExecutionException
+
+class Profile(Module):
+ def __init__(self, name=None, branch=None):
+ if branch:
+ pass
+ elif name:
+ pass
+ else:
+ raise ExecutionException('need a saved profile or a branch to lookup') \ No newline at end of file