Source code for repoman.common.parser

#!/usr/bin/env python
"""
When specifying a source for an artifact, you have to do it in this format::

    source_type:value[:filter[:filter[...]]]

For each source, it will be expanded, and filtered. An example::

    repo:master-nightly:name~ovirt-engine.*:latest=2

"""
import logging
from . import (
    sources,
    filters,
)


logger = logging.getLogger(__name__)


[docs]class Parser(object): def __init__(self, config, stores): """ :param config: configuration for the parser :param stores: instances of the available stores """ self.config = config self.stores = stores self.filters = config.getarray('filters') self.filters = dict([ ( cname, cls( stores=stores.values(), config=config.get_section( section='filter.' + cls.CONFIG_SECTION, ) ) ) for cname, cls in filters.FILTERS.iteritems() if cname in self.filters or 'all' in self.filters ]) self.sources = config.getarray('sources') self.sources = dict([ ( cname, cls( stores=stores.values(), config=config.get_section( section='source.' + cls.CONFIG_SECTION, ) ) ) for cname, cls in sources.SOURCES.iteritems() if cname in self.sources or 'all' in self.sources ])
[docs] def parse(self, full_source_str): """ Parses the given source sting and returns a list of resolved artifact paths :param full_source_str: Source sting to parse :type full_source_str: Sting :rtype: list of strings """ art_list = set() for stuple in self.sources.iteritems(): aname = stuple[0] source = stuple[1] source_str = full_source_str logger.debug('Checking source %s with %s', aname, source_str) result = source.expand(source_str) filters_str = result[0] art_list = result[1] if not art_list: # if no artifacts for this source type, try next continue # check if there were any filters in the source definition, finish # if not if not filters_str: break # check all the filters until finished or we can't resolve any more # of the filters strings prev_filters_str = '' while filters_str and filters_str != prev_filters_str: prev_filters_str = filters_str for fname, fclass in self.filters.iteritems(): logger.info('Filtering filter %s with %s', filters_str, fname) result = fclass.filter( filters_str, art_list, ) filters_str, art_list = result if not filters_str: break # We skip all other sources if we found the matching one break if not art_list: empty_source_action = self.config.get('on_empty_source') msg = 'No artifacts found for source %s' % source_str if empty_source_action in ['fail', 'warn']: logger.error(msg) if empty_source_action == 'fail': raise Exception(msg) logging.debug( 'From source string %s got: %s', full_source_str, art_list ) return art_list