Chromium Code Reviews| Index: mojo/dart/mojom/lib/generate.dart |
| diff --git a/mojo/dart/mojom/lib/generate.dart b/mojo/dart/mojom/lib/generate.dart |
| index 82f71df1d1d0738e8ee306ecffaa5780f5614312..bef349264abcdc9a2475ca7a53faae2b8af077d3 100644 |
| --- a/mojo/dart/mojom/lib/generate.dart |
| +++ b/mojo/dart/mojom/lib/generate.dart |
| @@ -12,77 +12,24 @@ |
| /// [-a additional-dirs] |
| /// [-m mojo-sdk] |
| /// [-g] # Generate from .mojom files |
| +/// [-d] # Download from .mojoms files |
| /// [-v] # verbose |
| -/// [-d] # Dry run |
| +/// [-f] # Fake (dry) run |
| + |
| +library generate; |
| import 'dart:async'; |
| +import 'dart:convert'; |
| import 'dart:io'; |
| import 'package:args/args.dart' as args; |
| import 'package:path/path.dart' as path; |
| +part 'src/utils.dart'; |
| + |
| bool verbose; |
| bool dryRun; |
| -bool isMojomDart(String path) => path.endsWith('.mojom.dart'); |
| -bool isMojom(String path) => path.endsWith('.mojom'); |
| - |
| -/// An Error for problems on the command line. |
| -class CommandLineError extends Error { |
| - final _msg; |
| - CommandLineError(this._msg); |
| - toString() => _msg; |
| -} |
| - |
| -/// An Error for failures of the bindings generation script. |
| -class GenerationError extends Error { |
| - final _msg; |
| - GenerationError(this._msg); |
| - toString() => _msg; |
| -} |
| - |
| -/// The base type of data passed to actions for [mojomDirIter]. |
| -class PackageIterData { |
| - final Directory _mojomPackage; |
| - PackageIterData(this._mojomPackage); |
| - Directory get mojomPackage => _mojomPackage; |
| -} |
| - |
| -/// Data for [mojomDirIter] that includes the path to the Mojo SDK for bindings |
| -/// generation. |
| -class GenerateIterData extends PackageIterData { |
| - final Directory _mojoSdk; |
| - GenerateIterData(this._mojoSdk, Directory mojomPackage) |
| - : super(mojomPackage); |
| - Directory get mojoSdk => _mojoSdk; |
| -} |
| - |
| -/// The type of action performed by [mojomDirIter]. |
| -typedef Future MojomAction(PackageIterData data, Directory mojomDirectory); |
| - |
| -/// Iterates over mojom directories of Dart packages, taking some action for |
| -/// each. |
| -/// |
| -/// For each 'mojom' subdirectory of each subdirectory in [packages], runs |
| -/// [action] on the subdirectory passing along [data] to [action]. |
| -mojomDirIter( |
| - Directory packages, PackageIterData data, MojomAction action) async { |
| - await for (var package in packages.list()) { |
| - if (package is Directory) { |
| - if (package.path == data.mojomPackage.path) continue; |
| - if (verbose) print("package = $package"); |
| - final mojomDirectory = new Directory(path.join(package.path, 'mojom')); |
| - if (verbose) print("looking for = $mojomDirectory"); |
| - if (await mojomDirectory.exists()) { |
| - await action(data, mojomDirectory); |
| - } else if (verbose) { |
| - print("$mojomDirectory not found"); |
| - } |
| - } |
| - } |
| -} |
| - |
| - |
| /// Searches for .mojom.dart files under [mojomDirectory] and copies them to |
| /// the 'mojom' packages. |
| copyAction(PackageIterData data, Directory mojomDirectory) async { |
| @@ -108,7 +55,6 @@ copyAction(PackageIterData data, Directory mojomDirectory) async { |
| } |
| } |
| - |
| /// Searches for .mojom files under [mojomDirectory], generates .mojom.dart |
| /// files for them, and copies them to the 'mojom' package. |
| generateAction(GenerateIterData data, Directory mojomDirectory) async { |
| @@ -118,14 +64,16 @@ generateAction(GenerateIterData data, Directory mojomDirectory) async { |
| if (verbose) print("Found $mojom"); |
| final script = path.join(data.mojoSdk.path, |
| - 'mojo', 'public', 'tools', 'bindings', 'mojom_bindings_generator.py'); |
| + 'tools', 'bindings', 'mojom_bindings_generator.py'); |
| + final sdkInc = path.normalize(path.join(data.mojoSdk.path, '..', '..')); |
| final outputDir = await data.mojomPackage.createTemp(); |
| final output = outputDir.path; |
| final arguments = [ |
| '--use_bundled_pylibs', |
| + '-g', 'dart', |
| '-o', output, |
| // TODO(zra): Are other include paths needed? |
| - '-I', data.mojoSdk.path, |
| + '-I', sdkInc, |
| '-I', mojomDirectory.path, |
| mojom.path]; |
| @@ -150,10 +98,75 @@ generateAction(GenerateIterData data, Directory mojomDirectory) async { |
| } |
| } |
| +/// In each package, look for a file named .mojoms. Populate a package's |
| +/// 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.
|
| +/// The .mojoms file should be formatted as follows: |
| +/// ''' |
| +/// 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
|
| +/// path/to/some/mojom1.mojom |
| +/// path/to/some/other/mojom2.mojom |
| +/// |
| +/// root: https://www.example-two.com/mojoms |
| +/// path/to/example/two/mojom1.mojom |
| +/// ... |
| +/// |
| +/// Lines beginning with '#' are ignored. |
| +downloadAction(GenerateIterData data, Directory packageDirectory) async { |
| + var mojomsPath = path.join(packageDirectory.path, '.mojoms'); |
| + var mojomsFile = new File(mojomsPath); |
| + if (!await mojomsFile.exists()) return; |
| + if (verbose) print("Found .mojoms file: $mojomsPath"); |
| + |
| + Directory mojomsDir; |
| + var httpClient = new HttpClient(); |
| + int repoCount = 0; |
| + int mojomCount = 0; |
| + String repoRoot; |
| + for (String line in await mojomsFile.readAsLines()) { |
| + if (line.isEmpty || line.startsWith('#')) continue; |
|
Cutch
2015/07/20 15:39:08
strip leading whitespace?
zra
2015/07/20 21:09:05
Done.
|
| + |
| + if (line.startsWith('root:')) { |
| + if ((mojomsDir != null) && (mojomCount == 0)) { |
| + throw new DownloadError("root with no mojoms: $repoRoot"); |
| + } |
| + mojomCount = 0; |
| + var rootWords = line.split(" "); |
| + if (rootWords.length != 2) { |
| + throw new DownloadError("Malformed root: $line"); |
| + } |
| + repoRoot = rootWords[1]; |
| + if (verbose) print("Found repo root: $repoRoot"); |
| + 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.
|
| + throw new DownloadError( |
| + 'Mojom repo "root" should be an https URL: $line'); |
| + } |
| + mojomsDir = new Directory(path.join( |
| + packageDirectory.parent.path, 'mojm.repo.$repoCount', 'mojom')); |
| + await mojomsDir.create(recursive: true); |
| + repoCount++; |
| + } else { |
| + if (mojomsDir == null) { |
| + throw new DownloadError('Malformed .mojoms file: $mojomsPath'); |
| + } |
| + String url = "$repoRoot/$line"; |
| + if (verbose) print("Found $url"); |
| + String fileString = await getUrl(httpClient, url); |
| + if (verbose) print("Downloaded $url"); |
| + String filePath = path.join(mojomsDir.path, line); |
| + var file = new File(filePath); |
| + if (!await file.exists()) { |
| + await file.create(recursive: true); |
| + await file.writeAsString(fileString); |
| + if (verbose) print("Wrote $filePath"); |
| + } |
| + mojomCount++; |
| + } |
| + } |
| +} |
| /// Ensures that the directories in [additionalPaths] are absolute and exist, |
| /// and creates Directories for them, which are returned. |
| -validateAdditionalDirs(Iterable additionalPaths) async { |
| +Future<List<Directory>> validateAdditionalDirs(Iterable additionalPaths) async { |
| var additionalDirs = []; |
| for (var mojomPath in additionalPaths) { |
| final mojomDir = new Directory(mojomPath); |
| @@ -171,19 +184,35 @@ validateAdditionalDirs(Iterable additionalPaths) async { |
| return additionalDirs; |
| } |
| +class GenerateOptions { |
| + final Directory packages; |
| + final Directory mojomPackage; |
| + final Directory mojoSdk; |
| + final List<Directory> additionalDirs; |
| + final bool download; |
| + final bool generate; |
| + GenerateOptions( |
| + this.packages, this.mojomPackage, this.mojoSdk, this.additionalDirs, |
| + this.download, this.generate); |
| +} |
| -main(List<String> arguments) async { |
| +Future<GenerateOptions> parseArguments(List<String> arguments) async { |
| final parser = new args.ArgParser() |
| ..addOption('additional-mojom-dir', |
| abbr: 'a', |
| allowMultiple: true, |
| help: 'Absolute path to an additional directory containing mojom.dart' |
| 'files to put in the mojom package. May be specified multiple times.') |
| - ..addFlag('dry-run', |
| + ..addFlag('download', |
| abbr: 'd', |
| defaultsTo: false, |
| - help: 'Print the copy operations that would have been run, but' |
| - 'do not copy anything.') |
| + help: 'Searches packages for a .mojoms file, and downloads .mojom files' |
| + 'as speficied in that file. Implies -g.') |
| + ..addFlag('fake', |
| + abbr: 'f', |
| + defaultsTo: false, |
| + help: 'Print the operations that would have been run, but' |
| + 'do not run anything.') |
| ..addFlag('generate', |
| abbr: 'g', |
| defaultsTo: false, |
| @@ -200,7 +229,7 @@ main(List<String> arguments) async { |
| ..addFlag('verbose', abbr: 'v', defaultsTo: false); |
| final result = parser.parse(arguments); |
| verbose = result['verbose']; |
| - dryRun = result['dry-run']; |
| + dryRun = result['fake']; |
| final packages = new Directory(result['package-root']); |
| if (!packages.isAbsolute) { |
| @@ -220,7 +249,8 @@ main(List<String> arguments) async { |
| "The mojom package directory $mojomPackage must exist"); |
| } |
| - final generate = result['generate']; |
| + final download = result['download']; |
| + final generate = result['generate'] || download; |
| var mojoSdk = null; |
| if (generate) { |
| final mojoSdkPath = result['mojo-sdk']; |
| @@ -237,18 +267,41 @@ main(List<String> arguments) async { |
| } |
| } |
| - await mojomDirIter(packages, new PackageIterData(mojomPackage), copyAction); |
| - if (generate) { |
| - await mojomDirIter(packages, new GenerateIterData(mojoSdk, mojomPackage), |
| - generateAction); |
| - } |
| - |
| final additionalDirs = |
| await validateAdditionalDirs(result['additional-mojom-dir']); |
| - final data = new GenerateIterData(mojoSdk, mojomPackage); |
| - for (var mojomDir in additionalDirs) { |
| + |
| + return new GenerateOptions( |
| + packages, mojomPackage, mojoSdk, additionalDirs, download, generate); |
| +} |
| + |
| +main(List<String> arguments) async { |
| + var options = await parseArguments(arguments); |
| + |
| + // Copy any pregenerated files form packages. |
| + await mojomDirIter( |
| + options.packages, |
| + new PackageIterData(options.mojomPackage), |
| + copyAction); |
| + |
| + // Download .mojom files. These will be picked up by the generation step |
| + // below. |
| + if (options.download) { |
| + await packageDirIter(options.packages, null, downloadAction); |
| + } |
| + |
| + // Generate mojom files. |
| + if (options.generate) { |
| + await mojomDirIter( |
| + options.packages, |
| + new GenerateIterData(options.mojoSdk, options.mojomPackage), |
| + generateAction); |
| + } |
| + |
| + // Copy pregenerated files from specified external directories. |
| + final data = new GenerateIterData(options.mojoSdk, options.mojomPackage); |
| + for (var mojomDir in options.additionalDirs) { |
| await copyAction(data, mojomDir); |
| - if (generate) { |
| + if (options.generate) { |
| await generateAction(data, mojomDir); |
| } |
| } |