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

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
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", it has many dependency 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_regexs', 'function_regexs',
23 'host_directories'])):
24 """A representation of a "project".
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_regexs (list of re.RegexObject): Patterns of paths that project has.
34 function_regexs (list of re.RegexObject): Patterns of functions that project
35 has.
36 host_directories (list of str): The root directoris of this project and its
37 dependency projects.
38 N.B. If ``host_directories`` is availabe, this project can match
39 it with the passed-in ``dep_path`` to tell whether a suspect or stack is
40 from this project, else 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_regexs`` or ``function_regexs`` to analyze.
44 """
45 __slots__ = ()
46
47 def __new__(cls, name, path_regexs=None,
48 function_regexs=None, host_directories=None):
49 path_regexs = [re.compile(path_regex) for path_regex in
50 path_regexs] if path_regexs else []
51 function_regexs = [re.compile(function_regex) for function_regex in
52 function_regexs] if function_regexs else []
53 host_directories = host_directories or []
54
55 return super(cls, Project).__new__(
56 cls, name, path_regexs, function_regexs, host_directories)
57
58 def MatchesStackFrame(self, frame):
59 """Returns true if this project matches the frame."""
60 for path_regex in self.path_regexs:
61 if (path_regex.match(frame.dep_path + frame.file_path) or
62 path_regex.match(frame.raw_file_path)):
63 return True
64
65 for function_regex in self.function_regexs:
66 if function_regex.match(frame.function):
67 return True
68
69 for host_directory in self.host_directories:
70 if frame.dep_path.startswith(host_directory):
71 return True
72
73 return False
74
75 def MatchesTouchedFile(self, dep_path, touched_file):
76 """Returns true if this project matches the file path."""
77 if touched_file.change_type == ChangeType.DELETE:
78 path = touched_file.old_path
79 else:
80 path = touched_file.new_path
81
82 # if the path matches the path patterns.
lijeffrey 2017/01/27 15:42:20 nit: If
Sharu Jiang 2017/01/27 18:39:04 Done.
83 for path_regex in self.path_regexs:
84 if path_regex.match(os.path.join(dep_path, path)):
85 return True
86
87 # If the dep_path hosted by this project.
88 for host_directory in self.host_directories:
89 if dep_path.startswith(host_directory):
90 return True
lijeffrey 2017/01/27 15:42:20 I think this can be simplified slightly to: retur
Sharu Jiang 2017/01/27 18:39:04 Hm... I want to keep these two conditions separate
91
92 return False
93
94 def GetName(self, dep_path=None):
95 """Returns the project name based on dep path.
96
97 N.B. (1) If this project doesn't have dep projects, just return the project
98 name. (2) If this project does, return the derived dep project name based on
99 the self.host_directories.
100 """
101 if self.name not in _PROJECTS_WITH_DEP_PROJECTS or dep_path is None:
102 return self.name
103
104 # For chromium project, get the name of the sub project from ``dep_path``.
105 for host_directory in self.host_directories:
106 if dep_path.startswith(host_directory):
107 path = dep_path[len(host_directory):]
108 if not path:
109 return self.name
110
111 return '%s-%s' % (self.name, path.split('/')[0].lower())
112
113 # Unknown path, return the whole path as project name.
114 return '%s-%s' % (self.name,
115 '_'.join([dep_part for dep_part in dep_path.split('/')
116 if dep_part]))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698