- Add mock-specific build artifacts (chroot/, mock-*, mockroot/) - Include package build files (*.deb, *.changes, *.buildinfo) - Add development tools (.coverage, .pytest_cache, .tox) - Include system files (.DS_Store, Thumbs.db, ._*) - Add temporary and backup files (*.tmp, *.bak, *.backup) - Include local configuration overrides (config.local.yaml, .env.local) - Add test artifacts and documentation builds - Comprehensive coverage for Python build system project This ensures build artifacts, chroot environments, and development tools are properly ignored in version control.
88 lines
3.5 KiB
Python
88 lines
3.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
# vim: noai:ts=4:sw=4:expandtab
|
|
|
|
import importlib.machinery
|
|
import importlib.util
|
|
import sys
|
|
|
|
from .exception import Error
|
|
from .trace_decorator import traceLog
|
|
|
|
current_api_version = '1.1'
|
|
|
|
|
|
class Plugins(object):
|
|
@traceLog()
|
|
def __init__(self, config, state):
|
|
self.config = config
|
|
self._hooks = {}
|
|
self.state = state
|
|
|
|
self.already_initialized = False
|
|
|
|
self.plugins = config['plugins']
|
|
self.plugin_conf = config['plugin_conf']
|
|
self.plugin_dir = config['plugin_dir']
|
|
|
|
def __repr__(self):
|
|
return "<mockbuild.plugin.Plugins: state={0}, _hooks={1}, already_initialized={2}".format(
|
|
self.state, self._hooks, self.already_initialized)
|
|
|
|
@traceLog()
|
|
def init_plugins(self, buildroot):
|
|
if self.already_initialized:
|
|
return
|
|
self.already_initialized = True
|
|
for key in list(self.plugin_conf.keys()):
|
|
if key.endswith('_opts'):
|
|
self.plugin_conf[key]['basedir'] = buildroot.basedir
|
|
self.plugin_conf[key]['cache_topdir'] = buildroot.cache_topdir
|
|
self.plugin_conf[key]['cachedir'] = buildroot.cachedir
|
|
self.plugin_conf[key]['root'] = buildroot.shared_root_name
|
|
self.plugin_conf[key]['resultdir'] = buildroot.resultdir
|
|
|
|
self.state.start("init plugins")
|
|
# Import plugins (simplified copy of what yum does). Can add yum
|
|
# features later when we prove we need them.
|
|
for plugin in self.plugins:
|
|
if self.plugin_conf.get("{0}_enable".format(plugin)):
|
|
spec = importlib.machinery.PathFinder.find_spec(plugin, [self.plugin_dir])
|
|
if not spec:
|
|
buildroot.root_log.warning(
|
|
"{0} plugin is enabled in configuration but is not installed".format(plugin))
|
|
continue
|
|
module = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(module)
|
|
sys.modules[spec.name] = module
|
|
|
|
if not hasattr(module, 'requires_api_version'):
|
|
raise Error('Plugin "%s" doesn\'t specify required API version' % plugin)
|
|
requested_api_version = module.requires_api_version
|
|
if requested_api_version != current_api_version:
|
|
raise Error('Plugin version mismatch - requested = %s, current = %s'
|
|
% (requested_api_version, current_api_version))
|
|
|
|
run_in_bootstrap = getattr(module, "run_in_bootstrap", True)
|
|
# simplified (buildroot.is_bootstrap and run_in_bootstrap) or not buildroot.is_bootstrap
|
|
if not buildroot.is_bootstrap or run_in_bootstrap:
|
|
module.init(self, self.plugin_conf["{0}_opts".format(plugin)], buildroot)
|
|
self.state.finish("init plugins")
|
|
|
|
@traceLog()
|
|
def call_hooks(self, stage, *args, **kwargs):
|
|
required = kwargs.get('required', False)
|
|
if 'required' in kwargs:
|
|
del kwargs['required']
|
|
hooks = self._hooks.get(stage, [])
|
|
if required and not hooks:
|
|
raise Error(
|
|
"Feature {0} is not provided by any of enabled plugins".format(stage))
|
|
for hook in hooks:
|
|
hook(*args, **kwargs)
|
|
|
|
@traceLog()
|
|
def add_hook(self, stage, function):
|
|
hooks = self._hooks.get(stage, [])
|
|
if function not in hooks:
|
|
hooks.append(function)
|
|
self._hooks[stage] = hooks
|