예제 #1
0
class cmd_distone(Command):
    doc = N_('Dist one or more modules')

    name = 'distone'
    usage_args = N_('[ options ... ] [ modules ... ]')

    def __init__(self):
        Command.__init__(self, [
            make_option('-s', '--skip', metavar='MODULES',
                        action='append', dest='skip', default=[],
                        help=_('don\'t package the given modules')),
            make_option('-c', '--compress-kind', metavar='MODULE',
                        action='store', dest='compress', default="gz",
                        help=_('compression type (default is gzip)')),
            make_option('-n', '--no-net',
                        action='store_true', dest='nonet', default=False,
                        help=_('package also downloadable libraries')),
            ])

    def run(self, config, options, args, help=None):
        module_set = jhbuild.moduleset.load(config)
        try:
            module_list = [module_set.get_module(modname, ignore_case = True) for modname in args]
        except KeyError as e:
            raise FatalError(_("A module called '%s' could not be found.") % e)

        if not module_list:
            self.parser.error(_('This command requires a module parameter.'))

        config.compress = options.compress
        config.nonet = options.nonet

        build = jhbuild.frontends.get_buildscript(config, module_list, module_set=module_set)
        return build.build(phases=['dist'])
예제 #2
0
class cmd_dot(Command):
    doc = N_('Output a Graphviz dependency graph for one or more modules')

    name = 'dot'
    usage_args = N_('[ modules ... ]')

    def __init__(self):
        Command.__init__(self, [
            make_option('--soft-deps',
                        action='store_true', dest='soft_deps', default=False,
                        help=_('add dotted lines to soft dependencies')),
            make_option('--clusters',
                        action='store_true', dest='clusters', default=False,
                        help=_('group modules from metamodule together')),
            ])

    def run(self, config, options, args, help=None):
        module_set = jhbuild.moduleset.load(config)
        if args:
            modules = args
        elif config.modules == 'all':
            modules = None
        else:
            modules = config.modules
        kwargs = {}
        if options.soft_deps:
            kwargs['suggests'] = True
        if options.clusters:
            kwargs['clusters'] = True
        module_set.write_dot(modules, **kwargs)
예제 #3
0
class cmd_updateone(Command):
    doc = N_('Update one or more modules from version control')

    name = 'updateone'
    usage_args = N_('[ options ... ] [ modules ... ]')

    def __init__(self):
        Command.__init__(self, [
            make_option('-D', metavar='DATE-SPEC',
                        action='store', dest='sticky_date', default=None,
                        help=_('set a sticky date when checking out modules')),
            ])

    def run(self, config, options, args, help=None):
        config.set_from_cmdline_options(options)
        module_set = jhbuild.moduleset.load(config)
        try:
            module_list = [module_set.get_module(modname, ignore_case = True) for modname in args]
        except KeyError as e:
            raise FatalError(_("A module called '%s' could not be found.") % e)

        if not module_list:
            self.parser.error(_('This command requires a module parameter.'))

        # don't actually perform build ...
        config.build_targets = ['checkout']
        config.nonetwork = False

        build = jhbuild.frontends.get_buildscript(config, module_list, module_set=module_set)
        return build.build()
예제 #4
0
class cmd_run(Command):
    doc = N_('Run a command under the JHBuild environment')

    name = 'run'
    usage_args = N_('[ options ... ] program [ arguments ... ]')

    def __init__(self):
        Command.__init__(self, [
            make_option('--in-builddir', metavar='MODULE',
                        action='store', dest='in_builddir', default = None,
                        help=_('run command in build dir of the given module')),
            make_option('--in-checkoutdir', metavar='MODULE',
                        action='store', dest='in_checkoutdir', default = None,
                        help=_('run command in checkout dir of the given module')),
            ])

    def execute(self, config, args, help=None):
        # Do a shallow check of the arguments list
        # so that '--' isn't always required when command has arguments, 
        # only if some of them look like they might be for us
        if not args or args[0] in ('--', '--help') or args[0].startswith('--in-builddir') or args[0].startswith('--in-checkoutdir'):
            options, args = self.parse_args(args)
            return self.run(config, options, args)
        try:
            return os.execlp(args[0], *args)
        except OSError as exc:
            raise FatalError(_("Unable to execute the command '%(command)s': %(err)s") % {
                    'command':args[0], 'err':str(exc)})

    def run(self, config, options, args, help=None):
        module_name = options.in_builddir or options.in_checkoutdir
        if module_name:
            module_set = jhbuild.moduleset.load(config)
            try:
                module = module_set.get_module(module_name, ignore_case = True)
            except KeyError as e:
                raise FatalError(_("A module called '%s' could not be found.") % e)

            build = jhbuild.frontends.get_buildscript(config, [module], module_set=module_set)
            if options.in_builddir:
                workingdir = module.get_builddir(build)
            else:
                workingdir = module.get_srcdir(build)
            try:
                build.execute(args, cwd=workingdir)
            except CommandError as exc:
                if args:
                    raise FatalError(_("Unable to execute the command '%s'") % args[0])
                else:
                    raise FatalError(str(exc))
        else:
            try:
                os.execlp(args[0], *args)
            except IndexError:
                raise FatalError(_('No command given'))
            except OSError as exc:
                raise FatalError(_("Unable to execute the command '%(command)s': %(err)s") % {
                        'command':args[0], 'err':str(exc)})
예제 #5
0
class cmd_bot(Command):
    doc = N_('Control buildbot')

    name = 'bot'
    usage_args = N_('[ options ... ]')

    def __init__(self):
        Command.__init__(self, [
            make_option('--setup',
                        action='store_true', dest='setup', default=False,
                        help=_('setup a buildbot environment')),
            make_option('--start',
                        action='store_true', dest='start', default=False,
                        help=_('start a buildbot slave server')),
            make_option('--stop',
                        action='store_true', dest='stop', default=False,
                        help=_('stop a buildbot slave server')),
            make_option('--start-server',
                        action='store_true', dest='start_server', default=False,
                        help=_('start a buildbot master server')),
            make_option('--reload-server-config',
                        action='store_true', dest='reload_server_config', default=False,
                        help=_('reload a buildbot master server configuration')),
            make_option('--stop-server',
                        action='store_true', dest='stop_server', default=False,
                        help=_('stop a buildbot master server')),
            make_option('--daemon',
                        action='store_true', dest='daemon', default=False,
                        help=_('start as daemon')),
            make_option('--pidfile', metavar='PIDFILE',
                        action='store', dest='pidfile', default=None,
                        help=_('PID file location')),
            make_option('--logfile', metavar='LOGFILE',
                        action='store', dest='logfile', default=None,
                        help=_('log file location')),
            make_option('--slaves-dir', metavar='SLAVESDIR',
                        action='store', dest='slaves_dir', default=None,
                        help=_('directory with slave files (only with --start-server)')),
            make_option('--buildbot-dir', metavar='BUILDBOTDIR',
                        action='store', dest='buildbot_dir', default=None,
                        help=_('directory with buildbot work files (only with --start-server)')),
            make_option('--mastercfg', metavar='CFGFILE',
                        action='store', dest='mastercfgfile', default=None,
                        help=_('master cfg file location (only with --start-server)')),
            make_option('--step',
                        action='store_true', dest='step', default=False,
                        help=_('exec a buildbot step (internal use only)')),
            ])

    def run(self, config, options, args, help=None):
        raise FatalError(_('buildbot commands are no longer supported'))
예제 #6
0
class cmd_cleanone(Command):
    doc = N_('Clean one or more modules')

    name = 'cleanone'
    usage_args = N_('[ options ... ] [ modules ... ]')

    def __init__(self):
        Command.__init__(self, [
            make_option('--honour-config',
                        action='store_true',
                        dest='honour_config',
                        default=False,
                        help=_('honour the makeclean setting in config file')),
            make_option('--distclean',
                        action='store_true',
                        dest='distclean',
                        default=False,
                        help=_('completely clean source tree')),
        ])

    def run(self, config, options, args, help=None):
        if options.honour_config is False:
            config.makeclean = True
        module_set = jhbuild.moduleset.load(config)
        try:
            module_list = [
                module_set.get_module(modname, ignore_case=True)
                for modname in args
            ]
        except KeyError as e:
            raise FatalError(_("A module called '%s' could not be found.") % e)

        if not module_list:
            self.parser.error(_('This command requires a module parameter.'))

        if not config.makeclean:
            logging.info(
                _('clean command called while makeclean is set to False, skipped.'
                  ))
            return 0

        build = jhbuild.frontends.get_buildscript(config,
                                                  module_list,
                                                  module_set=module_set)
        if options.distclean:
            clean_phase = 'distclean'
        else:
            clean_phase = 'clean'
        return build.build(phases=[clean_phase])
예제 #7
0
class cmd_postinst(Command):
    doc = N_('Run post-install triggers for named modules (or all)')

    name = 'postinst'
    usage_args = N_('[ modules ... ]')

    def __init__(self):
        Command.__init__(self, [])

    def run(self, config, options, args, help=None):
        config.set_from_cmdline_options(options)

        module_set = jhbuild.moduleset.load(config)
        build = jhbuild.frontends.get_buildscript(config, args, module_set=module_set)
        return build.run_triggers(args)
예제 #8
0
class Command:
    """Base class for Command objects"""

    doc = ''
    name = None
    usage_args = N_('[ options ... ]')

    def __init__(self, options=[]):
        self.options = options

    def execute(self, config, args, help):
        options, args = self.parse_args(args)
        return self.run(config, options, args, help)

    def parse_args(self, args):
        self.parser = OptionParser(usage='%%prog %s %s' %
                                   (self.name, _(self.usage_args)),
                                   description=_(self.doc))
        self.parser.add_options(self.options)
        return self.parser.parse_args(args)

    def get_cwd(self):
        # Get symbolic link path when inside one
        cwd = os.getenv('PWD')
        if not cwd:
            cwd = os.getcwd()
        return cwd

    def run(self, config, options, args, help=None):
        """The body of the command"""
        raise NotImplementedError
예제 #9
0
class cmd_snapshot(Command):
    doc = N_(
        'Print out a moduleset for the exact versions that are checked out')
    name = 'snapshot'

    def __init__(self):
        Command.__init__(self)

    def run(self, config, options, args, help=None):
        module_set = jhbuild.moduleset.load(config)
        module_list = module_set.get_module_list(args or config.modules,
                                                 config.skip)
        meta = [m for m in module_list if m.type == 'meta']
        checked_out_mods = [
            m for m in module_list
            if getattr(m, 'branch', None) and m.branch.tree_id()
        ]
        checked_out_repos = []

        for mod in checked_out_mods:
            if mod.branch.repository not in checked_out_repos:
                checked_out_repos.append(mod.branch.repository)

        x = ([sxml.moduleset] + [r.to_sxml() for r in checked_out_repos] +
             [m.to_sxml()
              for m in checked_out_mods] + [m.to_sxml() for m in meta])

        bprint(b'<?xml version="1.0"?>\n')
        bprint(sxml_to_string(x).encode("utf-8") + b'\n')
예제 #10
0
class cmd_help(Command):
    doc = N_('Information about available JHBuild commands')

    name = 'help'
    usage_args = ''

    def run(self, config, options, args, help=None):
        if help:
            return help()
예제 #11
0
class cmd_update(Command):
    doc = N_('Update all modules from version control')

    name = 'update'
    usage_args = N_('[ options ... ] [ modules ... ]')

    def __init__(self):
        Command.__init__(self, [
            make_option('-s', '--skip', metavar='MODULES',
                        action='append', dest='skip', default=[],
                        help=_('treat the given modules as up to date')),
            make_option('-t', '--start-at', metavar='MODULE',
                        action='store', dest='startat', default=None,
                        help=_('start updating at the given module')),
            make_option('--tags',
                        action='append', dest='tags', default=[],
                        help=_('update only modules with the given tags')),
            make_option('-D', metavar='DATE-SPEC',
                        action='store', dest='sticky_date', default=None,
                        help=_('set a sticky date when checking out modules')),
            make_option('--ignore-suggests',
                        action='store_true', dest='ignore_suggests', default=False,
                        help=_('ignore all soft-dependencies')),
            ])

    def run(self, config, options, args, help=None):
        config.set_from_cmdline_options(options)
        module_set = jhbuild.moduleset.load(config)
        module_list = module_set.get_module_list(args or config.modules,
                config.skip, tags=config.tags,
                include_suggests=not config.ignore_suggests)
        # remove modules up to startat
        if options.startat:
            while module_list and module_list[0].name != options.startat:
                del module_list[0]
            if not module_list:
                raise FatalError(_('%s not in module list') % options.startat)

        # don't actually perform build ...
        config.build_targets = ['checkout']
        config.nonetwork = False

        build = jhbuild.frontends.get_buildscript(config, module_list, module_set=module_set)
        return build.build()
예제 #12
0
class cmd_checkbranches(Command):
    doc = N_(
        'Check modules in GNOME Git repository have the correct branch definition'
    )
    name = 'checkbranches'

    def __init__(self):
        Command.__init__(self, [
            make_option('-b',
                        '--branch',
                        metavar='BRANCH',
                        action='store',
                        dest='branch',
                        default=None)
        ])

    def run(self, config, options, args, help=None):
        if options.branch:
            branch = options.branch
        else:
            if type(config.moduleset) is list:
                branch = config.moduleset[0].replace('.', '-')
            else:
                branch = config.moduleset.replace('.', '-')
            for prefix in ('gnome-suites-core-deps', 'gnome-suites-core',
                           'gnome-suites-', 'gnome-apps-'):
                branch = branch.replace(prefix, 'gnome-')

        module_set = jhbuild.moduleset.load(config)
        module_list = module_set.get_module_list(args or config.modules)
        for mod in module_list:
            if mod.type in ('meta', 'tarball'):
                continue
            if not mod.branch or not mod.branch.repository.__class__.__name__ == 'GitRepository':
                continue
            if 'git.gnome.org' not in mod.branch.repository.href:
                continue
            if mod.branch.branch:
                # there is already a branch defined
                continue

            try:
                if get_output([
                        'git', 'ls-remote',
                        'https://git.gnome.org/browse/%s' % mod.name,
                        'refs/heads/%s' % branch
                ]):
                    uprint(
                        _('%(module)s is missing branch definition for %(branch)s'
                          ) % {
                              'module': mod.name,
                              'branch': branch
                          })
            except CommandError:
                pass
예제 #13
0
class cmd_shell(Command):
    doc = N_('Start a shell under the JHBuild environment')

    name = 'shell'
    usage_args = ''

    def execute(self, config, args, help=None):
        if "--help" in args:
            self.parse_args(args) # This doesn't return
        user_shell = os.environ.get('SHELL', '/bin/sh')
        os.execlp(user_shell, user_shell)
예제 #14
0
파일: gui.py 프로젝트: isabella232/jhbuild
class cmd_gui(Command):
    doc = N_('Build targets from a GUI app')

    name = 'gui'
    usage_args = ''

    def run(self, config, options, args, help=None):
        import gi
        gi.require_version("Gtk", "3.0")
        from gi.repository import Gtk

        # request GTK build script.
        config.buildscript = 'gtkui'

        build = jhbuild.frontends.get_buildscript(config)
        build.show()
        Gtk.main()
예제 #15
0
class cmd_bootstrap(cmd_build):
    doc = N_('Build support tools')

    name = 'bootstrap'

    def run(self, config, options, args, help=None):
        config.moduleset = 'bootstrap'
        # load the bootstrap module set
        if not args:
            args = ['meta-bootstrap']

        for item in options.skip:
            config.skip += item.split(',')
        options.skip = []

        rc = cmd_build.run(self, config, options, args)
        return rc
예제 #16
0
class cmd_check(Command):
    doc = N_('Create tar packages for all modules')

    name = 'check'
    usage_args = '[ options ... ] [ modules ... ]'

    def __init__(self):
        Command.__init__(self, [
            make_option('-s',
                        '--skip',
                        metavar='MODULES',
                        action='append',
                        dest='skip',
                        default=[],
                        help=_('don\'t package the given modules')),
            make_option('-t',
                        '--start-at',
                        metavar='MODULE',
                        action='store',
                        dest='startat',
                        default=None,
                        help=_('start building at the given module')),
        ])

    def run(self, config, options, args, help=None):
        for item in options.skip:
            config.skip += item.split(',')

        module_set = jhbuild.moduleset.load(config)
        module_list = module_set.get_module_list(args or config.modules,
                                                 config.skip)
        # remove modules up to startat
        if options.startat:
            while module_list and module_list[0].name != options.startat:
                del module_list[0]
            if not module_list:
                raise FatalError(_('%s not in module list') % options.startat)

        build = jhbuild.frontends.get_buildscript(config,
                                                  module_list,
                                                  module_set=module_set)
        build.config.build_targets.insert(0, 'check')
        return build.build(phases=['check'])
예제 #17
0
class DownloadableModule:
    PHASE_CHECKOUT = 'checkout'
    PHASE_FORCE_CHECKOUT = 'force_checkout'

    def do_checkout(self, buildscript):
        self.checkout(buildscript)
    do_checkout.error_phases = [PHASE_FORCE_CHECKOUT]

    def 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)

        if self.check_build_policy(buildscript) == self.PHASE_DONE:
            raise SkipToEnd()

    def skip_checkout(self, buildscript, last_phase):
        # skip the checkout stage if the nonetwork flag is set
        if not self.branch.may_checkout(buildscript):
            if self.check_build_policy(buildscript) == self.PHASE_DONE:
                raise SkipToEnd()
            return True
        return False

    def do_force_checkout(self, buildscript):
        # Try to wipe the build directory. Ignore exceptions if the child class
        # does not implement get_builddir().
        try:
            builddir = self.get_builddir(buildscript)
            if os.path.exists(builddir):
                shutil.rmtree(builddir)
        except Exception:
            pass
        buildscript.set_action(_('Checking out'), self)
        self.branch.force_checkout(buildscript)
    do_force_checkout.error_phases = [PHASE_FORCE_CHECKOUT]
    do_force_checkout.label = N_('wipe directory and start over')
    do_force_checkout.needs_confirmation = True
예제 #18
0
class cmd_uninstall(Command):
    doc = _('Uninstall all modules')

    name = 'uninstall'
    usage_args = N_('[ modules ... ]')

    def run(self, config, options, args, help=None):
        config.set_from_cmdline_options(options)

        module_set = jhbuild.moduleset.load(config)
        module_list = []
        default_repo = jhbuild.moduleset.get_default_repo()
        for modname in args:
            try:
                module = module_set.get_module(modname, ignore_case=True)
            except KeyError:
                if not default_repo:
                    raise FatalError(
                        _('unknown module %s and no default repository to try an automatic module'
                          ) % modname)

                logging.info(_('module "%(modname)s" does not exist, created automatically using repository "%(reponame)s"') % \
                         {'modname': modname, 'reponame': default_repo.name})
                module = AutogenModule(modname, default_repo.branch(modname))
                module.config = config

            module_list.append(module)

        if not module_list:
            self.parser.error(_('This command requires a module parameter.'))

        # remove modules that are not marked as installed
        packagedb = module_set.packagedb
        for module in module_list[:]:
            if not packagedb.check(module.name):
                logging.warn(
                    _('Module %(mod)r is not installed') %
                    {'mod': module.name})
                module_list.remove(module)
            else:
                packagedb.uninstall(module.name)
예제 #19
0
class cmd_checkmodulesets(Command):
    doc = N_('Check if modules in JHBuild have the correct definition')
    name = 'checkmodulesets'

    def run(self, config, options, args, help=None):
        module_set = jhbuild.moduleset.load(config)
        module_list = module_set.get_full_module_list(
            warn_about_circular_dependencies=True)
        for mod in module_list:
            if mod.type in ('meta', 'tarball'):
                continue

            try:
                if not mod.branch.exists():
                    logging.error(
                        _('%(module)s is unreachable (%(href)s)') % {
                            'module': mod.name,
                            'href': mod.branch.module
                        })
            except NotImplementedError:
                logging.warning((_('Cannot check %(module)s (%(href)s)') % {
                    'module': mod.name,
                    'href': mod.branch.module
                }))
예제 #20
0
class cmd_rdepends(Command):
    doc = N_('Display reverse-dependencies of a module')

    name = 'rdepends'
    usage_args = N_('[ module ]')

    def __init__(self):
        Command.__init__(self, [
            make_option('--dependencies',
                        action='store_true',
                        dest='dependencies',
                        default=False,
                        help=_('display dependency path next to modules')),
            make_option(
                '--direct',
                action='store_true',
                dest='direct',
                default=False,
                help=
                _('limit display to modules directly depending on given module'
                  ))
        ])

    def run(self, config, options, args, help=None):
        module_set = jhbuild.moduleset.load(config)

        if not args:
            self.parser.error(_('This command requires a module parameter.'))

        try:
            modname = module_set.get_module(args[0], ignore_case=True).name
        except KeyError:
            raise FatalError(
                _("A module called '%s' could not be found.") % args[0])

        # get all modules but those that are a dependency of modname
        dependencies_list = [
            x.name for x in module_set.get_module_list([modname])
        ]
        if modname in dependencies_list:
            dependencies_list.remove(modname)
        modules = module_set.get_full_module_list(skip=dependencies_list)
        modules = modules[[x.name for x in modules].index(modname) + 1:]

        # iterate over remaining modules, and print those with modname as dep;
        # this is totally inefficient as a complete dependency list is computed
        # for each module.
        seen_modules = []
        for module in modules:
            if options.direct:
                if modname in module.dependencies:
                    uprint(module.name)
            else:
                module_list = module_set.get_module_list([module.name])
                if modname in [x.name for x in module_list]:
                    seen_modules.append(module.name)
                    deps = ''
                    if options.dependencies:
                        dependencies = [
                            x for x in module.dependencies if x in seen_modules
                        ]
                        if dependencies:
                            deps = '[' + ','.join(dependencies) + ']'
                    uprint(module.name, deps)
예제 #21
0
class cmd_sysdeps(cmd_build):
    doc = N_('Check and install tarball dependencies using system packages')

    name = 'sysdeps'

    def __init__(self):
        Command.__init__(self, [
            make_option('--dump',
                        action='store_true',
                        default=False,
                        help=_('Machine readable list of missing sysdeps')),
            make_option('--dump-all',
                        action='store_true',
                        default=False,
                        help=_('Machine readable list of all sysdeps')),
            make_option('--install',
                        action='store_true',
                        default=False,
                        help=_('Install pkg-config modules via system')),
            make_option(
                '--assume-yes',
                action="store_true",
                default=False,
                dest="assume_yes",
                help=
                _('assume yes/the default answer to interactive questions during installation of system '
                  + 'dependencies"'))
        ])

    def run(self, config, options, args, help=None):
        def fmt_details(pkg_config, req_version, installed_version):
            fmt_list = []
            if pkg_config:
                fmt_list.append(pkg_config)
            if req_version:
                fmt_list.append(_('required=%s') % req_version)
            if installed_version and installed_version != 'unknown':
                fmt_list.append(_('installed=%s') % installed_version)
            # Translators: This is used to separate items of package metadata
            fmt_str = _(', ').join(fmt_list)
            if fmt_str:
                return _('(%s)') % fmt_str
            else:
                return ''

        config.set_from_cmdline_options(options)

        module_set = jhbuild.moduleset.load(config)
        modules = args or config.modules
        module_list = module_set.get_full_module_list(modules, config.skip)

        if options.dump_all:
            for module in module_list:
                if (isinstance(module, SystemModule)
                        or isinstance(module.branch, TarballBranch)
                        and module.pkg_config is not None):
                    if module.pkg_config is not None:
                        print('pkgconfig:{0}'.format(
                            module.pkg_config[:-3]))  # remove .pc

                    if module.systemdependencies is not None:
                        for dep_type, value, altdeps in module.systemdependencies:
                            sys.stdout.write('{0}:{1}'.format(dep_type, value))
                            for dep_type, value, empty in altdeps:
                                sys.stdout.write(',{0}:{1}'.format(
                                    dep_type, value))
                            sys.stdout.write('\n')

            return

        module_state = module_set.get_module_state(module_list)

        have_new_enough = False
        have_too_old = False

        if options.dump:
            for module, (req_version, installed_version, new_enough,
                         systemmodule) in iteritems(module_state):
                if new_enough:
                    continue

                if installed_version is not None and systemmodule:
                    # it's already installed but it's too old and we
                    # don't know how to build a new one for ourselves
                    have_too_old = True

                # request installation in two cases:
                #   1) we don't know how to build it
                #   2) we don't want to build it ourselves
                #
                # partial_build is on by default so this check will only
                # fail if someone explicitly turned it off
                if systemmodule or config.partial_build:
                    assert (module.pkg_config or module.systemdependencies)

                    if module.pkg_config is not None:
                        print('pkgconfig:{0}'.format(
                            module.pkg_config[:-3]))  # remove .pc

                    if module.systemdependencies is not None:
                        for dep_type, value, altdeps in module.systemdependencies:
                            sys.stdout.write('{0}:{1}'.format(dep_type, value))
                            for dep_type, value, empty in altdeps:
                                sys.stdout.write(',{0}:{1}'.format(
                                    dep_type, value))
                            sys.stdout.write('\n')

            if have_too_old:
                return 1

            return

        print(_('System installed packages which are new enough:'))
        for module, (req_version, installed_version, new_enough,
                     systemmodule) in iteritems(module_state):
            if (installed_version
                    is not None) and new_enough and (config.partial_build
                                                     or systemmodule):
                have_new_enough = True
                print('    %s %s' %
                      (module.name,
                       fmt_details(module.pkg_config, req_version,
                                   installed_version)))
        if not have_new_enough:
            print(_('  (none)'))

        print(_('Required packages:'))
        print(_('  System installed packages which are too old:'))
        for module, (req_version, installed_version, new_enough,
                     systemmodule) in iteritems(module_state):
            if (installed_version
                    is not None) and (not new_enough) and systemmodule:
                have_too_old = True
                print('    %s %s' %
                      (module.name,
                       fmt_details(module.pkg_config, req_version,
                                   installed_version)))
        if not have_too_old:
            print(_('    (none)'))

        print(_('  No matching system package installed:'))
        uninstalled = []
        for module, (req_version, installed_version, new_enough,
                     systemmodule) in iteritems(module_state):
            if installed_version is None and (not new_enough) and systemmodule:
                print('    %s %s' %
                      (module.name,
                       fmt_details(module.pkg_config, req_version,
                                   installed_version)))
                if module.pkg_config is not None:
                    uninstalled.append((module.name, 'pkgconfig',
                                        module.pkg_config[:-3]))  # remove .pc
                elif module.systemdependencies is not None:
                    for dep_type, value, altdeps in module.systemdependencies:
                        uninstalled.append((module.name, dep_type, value))
        if len(uninstalled) == 0:
            print(_('    (none)'))

        have_too_old = False

        if config.partial_build:
            print(
                _('Optional packages: (JHBuild will build the missing packages)'
                  ))
            print(_('  System installed packages which are too old:'))
            for module, (req_version, installed_version, new_enough,
                         systemmodule) in iteritems(module_state):
                if (installed_version is not None) and (not new_enough) and (
                        not systemmodule):
                    have_too_old = True
                    print('    %s %s' %
                          (module.name,
                           fmt_details(module.pkg_config, req_version,
                                       installed_version)))
            if not have_too_old:
                print(_('    (none)'))

            print(_('  No matching system package installed:'))
            for module, (req_version, installed_version, new_enough,
                         systemmodule) in iteritems(module_state):
                if installed_version is None and (not new_enough) and (
                        not systemmodule):
                    print('    %s %s' %
                          (module.name,
                           fmt_details(module.pkg_config, req_version,
                                       installed_version)))
                    if module.pkg_config is not None:
                        uninstalled.append(
                            (module.name, 'pkgconfig',
                             module.pkg_config[:-3]))  # remove .pc

            if len(uninstalled) == 0:
                print(_('    (none)'))

        if options.install:
            installer = SystemInstall.find_best()
            if installer is None:
                # FIXME: This should be implemented per Colin's design:
                # https://bugzilla.gnome.org/show_bug.cgi?id=682104#c3
                if cmds.has_command('apt-get'):
                    raise FatalError(
                        _("%(cmd)s is required to install "
                          "packages on this system. Please "
                          "install %(cmd)s.") % {'cmd': 'apt-file'})

                raise FatalError(
                    _("Don't know how to install packages on this system"))

            if len(uninstalled) == 0:
                logging.info(
                    _("No uninstalled system dependencies to install for modules: %r"
                      ) % (modules, ))
            else:
                logging.info(_("Installing dependencies on system: %s") % \
                             ' '.join(pkg[0] for pkg in uninstalled))
                installer.install(uninstalled, assume_yes=options.assume_yes)
예제 #22
0
class cmd_make(Command):
    doc = N_('Compile and install the module for the current directory')

    name = 'make'
    usage_args = N_('[ options ... ]')

    def __init__(self):
        Command.__init__(self, [
            make_option('-a',
                        '--autogen',
                        action='store_true',
                        dest='autogen',
                        default=False,
                        help=_('always run autogen.sh')),
            make_option('-c',
                        '--clean',
                        action='store_true',
                        dest='clean',
                        default=False,
                        help=_('run make clean before make')),
            make_option('--check',
                        action='store_true',
                        dest='check',
                        default=False,
                        help=_('run make check after building')),
            make_option('-q',
                        '--quiet',
                        action='store_true',
                        dest='quiet',
                        default=False,
                        help=_('quiet (no output)')),
        ])

    def run(self, config, options, args, help=None):
        # Grab the cwd before anything changes it
        cwd = self.get_cwd()

        # Explicitly don't touch the network for this
        options.nonetwork = True
        options.force_policy = True
        config.set_from_cmdline_options(options)

        makeargs = config.makeargs
        for arg in args:
            # if uninstalling, skip install.
            if arg == 'uninstall' or arg.startswith('uninstall-'):
                config.noinstall = True
            # pipes.quote (and really, trying to safely quote shell arguments) is
            # broken, but executing commands as strings is pervasive throughout
            # jhbuild...this is a hack that will probably live until someone just
            # replaces jhbuild entirely.
            makeargs = '%s %s' % (makeargs, pipes.quote(arg))
        config.makeargs = makeargs

        module_set = jhbuild.moduleset.load(config)

        if not cwd.startswith(config.checkoutroot):
            logging.error(
                _('The current directory is not in the checkout root %r') %
                (config.checkoutroot, ))
            return False

        cwd = cwd[len(config.checkoutroot):]
        cwd = cwd.lstrip(os.sep)
        modname, _slash, _rest = cwd.partition(os.sep)

        try:
            module = module_set.get_module(modname, ignore_case=True)
        except KeyError:
            default_repo = jhbuild.moduleset.get_default_repo()
            if not default_repo:
                logging.error(
                    _('No module matching current directory %r in the moduleset'
                      ) % (modname, ))
                return False

            # Try meson first, then autotools
            if os.path.exists(os.path.join(self.get_cwd(), 'meson.build')):
                from jhbuild.modtypes.meson import MesonModule
                module = MesonModule(modname, default_repo.branch(modname))
            else:
                from jhbuild.modtypes.autotools import AutogenModule
                module = AutogenModule(modname, default_repo.branch(modname))

            module.config = config
            logging.info(_('module "%(modname)s" does not exist, created automatically using repository "%(reponame)s"') % \
                         {'modname': modname, 'reponame': default_repo.name})

        build = jhbuild.frontends.get_buildscript(config, [module],
                                                  module_set=module_set)
        return build.build()
예제 #23
0
class cmd_info(Command):
    doc = N_('Display information about one or more modules')

    name = 'info'
    usage_args = N_('[ modules ... ]')

    def __init__(self):
        Command.__init__(self, [
            make_option(
                '--installed',
                action='store_true',
                dest='installed',
                default=False,
                help=_(
                    'only display information for installed modules. '
                    'This will not list system dependencies. If one or more '
                    'module names are specified and at least one module is '
                    'not installed, then the command will return 1.'))
        ])

    def run(self, config, options, args, help=None):
        module_set = jhbuild.moduleset.load(config)
        packagedb = module_set.packagedb

        if args:
            # module names present
            all_installed = True
            for modname in args:
                try:
                    module = module_set.get_module(modname, ignore_case=True)
                except KeyError:
                    raise FatalError(_('unknown module %s') % modname)
                package_entry = packagedb.get(module.name)
                installed = package_entry is not None
                all_installed = all_installed and installed
                if (options.installed and installed) or not options.installed:
                    self.show_info(module, packagedb, module_set)
            if options.installed and not all_installed:
                return 1
        else:
            # no module names given
            for module in module_set.modules.values():
                package_entry = packagedb.get(module.name)
                if options.installed:
                    if package_entry is not None:
                        self.show_info(module, packagedb, module_set)
                else:
                    # no installed option selected, simply show all modules
                    self.show_info(module, packagedb, module_set)

    def show_info(self, module, packagedb, module_set):
        package_entry = packagedb.get(module.name)

        uprint(_('Name:'), module.name)
        uprint(_('Module Set:'), module.moduleset_name)
        uprint(_('Type:'), module.type)

        if package_entry is not None:
            uprint(_('Install version:'), package_entry.version)
            uprint(
                _('Install date:'),
                time.strftime(
                    '%Y-%m-%d %H:%M:%S',
                    time.localtime(packagedb.installdate(module.name))))
        else:
            uprint(_('Install version:'), _('not installed'))
            uprint(_('Install date:'), _('not installed'))

        if isinstance(module, MetaModule):
            pass
        elif isinstance(module.branch, CVSBranch):
            uprint(_('CVS Root:'), module.branch.repository.cvsroot)
            uprint(_('CVS Module:'), module.branch.module)
            if module.branch.revision:
                uprint(_('CVS Revision:'), module.branch.revision)
        elif isinstance(module.branch, SubversionBranch):
            uprint(_('Subversion Module:'), module.branch.module)
        elif isinstance(module.branch, DarcsBranch):
            uprint(_('Darcs Archive:'), module.branch.module)
        elif isinstance(module.branch, GitBranch):
            uprint(_('Git Module:'), module.branch.module)
            if module.branch.unmirrored_module:
                uprint(_('Git Origin Module:'),
                       module.branch.unmirrored_module)
            git_branch = module.branch.branch
            if not git_branch:
                git_branch = 'master'
            uprint(_('Git Branch:'), git_branch)
            if module.branch.tag:
                uprint(_('Git Tag:'), module.branch.tag)
        elif isinstance(module.branch, TarballBranch):
            uprint(_('URL:'), module.branch.module)
            uprint(_('Version:'), module.branch.version)
        try:
            tree_id = module.branch.tree_id()
            uprint(_('Tree-ID:'), tree_id)
        except (NotImplementedError, AttributeError):
            pass
        try:
            source_dir = module.branch.srcdir
            uprint(_('Sourcedir:'), source_dir)
        except (NotImplementedError, AttributeError):
            pass

        # dependencies
        if module.dependencies:
            uprint(_('Requires:'), ', '.join(module.dependencies))
        requiredby = [
            mod.name for mod in module_set.modules.values()
            if module.name in mod.dependencies
        ]
        if requiredby:
            uprint(_('Required by:'), ', '.join(requiredby))
        if module.suggests:
            uprint(_('Suggests:'), ', '.join(module.suggests))
        if module.after:
            uprint(_('After:'), ', '.join(module.after))
        before = [
            mod.name for mod in module_set.modules.values()
            if module.name in mod.after
        ]
        if before:
            uprint(_('Before:'), ', '.join(before))

        print()
예제 #24
0
class cmd_build(BuildCommand):
    doc = N_('Update and compile all modules (the default)')

    name = 'build'
    usage_args = N_('[ options ... ] [ modules ... ]')

    def __init__(self):
        Command.__init__(self, [
            make_option('-a', '--autogen',
                        action='store_true', dest='autogen', default=False,
                        help=_('always run autogen.sh')),
            make_option('', '--distclean',
                        action='store_true', dest='distclean', default=False,
                        help=_('completely clean source tree')),
            make_option('-c', '--clean',
                        action='store_true', dest='clean', default=False,
                        help=_('run make clean before make')),
            make_option('--check',
                        action='store_true', dest='check', default=False,
                        help=_('run make check after building')),
            make_option('-d', '--dist',
                        action='store_true', dest='dist', default=False,
                        help=_('run make dist after building')),
            make_option('--distcheck',
                        action='store_true', dest='distcheck', default=False,
                        help=_('run make distcheck after building')),
            make_option('--ignore-suggests',
                        action='store_true', dest='ignore_suggests', default=False,
                        help=_('ignore all soft-dependencies')),
            make_option('-n', '--no-network',
                        action='store_true', dest='nonetwork', default=False,
                        help=_('skip version control update')),
            make_option('-q', '--quiet',
                        action='store_true', dest='quiet', default=False,
                        help=_('quiet (no output)')),
            make_option('-s', '--skip', metavar='MODULES',
                        action='append', dest='skip', default=[],
                        help=_('treat the given modules as up to date')),
            make_option('-t', '--start-at', metavar='MODULE',
                        action='store', dest='startat', default=None,
                        help=_('start building at the given module')),
            make_option('--tags',
                        action='append', dest='tags', default=[],
                        help=_('build only modules with the given tags')),
            make_option('-D', metavar='DATE-SPEC',
                        action='store', dest='sticky_date', default=None,
                        help=_('set a sticky date when checking out modules')),
            make_option('-x', '--no-xvfb',
                        action='store_true', dest='noxvfb', default=False,
                        help=_('run tests in real X and not in Xvfb')),
            make_option('-C', '--try-checkout',
                        action='store_true', dest='trycheckout', default=False,
                        help=_('try to force checkout and autogen on failure')),
            make_option('-N', '--no-poison',
                        action='store_true', dest='nopoison', default=False,
                        help=_("don't poison modules on failure")),
            make_option('-f', '--force',
                        action='store_true', dest='force_policy', default=False,
                        help=_('build even if policy says not to')),
            make_option('--build-optional-modules',
                        action='store_true', dest='build_optional_modules', default=False,
                        help=_('also build soft-dependencies that could be skipped')),
            make_option('--min-age', metavar='TIME-SPEC',
                        action='store', dest='min_age', default=None,
                        help=_('skip modules installed less than the given time ago')),
            make_option('--nodeps',
                        action='store_false', dest='check_sysdeps', default=None,
                        help=_('ignore missing system dependencies')),
            ])

    def run(self, config, options, args, help=None):
        config.set_from_cmdline_options(options)

        module_set = jhbuild.moduleset.load(config)
        modules = args or config.modules
        full_module_list = module_set.get_full_module_list(
                                modules, config.skip,
                                include_suggests=not config.ignore_suggests,
                                include_afters=options.build_optional_modules)
        full_module_list = module_set.remove_tag_modules(full_module_list,
                                                         config.tags)
        module_list = module_set.remove_system_modules(full_module_list)
        # remove modules up to startat
        if options.startat:
            while module_list and module_list[0].name != options.startat:
                del module_list[0]
            if not module_list:
                raise FatalError(_('%s not in module list') % options.startat)

        if len(module_list) == 0 and modules[0] in (config.skip or []):
            logging.info(
                    _('requested module is in the ignore list, nothing to do.'))
            return 0

        if config.check_sysdeps:
            install_cmd = 'jhbuild sysdeps --install' + (' ' + ' '.join(args) if args else '')
            module_state = module_set.get_module_state(full_module_list)
            if not self.required_system_dependencies_installed(module_state):
                self.print_system_dependencies(module_state)
                raise FatalError(_('Required system dependencies not installed.'
                                   ' Install using the command %(cmd)s or to '
                                   'ignore system dependencies use command-line'
                                   ' option %(opt)s' \
                                   % {'cmd' : "'%s'" % install_cmd,
                                      'opt' : '--nodeps'}))

        build = jhbuild.frontends.get_buildscript(config, module_list, module_set=module_set)
        return build.build()
예제 #25
0
class cmd_buildone(BuildCommand):
    doc = N_('Update and compile one or more modules')

    name = 'buildone'
    usage_args = N_('[ options ... ] [ modules ... ]')

    def __init__(self):
        Command.__init__(self, [
            make_option('-a', '--autogen',
                        action='store_true', dest='autogen', default=False,
                        help=_('always run autogen.sh')),
            make_option('-c', '--clean',
                        action='store_true', dest='clean', default=False,
                        help=_('run make clean before make')),
            make_option('', '--distclean',
                        action='store_true', dest='distclean', default=False,
                        help=_('completely clean source tree')),
            make_option('--check',
                        action='store_true', dest='check', default=False,
                        help=_('run make check after building')),
            make_option('-d', '--dist',
                        action='store_true', dest='dist', default=False,
                        help=_('run make dist after building')),
            make_option('--distcheck',
                        action='store_true', dest='distcheck', default=False,
                        help=_('run make distcheck after building')),
            make_option('-n', '--no-network',
                        action='store_true', dest='nonetwork', default=False,
                        help=_('skip version control update')),
            make_option('-q', '--quiet',
                        action='store_true', dest='quiet', default=False,
                        help=_('quiet (no output)')),
            make_option('-D', metavar='DATE-SPEC',
                        action='store', dest='sticky_date', default=None,
                        help=_('set a sticky date when checking out modules')),
            make_option('-x', '--no-xvfb',
                        action='store_true', dest='noxvfb', default=False,
                        help=_('run tests in real X and not in Xvfb')),
            make_option('-N', '--no-poison',
                        action='store_true', dest='nopoison', default=False,
                        help=_("don't poison modules on failure")),
            make_option('-f', '--force',
                        action='store_true', dest='force_policy', default=False,
                        help=_('build even if policy says not to')),
            make_option('--min-age', metavar='TIME-SPEC',
                        action='store', dest='min_age', default=None,
                        help=_('skip modules installed less than the given time ago')),
            ])

    def run(self, config, options, args, help=None):
        config.set_from_cmdline_options(options)

        module_set = jhbuild.moduleset.load(config)
        module_list = []
        for modname in args:
            modname = modname.rstrip(os.sep)
            try:
                module = module_set.get_module(modname, ignore_case=True)
            except KeyError:
                default_repo = jhbuild.moduleset.get_default_repo()
                if not default_repo:
                    continue
                from jhbuild.modtypes.autotools import AutogenModule
                module = AutogenModule(modname, default_repo.branch(modname))
                module.config = config
                logging.info(_('module "%(modname)s" does not exist, created automatically using repository "%(reponame)s"') % \
                             {'modname': modname, 'reponame': default_repo.name})
            module_list.append(module)

        if not module_list:
            self.parser.error(_('This command requires a module parameter.'))

        build = jhbuild.frontends.get_buildscript(config, module_list, module_set=module_set)
        return build.build()
예제 #26
0
class cmd_tinderbox(BuildCommand):
    doc = N_('Build modules non-interactively and store build logs')

    name = 'tinderbox'
    usage_args = N_('[ options ... ] [ modules ... ]')

    def __init__(self):
        Command.__init__(self, [
            make_option('-a',
                        '--autogen',
                        action='store_true',
                        dest='autogen',
                        default=False,
                        help=_('always run autogen.sh')),
            make_option('',
                        '--distclean',
                        action='store_true',
                        dest='distclean',
                        default=False,
                        help=_('completely clean source tree')),
            make_option('-c',
                        '--clean',
                        action='store_true',
                        dest='clean',
                        default=False,
                        help=_('run make clean before make')),
            make_option('-n',
                        '--no-network',
                        action='store_true',
                        dest='nonetwork',
                        default=False,
                        help=_('skip version control update')),
            make_option('-o',
                        '--output',
                        metavar='DIR',
                        action='store',
                        dest='outputdir',
                        default=None,
                        help=_('directory to store build logs in')),
            make_option('-s',
                        '--skip',
                        metavar='MODULES',
                        action='append',
                        dest='skip',
                        default=[],
                        help=_('treat the given modules as up to date')),
            make_option('-t',
                        '--start-at',
                        metavar='MODULE',
                        action='store',
                        dest='startat',
                        default=None,
                        help=_('start building at the given module')),
            make_option('-D',
                        metavar='DATE-SPEC',
                        action='store',
                        dest='sticky_date',
                        default=None,
                        help=_('set a sticky date when checking out modules')),
            make_option(
                '-C',
                '--try-checkout',
                action='store_true',
                dest='trycheckout',
                default=False,
                help=_('try to force checkout and autogen on failure')),
            make_option('-N',
                        '--no-poison',
                        action='store_true',
                        dest='nopoison',
                        default=False,
                        help=_("don't poison modules on failure")),
            make_option('-f',
                        '--force',
                        action='store_true',
                        dest='force_policy',
                        default=False,
                        help=_('build even if policy says not to')),
            make_option('--nodeps',
                        action='store_false',
                        dest='check_sysdeps',
                        default=None,
                        help=_('ignore missing system dependencies'))
        ])

    def run(self, config, options, args, help=None):
        config.set_from_cmdline_options(options)
        config.buildscript = 'tinderbox'

        if options.outputdir is not None:
            config.tinderbox_outputdir = options.outputdir

        if not config.tinderbox_outputdir:
            raise UsageError(
                _('output directory for tinderbox build not specified'))

        module_set = jhbuild.moduleset.load(config)
        full_module_list = module_set.get_full_module_list(
            args or config.modules, config.skip)
        module_list = module_set.remove_system_modules(full_module_list)

        # remove modules up to startat
        if options.startat:
            while module_list and module_list[0].name != options.startat:
                del module_list[0]
            if not module_list:
                raise FatalError(_('%s not in module list') % options.startat)

        if config.check_sysdeps:
            module_state = module_set.get_module_state(full_module_list)
            if not self.required_system_dependencies_installed(module_state):
                self.print_system_dependencies(module_state)
                raise FatalError(_('Required system dependencies not installed.'
                                   ' Install using the command %(cmd)s or to '
                                   'ignore system dependencies use command-line'
                                   ' option %(opt)s' \
                                   % {'cmd' : "'jhbuild sysdeps --install'",
                                      'opt' : '--nodeps'}))

        build = jhbuild.frontends.get_buildscript(config,
                                                  module_list,
                                                  module_set=module_set)
        return build.build()
예제 #27
0
class cmd_list(Command):
    doc = N_('List the modules that would be built')

    name = 'list'
    usage_args = N_('[ options ... ] [ modules ... ]')

    def __init__(self):
        Command.__init__(self, [
            make_option('-r', '--show-revision',
                        action='store_true', dest='show_rev', default=False,
                        help=_('show which revision will be built')),
            make_option('-s', '--skip', metavar='MODULES',
                        action='append', dest='skip', default=[],
                        help=_('treat the given modules as up to date')),
            make_option('-t', '--start-at', metavar='MODULE',
                        action='store', dest='startat', default=None,
                        help=_('start list at the given module')),
            make_option('--tags',
                        action='append', dest='tags', default=[],
                        help=_('build only modules with the given tags')),
            make_option('--ignore-suggests',
                        action='store_true', dest='ignore_suggests', default=False,
                        help=_('ignore all soft-dependencies')),
            make_option('--list-optional-modules',
                        action='store_true', dest='list_optional_modules', default=False,
                        help=_('also list soft-dependencies that could be skipped')),
            make_option('-a', '--all-modules',
                        action='store_true', dest='list_all_modules', default=False,
                        help=_('list all modules, not only those that would be built')),
            ])

    def run(self, config, options, args, help=None):
        config.set_from_cmdline_options(options)
        module_set = jhbuild.moduleset.load(config)
        if options.startat and options.list_all_modules:
            raise UsageError(_('Conflicting options specified (\'--start-at\' and \'--all-modules\')'))

        if options.list_all_modules:
            module_list = module_set.modules.values()
        else:
            module_list = module_set.get_module_list \
                              (args or config.modules, config.skip,
                               tags=config.tags,
                               include_suggests= not config.ignore_suggests,
                               include_afters=options.list_optional_modules)

        # remove modules up to startat
        if options.startat:
            while module_list and module_list[0].name != options.startat:
                del module_list[0]
            if not module_list:
                raise FatalError(_('%s not in module list') % options.startat)

        for mod in module_list:
            if options.show_rev:
                rev = mod.get_revision()
                if rev:
                    uprint('%s (%s)' % (mod.name, rev))
                else:
                    uprint(mod.name)
            else:
                uprint(mod.name)
예제 #28
0
class cmd_sanitycheck(Command):
    doc = N_('Check that required support tools are available')

    name = 'sanitycheck'
    usage_args = ''

    def run(self, config, options, args, help=None):
        if args:
            raise UsageError(_('no extra arguments expected'))

        # try creating jhbuild directories before checking they are accessible.
        try:
            os.makedirs(config.checkoutroot)
            os.makedirs(config.prefix)
        except OSError:
            pass

        # check whether the checkout root and install prefix are writable
        if not (os.path.isdir(config.checkoutroot) and os.access(
                config.checkoutroot, os.R_OK | os.W_OK | os.X_OK)):
            uprint(
                _('checkout root (%s) is not writable') % config.checkoutroot)
        if not (os.path.isdir(config.prefix)
                and os.access(config.prefix, os.R_OK | os.W_OK | os.X_OK)):
            uprint(_('install prefix (%s) is not writable') % config.prefix)

        autoconf = True

        # check whether various tools are installed
        if not check_version(['libtoolize', '--version'],
                             r'libtoolize \([^)]*\) ([\d.]+)', '1.5'):
            uprint(_('%s not found') % 'libtool >= 1.5')
        if not check_version(['gettext', '--version'],
                             r'gettext \([^)]*\) ([\d.]+)', '0.10.40'):
            uprint(_('%s not found') % 'gettext >= 0.10.40')
        if not check_version(['pkg-config', '--version'], r'^([\d.]+)',
                             '0.14.0'):
            uprint(_('%s not found') % 'pkg-config >= 0.14.0')
        if not check_version(['autoconf', '--version'],
                             r'autoconf \([^)]*\) ([\d.]+)', '2.53'):
            autoconf = False
            uprint(_('%s not found') % 'autoconf >= 2.53')
        if not check_version(['automake', '--version'],
                             r'automake \([^)]*\) ([\d.]+)', '1.10'):
            uprint(_('%s not found') % 'automake >= 1.10')

        if (autoconf):
            self.check_m4()

        # XML catalog sanity checks
        xmlcatalog = True
        try:
            get_output(['which', 'xmlcatalog'])
        except CommandError:
            xmlcatalog = False
            uprint(
                _('Could not find XML catalog (usually part of the package \'libxml2-utils\')'
                  ))

        if (xmlcatalog):
            for (item, name) in [
                ('-//OASIS//DTD DocBook XML V4.1.2//EN',
                 'DocBook XML DTD V4.1.2'),
                ('http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl',
                 'DocBook XSL Stylesheets')
            ]:
                try:
                    get_output(['xmlcatalog', '/etc/xml/catalog', item])
                except CommandError:
                    uprint(
                        _('Could not find %s in XML catalog (usually part of package \'docbook-xsl\')'
                          ) % name)

        # Perl module used by tools such as intltool:
        perlmod = 'XML::Parser'
        try:
            get_output(['perl', '-M%s' % perlmod, '-e', 'exit'])
        except CommandError:
            uprint(
                _('Could not find the Perl module %s (usually part of package \'libxml-parser-perl\' or \'perl-XML-Parser\')'
                  ) % perlmod)

        # check for a downloading util:
        if not (inpath('curl', os.environ['PATH'].split(os.pathsep))
                or inpath('wget', os.environ['PATH'].split(os.pathsep))):
            uprint(_('curl or wget not found'))

        # check for git:
        if not inpath('git', os.environ['PATH'].split(os.pathsep)):
            uprint(_('%s not found') % 'git')
        else:
            try:
                git_help = os.popen('git --help', 'r').read()
                if 'clone' not in git_help:
                    uprint(_('Installed git program is not the right git'))
                else:
                    if not check_version(['git', '--version'],
                                         r'git version ([\d.]+)', '1.5.6'):
                        uprint(_('%s not found') % 'git >= 1.5.6')
            except EnvironmentError:
                uprint(_('Could not check git program'))

        # check for flex/bison:
        if not inpath('flex', os.environ['PATH'].split(os.pathsep)):
            uprint(_('%s not found') % 'flex')
        if not inpath('bison', os.environ['PATH'].split(os.pathsep)):
            uprint(_('%s not found') % 'bison')
        if not inpath('xzcat', os.environ['PATH'].split(os.pathsep)):
            uprint(_('%s not found') % 'xzcat')

        # check for "sysdeps --install" deps:
        try:
            from gi.repository import GLib
            GLib
        except ImportError:
            uprint(_('%s not found') % 'python-gobject')
        try:
            import dbus.glib
            dbus.glib
        except ImportError:
            uprint(_('%s not found') % 'dbus-python')

    def check_m4(self):
        try:
            not_in_path = []
            path = get_aclocal_path()

            macros = ['libtool.m4', 'gettext.m4', 'pkg.m4']
            for macro in macros:
                if not inpath(macro, path):
                    uprint(
                        _("aclocal can't see %s macros") %
                        (macro.split('.m4')[0]))
                    if not_in_path.count(macro) == 0:
                        not_in_path.append(macro)

            if len(not_in_path) > 0:
                uprint(_("Please copy the lacking macros (%(macros)s) in one of the following paths: %(path)s") % \
                       {'macros': ', '.join(not_in_path), 'path': ', '.join(path)})

        except CommandError as exc:
            uprint(str(exc))