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

Side by Side Diff: third_party/polymer/v1_0/find_unused_elements.py

Issue 1944133002: Unused Polymer elements script (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python2 1 #!/usr/bin/python2
2 2
3 # Copyright 2016 The Chromium Authors. All rights reserved. 3 # Copyright 2016 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 """Identifies Polymer elements that downloaded but not used by Chrome. 7 """Identifies Polymer elements that downloaded but not used by Chrome.
8 8
9 Only finds "first-order" unused elements; re-run after removing unused elements 9 Only finds "first-order" unused elements; re-run after removing unused elements
10 to check if other elements have become unused. 10 to check if other elements have become unused.
11 """ 11 """
12 12
13 import os 13 import os
14 import re 14 import re
15 import subprocess 15 import subprocess
16 16
17 17
18 class UnusedElementsDetector: 18 class UnusedElementsDetector(object):
19 """Finds unused Polymer elements.""" 19 """Finds unused Polymer elements."""
20 20
21 # Unused elements to ignore because we plan to use them soon. 21 # Unused elements to ignore because we plan to use them soon.
22 __whitelist = ( 22 __WHITELIST = (
23 # TODO(dschuyler): Use element or remove from whitelist. 23 # TODO(dschuyler): Use element or remove from whitelist.
24 'carbon-route', 24 'carbon-route',
25 # TODO(tsergeant): Use element or remove from whitelist. 25 # TODO(tsergeant): Use element or remove from whitelist.
26 'iron-scroll-threshold', 26 'iron-scroll-threshold',
27 # Necessary for closure. 27 # Necessary for closure.
28 'polymer-externs', 28 'polymer-externs',
29 ) 29 )
30 30
31 def __init__(self):
32 polymer_dir = os.path.dirname(os.path.realpath(__file__))
33 self.__COMPONENTS_DIR = os.path.join(polymer_dir, 'components-chromium')
34
31 @staticmethod 35 @staticmethod
32 def __StripHtmlComments(filename): 36 def __StripHtmlComments(filename):
33 """Returns the contents of an HTML file with <!-- --> comments stripped. 37 """Returns the contents of an HTML file with <!-- --> comments stripped.
34 38
35 Not a real parser. 39 Not a real parser.
36 40
37 Args: 41 Args:
38 filename: The name of the file to read. 42 filename: The name of the file to read.
39 43
40 Returns: 44 Returns:
41 A string consisting of the file contents with comments removed. 45 A string consisting of the file contents with comments removed.
42 """ 46 """
43 with open(filename) as f: 47 with open(filename) as f:
44 return re.sub('<!--.*?-->', '', f.read(), flags=re.MULTILINE|re.DOTALL) 48 return re.sub('<!--.*?-->', '', f.read(), flags=re.MULTILINE | re.DOTALL)
45 49
46 @staticmethod 50 @staticmethod
47 def __StripJsComments(filename): 51 def __StripJsComments(filename):
48 """Returns the minified contents of a JavaScript file with comments and 52 """Returns the minified contents of a JavaScript file with comments and
49 grit directives removed. 53 grit directives removed.
50 54
51 Args: 55 Args:
52 filename: The name of the file to read. 56 filename: The name of the file to read.
53 57
54 Returns: 58 Returns:
55 A string consisting of the minified file contents with comments and grit 59 A string consisting of the minified file contents with comments and grit
56 directives removed. 60 directives removed.
57 """ 61 """
58 with open(filename) as f: 62 with open(filename) as f:
59 text = f.read() 63 text = f.read()
60 text = re.sub('<if .*?>', '', text) 64 text = re.sub('<if .*?>', '', text, flags=re.IGNORECASE)
61 text = re.sub('</if>', '', text) 65 text = re.sub('</if>', '', text, flags=re.IGNORECASE)
62 66
63 proc = subprocess.Popen(['uglifyjs', filename], stdout=subprocess.PIPE) 67 proc = subprocess.Popen(['uglifyjs', filename], stdout=subprocess.PIPE)
64 return proc.stdout.read() 68 return proc.stdout.read()
65 69
66 @staticmethod 70 @staticmethod
67 def __StripComments(filename): 71 def __StripComments(filename):
68 """Returns the contents of a JavaScript or HTML file with comments removed. 72 """Returns the contents of a JavaScript or HTML file with comments removed.
69 73
70 Args: 74 Args:
71 filename: The name of the file to read. 75 filename: The name of the file to read.
72 76
73 Returns: 77 Returns:
74 A string consisting of the file contents processed via 78 A string consisting of the file contents processed via
75 __StripHtmlComments or __StripJsComments. 79 __StripHtmlComments or __StripJsComments.
76 """ 80 """
77 if filename.endswith('.html'): 81 if filename.endswith('.html'):
78 text = UnusedElementsDetector.__StripHtmlComments(filename) 82 text = UnusedElementsDetector.__StripHtmlComments(filename)
79 elif filename.endswith('.js'): 83 elif filename.endswith('.js'):
80 text = UnusedElementsDetector.__StripJsComments(filename) 84 text = UnusedElementsDetector.__StripJsComments(filename)
81 else: 85 else:
82 assert False, 'Invalid filename: %s' % filename 86 assert False, 'Invalid filename: %s' % filename
83 return text 87 return text
84 88
85 @staticmethod 89 def Run(self):
86 def Run():
87 """Finds unused Polymer elements and prints a summary.""" 90 """Finds unused Polymer elements and prints a summary."""
88 proc = subprocess.Popen( 91 proc = subprocess.Popen(
89 ['git', 'rev-parse', '--show-toplevel'], 92 ['git', 'rev-parse', '--show-toplevel'],
90 stdout=subprocess.PIPE) 93 stdout=subprocess.PIPE)
91 src_dir = proc.stdout.read().strip() 94 src_dir = proc.stdout.read().strip()
92 polymer_dir = os.path.dirname(os.path.realpath(__file__))
93 components_dir = os.path.join(polymer_dir, 'components-chromium')
94 95
95 elements = [] 96 elements = []
96 for name in os.listdir(components_dir): 97 for name in os.listdir(self.__COMPONENTS_DIR):
97 path = os.path.join(components_dir, name) 98 path = os.path.join(self.__COMPONENTS_DIR, name)
98 if os.path.isdir(path): 99 if os.path.isdir(path):
99 elements.append(name) 100 elements.append(name)
100 101
101 relevant_src_dirs = ( 102 relevant_src_dirs = (
102 os.path.join(src_dir, 'chrome'), 103 os.path.join(src_dir, 'chrome'),
103 os.path.join(src_dir, 'ui'), 104 os.path.join(src_dir, 'ui'),
104 os.path.join(src_dir, 'components'), 105 os.path.join(src_dir, 'components'),
105 components_dir 106 self.__COMPONENTS_DIR
106 ) 107 )
107 108
108 for element in elements:
109 if element in UnusedElementsDetector.__whitelist:
110 continue
111
112 unused_elements = [] 109 unused_elements = []
113 for element in elements: 110 for element in elements:
114 if (element not in UnusedElementsDetector.__whitelist and 111 if (element not in UnusedElementsDetector.__WHITELIST and
Dan Beam 2016/05/04 02:15:14 self.__WHITELIST
michaelpg 2016/05/04 02:57:18 Done.
115 not UnusedElementsDetector.__IsImported(element, relevant_src_dirs)): 112 not self.__IsImported(element, relevant_src_dirs)):
116 unused_elements.append(element) 113 unused_elements.append(element)
117 114
118 if len(unused_elements): 115 if unused_elements:
119 print 'Found unused elements: %s\nRemove from bower.json and re-run ' \ 116 print 'Found unused elements: %s\nRemove from bower.json and re-run ' \
120 'reproduce.sh, or add to whitelist in %s' % ( 117 'reproduce.sh, or add to whitelist in %s' % (
121 ', '.join(unused_elements), os.path.basename(__file__)) 118 ', '.join(unused_elements), os.path.basename(__file__))
122 119
123 @staticmethod 120 def __IsImported(self, element_dir, dirs):
124 def __IsImported(element_dir, dirs):
125 """Returns whether the element directory is used in HTML or JavaScript. 121 """Returns whether the element directory is used in HTML or JavaScript.
126 122
127 Args: 123 Args:
128 element_dir: The name of the element's directory. 124 element_dir: The name of the element's directory.
129 dirs: The directories in which to check for usage. 125 dirs: The directories in which to check for usage.
130 126
131 Returns: 127 Returns:
132 True if the element's directory is used in |dirs|. 128 True if the element's directory is used in |dirs|.
133 """ 129 """
134 polymer_dir = os.path.dirname(os.path.realpath(__file__))
135 components_dir = os.path.join(polymer_dir, 'components-chromium')
136 for path in dirs: 130 for path in dirs:
137 # Find an import or script referencing the tag's directory. 131 # Find an import or script referencing the tag's directory.
138 for (dirpath, _, filenames) in os.walk(path): 132 for (dirpath, _, filenames) in os.walk(path):
139 # Ignore the element's own files. 133 # Ignore the element's own files.
140 if dirpath.startswith(os.path.join(components_dir, element_dir)): 134 if dirpath.startswith(os.path.join(
135 self.__COMPONENTS_DIR, element_dir)):
141 continue 136 continue
142 137
143 for filename in filenames: 138 for filename in filenames:
144 if not filename.endswith('.html') and not filename.endswith('.js'): 139 if not filename.endswith('.html') and not filename.endswith('.js'):
145 continue 140 continue
146 141
147 # Skip generated files that may include the element source. 142 # Skip generated files that may include the element source.
148 if filename in ('crisper.js', 'vulcanized.html'): 143 if filename in ('crisper.js', 'vulcanized.html'):
149 continue 144 continue
150 145
151 with open(os.path.join(dirpath, filename)) as f: 146 with open(os.path.join(dirpath, filename)) as f:
152 text = f.read() 147 text = f.read()
153 if not re.search('/%s/' % element_dir, text): 148 if not re.search('/%s/' % element_dir, text):
154 continue 149 continue
155 150
156 # Check the file again, ignoring comments (e.g. example imports and 151 # Check the file again, ignoring comments (e.g. example imports and
157 # scripts). 152 # scripts).
158 if re.search('/%s' % element_dir, 153 if re.search('/%s' % element_dir,
159 UnusedElementsDetector.__StripComments( 154 self.__StripComments(
160 os.path.join(dirpath, filename))): 155 os.path.join(dirpath, filename))):
161 return True 156 return True
162 return False 157 return False
163 158
164 159
165 UnusedElementsDetector.Run() 160 if __name__ == '__main__':
161 UnusedElementsDetector().Run()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698