# Fedora Developer Shell # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # Authors: Yaakov M. Nemoy # 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.exceptions import ExecutionException from base.dirfactory import DirFactory from base.util import pwd, one, log_file from base.vars import orig_src_dir, haskell_compiler from modules.buildsystem import BuildSystem from modules.sourceball import SourceBall class Cabal(BuildSystem): '''A wrapper around common cabal operations This provides a useful api for other modules around the cabal build system ''' def __init__(self, name): '''creates a new cabal module this api is deprecated, because it should be more autodetecting name is a Package (Directory) that uses cabal for its build system ''' if type(name) is string: self.pkg_src = DirFactory(name) self.name = name else: self.pkg_src = name self.name = name.name self.compiler = haskell_compiler def find_setup(self): '''returns the name of the Setup.?hs script for cabal. ''' setup_re = compile("Setup\.l?hs") with self.pkg_src.src_dir(): return one(listdir(getcwd()), setup_re.search) def compile_setup(self, *args): '''compiles the setup script for faster execution ''' with self.pkg_src.src(*args): with pwd(self.pkg_src.pkg_src_dir): with log_file('ghc.log') as ghc_out: with self.pkg_src.src_dir(): setup_f = self.find_setup() p = Popen([self.compiler, '--make', setup_f], stdout = ghc_out, stderr = ghc_out) log.info('Building %s, please wait...' % setup_f) p.communicate() def configure(self, target='home', *args): '''runs the configure stage of cabal target is either 'home' or 'root' and will configure the package to install either to the user's home directory, or to the system wide haskell. Some help is needed making this more flexible ''' user = True if target == 'home' else False with self.pkg_src.src(*args): self.compile_setup() with pwd(self.pkg_src.pkg_src_dir): with log_file('cabal.log') as cabal_out: with self.pkg_src.src_dir(): cmd = [abspath('Setup'), 'configure'] \ + (['--user', '--prefix=' + expanduser('~')] if user else []) p = Popen(cmd, stdout=cabal_out, stderr=cabal_out) log.info('Configuring %s, please wait...' % self.name) p.communicate() def build(self, *args): '''runs the build stage of cabal This is not safe to run on an unconfigured source dir, because this module does not track the state of cabal systems. The user must do this on their own. ''' with self.pkg_src.src(*args): self.compile_setup() with pwd(self.pkg_src.pkg_src_dir): with log_file('cabal.log') as cabal_out: with self.pkg_src.src_dir(): cmd = [abspath('Setup'), 'build'] p = Popen(cmd, stdout=cabal_out, stderr=cabal_out) log.info('Building %s, please wait...' % self.name) p.communicate() def install(self, *args): '''runs the install stage of cabal This is not safe to run on an unconfigured source dir, because this module does not track the state of cabal systems. The user must do this on their own. ''' with self.pkg_src.src(*args): self.compile_setup() with pwd(self.pkg_src.pkg_src_dir): with log_file('cabal.log') as cabal_out: with pwd(self.pkg_src.src_dir()): cmd = [abspath('Setup'), 'install'] p = Popen(cmd, stdout=cabal_out, stderr=cabal_out) log.info('Building %s, please wait...' % self.name) p.communicate() def install_source(self, target='home', *args): '''perform configure, build, and install steps in one ''' with self.pkg_src.src(*args): self.configure(target, orig) self.build(orig) self.install(orig) def gen_spec(self): cabal_file = self.pkg_src.hackage_name + '.spec' with pwd(self.pkg_src.pkg_src_dir): with log_file('cabal2spec.log') as c2s_log: with pwd(self.pkg_src.dir): cmd = ['cabal2spec', cabal_file] p = Popen(cmd, stdout=c2s_log, stderr=c2s_log) log.info('Generating spec file for %s' % cabal_file) p.communicate() def close(self): self.pkg_src.close() __all__ = ['Cabal']