Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /// This script should be run by every project that consumes Mojom IDL | 5 /// This script should be run by every project that consumes Mojom IDL |
| 6 /// interfaces. It populates the 'mojom' package with the generated Dart | 6 /// interfaces. It populates the 'mojom' package with the generated Dart |
| 7 /// bindings for the Mojom IDL files. | 7 /// bindings for the Mojom IDL files. |
| 8 /// | 8 /// |
| 9 /// From a consuming project, it should be invoked as follows: | 9 /// From a consuming project, it should be invoked as follows: |
| 10 /// | 10 /// |
| 11 /// $ dart packages/mojom/generate.dart [-p package-root] | 11 /// $ dart packages/mojom/generate.dart [-p package-root] |
| 12 /// [-a additional-dirs] | 12 /// [-a additional-dirs] |
| 13 /// [-m mojo-sdk] | 13 /// [-m mojo-sdk] |
| 14 /// [-g] # Generate from .mojom files | 14 /// [-g] # Generate from .mojom files |
| 15 /// [-d] # Download from .mojoms files | |
| 15 /// [-v] # verbose | 16 /// [-v] # verbose |
| 16 /// [-d] # Dry run | 17 /// [-f] # Fake (dry) run |
| 18 | |
| 19 library generate; | |
| 17 | 20 |
| 18 import 'dart:async'; | 21 import 'dart:async'; |
| 22 import 'dart:convert'; | |
| 19 import 'dart:io'; | 23 import 'dart:io'; |
| 20 | 24 |
| 21 import 'package:args/args.dart' as args; | 25 import 'package:args/args.dart' as args; |
| 22 import 'package:path/path.dart' as path; | 26 import 'package:path/path.dart' as path; |
| 23 | 27 |
| 28 part 'src/utils.dart'; | |
| 29 | |
| 24 bool verbose; | 30 bool verbose; |
| 25 bool dryRun; | 31 bool dryRun; |
| 26 | 32 |
| 27 bool isMojomDart(String path) => path.endsWith('.mojom.dart'); | |
| 28 bool isMojom(String path) => path.endsWith('.mojom'); | |
| 29 | |
| 30 /// An Error for problems on the command line. | |
| 31 class CommandLineError extends Error { | |
| 32 final _msg; | |
| 33 CommandLineError(this._msg); | |
| 34 toString() => _msg; | |
| 35 } | |
| 36 | |
| 37 /// An Error for failures of the bindings generation script. | |
| 38 class GenerationError extends Error { | |
| 39 final _msg; | |
| 40 GenerationError(this._msg); | |
| 41 toString() => _msg; | |
| 42 } | |
| 43 | |
| 44 /// The base type of data passed to actions for [mojomDirIter]. | |
| 45 class PackageIterData { | |
| 46 final Directory _mojomPackage; | |
| 47 PackageIterData(this._mojomPackage); | |
| 48 Directory get mojomPackage => _mojomPackage; | |
| 49 } | |
| 50 | |
| 51 /// Data for [mojomDirIter] that includes the path to the Mojo SDK for bindings | |
| 52 /// generation. | |
| 53 class GenerateIterData extends PackageIterData { | |
| 54 final Directory _mojoSdk; | |
| 55 GenerateIterData(this._mojoSdk, Directory mojomPackage) | |
| 56 : super(mojomPackage); | |
| 57 Directory get mojoSdk => _mojoSdk; | |
| 58 } | |
| 59 | |
| 60 /// The type of action performed by [mojomDirIter]. | |
| 61 typedef Future MojomAction(PackageIterData data, Directory mojomDirectory); | |
| 62 | |
| 63 /// Iterates over mojom directories of Dart packages, taking some action for | |
| 64 /// each. | |
| 65 /// | |
| 66 /// For each 'mojom' subdirectory of each subdirectory in [packages], runs | |
| 67 /// [action] on the subdirectory passing along [data] to [action]. | |
| 68 mojomDirIter( | |
| 69 Directory packages, PackageIterData data, MojomAction action) async { | |
| 70 await for (var package in packages.list()) { | |
| 71 if (package is Directory) { | |
| 72 if (package.path == data.mojomPackage.path) continue; | |
| 73 if (verbose) print("package = $package"); | |
| 74 final mojomDirectory = new Directory(path.join(package.path, 'mojom')); | |
| 75 if (verbose) print("looking for = $mojomDirectory"); | |
| 76 if (await mojomDirectory.exists()) { | |
| 77 await action(data, mojomDirectory); | |
| 78 } else if (verbose) { | |
| 79 print("$mojomDirectory not found"); | |
| 80 } | |
| 81 } | |
| 82 } | |
| 83 } | |
| 84 | |
| 85 | |
| 86 /// Searches for .mojom.dart files under [mojomDirectory] and copies them to | 33 /// Searches for .mojom.dart files under [mojomDirectory] and copies them to |
| 87 /// the 'mojom' packages. | 34 /// the 'mojom' packages. |
| 88 copyAction(PackageIterData data, Directory mojomDirectory) async { | 35 copyAction(PackageIterData data, Directory mojomDirectory) async { |
| 89 await for (var mojom in mojomDirectory.list(recursive: true)) { | 36 await for (var mojom in mojomDirectory.list(recursive: true)) { |
| 90 if (mojom is! File) continue; | 37 if (mojom is! File) continue; |
| 91 if (!isMojomDart(mojom.path)) continue; | 38 if (!isMojomDart(mojom.path)) continue; |
| 92 if (verbose) print("Found $mojom"); | 39 if (verbose) print("Found $mojom"); |
| 93 | 40 |
| 94 final relative = path.relative(mojom.path, from: mojomDirectory.path); | 41 final relative = path.relative(mojom.path, from: mojomDirectory.path); |
| 95 final dest = path.join(data.mojomPackage.path, relative); | 42 final dest = path.join(data.mojomPackage.path, relative); |
| 96 final destDirectory = new Directory(path.dirname(dest)); | 43 final destDirectory = new Directory(path.dirname(dest)); |
| 97 | 44 |
| 98 if (verbose || dryRun) { | 45 if (verbose || dryRun) { |
| 99 print('Copying $mojom to $dest'); | 46 print('Copying $mojom to $dest'); |
| 100 } | 47 } |
| 101 | 48 |
| 102 if (!dryRun) { | 49 if (!dryRun) { |
| 103 final File source = new File(mojom.path); | 50 final File source = new File(mojom.path); |
| 104 if (verbose) print("Ensuring $destDirectory exists"); | 51 if (verbose) print("Ensuring $destDirectory exists"); |
| 105 await destDirectory.create(recursive: true); | 52 await destDirectory.create(recursive: true); |
| 106 source.copy(dest); | 53 source.copy(dest); |
| 107 } | 54 } |
| 108 } | 55 } |
| 109 } | 56 } |
| 110 | 57 |
| 111 | |
| 112 /// Searches for .mojom files under [mojomDirectory], generates .mojom.dart | 58 /// Searches for .mojom files under [mojomDirectory], generates .mojom.dart |
| 113 /// files for them, and copies them to the 'mojom' package. | 59 /// files for them, and copies them to the 'mojom' package. |
| 114 generateAction(GenerateIterData data, Directory mojomDirectory) async { | 60 generateAction(GenerateIterData data, Directory mojomDirectory) async { |
| 115 await for (var mojom in mojomDirectory.list(recursive: true)) { | 61 await for (var mojom in mojomDirectory.list(recursive: true)) { |
| 116 if (mojom is! File) continue; | 62 if (mojom is! File) continue; |
| 117 if (!isMojom(mojom.path)) continue; | 63 if (!isMojom(mojom.path)) continue; |
| 118 if (verbose) print("Found $mojom"); | 64 if (verbose) print("Found $mojom"); |
| 119 | 65 |
| 120 final script = path.join(data.mojoSdk.path, | 66 final script = path.join(data.mojoSdk.path, |
| 121 'mojo', 'public', 'tools', 'bindings', 'mojom_bindings_generator.py'); | 67 'tools', 'bindings', 'mojom_bindings_generator.py'); |
| 68 final sdkInc = path.normalize(path.join(data.mojoSdk.path, '..', '..')); | |
| 122 final outputDir = await data.mojomPackage.createTemp(); | 69 final outputDir = await data.mojomPackage.createTemp(); |
| 123 final output = outputDir.path; | 70 final output = outputDir.path; |
| 124 final arguments = [ | 71 final arguments = [ |
| 125 '--use_bundled_pylibs', | 72 '--use_bundled_pylibs', |
| 73 '-g', 'dart', | |
| 126 '-o', output, | 74 '-o', output, |
| 127 // TODO(zra): Are other include paths needed? | 75 // TODO(zra): Are other include paths needed? |
| 128 '-I', data.mojoSdk.path, | 76 '-I', sdkInc, |
| 129 '-I', mojomDirectory.path, | 77 '-I', mojomDirectory.path, |
| 130 mojom.path]; | 78 mojom.path]; |
| 131 | 79 |
| 132 if (verbose || dryRun) { | 80 if (verbose || dryRun) { |
| 133 print('Generating $mojom'); | 81 print('Generating $mojom'); |
| 134 print('$script ${arguments.join(" ")}'); | 82 print('$script ${arguments.join(" ")}'); |
| 135 } | 83 } |
| 136 if (!dryRun) { | 84 if (!dryRun) { |
| 137 final result = await Process.run(script, arguments); | 85 final result = await Process.run(script, arguments); |
| 138 if (result.exitCode != 0) { | 86 if (result.exitCode != 0) { |
| 139 throw new GenerationError("$script failed:\n${result.stderr}"); | 87 throw new GenerationError("$script failed:\n${result.stderr}"); |
| 140 } | 88 } |
| 141 // Generated .mojom.dart is under $output/dart-gen/mojom/lib/X | 89 // Generated .mojom.dart is under $output/dart-gen/mojom/lib/X |
| 142 // Move X to $mojomPackage. Then rm -rf $output | 90 // Move X to $mojomPackage. Then rm -rf $output |
| 143 final generatedDirName = path.join(output, 'dart-gen', 'mojom', 'lib'); | 91 final generatedDirName = path.join(output, 'dart-gen', 'mojom', 'lib'); |
| 144 final generatedDir = new Directory(generatedDirName); | 92 final generatedDir = new Directory(generatedDirName); |
| 145 | 93 |
| 146 await copyAction(data, generatedDir); | 94 await copyAction(data, generatedDir); |
| 147 | 95 |
| 148 await outputDir.delete(recursive: true); | 96 await outputDir.delete(recursive: true); |
| 149 } | 97 } |
| 150 } | 98 } |
| 151 } | 99 } |
| 152 | 100 |
| 101 /// In each package, look for a file named .mojoms. Populate a package's | |
| 102 /// mojom direcoty with the downloaded mojoms, creating the directory if needed. | |
|
Cutch
2015/07/20 15:39:09
direcoty -> directory
zra
2015/07/20 21:09:05
Done.
| |
| 103 /// The .mojoms file should be formatted as follows: | |
| 104 /// ''' | |
| 105 /// root: https://www.example.com/mojoms | |
|
Cutch
2015/07/20 15:39:08
Why use a stateful format over a list of uris?
zra
2015/07/20 21:09:05
Related mojoms can import each other. The conventi
| |
| 106 /// path/to/some/mojom1.mojom | |
| 107 /// path/to/some/other/mojom2.mojom | |
| 108 /// | |
| 109 /// root: https://www.example-two.com/mojoms | |
| 110 /// path/to/example/two/mojom1.mojom | |
| 111 /// ... | |
| 112 /// | |
| 113 /// Lines beginning with '#' are ignored. | |
| 114 downloadAction(GenerateIterData data, Directory packageDirectory) async { | |
| 115 var mojomsPath = path.join(packageDirectory.path, '.mojoms'); | |
| 116 var mojomsFile = new File(mojomsPath); | |
| 117 if (!await mojomsFile.exists()) return; | |
| 118 if (verbose) print("Found .mojoms file: $mojomsPath"); | |
| 119 | |
| 120 Directory mojomsDir; | |
| 121 var httpClient = new HttpClient(); | |
| 122 int repoCount = 0; | |
| 123 int mojomCount = 0; | |
| 124 String repoRoot; | |
| 125 for (String line in await mojomsFile.readAsLines()) { | |
| 126 if (line.isEmpty || line.startsWith('#')) continue; | |
|
Cutch
2015/07/20 15:39:08
strip leading whitespace?
zra
2015/07/20 21:09:05
Done.
| |
| 127 | |
| 128 if (line.startsWith('root:')) { | |
| 129 if ((mojomsDir != null) && (mojomCount == 0)) { | |
| 130 throw new DownloadError("root with no mojoms: $repoRoot"); | |
| 131 } | |
| 132 mojomCount = 0; | |
| 133 var rootWords = line.split(" "); | |
| 134 if (rootWords.length != 2) { | |
| 135 throw new DownloadError("Malformed root: $line"); | |
| 136 } | |
| 137 repoRoot = rootWords[1]; | |
| 138 if (verbose) print("Found repo root: $repoRoot"); | |
| 139 if (!repoRoot.startsWith('https://')) { | |
|
Cutch
2015/07/20 15:39:08
What if I want to use http?
zra
2015/07/20 21:09:05
Removed restriction as discussed.
| |
| 140 throw new DownloadError( | |
| 141 'Mojom repo "root" should be an https URL: $line'); | |
| 142 } | |
| 143 mojomsDir = new Directory(path.join( | |
| 144 packageDirectory.parent.path, 'mojm.repo.$repoCount', 'mojom')); | |
| 145 await mojomsDir.create(recursive: true); | |
| 146 repoCount++; | |
| 147 } else { | |
| 148 if (mojomsDir == null) { | |
| 149 throw new DownloadError('Malformed .mojoms file: $mojomsPath'); | |
| 150 } | |
| 151 String url = "$repoRoot/$line"; | |
| 152 if (verbose) print("Found $url"); | |
| 153 String fileString = await getUrl(httpClient, url); | |
| 154 if (verbose) print("Downloaded $url"); | |
| 155 String filePath = path.join(mojomsDir.path, line); | |
| 156 var file = new File(filePath); | |
| 157 if (!await file.exists()) { | |
| 158 await file.create(recursive: true); | |
| 159 await file.writeAsString(fileString); | |
| 160 if (verbose) print("Wrote $filePath"); | |
| 161 } | |
| 162 mojomCount++; | |
| 163 } | |
| 164 } | |
| 165 } | |
| 153 | 166 |
| 154 /// Ensures that the directories in [additionalPaths] are absolute and exist, | 167 /// Ensures that the directories in [additionalPaths] are absolute and exist, |
| 155 /// and creates Directories for them, which are returned. | 168 /// and creates Directories for them, which are returned. |
| 156 validateAdditionalDirs(Iterable additionalPaths) async { | 169 Future<List<Directory>> validateAdditionalDirs(Iterable additionalPaths) async { |
| 157 var additionalDirs = []; | 170 var additionalDirs = []; |
| 158 for (var mojomPath in additionalPaths) { | 171 for (var mojomPath in additionalPaths) { |
| 159 final mojomDir = new Directory(mojomPath); | 172 final mojomDir = new Directory(mojomPath); |
| 160 if (!mojomDir.isAbsolute) { | 173 if (!mojomDir.isAbsolute) { |
| 161 throw new CommandLineError( | 174 throw new CommandLineError( |
| 162 "All --additional-mojom-dir parameters must be absolute paths."); | 175 "All --additional-mojom-dir parameters must be absolute paths."); |
| 163 } | 176 } |
| 164 if (!(await mojomDir.exists())) { | 177 if (!(await mojomDir.exists())) { |
| 165 throw new CommandLineError( | 178 throw new CommandLineError( |
| 166 "The additional mojom directory $mojomDir must exist"); | 179 "The additional mojom directory $mojomDir must exist"); |
| 167 } | 180 } |
| 168 additionalDirs.add(mojomDir); | 181 additionalDirs.add(mojomDir); |
| 169 } | 182 } |
| 170 if (verbose) print("additional_mojom_dirs = $additionalDirs"); | 183 if (verbose) print("additional_mojom_dirs = $additionalDirs"); |
| 171 return additionalDirs; | 184 return additionalDirs; |
| 172 } | 185 } |
| 173 | 186 |
| 187 class GenerateOptions { | |
| 188 final Directory packages; | |
| 189 final Directory mojomPackage; | |
| 190 final Directory mojoSdk; | |
| 191 final List<Directory> additionalDirs; | |
| 192 final bool download; | |
| 193 final bool generate; | |
| 194 GenerateOptions( | |
| 195 this.packages, this.mojomPackage, this.mojoSdk, this.additionalDirs, | |
| 196 this.download, this.generate); | |
| 197 } | |
| 174 | 198 |
| 175 main(List<String> arguments) async { | 199 Future<GenerateOptions> parseArguments(List<String> arguments) async { |
| 176 final parser = new args.ArgParser() | 200 final parser = new args.ArgParser() |
| 177 ..addOption('additional-mojom-dir', | 201 ..addOption('additional-mojom-dir', |
| 178 abbr: 'a', | 202 abbr: 'a', |
| 179 allowMultiple: true, | 203 allowMultiple: true, |
| 180 help: 'Absolute path to an additional directory containing mojom.dart' | 204 help: 'Absolute path to an additional directory containing mojom.dart' |
| 181 'files to put in the mojom package. May be specified multiple times.') | 205 'files to put in the mojom package. May be specified multiple times.') |
| 182 ..addFlag('dry-run', | 206 ..addFlag('download', |
| 183 abbr: 'd', | 207 abbr: 'd', |
| 184 defaultsTo: false, | 208 defaultsTo: false, |
| 185 help: 'Print the copy operations that would have been run, but' | 209 help: 'Searches packages for a .mojoms file, and downloads .mojom files' |
| 186 'do not copy anything.') | 210 'as speficied in that file. Implies -g.') |
| 211 ..addFlag('fake', | |
| 212 abbr: 'f', | |
| 213 defaultsTo: false, | |
| 214 help: 'Print the operations that would have been run, but' | |
| 215 'do not run anything.') | |
| 187 ..addFlag('generate', | 216 ..addFlag('generate', |
| 188 abbr: 'g', | 217 abbr: 'g', |
| 189 defaultsTo: false, | 218 defaultsTo: false, |
| 190 help: 'Generate Dart bindings for .mojom files.') | 219 help: 'Generate Dart bindings for .mojom files.') |
| 191 ..addOption('mojo-sdk', | 220 ..addOption('mojo-sdk', |
| 192 abbr: 'm', | 221 abbr: 'm', |
| 193 defaultsTo: Platform.environment['MOJO_SDK'], | 222 defaultsTo: Platform.environment['MOJO_SDK'], |
| 194 help: 'Absolute path to the Mojo SDK, which can also be specified ' | 223 help: 'Absolute path to the Mojo SDK, which can also be specified ' |
| 195 'with the environment variable MOJO_SDK.') | 224 'with the environment variable MOJO_SDK.') |
| 196 ..addOption('package-root', | 225 ..addOption('package-root', |
| 197 abbr: 'p', | 226 abbr: 'p', |
| 198 defaultsTo: path.join(Directory.current.path, 'packages'), | 227 defaultsTo: path.join(Directory.current.path, 'packages'), |
| 199 help: 'An absolute path to an application\'s package root') | 228 help: 'An absolute path to an application\'s package root') |
| 200 ..addFlag('verbose', abbr: 'v', defaultsTo: false); | 229 ..addFlag('verbose', abbr: 'v', defaultsTo: false); |
| 201 final result = parser.parse(arguments); | 230 final result = parser.parse(arguments); |
| 202 verbose = result['verbose']; | 231 verbose = result['verbose']; |
| 203 dryRun = result['dry-run']; | 232 dryRun = result['fake']; |
| 204 | 233 |
| 205 final packages = new Directory(result['package-root']); | 234 final packages = new Directory(result['package-root']); |
| 206 if (!packages.isAbsolute) { | 235 if (!packages.isAbsolute) { |
| 207 throw new CommandLineError( | 236 throw new CommandLineError( |
| 208 "The --package-root parameter must be an absolute path."); | 237 "The --package-root parameter must be an absolute path."); |
| 209 } | 238 } |
| 210 if (verbose) print("packages = $packages"); | 239 if (verbose) print("packages = $packages"); |
| 211 if (!(await packages.exists())) { | 240 if (!(await packages.exists())) { |
| 212 throw new CommandLineError( | 241 throw new CommandLineError( |
| 213 "The packages directory $packages must exist"); | 242 "The packages directory $packages must exist"); |
| 214 } | 243 } |
| 215 | 244 |
| 216 final mojomPackage = new Directory(path.join(packages.path, 'mojom')); | 245 final mojomPackage = new Directory(path.join(packages.path, 'mojom')); |
| 217 if (verbose) print("mojom package = $mojomPackage"); | 246 if (verbose) print("mojom package = $mojomPackage"); |
| 218 if (!(await mojomPackage.exists())) { | 247 if (!(await mojomPackage.exists())) { |
| 219 throw new CommandLineError( | 248 throw new CommandLineError( |
| 220 "The mojom package directory $mojomPackage must exist"); | 249 "The mojom package directory $mojomPackage must exist"); |
| 221 } | 250 } |
| 222 | 251 |
| 223 final generate = result['generate']; | 252 final download = result['download']; |
| 253 final generate = result['generate'] || download; | |
| 224 var mojoSdk = null; | 254 var mojoSdk = null; |
| 225 if (generate) { | 255 if (generate) { |
| 226 final mojoSdkPath = result['mojo-sdk']; | 256 final mojoSdkPath = result['mojo-sdk']; |
| 227 if (mojoSdkPath == null) { | 257 if (mojoSdkPath == null) { |
| 228 throw new CommandLineError( | 258 throw new CommandLineError( |
| 229 "The Mojo SDK directory must be specified with the --mojo-sdk flag or" | 259 "The Mojo SDK directory must be specified with the --mojo-sdk flag or" |
| 230 "the MOJO_SDK environment variable."); | 260 "the MOJO_SDK environment variable."); |
| 231 } | 261 } |
| 232 mojoSdk = new Directory(mojoSdkPath); | 262 mojoSdk = new Directory(mojoSdkPath); |
| 233 if (verbose) print("Mojo SDK = $mojoSdk"); | 263 if (verbose) print("Mojo SDK = $mojoSdk"); |
| 234 if (!(await mojoSdk.exists())) { | 264 if (!(await mojoSdk.exists())) { |
| 235 throw new CommandLineError( | 265 throw new CommandLineError( |
| 236 "The specified Mojo SDK directory $mojoSdk must exist."); | 266 "The specified Mojo SDK directory $mojoSdk must exist."); |
| 237 } | 267 } |
| 238 } | 268 } |
| 239 | 269 |
| 240 await mojomDirIter(packages, new PackageIterData(mojomPackage), copyAction); | |
| 241 if (generate) { | |
| 242 await mojomDirIter(packages, new GenerateIterData(mojoSdk, mojomPackage), | |
| 243 generateAction); | |
| 244 } | |
| 245 | |
| 246 final additionalDirs = | 270 final additionalDirs = |
| 247 await validateAdditionalDirs(result['additional-mojom-dir']); | 271 await validateAdditionalDirs(result['additional-mojom-dir']); |
| 248 final data = new GenerateIterData(mojoSdk, mojomPackage); | 272 |
| 249 for (var mojomDir in additionalDirs) { | 273 return new GenerateOptions( |
| 274 packages, mojomPackage, mojoSdk, additionalDirs, download, generate); | |
| 275 } | |
| 276 | |
| 277 main(List<String> arguments) async { | |
| 278 var options = await parseArguments(arguments); | |
| 279 | |
| 280 // Copy any pregenerated files form packages. | |
| 281 await mojomDirIter( | |
| 282 options.packages, | |
| 283 new PackageIterData(options.mojomPackage), | |
| 284 copyAction); | |
| 285 | |
| 286 // Download .mojom files. These will be picked up by the generation step | |
| 287 // below. | |
| 288 if (options.download) { | |
| 289 await packageDirIter(options.packages, null, downloadAction); | |
| 290 } | |
| 291 | |
| 292 // Generate mojom files. | |
| 293 if (options.generate) { | |
| 294 await mojomDirIter( | |
| 295 options.packages, | |
| 296 new GenerateIterData(options.mojoSdk, options.mojomPackage), | |
| 297 generateAction); | |
| 298 } | |
| 299 | |
| 300 // Copy pregenerated files from specified external directories. | |
| 301 final data = new GenerateIterData(options.mojoSdk, options.mojomPackage); | |
| 302 for (var mojomDir in options.additionalDirs) { | |
| 250 await copyAction(data, mojomDir); | 303 await copyAction(data, mojomDir); |
| 251 if (generate) { | 304 if (options.generate) { |
| 252 await generateAction(data, mojomDir); | 305 await generateAction(data, mojomDir); |
| 253 } | 306 } |
| 254 } | 307 } |
| 255 } | 308 } |
| OLD | NEW |