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'])
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)
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()
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)})
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'))
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])
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)
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
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')
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()
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()
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
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)
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()
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
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'])
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
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)
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 }))
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)
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)
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()
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()
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()
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()
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()
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)
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))