Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | |
| 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. | |
| 4 | |
| 5 library command_deploy; | |
| 6 | |
| 7 import 'dart:async'; | |
| 8 import 'dart:math' as math; | |
| 9 | |
| 10 import 'package:analyzer_experimental/analyzer.dart'; | |
| 11 import 'package:pathos/path.dart' as path; | |
| 12 | |
| 13 import 'command.dart'; | |
| 14 import 'dart.dart' as dart; | |
| 15 import 'io.dart'; | |
| 16 import 'log.dart' as log; | |
| 17 import 'utils.dart'; | |
| 18 | |
| 19 final _arrow = getSpecial('\u2192', '=>'); | |
| 20 | |
| 21 /// Handles the `deploy` pub command. | |
|
Andrei Mouravski
2013/05/10 21:56:34
Probably should mention what exactly it does and m
nweiz
2013/05/13 21:59:45
This isn't the place for that. We'll add full docu
Andrei Mouravski
2013/05/13 22:40:33
You don't have to add much, and it might be valuab
nweiz
2013/05/13 23:32:59
The class itself includes as much information as "
| |
| 22 class DeployCommand extends PubCommand { | |
| 23 final description = "Copy and compile all Dart entrypoints in the 'web' " | |
| 24 "directory."; | |
| 25 final usage = "pub deploy [options]"; | |
| 26 final aliases = const ["settle-up"]; | |
| 27 | |
| 28 // TODO(nweiz): make these configurable. | |
| 29 /// The path to the source directory of the deployment. | |
| 30 String get source => path.join(entrypoint.root.dir, 'web'); | |
| 31 | |
| 32 /// The path to the target directory of the deployment. | |
| 33 String get target => path.join(entrypoint.root.dir, 'deploy'); | |
| 34 | |
| 35 /// The set of Dart entrypoints in [source] that should be compiled to [out]. | |
| 36 final _entrypoints = new List<String>(); | |
| 37 | |
| 38 var _maxVerbLength; | |
| 39 var _maxSourceLength; | |
| 40 | |
| 41 Future onRun() { | |
| 42 if (!dirExists(source)) { | |
| 43 throw new ApplicationException("There is no '$source' directory."); | |
| 44 } | |
| 45 | |
| 46 return entrypoint.packageFiles(beneath: source).then((files) { | |
| 47 log.message("Finding entrypoints..."); | |
| 48 _findEntrypoints(files); | |
| 49 _computeLogSize(); | |
| 50 | |
| 51 cleanDir(target); | |
| 52 _logAction("Copying", "${path.relative(source)}/", | |
| 53 "${path.relative(target)}/"); | |
| 54 copyFiles(files.where((file) => path.extension(file) != '.dart'), | |
| 55 source, target); | |
| 56 | |
| 57 return Future.forEach(_entrypoints, (sourceFile) { | |
| 58 var targetFile = | |
| 59 path.join(target, path.relative(sourceFile, from: source)); | |
| 60 var relativeTargetFile = path.relative(targetFile); | |
| 61 var relativeSourceFile = path.relative(sourceFile); | |
| 62 | |
| 63 ensureDir(path.dirname(targetFile)); | |
| 64 _logAction("Compiling", relativeSourceFile, "$relativeTargetFile.js"); | |
| 65 // TODO(nweiz): print dart2js errors/warnings in red. | |
| 66 return dart.compile(sourceFile, packageRoot: entrypoint.packagesDir) | |
| 67 .then((js) { | |
| 68 writeTextFile("$targetFile.js", js, dontLogContents: true); | |
| 69 _logAction("Compiling", relativeSourceFile, "$relativeTargetFile"); | |
| 70 return dart.compile(sourceFile, | |
| 71 packageRoot: entrypoint.packagesDir, toDart: true); | |
| 72 }).then((dart) { | |
| 73 writeTextFile(targetFile, dart, dontLogContents: true); | |
| 74 // TODO(nweiz): we should put dart.js files next to any HTML file | |
| 75 // rather than any entrypoint. An HTML file could import an entrypoint | |
| 76 // that's not adjacent. | |
| 77 _maybeAddDartJs(path.dirname(targetFile)); | |
| 78 }); | |
| 79 }); | |
| 80 }); | |
| 81 } | |
| 82 | |
| 83 /// Populates [_entrypoints] with all of the Dart entrypoints in [files]. | |
| 84 /// [files] should be a list of paths in [source]. | |
| 85 void _findEntrypoints(List<String> files) { | |
| 86 for (var file in files) { | |
| 87 if (path.extension(file) != '.dart') continue; | |
| 88 try { | |
| 89 if (!dart.isEntrypoint(parseDartFile(file))) continue; | |
| 90 } on FormatException catch (e) { | |
| 91 log.warning(e.message); | |
| 92 continue; | |
| 93 } | |
| 94 _entrypoints.add(file); | |
| 95 } | |
| 96 // Sort to ensure a deterministic order of compilation and output. | |
| 97 _entrypoints.sort(); | |
| 98 } | |
| 99 | |
| 100 /// Computes the maximum widths of words that will be used in log output for | |
| 101 /// the deploy command. | |
|
Andrei Mouravski
2013/05/10 22:25:02
Please document that this should be run after _fin
nweiz
2013/05/13 21:59:45
Done.
| |
| 102 void _computeLogSize() { | |
| 103 _maxVerbLength = ["Copying", "Compiling"] | |
| 104 .map((verb) => verb.length).reduce(math.max); | |
| 105 var sourceLengths = new List.from( | |
| 106 _entrypoints.map((file) => path.relative(file).length)) | |
| 107 ..add("${path.relative(source)}/".length); | |
| 108 if (_shouldAddDartJs) sourceLengths.add("package:browser/dart.js".length); | |
| 109 _maxSourceLength = sourceLengths.reduce(math.max); | |
| 110 } | |
| 111 | |
| 112 /// Log a deployment action. | |
| 113 void _logAction(String verb, String source, String target) { | |
| 114 verb = padRight(verb, _maxVerbLength); | |
| 115 source = padRight(source, _maxSourceLength); | |
| 116 log.message("$verb $source $_arrow $target"); | |
| 117 } | |
| 118 | |
| 119 // TODO(nweiz): do something more principled when issue 6101 is fixed. | |
| 120 /// If this package depends non-transitively on the `browser` package, this | |
| 121 /// ensures that the `dart.js` file is copied into [directory], under | |
| 122 /// `packages/browser/`. | |
| 123 void _maybeAddDartJs(String directory) { | |
| 124 var jsPath = path.join(directory, 'packages', 'browser', 'dart.js'); | |
| 125 // TODO(nweiz): warn if they don't depend on browser? | |
| 126 if (!_shouldAddDartJs || fileExists(jsPath)) return; | |
| 127 | |
| 128 _logAction("Copying", "package:browser/dart.js", path.relative(jsPath)); | |
| 129 ensureDir(path.dirname(jsPath)); | |
| 130 copyFile(path.join(entrypoint.packagesDir, 'browser', 'dart.js'), jsPath); | |
| 131 } | |
| 132 | |
| 133 /// Whether we should copy the browser package's dart.js file into the | |
| 134 /// deployed app. | |
| 135 bool get _shouldAddDartJs { | |
| 136 return !_entrypoints.isEmpty && | |
| 137 entrypoint.root.dependencies.any((dep) => | |
| 138 dep.name == 'browser' && dep.source.name == 'hosted'); | |
| 139 } | |
| 140 } | |
| OLD | NEW |