Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: appengine/findit/crash/project.py

Issue 2657913002: [Predator] Add ``Project`` class and ``ClassifySuspect`` method to project and component classifier (Closed)
Patch Set: Fix nits. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « appengine/findit/crash/predator.py ('k') | appengine/findit/crash/project_classifier.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright 2017 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 from collections import namedtuple
6 import os
7 import re
8
9 from libs.gitiles.diff import ChangeType
10
11 # Some projects like "chromium", have many sub projects like
12 # "chromium-blink", "chromium-skia", "chromium-pdfium"...etc., for those
13 # dep projects, the "chromium" ``Project`` can derive the names from their
14 # dep paths.
15 # Some other projects like "android_os", "clank", they don't have any dependency
16 # projects that are relavent to Predator.
17 _PROJECTS_WITH_DEP_PROJECTS = ['chromium']
18
19
20 # TODO(http://crbug.com/659346): write the coverage tests.
21 class Project(namedtuple('Project',
22 ['name', 'path_regexes', 'function_regexes',
23 'host_directories'])):
24 """A representation of a "project", which may host many sub projects.
25
26 For example: 'android_os', 'clank' or 'chromium'. Notably, a project knows
27 how to identify itself. Hence, given a stack frame, file path or dependency
28 path or whatever, we ask the ``Project`` whether it matches that frame,
29 CL, etc.
30
31 Properties:
32 name (str): The name of the project, like "chromium", "android_os".
33 path_regexes (list of re.RegexObject): Patterns of paths that project has.
34 function_regexes (list of re.RegexObject): Patterns of functions that
35 project has.
36 host_directories (list of str): The root directories of this project and
37 sub projects this project hosts.
38 N.B. If ``host_directories`` is available, this project can match
39 it with the passed-in ``dep_path`` to tell whether a suspect or stack is
40 from this project. If this information is missing, the project cannot
41 tell that from ``dep_path``; However, that doesn't mean the suspect or
42 stack does not belong to this project, we can use other information like
43 ``path_regexes`` or ``function_regexes`` to analyze.
44 """
45 __slots__ = ()
46
47 def __new__(cls, name, path_regexes=None,
48 function_regexes=None, host_directories=None):
49 path_regexes = map(re.compile, path_regexes or [])
50 function_regexes = map(re.compile, function_regexes or [])
51 host_directories = host_directories or []
52
53 return super(cls, Project).__new__(
54 cls, name, path_regexes, function_regexes, host_directories)
55
56 def MatchesStackFrame(self, frame):
57 """Returns true if this project matches the frame."""
58 # Sometimes some marker information are in the frame.raw_file_path.
59 # An example, the path_regex for android_os is --
60 # "https___googleplex-android.googlesource.com_a_platform_manifest.git/".
61 # It can only be found in frame.raw_file_path, since the frame.file_path
62 # has those kind of information stripped.
63 for path_regex in self.path_regexes:
64 if (path_regex.match(os.path.join(frame.dep_path, frame.file_path)) or
65 path_regex.match(frame.raw_file_path)):
66 return True
67
68 for function_regex in self.function_regexes:
69 if function_regex.match(frame.function):
70 return True
71
72 for host_directory in self.host_directories:
73 if frame.dep_path.startswith(host_directory):
74 return True
75
76 return False
77
78 def MatchesTouchedFile(self, dep_path, file_path):
79 """Returns true if this project matches the file path."""
80 # If the path matches the path patterns.
81 for path_regex in self.path_regexes:
82 if path_regex.match(os.path.join(dep_path, file_path)):
83 return True
84
85 # If the dep_path hosted by this project.
86 for host_directory in self.host_directories:
87 if dep_path.startswith(host_directory):
88 return True
89
90 return False
91
92 def GetName(self, dep_path=None):
93 """Returns the project name based on dep path.
94
95 N.B. (1) If this project doesn't have dep projects, just return the project
96 name. (2) If this project does, return the derived dep project name based on
97 the self.host_directories.
98 """
99 if self.name not in _PROJECTS_WITH_DEP_PROJECTS or dep_path is None:
100 return self.name
101
102 # For chromium project, get the name of the sub project from ``dep_path``.
103 for host_directory in self.host_directories:
104 if dep_path.startswith(host_directory):
105 path = dep_path[len(host_directory):]
106 if not path:
107 return self.name
108
109 return '%s-%s' % (self.name, path.split('/')[0].lower())
110
111 # Unknown path, return the whole path as project name.
112 return '%s-%s' % (self.name,
113 '_'.join([dep_part for dep_part in dep_path.split('/')
114 if dep_part]))
OLDNEW
« no previous file with comments | « appengine/findit/crash/predator.py ('k') | appengine/findit/crash/project_classifier.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698