Chromium Code Reviews

Side by Side 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 chagnes Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | | Annotate | Revision Log
OLDNEW
(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 }
OLDNEW

Powered by Google App Engine