def glob(include, exclude=None, excludes=None, allow_empty=False):
    """This function can be called in BUILD to specify a set of files using patterns.
    Args:
        include:List[str], file patterns to be matched.
        exclude:Optional[List[str]], file patterns to be removed from the result.
        allow_empty:bool: Whether a empty result is a error.

    Patterns may contain shell-like wildcards, such as * , ? , or [charset].
    Additionally, the path element '**' matches any subpath.
    """
    from blade import build_manager  # pylint: disable=import-outside-toplevel
    source_dir = Path(build_manager.instance.get_current_source_path())
    source_loc = source_location(os.path.join(str(source_dir), 'BUILD'))
    include = var_to_list(include)
    severity = config.get_item('global_config', 'glob_error_severity')
    output = getattr(console, severity)
    if excludes:
        output('%s %s: "excludes" is deprecated, use "exclude" instead' % (source_loc, severity),
               prefix=False)
    exclude = var_to_list(exclude) + var_to_list(excludes)

    def includes_iterator():
        results = []
        for pattern in include:
            for path in source_dir.glob(pattern):
                if path.is_file() and not path.name.startswith('.'):
                    results.append(path.relative_to(source_dir))

        return results

    def is_special(pattern):
        return '*' in pattern or '?' in pattern or '[' in pattern

    non_special_excludes = set()
    match_excludes = set()
    for pattern in exclude:
        if is_special(pattern):
            match_excludes.add(pattern)
        else:
            non_special_excludes.add(pattern)

    def exclusion(path):
        if str(path) in non_special_excludes:
            return True
        for pattern in match_excludes:
            ret = path.match(pattern)
            if ret:
                return True
        return False

    result = sorted({str(p) for p in includes_iterator() if not exclusion(p)})
    if not result and not allow_empty:
        args = repr(include)
        if exclude:
            args += ', exclude=%s' % repr(exclude)
        output('%s %s: "glob(%s)" got an empty result. If it is the expected behavior, '
               'specify "allow_empty=True" to eliminate this message' % (source_loc, severity, args),
               prefix=False)

    return result
Beispiel #2
0
    def __init__(self, name, type, srcs, deps, visibility, kwargs):
        """Init method.

        Init the target.

        """
        from blade import build_manager  # pylint: disable=import-outside-toplevel
        self.blade = build_manager.instance
        self.build_dir = self.blade.get_build_dir()
        current_source_path = self.blade.get_current_source_path()
        self.target_database = self.blade.get_target_database()

        self.name = name
        self.path = current_source_path
        # The unique key of this target, for internal use mainly.
        self.key = '%s:%s' % (current_source_path, name)
        # The full qualified target id, to be displayed in diagnostic message
        self.fullname = '//' + self.key
        self.source_location = source_location(
            os.path.join(current_source_path, 'BUILD'))
        self.type = type
        self.srcs = srcs
        self.deps = []
        self.expanded_deps = None  # Expanded dependencies, includes direct and indirect dependies.
        self.dependents = set()  # Target keys which depends on this
        self.expanded_dependents = set(
        )  # Expanded target keys which depends on this
        self._implicit_deps = set()
        self.visibility = 'PUBLIC'

        if not name:
            self.fatal('Missing "name"')

        # Keep track of target filess generated by this target. Note that one target rule
        # may correspond to several target files, such as:
        # proto_library: static lib/shared lib/jar variables
        self.__targets = {}
        self.__default_target = ''
        self.__clean_list = []  # Paths to be cleaned

        # Target releated attributes, they should be set only before generating build rules.
        self.attr = {}

        # For temporary, mutable fields only, their values should not relate to rule_hash
        self.data = {}

        # TODO: Remove it, make a `TestTargetMixin`
        self.attr['test_timeout'] = config.get_item('global_config',
                                                    'test_timeout')

        self._check_name()
        self._check_kwargs(kwargs)
        self._check_srcs()
        self._check_deps(deps)
        self._init_target_deps(deps)
        self._init_visibility(visibility)
        self.__build_rules = None
        self.__rule_hash = None  # Cached rule hash
Beispiel #3
0
    def __init__(self,
                 name,
                 type,
                 srcs,
                 deps,
                 visibility,
                 kwargs):
        """Init method.

        Init the target.

        """
        from blade import build_manager
        self.blade = build_manager.instance
        self.build_dir = self.blade.get_build_dir()
        current_source_path = self.blade.get_current_source_path()
        self.target_database = self.blade.get_target_database()

        self.key = (current_source_path, name)
        self.fullname = '%s:%s' % self.key
        self.name = name
        self.path = current_source_path
        self.source_location = source_location(os.path.join(current_source_path, 'BUILD'))
        self.type = type
        self.srcs = srcs
        self.deps = []
        self.expanded_deps = []
        self.visibility = 'PUBLIC'
        self.data = {}
        self.data['test_timeout'] = config.get_item('global_config', 'test_timeout')

        # Keep track of target filess generated by this target. Note that one target rule
        # may correspond to several target files, such as:
        # proto_library: static lib/shared lib/jar variables
        self.data['targets'] = {}
        self.data['default_target'] = ''

        self._check_name()
        self._check_kwargs(kwargs)
        self._check_srcs()
        self._check_deps(deps)
        self._init_target_deps(deps)
        self._init_visibility(visibility)
        self.build_rules = []
        self.data['generated_hdrs'] = []
Beispiel #4
0
 def fatal(self, msg):
     # NOTE: VSCode's problem matcher doesn't recognize 'fatal', use 'error' instead
     console.fatal('%s error: %s' % (source_location(self.current_file_name), msg), prefix=False)
Beispiel #5
0
 def error(self, msg):
     console.error('%s error: %s' % (source_location(self.current_file_name), msg), prefix=False)
Beispiel #6
0
 def warning(self, msg):
     console.warning('%s warning: %s' % (source_location(self.current_file_name), msg), prefix=False)
Beispiel #7
0
 def info(self, msg):
     console.info('%s info: %s' % (source_location(self.current_file_name), msg), prefix=False)
Beispiel #8
0
def _current_source_location():
    """Return source location in current BUILD file"""
    from blade import build_manager  # pylint: disable=import-outside-toplevel
    source_dir = Path(build_manager.instance.get_current_source_path())
    return source_location(os.path.join(str(source_dir), 'BUILD'))
Beispiel #9
0
 def fatal(self, msg):
     console.fatal('%s: %s' %
                   (source_location(self.current_file_name), msg),
                   prefix=False)