Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * Common logic to make it easy to create a `build.dart` for your project. | 6 * Common logic to make it easy to create a `build.dart` for your project. |
| 7 * | 7 * |
| 8 * The `build.dart` script is invoked automatically by the Editor whenever a | 8 * The `build.dart` script is invoked automatically by the Editor whenever a |
| 9 * file in the project changes. It must be placed in the root of a project | 9 * file in the project changes. It must be placed in the root of a project |
| 10 * (where pubspec.yaml lives) and should be named exactly 'build.dart'. | 10 * (where pubspec.yaml lives) and should be named exactly 'build.dart'. |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 | 25 |
| 26 import 'dwc.dart' as dwc; | 26 import 'dwc.dart' as dwc; |
| 27 import 'src/utils.dart'; | 27 import 'src/utils.dart'; |
| 28 import 'src/compiler_options.dart'; | 28 import 'src/compiler_options.dart'; |
| 29 | 29 |
| 30 /** | 30 /** |
| 31 * Set up 'build.dart' to compile with the dart web components compiler every | 31 * Set up 'build.dart' to compile with the dart web components compiler every |
| 32 * [entryPoints] listed. On clean commands, the directory where [entryPoints] | 32 * [entryPoints] listed. On clean commands, the directory where [entryPoints] |
| 33 * live will be scanned for generated files to delete them. | 33 * live will be scanned for generated files to delete them. |
| 34 */ | 34 */ |
| 35 // TODO(jmesserly): we need a better way to automatically detect input files | 35 Future<List<dwc.AnalysisResult>> build(List<String> arguments, |
| 36 Future<List<dwc.CompilerResult>> build(List<String> arguments, | |
| 37 List<String> entryPoints, | 36 List<String> entryPoints, |
| 38 {bool printTime: true, bool shouldPrint: true}) { | 37 {bool printTime: true, bool shouldPrint: true}) { |
| 39 bool useColors = stdioType(stdout) == StdioType.TERMINAL; | 38 bool useColors = stdioType(stdout) == StdioType.TERMINAL; |
| 40 return asyncTime('Total time', () { | 39 return asyncTime('Total time', () { |
| 41 var args = _processArgs(arguments); | 40 var args = _processArgs(arguments); |
| 42 var tasks = new FutureGroup(); | 41 var tasks = new FutureGroup(); |
| 43 var lastTask = new Future.value(null); | 42 var lastTask = new Future.value(null); |
| 44 tasks.add(lastTask); | 43 tasks.add(lastTask); |
| 45 | 44 |
| 46 var changedFiles = args["changed"]; | 45 var changedFiles = args["changed"]; |
| 47 var removedFiles = args["removed"]; | 46 var removedFiles = args["removed"]; |
| 48 var cleanBuild = args["clean"]; | 47 var cleanBuild = args["clean"]; |
| 49 var machineFormat = args["machine"]; | 48 var machineFormat = args["machine"]; |
| 50 // Also trigger a full build if the script was run from the command line | 49 // Also trigger a full build if the script was run from the command line |
| 51 // with no arguments | 50 // with no arguments |
| 52 var fullBuild = args["full"] || (!machineFormat && changedFiles.isEmpty && | 51 var fullBuild = args["full"] || (!machineFormat && changedFiles.isEmpty && |
| 53 removedFiles.isEmpty && !cleanBuild); | 52 removedFiles.isEmpty && !cleanBuild); |
| 54 | 53 |
| 55 var options = CompilerOptions.parse(args.rest, checkUsage: false); | 54 var options = CompilerOptions.parse(args.rest, checkUsage: false); |
| 56 | 55 |
| 57 // [outputOnlyDirs] contains directories known to only have output files. | 56 if (fullBuild || !changedFiles.isEmpty || !removedFiles.isEmpty) { |
| 58 // When outputDir is not specified, we create a new directory which only | |
| 59 // contains output files. If options.outputDir is specified, we don't know | |
| 60 // if the output directory may also have input files. In which case, | |
| 61 // [_handleCleanCommand] and [_isInputFile] are more conservative. | |
| 62 // | |
| 63 // TODO(sigmund): get rid of this. Instead, use the compiler to understand | |
| 64 // which files are input or output files. | |
| 65 var outputOnlyDirs = options.outputDir == null ? [] | |
| 66 : entryPoints.map((e) => _outDir(e)).toList(); | |
| 67 | |
| 68 if (cleanBuild) { | |
| 69 _handleCleanCommand(outputOnlyDirs); | |
| 70 } else if (fullBuild | |
| 71 || changedFiles.any((f) => _isInputFile(f, outputOnlyDirs)) | |
| 72 || removedFiles.any((f) => _isInputFile(f, outputOnlyDirs))) { | |
| 73 for (var file in entryPoints) { | 57 for (var file in entryPoints) { |
| 74 var dwcArgs = new List.from(args.rest); | 58 var dwcArgs = new List.from(args.rest); |
| 75 if (machineFormat) dwcArgs.add('--json_format'); | 59 if (machineFormat) dwcArgs.add('--json_format'); |
| 76 if (!useColors) dwcArgs.add('--no-colors'); | 60 if (!useColors) dwcArgs.add('--no-colors'); |
| 77 // We'll set 'out/' as the out folder, unless an output directory was | |
| 78 // already specified in the command line. | |
| 79 if (options.outputDir == null) dwcArgs.addAll(['-o', _outDir(file)]); | |
| 80 dwcArgs.add(file); | 61 dwcArgs.add(file); |
| 81 // Chain tasks to that we run one at a time. | 62 // Chain tasks to that we run one at a time. |
| 82 lastTask = lastTask.then((_) => dwc.run(dwcArgs, printTime: printTime, | 63 lastTask = lastTask.then((_) => dwc.run(dwcArgs, printTime: printTime, |
| 83 shouldPrint: shouldPrint)); | 64 shouldPrint: shouldPrint)); |
| 84 if (machineFormat) { | 65 if (machineFormat) { |
| 85 lastTask = lastTask.then((res) { | 66 lastTask = lastTask.then((res) { |
| 86 appendMessage(Map jsonMessage) { | 67 appendMessage(Map jsonMessage) { |
| 87 var message = json.stringify([jsonMessage]); | 68 var message = json.stringify([jsonMessage]); |
| 88 if (shouldPrint) print(message); | 69 if (shouldPrint) print(message); |
| 89 res.messages.add(message); | 70 res.messages.add(message); |
| 90 } | 71 } |
| 91 // Print for the Editor messages about mappings and generated files | |
| 92 res.outputs.forEach((out, input) { | |
| 93 if (out.endsWith(".html") && input != null) { | |
| 94 appendMessage({ | |
| 95 "method": "mapping", | |
| 96 "params": {"from": input, "to": out}, | |
| 97 }); | |
| 98 } | |
| 99 appendMessage({"method": "generated", "params": {"file": out}}); | |
| 100 }); | |
| 101 return res; | 72 return res; |
| 102 }); | 73 }); |
| 103 } | 74 } |
| 104 tasks.add(lastTask); | 75 tasks.add(lastTask); |
| 105 } | 76 } |
| 106 } | 77 } |
| 107 return tasks.future.then((r) => r.where((v) => v != null)); | 78 return tasks.future.then((r) => r.where((v) => v != null)); |
| 108 }, printTime: printTime, useColors: useColors); | 79 }, printTime: printTime, useColors: useColors); |
| 109 } | 80 } |
| 110 | 81 |
| 111 String _outDir(String file) => path.join(path.dirname(file), 'out'); | |
| 112 | |
| 113 /** Tell whether [filePath] is a generated file. */ | |
| 114 bool _isGeneratedFile(String filePath, List<String> outputOnlyDirs) { | |
| 115 var dirPrefix = path.dirname(filePath); | |
| 116 for (var outDir in outputOnlyDirs) { | |
| 117 if (dirPrefix.startsWith(outDir)) return true; | |
| 118 } | |
| 119 return path.basename(filePath).startsWith('_'); | |
| 120 } | |
| 121 | |
| 122 /** Tell whether [filePath] is an input file. */ | |
| 123 bool _isInputFile(String filePath, List<String> outputOnlyDirs) { | |
| 124 var ext = path.extension(filePath); | |
| 125 return (ext == '.dart' || ext == '.html') && | |
| 126 !_isGeneratedFile(filePath, outputOnlyDirs); | |
| 127 } | |
| 128 | |
| 129 /** | |
| 130 * Delete all generated files. Currently we only delete files under directories | |
| 131 * that are known to contain only generated code. | |
| 132 */ | |
| 133 void _handleCleanCommand(List<String> outputOnlyDirs) { | |
| 134 for (var dirPath in outputOnlyDirs) { | |
| 135 var dir = new Directory(dirPath); | |
| 136 if (!dir.existsSync()) continue; | |
| 137 for (var f in dir.listSync(recursive: false)) { | |
| 138 if (f is File && _isGeneratedFile(f.path, outputOnlyDirs)) f.deleteSync(); | |
| 139 } | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 /** Process the command-line arguments. */ | 82 /** Process the command-line arguments. */ |
| 144 ArgResults _processArgs(List<String> arguments) { | 83 ArgResults _processArgs(List<String> arguments) { |
| 145 var parser = new ArgParser() | 84 var parser = new ArgParser() |
| 146 ..addOption("changed", help: "the file has changed since the last build", | 85 ..addOption("changed", help: "the file has changed since the last build", |
| 147 allowMultiple: true) | 86 allowMultiple: true) |
| 148 ..addOption("removed", help: "the file was removed since the last build", | 87 ..addOption("removed", help: "the file was removed since the last build", |
| 149 allowMultiple: true) | 88 allowMultiple: true) |
| 150 ..addFlag("clean", negatable: false, help: "remove any build artifacts") | 89 ..addFlag("clean", negatable: false, help: "remove any build artifacts") |
|
Jennifer Messerly
2013/08/28 22:25:45
Consider: adding a note here that we don't actuall
Siggi Cherem (dart-lang)
2013/08/28 23:17:06
Done.
| |
| 151 ..addFlag("full", negatable: false, help: "perform a full build") | 90 ..addFlag("full", negatable: false, help: "perform a full build") |
| 152 ..addFlag("machine", negatable: false, | 91 ..addFlag("machine", negatable: false, |
| 153 help: "produce warnings in a machine parseable format") | 92 help: "produce warnings in a machine parseable format") |
| 154 ..addFlag("help", abbr: 'h', | 93 ..addFlag("help", abbr: 'h', |
| 155 negatable: false, help: "displays this help and exit"); | 94 negatable: false, help: "displays this help and exit"); |
| 156 var args = parser.parse(arguments); | 95 var args = parser.parse(arguments); |
| 157 if (args["help"]) { | 96 if (args["help"]) { |
| 158 print('A build script that invokes the web-ui compiler (dwc).'); | 97 print('A build script that invokes the web-ui compiler (dwc).'); |
| 159 print('Usage: dart build.dart [options] [-- [dwc-options]]'); | 98 print('Usage: dart build.dart [options] [-- [dwc-options]]'); |
| 160 print('\nThese are valid options expected by build.dart:'); | 99 print('\nThese are valid options expected by build.dart:'); |
| 161 print(parser.getUsage()); | 100 print(parser.getUsage()); |
| 162 print('\nThese are valid options expected by dwc:'); | 101 print('\nThese are valid options expected by dwc:'); |
| 163 dwc.run(['-h']).then((_) => exit(0)); | 102 dwc.run(['-h']).then((_) => exit(0)); |
| 164 } | 103 } |
| 165 return args; | 104 return args; |
| 166 } | 105 } |
| OLD | NEW |