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

Unified Diff: sdk/lib/_internal/pub/lib/src/command_deploy.dart

Issue 14914007: Add a "pub deploy" command. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review changes. Created 7 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/pub/lib/src/command_deploy.dart
diff --git a/sdk/lib/_internal/pub/lib/src/command_deploy.dart b/sdk/lib/_internal/pub/lib/src/command_deploy.dart
new file mode 100644
index 0000000000000000000000000000000000000000..94decb64df63846d96829362226a77ce8264b861
--- /dev/null
+++ b/sdk/lib/_internal/pub/lib/src/command_deploy.dart
@@ -0,0 +1,141 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library command_deploy;
+
+import 'dart:async';
+import 'dart:math' as math;
+
+import 'package:analyzer_experimental/analyzer.dart';
+import 'package:pathos/path.dart' as path;
+
+import 'command.dart';
+import 'dart.dart' as dart;
+import 'io.dart';
+import 'log.dart' as log;
+import 'utils.dart';
+
+final _arrow = getSpecial('\u2192', '=>');
+
+/// Handles the `deploy` pub command.
+class DeployCommand extends PubCommand {
+ final description = "Copy and compile all Dart entrypoints in the 'web' "
+ "directory.";
+ final usage = "pub deploy [options]";
+ final aliases = const ["settle-up"];
+
+ // TODO(nweiz): make these configurable.
+ /// The path to the source directory of the deployment.
+ String get source => path.join(entrypoint.root.dir, 'web');
+
+ /// The path to the target directory of the deployment.
+ String get target => path.join(entrypoint.root.dir, 'deploy');
+
+ /// The set of Dart entrypoints in [source] that should be compiled to [out].
+ final _entrypoints = new List<String>();
+
+ int _maxVerbLength;
+ int _maxSourceLength;
+
+ Future onRun() {
+ if (!dirExists(source)) {
+ throw new ApplicationException("There is no '$source' directory.");
+ }
+
+ return entrypoint.packageFiles(beneath: source).then((files) {
+ log.message("Finding entrypoints...");
+ _findEntrypoints(files);
+ _computeLogSize();
+
+ cleanDir(target);
+ _logAction("Copying", "${path.relative(source)}/",
+ "${path.relative(target)}/");
+ copyFiles(files.where((file) => path.extension(file) != '.dart'),
+ source, target);
+
+ return Future.forEach(_entrypoints, (sourceFile) {
+ var targetFile =
+ path.join(target, path.relative(sourceFile, from: source));
+ var relativeTargetFile = path.relative(targetFile);
+ var relativeSourceFile = path.relative(sourceFile);
+
+ ensureDir(path.dirname(targetFile));
+ _logAction("Compiling", relativeSourceFile, "$relativeTargetFile.js");
+ // TODO(nweiz): print dart2js errors/warnings in red.
+ return dart.compile(sourceFile, packageRoot: entrypoint.packagesDir)
+ .then((js) {
+ writeTextFile("$targetFile.js", js, dontLogContents: true);
+ _logAction("Compiling", relativeSourceFile, "$relativeTargetFile");
+ return dart.compile(sourceFile,
+ packageRoot: entrypoint.packagesDir, toDart: true);
+ }).then((dart) {
+ writeTextFile(targetFile, dart, dontLogContents: true);
+ // TODO(nweiz): we should put dart.js files next to any HTML file
+ // rather than any entrypoint. An HTML file could import an entrypoint
+ // that's not adjacent.
+ _maybeAddDartJs(path.dirname(targetFile));
+ });
+ });
+ });
+ }
+
+ /// Populates [_entrypoints] with all of the Dart entrypoints in [files].
+ /// [files] should be a list of paths in [source].
+ void _findEntrypoints(List<String> files) {
+ for (var file in files) {
+ if (path.extension(file) != '.dart') continue;
+ try {
+ if (!dart.isEntrypoint(parseDartFile(file))) continue;
+ } on AnalyzerErrorGroup catch (e) {
+ log.warning(e.message);
+ continue;
+ }
+ _entrypoints.add(file);
+ }
+ // Sort to ensure a deterministic order of compilation and output.
+ _entrypoints.sort();
+ }
+
+ /// Computes the maximum widths of words that will be used in log output for
+ /// the deploy command so we know how much padding to add when printing them.
+ /// This should only be run after [_findEntrypoints].
+ void _computeLogSize() {
+ _maxVerbLength = ["Copying", "Compiling"]
+ .map((verb) => verb.length).reduce(math.max);
+ var sourceLengths = new List.from(
+ _entrypoints.map((file) => path.relative(file).length))
+ ..add("${path.relative(source)}/".length);
+ if (_shouldAddDartJs) sourceLengths.add("package:browser/dart.js".length);
+ _maxSourceLength = sourceLengths.reduce(math.max);
+ }
+
+ /// Log a deployment action. This should only be run after [_computeLogSize].
+ void _logAction(String verb, String source, String target) {
+ verb = padRight(verb, _maxVerbLength);
+ source = padRight(source, _maxSourceLength);
+ log.message("$verb $source $_arrow $target");
+ }
+
+ // TODO(nweiz): do something more principled when issue 6101 is fixed.
+ /// If this package depends non-transitively on the `browser` package, this
+ /// ensures that the `dart.js` file is copied into [directory], under
+ /// `packages/browser/`.
+ void _maybeAddDartJs(String directory) {
+ var jsPath = path.join(directory, 'packages', 'browser', 'dart.js');
+ // TODO(nweiz): warn if they don't depend on browser?
+ if (!_shouldAddDartJs || fileExists(jsPath)) return;
+
+ _logAction("Copying", "package:browser/dart.js", path.relative(jsPath));
+ ensureDir(path.dirname(jsPath));
+ copyFile(path.join(entrypoint.packagesDir, 'browser', 'dart.js'), jsPath);
+ }
+
+ /// Whether we should copy the browser package's dart.js file into the
+ /// deployed app.
+ bool get _shouldAddDartJs {
+ return !_entrypoints.isEmpty &&
+ entrypoint.root.dependencies.any((dep) =>
+ dep.name == 'browser' && dep.source.name == 'hosted');
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698