Home | History | Annotate | Download | only in story
      1 # Copyright 2013 The Chromium Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 import optparse
      6 import re
      7 
      8 from telemetry.internal.util import command_line
      9 
     10 
     11 class _StoryMatcher(object):
     12   def __init__(self, pattern):
     13     self._regex = None
     14     self.has_compile_error = False
     15     if pattern:
     16       try:
     17         self._regex = re.compile(pattern)
     18       except re.error:
     19         self.has_compile_error = True
     20 
     21   def __nonzero__(self):
     22     return self._regex is not None
     23 
     24   def HasMatch(self, story):
     25     return self and bool(
     26         self._regex.search(story.display_name) or
     27         (story.name and self._regex.search(story.name)))
     28 
     29 
     30 class _StoryTagMatcher(object):
     31   def __init__(self, tags_str):
     32     self._tags = tags_str.split(',') if tags_str else None
     33 
     34   def __nonzero__(self):
     35     return self._tags is not None
     36 
     37   def HasLabelIn(self, story):
     38     return self and bool(story.tags.intersection(self._tags))
     39 
     40 
     41 class StoryFilter(command_line.ArgumentHandlerMixIn):
     42   """Filters stories in the story set based on command-line flags."""
     43 
     44   @classmethod
     45   def AddCommandLineArgs(cls, parser):
     46     group = optparse.OptionGroup(parser, 'User story filtering options')
     47     group.add_option('--story-filter',
     48         help='Use only stories whose names match the given filter regexp.')
     49     group.add_option('--story-filter-exclude',
     50         help='Exclude stories whose names match the given filter regexp.')
     51     group.add_option('--story-tag-filter',
     52         help='Use only stories that have any of these tags')
     53     group.add_option('--story-tag-filter-exclude',
     54         help='Exclude stories that have any of these tags')
     55     parser.add_option_group(group)
     56 
     57   @classmethod
     58   def ProcessCommandLineArgs(cls, parser, args):
     59     cls._include_regex = _StoryMatcher(args.story_filter)
     60     cls._exclude_regex = _StoryMatcher(args.story_filter_exclude)
     61 
     62     cls._include_tags = _StoryTagMatcher(args.story_tag_filter)
     63     cls._exclude_tags = _StoryTagMatcher(args.story_tag_filter_exclude)
     64 
     65     if cls._include_regex.has_compile_error:
     66       raise parser.error('--story-filter: Invalid regex.')
     67     if cls._exclude_regex.has_compile_error:
     68       raise parser.error('--story-filter-exclude: Invalid regex.')
     69 
     70   @classmethod
     71   def IsSelected(cls, story):
     72     # Exclude filters take priority.
     73     if cls._exclude_tags.HasLabelIn(story):
     74       return False
     75     if cls._exclude_regex.HasMatch(story):
     76       return False
     77 
     78     if cls._include_tags and not cls._include_tags.HasLabelIn(story):
     79       return False
     80     if cls._include_regex and not cls._include_regex.HasMatch(story):
     81       return False
     82     return True
     83