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

Side by Side Diff: mojo/dart/tools/presubmit/check_mojom_dart.py

Issue 1449203002: Check in generated Dart bindings and add presubmit script (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 1 month 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 #!/usr/bin/env python
2 # Copyright 2015 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """Checks that released mojom.dart files in the source tree are up to date"""
7
8 import os
9 import subprocess
10 import sys
11
12 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
13 SRC_DIR = os.path.dirname(
14 os.path.dirname(
15 os.path.dirname(
16 os.path.dirname(SCRIPT_DIR))))
17
18 PACKAGES_DIR = os.path.join(SRC_DIR, 'mojo', 'dart', 'packages')
19
20 # Script that calculates mojom output paths.
21 DART_OUTPUTS_SCRIPT = os.path.join(SRC_DIR,
22 'mojo',
23 'public',
24 'tools',
25 'bindings',
26 'mojom_list_dart_outputs.py')
27
28 # Runs command line in args from cwd. Returns the output as a string.
29 def run(cwd, args):
30 return subprocess.check_output(args, cwd=cwd)
31
32
33 def _print_regenerate_message(package):
34 print('*** Dart Generated Bindings Check Failed:')
jamesr 2015/11/17 01:35:07 this is a good place to use python's """, i.e. pr
Cutch 2015/11/17 18:17:15 Done.
35 print('You must regenerate bindings for %s.' % package)
36 print('From the src directory, run:')
37 print('$ dart mojo/dart/packages/mojom/bin/mojom.dart gen -m mojo/public ' +
38 '-r mojo/ --output mojo/dart/packages/');
39
40
41 # Returns a map from package name to source directory.
42 def _build_package_map():
43 packages = {}
44 for package in os.listdir(PACKAGES_DIR):
45 package_path = os.path.join(PACKAGES_DIR, package)
46 # Skip everything but directories.
47 if not os.path.isdir(package_path):
48 continue
49 packages[package] = package_path
50 return packages
51
52
53 # Returns a list of paths to .mojom files vended by package_name.
54 def _find_mojoms_for_package(package_name):
55 # Run git grep for all .mojom files with DartPackage="package_name"
56 try:
57 output = run(SRC_DIR, ['git',
58 'grep',
59 '--name-only',
60 'DartPackage="' + package_name + '"',
61 '--',
62 '*.mojom'])
63 except subprocess.CalledProcessError as e:
64 # git grep exits with code 1 if nothing was found.
65 if e.returncode == 1:
66 return []
67
68 # Process output
69 mojoms = []
70 for line in output.splitlines():
71 line = line.strip()
72 # Skip empty lines.
73 if not line:
74 continue
75 mojoms.append(line)
76 return mojoms
77
78
79 # Return the list of expected mojom.dart files for a package.
80 def _expected_mojom_darts_for_package(mojoms):
81 output = run(SRC_DIR, ['python',
82 DART_OUTPUTS_SCRIPT,
83 '--mojoms'] + mojoms)
84 mojom_darts = []
85 for line in output.splitlines():
86 line = line.strip()
87 # Skip empty lines.
88 if not line:
89 continue
90 mojom_darts.append(line)
91 return mojom_darts
92
93
94 # Returns a map indexed by output mojom.dart name with the value of
95 # the modification time of the .mojom file in the source tree.
96 def _build_expected_map(mojoms, mojom_darts):
97 assert(len(mojom_darts) == len(mojoms))
98 expected = {}
99 for i in range(0, len(mojoms)):
100 mojom_path = os.path.join(SRC_DIR, mojoms[i])
101 expected[mojom_darts[i]] = os.path.getmtime(mojom_path)
102 return expected
103
104
105 # Returns a map indexed by output mojom.dart name with the value of
106 # the modification time of the .mojom.dart file in the source tree.
107 def _build_current_map(package):
108 current = {}
109 package_path = os.path.join(PACKAGES_DIR, package)
110 for directory, _, files in os.walk(package_path):
111 for filename in files:
112 if filename.endswith('.mojom.dart'):
113 path = os.path.abspath(os.path.join(directory, filename))
114 relpath = os.path.relpath(path, start=PACKAGES_DIR)
115 current[relpath] = os.path.getmtime(path)
116 return current
117
118
119 # Checks if a mojom.dart file we expected in the source tree isn't there.
120 def _check_new(package, expected, current):
121 checkFailure = False
122 for mojom_dart in expected:
123 if not current.get(mojom_dart):
124 print("Package %s missing %s" % (package, mojom_dart))
125 checkFailure = True
126 return checkFailure
127
128
129 # Checks if a mojom.dart file exists without an associated .mojom file.
130 def _check_delete(package, expected, current):
131 checkFailure = False
132 for mojom_dart in current:
133 if not expected.get(mojom_dart):
134 print("Package %s no longer has %s." % (package, mojom_dart))
135 print("Delete %s", os.path.join(PACKAGES_DIR, mojom_dart))
136 checkFailure = True
137 return checkFailure
138
139
140 # Checks if a .mojom.dart file is older than the associated .mojom file.
141 # TODO(johnmccutchan): Handle the case where someone edited a .mojom.dart file
142 # directly instead of through the bindings generation script.
143 def _check_stale(package, expected, current):
144 checkFailure = False
145 for mojom_dart in expected:
jamesr 2015/11/17 01:35:07 the mix of hacker_style and camelCase is confusing
Cutch 2015/11/17 18:17:15 Done. I was switching between Dart and Python yest
146 # Missing mojom.dart file in source tree case handled by _check_new.
147 source_mtime = expected[mojom_dart]
148 if not current.get(mojom_dart):
149 continue
150 generated_mtime = current[mojom_dart]
151 if generated_mtime < source_mtime:
152 print("Package %s has old %s" % (package, mojom_dart))
153 checkFailure = True
154 return checkFailure
155
156
157 # Returns True if any checks fail.
158 def _check(package, expected, current):
159 checkFailure = False
160 if _check_new(package, expected, current):
161 checkFailure = True
162 if _check_stale(package, expected, current):
163 checkFailure = True
164 if _check_delete(package, expected, current):
165 checkFailure = True
166 # No check failures.
167 return checkFailure
168
169 def main():
170 packages = _build_package_map()
171 checkFailed = False
172 for package in packages:
173 mojoms = _find_mojoms_for_package(package)
174 if not mojoms:
175 continue
176 mojom_darts = _expected_mojom_darts_for_package(mojoms)
177 # We only feed in mojom files with DartPackage annotations, therefore, we
178 # should have a 1:1 mapping from mojoms[i] to mojom_darts[i].
179 assert(len(mojom_darts) == len(mojoms))
180 expected = _build_expected_map(mojoms, mojom_darts)
181 current = _build_current_map(package)
182 if _check(package, expected, current):
183 _print_regenerate_message(package)
184 checkFailed = True
185 if checkFailed:
186 sys.exit(2)
187 print('OK.')
188 sys.exit(0)
189
190 if __name__ == '__main__':
191 sys.exit(main())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698