def limit_version(item, oper, version): if oper in ['>', '>=']: if item.lower: _, saved_version = item.lower if Version(saved_version) < Version(version): item.lower = [oper, version] elif Version(saved_version) == Version( version) and oper == '>': item.lower = [oper, version] else: item.lower = [oper, version] elif oper in ['<', '<=']: if item.upper: _, saved_version = item.upper if Version(saved_version) > Version(version): item.upper = [oper, version] elif Version(saved_version) == Version( version) and oper == '<': item.upper = [oper, version] else: item.upper = [oper, version] elif oper in ['==']: if item.equal and item.equal != version: raise gluetool.GlueError( "Different versions '{}' and '{}' of package '{}' required" .format(item.equal, version, item.pkg)) item.equal = version else: raise gluetool.GlueError("Unsupported operator '{}'".format(oper))
def sanity(self): if not self.glue.tool: # Don't know how to tell it better - it needs access to self.glue.tool # to find out what tool's running this show, to find out its command-name # for the completion configuration. raise gluetool.GlueError( 'Module must be used via a gluetool-like tool (e.g. `gluetool bash-completion`' )
def get_allowed_version_bounds(self, item): if not item.equal and not item.lower and not item.upper: return item.pkg if item.equal: if item.upper: oper, version = item.upper relate = self.ops_map[oper] if not relate(Version(item.equal), Version(version)): raise gluetool.GlueError( "Cannot find common version for package '{}'".format( item.pkg)) if item.lower: oper, version = item.lower relate = self.ops_map[oper] if not relate(Version(item.equal), Version(version)): raise gluetool.GlueError( "Cannot find common version for package '{}'".format( item.pkg)) return '{}=={}'.format(item.pkg, item.equal) if item.upper and item.lower: lower_operator, lower_version = item.lower upper_operator, upper_version = item.upper relate = self.ops_map[lower_operator] if not relate(Version(upper_version), Version(lower_version)): raise gluetool.GlueError( "Cannot find common version for package '{}'".format( item.pkg)) relate = self.ops_map[upper_operator] if not relate(Version(lower_version), Version(upper_version)): raise gluetool.GlueError( "Cannot find common version for package '{}'".format( item.pkg)) return '{}{}{},{}{}'.format(item.pkg, lower_operator, lower_version, upper_operator, upper_version) if item.upper: upper_operator, upper_version = item.upper return '{}{}{}'.format(item.pkg, upper_operator, upper_version) if item.lower: lower_operator, lower_version = item.lower return '{}{}{}'.format(item.pkg, lower_operator, lower_version)
def __init__(self, dsn_env_var='SENTRY_DSN', base_url_env_var='SENTRY_BASE_URL', tags_map_env_var='SENTRY_TAG_MAP'): # type: (Optional[str], Optional[str], Optional[str]) -> None self._client = None self._base_url = None if base_url_env_var: self._base_url = os.environ.get(base_url_env_var, None) self._tag_map = {} # type: Dict[str, str] if tags_map_env_var and os.environ.get(tags_map_env_var): try: for pair in os.environ[tags_map_env_var].split(','): tag, env_var = pair.split('=') self._tag_map[env_var.strip()] = tag.strip() except ValueError: raise gluetool.GlueError( 'Cannot parse content of {} environment variable'.format( tags_map_env_var)) if not dsn_env_var: return dsn = os.environ.get(dsn_env_var, None) if not dsn: return self._client = raven.Client(dsn, install_logging_hook=True) # Enrich Sentry context with information that are important for us context = {} # env variables for name, value in os.environ.iteritems(): context['env.{}'.format(name)] = value self._client.extra_context(context)
def foo(): try: return bar(17) except ValueError: raise gluetool.GlueError('Foo failed')
def execute(self): # we must fix "type" keys in pipeline options: it's supposed to be a callable # but we cannot store callable in YAML, therefore let's convert from strings, # using builtins. # # Also, find required options/ required_options = [] for name, properties in self.pipeline['options'].iteritems(): if 'required' in properties: if properties['required'] is True: required_options.append(name) del properties['required'] option_type = properties.get('type', None) if option_type is None: continue if option_type not in __builtins__: raise gluetool.GlueError("Cannot find option type '{}'".format(option_type)) properties['type'] = __builtins__[option_type] # our custom "pipeline" module class Pipeline(gluetool.Module): name = self.pipeline['name'] desc = self.pipeline['description'] options = self.pipeline['options'] # cannot assign local name to Pipeline's class property while delcaring it, therefore setting it now Pipeline.required_options = required_options log_dict(self.debug, 'pipeline options', Pipeline.options) pipeline_module = Pipeline(self.glue, self.pipeline['name']) pipeline_module.parse_args(self.option('pipeline_options')[1:]) # skip leading '--' pipeline_module.check_dryrun() pipeline_module.check_required_options() # Run each module, one by one - we cannot construct a pipeline, because options # of a module might depend on state of previous modules - available via # PIPELINE.shared, for example. run_module = functools.partial(self.glue.run_module, register=True) def evaluate_value(value): # If the template is not a string type, just return it as a string. This helps # simplifyusers of this method: *every* value is treated by this method, no # exceptions. User gets new one, and is not concerned whether the original was # a template or boolean or whatever. if not isinstance(value, str): return str(value) return jinja2.Template(value).render(PIPELINE=pipeline_module, ENV=os.environ) for module in self.pipeline['pipeline']: log_dict(self.debug, 'module', module) # just a module name if isinstance(module, str): run_module(module, []) continue if not isinstance(module, dict): raise gluetool.GlueError('Unexpected module syntax: {}'.format(module)) # Check 'when' - if it's set and evaluates as false-ish, skip the module when = module.pop('when', None) if when is not None: # If "when" is a string, expect it's an expression - wrap it with {{ }} # to form a Jinja template, and evaluate it. if isinstance(when, str): when = evaluate_value('{{ ' + when + ' }}') self.debug("evalued when: '{}' ({})".format(when, type(when))) # Works for both Python false-ish values and strings, coming from template evaluation # If it's false-ish by nature, or its string representation is false-ish, skip the module. if not when or when.lower() in ('no', 'off', '0', 'false', 'none'): self.debug('skipping module') continue # remaining key is the module name module_name = module.keys()[0] # empty options if module[module_name] is None: run_module(module_name, []) continue module_argv = [] for option, value in module[module_name].iteritems(): value = evaluate_value(value) if value is None: module_argv.append('--{}'.format(option)) else: module_argv.append('--{}={}'.format(option, value)) run_module(module_name, module_argv)