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

Side by Side Diff: mojo/dart/mojom/lib/generate.dart

Issue 1318903005: Move mojom to public/dart (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 3 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 | « mojo/dart/mojom/lib/README.md ('k') | mojo/dart/mojom/lib/src/options.dart » ('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 2015 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 /// This script generates Mojo bindings for a Dart package. See README.md for
6 /// details.
7
8 library generate;
9
10 import 'dart:async';
11 import 'dart:convert';
12 import 'dart:io';
13
14 import 'package:args/args.dart' as args;
15 import 'package:path/path.dart' as path;
16
17 part 'src/options.dart';
18 part 'src/utils.dart';
19
20 bool errorOnDuplicate;
21 bool verbose;
22 bool dryRun;
23 Map<String, String> duplicateDetection;
24
25 /// Searches for .mojom.dart files under [mojomDirectory] and copies them to
26 /// [data.currentPackage].
27 copyAction(PackageIterData data, Directory mojomDirectory) async {
28 await for (var mojom in mojomDirectory.list(recursive: true)) {
29 if (mojom is! File) continue;
30 if (!isMojomDart(mojom.path)) continue;
31 if (verbose) print("Found $mojom");
32
33 final relative = path.relative(mojom.path, from: mojomDirectory.path);
34 final dest = path.join(data.currentPackage.path, relative);
35 final destDirectory = new Directory(path.dirname(dest));
36
37 if (errorOnDuplicate && duplicateDetection.containsKey(dest)) {
38 String original = duplicateDetection[dest];
39 throw new GenerationError(
40 'Conflict: Both ${original} and ${mojom.path} supply ${dest}');
41 }
42 duplicateDetection[dest] = mojom.path;
43
44 if (verbose || dryRun) {
45 print('Copying $mojom to $dest');
46 }
47
48 if (!dryRun) {
49 final File source = new File(mojom.path);
50 if (verbose) print("Ensuring $destDirectory exists");
51 await destDirectory.create(recursive: true);
52 source.copy(dest);
53 }
54 }
55 }
56
57 /// Searches for .mojom files under [mojomDirectory], generates .mojom.dart
58 /// files for them, and copies them to the 'mojom' package.
59 generateAction(GenerateIterData data, Directory mojomDirectory) async {
60 final packageRoot = data.currentPackage.parent;
61 await for (var mojom in mojomDirectory.list(recursive: true)) {
62 if (mojom is! File) continue;
63 if (!isMojom(mojom.path)) continue;
64 if (verbose) print("Found $mojom");
65
66 final script = path.join(
67 data.mojoSdk.path, 'tools', 'bindings', 'mojom_bindings_generator.py');
68 final sdkInc = path.normalize(path.join(data.mojoSdk.path, '..', '..'));
69 final outputDir = await data.currentPackage.createTemp();
70 final output = outputDir.path;
71 final arguments = [
72 '--use_bundled_pylibs',
73 '-g',
74 'dart',
75 '-o',
76 output,
77 // TODO(zra): Are other include paths needed?
78 '-I',
79 sdkInc,
80 '-I',
81 mojomDirectory.path,
82 mojom.path
83 ];
84
85 if (verbose || dryRun) {
86 print('Generating $mojom');
87 print('$script ${arguments.join(" ")}');
88 }
89 if (!dryRun) {
90 final result = await Process.run(script, arguments);
91 if (result.exitCode != 0) {
92 throw new GenerationError("$script failed:\n${result.stderr}");
93 }
94
95 // Generated .mojom.dart is under $output/dart-pkg/$PACKAGE/lib/$X
96 // Move $X to $PACKAGE_ROOT/$PACKAGE/$X
97 final generatedDirName = path.join(output, 'dart-pkg');
98 final generatedDir = new Directory(generatedDirName);
99 await for (var genpack in generatedDir.list()) {
100 if (genpack is! Directory) continue;
101 var libDir = new Directory(path.join(genpack.path, 'lib'));
102 var name = path.relative(genpack.path, from: generatedDirName);
103 var copyData = new GenerateIterData(data.mojoSdk);
104 copyData.currentPackage =
105 new Directory(path.join(packageRoot.path, name));
106 await copyAction(copyData, libDir);
107 }
108
109 await outputDir.delete(recursive: true);
110 }
111 }
112 }
113
114 /// In each package, look for a file named .mojoms. Populate a package's
115 /// mojom directory with the downloaded mojoms, creating the directory if
116 /// needed. The .mojoms file should be formatted as follows:
117 /// '''
118 /// root: https://www.example.com/mojoms
119 /// path/to/some/mojom1.mojom
120 /// path/to/some/other/mojom2.mojom
121 ///
122 /// root: https://www.example-two.com/mojoms
123 /// path/to/example/two/mojom1.mojom
124 /// ...
125 ///
126 /// Lines beginning with '#' are ignored.
127 downloadAction(GenerateIterData _, Directory packageDirectory) async {
128 var mojomsPath = path.join(packageDirectory.path, '.mojoms');
129 var mojomsFile = new File(mojomsPath);
130 if (!await mojomsFile.exists()) return;
131 if (verbose) print("Found .mojoms file: $mojomsPath");
132
133 Directory mojomsDir;
134 var httpClient = new HttpClient();
135 int repoCount = 0;
136 int mojomCount = 0;
137 String repoRoot;
138 for (String line in await mojomsFile.readAsLines()) {
139 line = line.trim();
140 if (line.isEmpty || line.startsWith('#')) continue;
141
142 if (line.startsWith('root:')) {
143 if ((mojomsDir != null) && (mojomCount == 0)) {
144 throw new DownloadError("root with no mojoms: $repoRoot");
145 }
146 mojomCount = 0;
147 var rootWords = line.split(" ");
148 if (rootWords.length != 2) {
149 throw new DownloadError("Malformed root: $line");
150 }
151 repoRoot = rootWords[1];
152 if (verbose) print("Found repo root: $repoRoot");
153 if (!repoRoot.startsWith('http://') && !repoRoot.startsWith('https://')) {
154 throw new DownloadError(
155 'Mojom repo "root" should be an http or https URL: $line');
156 }
157 mojomsDir = new Directory(path.join(
158 packageDirectory.parent.path, 'mojm.repo.$repoCount', 'mojom'));
159 await mojomsDir.create(recursive: true);
160 repoCount++;
161 } else {
162 if (mojomsDir == null) {
163 throw new DownloadError('Malformed .mojoms file: $mojomsPath');
164 }
165 String url = "$repoRoot/$line";
166 if (verbose) print("Found $url");
167 String fileString = await getUrl(httpClient, url);
168 if (verbose) print("Downloaded $url");
169 String filePath = path.join(mojomsDir.path, line);
170 var file = new File(filePath);
171 if (!await file.exists()) {
172 await file.create(recursive: true);
173 await file.writeAsString(fileString);
174 if (verbose) print("Wrote $filePath");
175 }
176 mojomCount++;
177 }
178 }
179 }
180
181 /// The "mojom" entry in [packages] is a symbolic link to the mojom package in
182 /// the global pub cache directory. Because we might need to write package
183 /// specific .mojom.dart files into the mojom package, we need to make a local
184 /// copy of it.
185 copyMojomPackage(Directory packages) async {
186 var link = new Link(path.join(packages.path, "mojom"));
187 if (!await link.exists()) {
188 // If the "mojom" entry in packages is not a symbolic link, then do nothing.
189 return;
190 }
191
192 var realpath = await link.resolveSymbolicLinks();
193 var realDir = new Directory(realpath);
194 var mojomDir = new Directory(path.join(packages.path, "mojom"));
195
196 await link.delete();
197 await mojomDir.create();
198 await for (var file in realDir.list(recursive: true)) {
199 if (file is File) {
200 var relative = path.relative(file.path, from: realDir.path);
201 var destPath = path.join(mojomDir.path, relative);
202 var destDir = new Directory(path.dirname(destPath));
203 await destDir.create(recursive: true);
204 await file.copy(path.join(mojomDir.path, relative));
205 }
206 }
207 }
208
209 main(List<String> arguments) async {
210 var options = await parseArguments(arguments);
211 duplicateDetection = new Map<String, String>();
212 errorOnDuplicate = options.errorOnDuplicate;
213 verbose = options.verbose;
214 dryRun = options.dryRun;
215
216 // mojoms without a DartPackage annotation, and pregenerated mojoms from
217 // [options.additionalDirs] will go into the mojom package, so we make a local
218 // copy of it so we don't pollute the global pub cache.
219 //
220 // TODO(zra): Fail if a mojom has no DartPackage annotation, and remove the
221 // need for [options.additionalDirs].
222 if (!dryRun) {
223 await copyMojomPackage(options.packages);
224 }
225
226 // Download .mojom files. These will be picked up by the generation step
227 // below.
228 if (options.download) {
229 await packageDirIter(options.packages, null, downloadAction);
230 }
231
232 // Generate mojom files.
233 if (options.generate) {
234 await mojomDirIter(options.packages, new GenerateIterData(options.mojoSdk),
235 generateAction);
236 }
237
238 // TODO(zra): As mentioned above, this should go away.
239 // Copy pregenerated files from specified external directories into the
240 // mojom package.
241 final data = new GenerateIterData(options.mojoSdk);
242 data.currentPackage = options.mojomPackage;
243 for (var mojomDir in options.additionalDirs) {
244 await copyAction(data, mojomDir);
245 if (options.generate) {
246 await generateAction(data, mojomDir);
247 }
248 }
249 }
OLDNEW
« no previous file with comments | « mojo/dart/mojom/lib/README.md ('k') | mojo/dart/mojom/lib/src/options.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698