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

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
Martin Barbella 2017/01/27 23:30:58 Nit: s/it has/have/
Sharu Jiang 2017/01/30 22:23:52 Done.
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',
wrengr 2017/01/30 19:14:19 Nit: "regexes" is the standard way to pluralize "r
Sharu Jiang 2017/01/30 22:23:52 Done.
23 'host_directories'])):
24 """A representation of a "project".
wrengr 2017/01/30 19:14:19 This line doesn't explain anything beyond what the
Sharu Jiang 2017/01/30 22:23:52 Done.
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
wrengr 2017/01/30 19:14:19 (s/directoris/directories/ && s/and its/and their/
Sharu Jiang 2017/01/30 22:23:52 Done.
37 dependency projects.
38 N.B. If ``host_directories`` is availabe, this project can match
wrengr 2017/01/30 19:14:19 s/availabe/available/
Sharu Jiang 2017/01/30 22:23:52 Done.
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
wrengr 2017/01/30 19:14:19 s/, else if/. If/
Sharu Jiang 2017/01/30 22:23:52 Done.
41 tell that from ``dep_path``, however that doesn't mean the suspect or
wrengr 2017/01/30 19:14:19 s/, however/; however,/
Sharu Jiang 2017/01/30 22:23:52 Done.
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
wrengr 2017/01/30 19:14:19 can replace this line with ``map(re.compile, path_
Sharu Jiang 2017/01/30 22:23:52 Done.
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 []
wrengr 2017/01/30 19:14:19 ditto
Sharu Jiang 2017/01/30 22:23:52 Done.
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 # Sometimes some marker information are in the frame.raw_file_path.
61 # An example, the path_regex for android_os is --
62 # "https___googleplex-android.googlesource.com_a_platform_manifest.git/".
63 # It can only be found in frame.raw_file_path, since the frame.file_path
64 # has those kind of information stripped.
65 for path_regex in self.path_regexs:
66 if (path_regex.match(os.path.join(frame.dep_path, frame.file_path)) or
67 path_regex.match(frame.raw_file_path)):
68 return True
69
70 for function_regex in self.function_regexs:
71 if function_regex.match(frame.function):
72 return True
73
74 for host_directory in self.host_directories:
75 if frame.dep_path.startswith(host_directory):
76 return True
77
78 return False
79
80 def MatchesTouchedFile(self, dep_path, touched_file):
81 """Returns true if this project matches the file path."""
82 if touched_file.change_type == ChangeType.DELETE:
wrengr 2017/01/30 19:14:19 Since this conditional shows up repeatedly, should
Sharu Jiang 2017/01/30 22:23:52 Done.
83 path = touched_file.old_path
84 else:
85 path = touched_file.new_path
86
87 # If the path matches the path patterns.
88 for path_regex in self.path_regexs:
89 if path_regex.match(os.path.join(dep_path, path)):
90 return True
91
92 # If the dep_path hosted by this project.
93 for host_directory in self.host_directories:
94 if dep_path.startswith(host_directory):
95 return True
96
97 return False
98
99 def GetName(self, dep_path=None):
100 """Returns the project name based on dep path.
101
102 N.B. (1) If this project doesn't have dep projects, just return the project
103 name. (2) If this project does, return the derived dep project name based on
104 the self.host_directories.
105 """
106 if self.name not in _PROJECTS_WITH_DEP_PROJECTS or dep_path is None:
107 return self.name
108
109 # For chromium project, get the name of the sub project from ``dep_path``.
110 for host_directory in self.host_directories:
111 if dep_path.startswith(host_directory):
112 path = dep_path[len(host_directory):]
113 if not path:
114 return self.name
115
116 return '%s-%s' % (self.name, path.split('/')[0].lower())
117
118 # Unknown path, return the whole path as project name.
119 return '%s-%s' % (self.name,
120 '_'.join([dep_part for dep_part in dep_path.split('/')
121 if dep_part]))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698