diff options
author | Marco Pesenti Gritti <marco@marcopg.org> | 2009-01-20 17:21:49 (GMT) |
---|---|---|
committer | Marco Pesenti Gritti <marco@marcopg.org> | 2009-01-20 17:21:49 (GMT) |
commit | 7cd4cee4819b134a195ffb26eae26032493ef6bd (patch) | |
tree | 5229ef759ec97f1123e21f2bb162d59e9d5d02cb /scripts | |
parent | ffe31992dd4796c576ab58b61d61bbb772b982f0 (diff) |
Some refactoring and fixes.
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/bundlemodule.py | 94 | ||||
-rw-r--r-- | scripts/config.py | 64 | ||||
-rw-r--r-- | scripts/main.py | 127 | ||||
-rw-r--r-- | scripts/sysdeps.py | 91 |
4 files changed, 283 insertions, 93 deletions
diff --git a/scripts/bundlemodule.py b/scripts/bundlemodule.py new file mode 100644 index 0000000..3a662c1 --- /dev/null +++ b/scripts/bundlemodule.py @@ -0,0 +1,94 @@ +__metaclass__ = type + +import os + +from jhbuild.errors import BuildStateError +from jhbuild.modtypes import Package, get_branch, register_module_type + +__all__ = [ 'BundleModule' ] + +class BundleModule(Package): + type = 'bundle' + + STATE_CHECKOUT = 'checkout' + STATE_FORCE_CHECKOUT = 'force_checkout' + STATE_BUILD = 'build' + STATE_INSTALL = 'install' + + def __init__(self, name, branch, dependencies=[], after=[]): + Package.__init__(self, name, dependencies, after) + self.branch = branch + + def get_srcdir(self, buildscript): + return self.branch.srcdir + + def get_builddir(self, buildscript): + return self.get_srcdir(buildscript) + + def get_revision(self): + return self.branch.branchname + + def do_start(self, buildscript): + pass + do_start.next_state = STATE_CHECKOUT + do_start.error_states = [] + + def skip_checkout(self, buildscript, last_state): + # skip the checkout stage if the nonetwork flag is set + return buildscript.config.nonetwork + + def do_checkout(self, buildscript): + srcdir = self.get_srcdir(buildscript) + buildscript.set_action('Checking out', self) + self.branch.checkout(buildscript) + # did the checkout succeed? + if not os.path.exists(srcdir): + raise BuildStateError('source directory %s was not created' + % srcdir) + do_checkout.next_state = STATE_BUILD + do_checkout.error_states = [STATE_FORCE_CHECKOUT] + + def skip_force_checkout(self, buildscript, last_state): + return False + + def do_force_checkout(self, buildscript): + buildscript.set_action('Checking out', self) + self.branch.force_checkout(buildscript) + do_force_checkout.next_state = STATE_BUILD + do_force_checkout.error_states = [STATE_FORCE_CHECKOUT] + + def skip_build(self, buildscript, last_state): + return buildscript.config.nobuild + + def do_build(self, buildscript): + buildscript.set_action('Building', self) + srcdir = self.get_srcdir(buildscript) + builddir = self.get_builddir(buildscript) + python = os.environ.get('PYTHON', 'python') + cmd = [python, 'setup.py', 'build'] + buildscript.execute(cmd, cwd=srcdir) + do_build.next_state = STATE_INSTALL + do_build.error_states = [STATE_FORCE_CHECKOUT] + + def skip_install(self, buildscript, last_state): + return buildscript.config.nobuild + + def do_install(self, buildscript): + buildscript.set_action('Installing', self) + srcdir = self.get_srcdir(buildscript) + builddir = self.get_builddir(buildscript) + python = os.environ.get('PYTHON', 'python') + cmd = [python, 'setup.py', 'install'] + cmd.extend(['--prefix', buildscript.config.prefix]) + buildscript.execute(cmd, cwd=srcdir) + buildscript.packagedb.add(self.name, self.get_revision() or '') + do_install.next_state = Package.STATE_DONE + do_install.error_states = [] + + +def parse_bundle(node, config, uri, repositories, default_repo): + id = node.getAttribute('id') + branch = get_branch(node, repositories, default_repo, config) + return BundleModule(id, branch) + +register_module_type('bundle', parse_bundle) diff --git a/scripts/config.py b/scripts/config.py index 0d7a1b8..c9a1049 100644 --- a/scripts/config.py +++ b/scripts/config.py @@ -6,69 +6,33 @@ import jhbuild.config import sysdeps class Config(jhbuild.config.Config): - def __init__(self, rc_file): - scripts_dir = os.path.dirname(__file__) - self._base_dir = os.path.dirname(scripts_dir) - self._set_dir = os.path.join(self._base_dir, 'config', 'modulesets') - - jhbuild.config.Config.__init__(self, self._ensure_rc_file(rc_file)) - + def __init__(self, base_dir, rc_file): + self.base_dir = base_dir + jhbuild.config.Config.__init__(self, os.path.join(self.base_dir, 'sugar.jhbuildrc')) self._setup() - def get_user_path(self): - user_path = os.path.expanduser('~/.sugar-jhbuild') - if not os.path.exists(user_path): - os.mkdir(user_path) - return user_path - - def _ensure_rc_file(self, rc_file): - if not os.path.exists(rc_file): - f = open(rc_file, 'w') - f.write('# Created by sugar-jhbuild') - f.close - return rc_file - def _setup(self): self.autogenargs = '' - self.moduleset = [] - self._add_moduleset('glucose-external.modules') - self._add_moduleset('tools.modules') - self._add_moduleset('extra.modules') - self._add_moduleset('extra-activities.modules') - - release_dir = None - for f in os.listdir(self._set_dir): - if f.startswith('release-'): - release_dir = f - - self._add_moduleset('glucose.modules', release_dir) - self._add_moduleset('fructose.modules', release_dir) - - self.modules = [ 'meta-tools', - 'meta-glucose', - 'meta-fructose' ] - - self.checkoutroot = os.path.join(self._base_dir, 'source') - self.tarballdir = self.checkoutroot - + self.checkoutroot = os.path.join(self.base_dir, 'source') + self.tarballdir = os.path.join(self.base_dir, 'source') + self.moduleset = os.path.join(self.base_dir, 'config', + 'modulesets', 'sugar.modules') + for package, source in sysdeps.get_packages(): if source and source not in self.skip: self.skip.append(source) - def _add_moduleset(self, moduleset, release_dir=None): - if release_dir: - path = os.path.join(self._set_dir, release_dir) - else: - path = self._set_dir - - self.moduleset.append(os.path.join(path, moduleset)) - def setup_env(self): # Hack to replace the default prefix if self.prefix == '/opt/gnome2': - self.prefix = os.path.join(self._base_dir, 'install') + self.prefix = os.path.join(self.base_dir, 'install') + + #Hack to allow sugar-jhbuild to find its self again. + MY_PATH = os.getenv('PATH', 'Error') + os.environ["PATH"] = MY_PATH + ':' + self.base_dir + jhbuild.config.Config.setup_env(self) jhbuild.config.addpath('XDG_DATA_DIRS', '/usr/share') diff --git a/scripts/main.py b/scripts/main.py index fd06471..44e27fb 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -18,70 +18,108 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -import sys, os +import sys, os, errno import optparse import traceback -import jhbuild.main +import gettext +localedir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../mo')) +gettext.install('jhbuild', localedir=localedir, unicode=True) +import __builtin__ +__builtin__.__dict__['N_'] = lambda x: x + import jhbuild.commands from jhbuild.errors import UsageError, FatalError +from jhbuild.utils.cmds import get_output +from jhbuild.moduleset import warn_local_modulesets import bundlemodule import depscheck -import check -import report import clear from config import Config +if sys.platform == 'darwin': + # work around locale.getpreferredencoding() returning an empty string in + # Mac OS X, see http://bugzilla.gnome.org/show_bug.cgi?id=534650 and + # http://bazaar-vcs.org/DarwinCommandLineArgumentDecoding + sys.platform = 'posix' + try: + import locale + finally: + sys.platform = 'darwin' +else: + import locale + +try: + _encoding = locale.getpreferredencoding() + assert _encoding +except (locale.Error, AssertionError): + _encoding = 'ascii' + +def uencode(s): + if type(s) is unicode: + return s.encode(_encoding, 'replace') + else: + return s + +def uprint(*args): + '''Print Unicode string encoded for the terminal''' + for s in args[:-1]: + print uencode(s), + s = args[-1] + print uencode(s) + +__builtin__.__dict__['uprint'] = uprint +__builtin__.__dict__['uencode'] = uencode + def help_commands(option, opt_str, value, parser): - commands = [ - ('build', 'update and compile (the default)'), - ('build-base', 'build the base sugar dependencies'), - ('buildone', 'modules build a single module'), - ('update', 'update from version control'), - ('updateone', 'update a fixed set of modules'), - ('list', 'list what modules would be built'), - ('info', 'prints information about modules'), - ('tinderbox', 'build non-interactively with logging'), - ('gui', 'build targets from a gui app'), - ('run', 'run a command in the build environment'), - ('shell', 'start a shell in the build environment'), - ('depscheck', 'check that required dependencies exists'), - ('dot', 'output a dependency graph for processing with graphviz'), - ] - print 'sugar-jhbuild commands are:' - for (cmd, description) in commands: - print ' %-15s %s' % (cmd, description) + thisdir = os.path.abspath(os.path.dirname(__file__)) + + # import all available commands + for fname in os.listdir(os.path.join(thisdir, 'commands')): + name, ext = os.path.splitext(fname) + if not ext == '.py': + continue + try: + __import__('jhbuild.commands.%s' % name) + except ImportError: + pass + + uprint(_('JHBuild commands are:')) + commands = [(x.name, x.doc) for x in jhbuild.commands.get_commands().values()] + commands.sort() + for name, description in commands: + uprint(' %-15s %s' % (name, description)) print - print 'For more information run "sugar-jhbuild <command> --help"' + uprint(_('For more information run "jhbuild <command> --help"')) parser.exit() -def main(args): +def main(base_dir, args): parser = optparse.OptionParser( - usage='%prog [ -f config ] command [ options ... ]', - description='Build sugar and his dependencies.') + usage=_('%prog [ -f config ] command [ options ... ]'), + description=_('Build a set of modules from diverse repositories in correct dependency order (such as GNOME).')) parser.disable_interspersed_args() parser.add_option('--help-commands', action='callback', callback=help_commands, - help='Information about available jhbuild commands') + help=_('Information about available jhbuild commands')) parser.add_option('-f', '--file', action='store', metavar='CONFIG', type='string', dest='configfile', - default=os.path.join(os.environ['HOME'], '.sugar.jhbuildrc'), - help='use a non default configuration file') + default=os.environ.get("JHBUILDRC", os.path.join(os.environ['HOME'], '.jhbuildrc')), + help=_('use a non default configuration file')) parser.add_option('-m', '--moduleset', action='store', metavar='URI', type='string', dest='moduleset', default=None, - help='use a non default module set') + help=_('use a non default module set')) parser.add_option('--no-interact', action='store_true', dest='nointeract', default=False, - help='do not prompt for input') + help=_('do not prompt for input')) options, args = parser.parse_args(args) try: - config = Config(options.configfile) + config = Config(base_dir, options.configfile) except FatalError, exc: - sys.stderr.write('sugar-jhbuild: %s\n' % (str(exc))) + sys.stderr.write('sugar-jhbuild: %s\n' % exc.args[0].encode(_encoding, 'replace')) sys.exit(1) if options.moduleset: config.moduleset = options.moduleset @@ -93,24 +131,27 @@ def main(args): command = args[0] args = args[1:] - if command == 'build' and len(args) == 0: - print 'Checking dependencies...' - jhbuild.commands.run('depscheck', config, []) - elif command == 'run' and len(args) == 0: - args.append('sugar-emulator') + warn_local_modulesets(config) try: - return jhbuild.commands.run(command, config, args) + rc = jhbuild.commands.run(command, config, args) except UsageError, exc: - sys.stderr.write('sugar-jhbuild %s: %s\n' % (command, str(exc))) + sys.stderr.write('sugar-jhbuild %s: %s\n' % (command, exc.args[0].encode(_encoding, 'replace'))) parser.print_usage() sys.exit(1) except FatalError, exc: - sys.stderr.write('sugar-jhbuild %s: %s\n' % (command, str(exc))) + sys.stderr.write('sugar-jhbuild %s: %s\n' % (command, exc.args[0].encode(_encoding, 'replace'))) sys.exit(1) except KeyboardInterrupt: - print "Interrupted" + uprint(_('Interrupted')) sys.exit(1) except EOFError: - print "EOF" + uprint(_('EOF')) sys.exit(1) + except IOError, e: + if e.errno != errno.EPIPE: + raise + sys.exit(0) + if rc: + sys.exit(rc) + diff --git a/scripts/sysdeps.py b/scripts/sysdeps.py new file mode 100644 index 0000000..b398cff --- /dev/null +++ b/scripts/sysdeps.py @@ -0,0 +1,91 @@ +import os +import subprocess + +from xml.dom import minidom + +scripts_dir = os.path.dirname(__file__) +base_dir = os.path.dirname(scripts_dir) + +def get_distribution(): + if 'SJH_DISTRIBUTION' in os.environ: + return os.environ['SJH_DISTRIBUTION'].split('-') + + # Fedora + if os.path.exists('/etc/fedora-release'): + name = 'fedora' + + f = open('/etc/fedora-release') + full_name = f.read() + f.close() + + if 'Rawhide' in full_name: + version = 'rawhide' + else: + version = full_name.split(' ')[2] + + return name, version + + # Debian and Ubuntu + try: + out, err = subprocess.Popen(['lsb_release', '-is'], + stdout=subprocess.PIPE).communicate() + name = out.strip().lower() + + out, err = subprocess.Popen(['lsb_release', '-rs'], + stdout=subprocess.PIPE).communicate() + version = out.strip() + + if name == 'debian' and version == 'testing': + version = 'unstable' + + return name, version + except OSError: + pass + + return None, None + +def check_package(package): + name, version = get_distribution() + if name == 'fedora': + ret = subprocess.call(['rpm', '--quiet', '-q', package]) + return ret == 0 + elif name in ['ubuntu', 'debian']: + cmd = ["dpkg-query", "-f='${status}'", "-W", package] + out, err = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate() + return out.find('install ok installed') != -1 + + return None + +def parse_dependencies(): + name, version = get_distribution() + if name is None or version is None: + return None + + filename = os.path.join(base_dir, 'config', 'sysdeps', + '%s-%s.xml' % (name, version)) + + if not os.path.exists(filename): + return None + + return minidom.parse(filename) + +def get_packages(): + document = parse_dependencies() + if document is None: + return [] + + packages = [] + root = document.childNodes[0] + + for node in root.childNodes: + if node.nodeType == node.ELEMENT_NODE: + if node.nodeName == 'package': + name = node.getAttribute('name') + if node.hasAttribute('source'): + source = node.getAttribute('source') + else: + source = None + + packages.append((name, source)) + + return packages |