OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library pub.command.list; | 5 library pub.command.list; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import '../ascii_tree.dart' as tree; | 9 import '../ascii_tree.dart' as tree; |
10 import '../command.dart'; | 10 import '../command.dart'; |
11 import '../log.dart' as log; | 11 import '../log.dart' as log; |
12 import '../package.dart'; | 12 import '../package.dart'; |
13 import '../utils.dart'; | 13 import '../utils.dart'; |
14 | 14 |
15 /// Handles the `deps` pub command. | 15 /// Handles the `deps` pub command. |
16 class DepsCommand extends PubCommand { | 16 class DepsCommand extends PubCommand { |
17 String get name => "deps"; | 17 String get name => "deps"; |
18 String get description => "Print package dependencies."; | 18 String get description => "Print package dependencies."; |
19 List<String> get aliases => const ["dependencies", "tab"]; | 19 List<String> get aliases => const ["dependencies", "tab"]; |
20 String get invocation => "pub deps"; | 20 String get invocation => "pub deps"; |
21 String get docUrl => "http://dartlang.org/tools/pub/cmd/pub-deps.html"; | 21 String get docUrl => "http://dartlang.org/tools/pub/cmd/pub-deps.html"; |
22 bool get takesArguments => false; | 22 bool get takesArguments => false; |
23 | 23 |
24 /// The [StringBuffer] used to accumulate the output. | 24 /// The [StringBuffer] used to accumulate the output. |
25 StringBuffer _buffer; | 25 StringBuffer _buffer; |
26 | 26 |
| 27 /// Whether to include dev dependencies. |
| 28 bool get _includeDev => argResults['dev']; |
| 29 |
27 DepsCommand() { | 30 DepsCommand() { |
28 argParser.addOption("style", abbr: "s", | 31 argParser.addOption("style", abbr: "s", |
29 help: "How output should be displayed.", | 32 help: "How output should be displayed.", |
30 allowed: ["compact", "tree", "list"], | 33 allowed: ["compact", "tree", "list"], |
31 defaultsTo: "tree"); | 34 defaultsTo: "tree"); |
| 35 |
| 36 argParser.addFlag("dev", negatable: true, |
| 37 help: "Whether to include dev dependencies.", |
| 38 defaultsTo: true); |
32 } | 39 } |
33 | 40 |
34 void run() { | 41 void run() { |
35 // Explicitly run this in case we don't access `entrypoint.packageGraph`. | 42 // Explicitly run this in case we don't access `entrypoint.packageGraph`. |
36 entrypoint.assertUpToDate(); | 43 entrypoint.assertUpToDate(); |
37 | 44 |
38 _buffer = new StringBuffer(); | 45 _buffer = new StringBuffer(); |
39 | 46 |
40 _buffer.writeln(_labelPackage(entrypoint.root)); | 47 _buffer.writeln(_labelPackage(entrypoint.root)); |
41 | 48 |
42 switch (argResults["style"]) { | 49 switch (argResults["style"]) { |
43 case "compact": _outputCompact(); break; | 50 case "compact": _outputCompact(); break; |
44 case "list": _outputList(); break; | 51 case "list": _outputList(); break; |
45 case "tree": _outputTree(); break; | 52 case "tree": _outputTree(); break; |
46 } | 53 } |
47 | 54 |
48 log.message(_buffer); | 55 log.message(_buffer); |
49 } | 56 } |
50 | 57 |
51 /// Outputs a list of all of the package's immediate, dev, override, and | 58 /// Outputs a list of all of the package's immediate, dev, override, and |
52 /// transitive dependencies. | 59 /// transitive dependencies. |
53 /// | 60 /// |
54 /// For each dependency listed, *that* package's immediate dependencies are | 61 /// For each dependency listed, *that* package's immediate dependencies are |
55 /// shown. Unlike [_outputList], this prints all of these dependencies on one | 62 /// shown. Unlike [_outputList], this prints all of these dependencies on one |
56 /// line. | 63 /// line. |
57 void _outputCompact() { | 64 void _outputCompact() { |
58 var root = entrypoint.root; | 65 var root = entrypoint.root; |
59 _outputCompactPackages("dependencies", | 66 _outputCompactPackages("dependencies", |
60 root.dependencies.map((dep) => dep.name)); | 67 root.dependencies.map((dep) => dep.name)); |
61 _outputCompactPackages("dev dependencies", | 68 if (_includeDev) { |
62 root.devDependencies.map((dep) => dep.name)); | 69 _outputCompactPackages("dev dependencies", |
| 70 root.devDependencies.map((dep) => dep.name)); |
| 71 } |
63 _outputCompactPackages("dependency overrides", | 72 _outputCompactPackages("dependency overrides", |
64 root.dependencyOverrides.map((dep) => dep.name)); | 73 root.dependencyOverrides.map((dep) => dep.name)); |
65 | 74 |
66 var transitive = _getTransitiveDependencies(); | 75 var transitive = _getTransitiveDependencies(); |
67 _outputCompactPackages("transitive dependencies", transitive); | 76 _outputCompactPackages("transitive dependencies", transitive); |
68 } | 77 } |
69 | 78 |
70 /// Outputs one section of packages in the compact output. | 79 /// Outputs one section of packages in the compact output. |
71 _outputCompactPackages(String section, Iterable<String> names) { | 80 _outputCompactPackages(String section, Iterable<String> names) { |
72 if (names.isEmpty) return; | 81 if (names.isEmpty) return; |
(...skipping 16 matching lines...) Expand all Loading... |
89 | 98 |
90 /// Outputs a list of all of the package's immediate, dev, override, and | 99 /// Outputs a list of all of the package's immediate, dev, override, and |
91 /// transitive dependencies. | 100 /// transitive dependencies. |
92 /// | 101 /// |
93 /// For each dependency listed, *that* package's immediate dependencies are | 102 /// For each dependency listed, *that* package's immediate dependencies are |
94 /// shown. | 103 /// shown. |
95 void _outputList() { | 104 void _outputList() { |
96 var root = entrypoint.root; | 105 var root = entrypoint.root; |
97 _outputListSection("dependencies", | 106 _outputListSection("dependencies", |
98 root.dependencies.map((dep) => dep.name)); | 107 root.dependencies.map((dep) => dep.name)); |
99 _outputListSection("dev dependencies", | 108 if (_includeDev) { |
100 root.devDependencies.map((dep) => dep.name)); | 109 _outputListSection("dev dependencies", |
| 110 root.devDependencies.map((dep) => dep.name)); |
| 111 } |
101 _outputListSection("dependency overrides", | 112 _outputListSection("dependency overrides", |
102 root.dependencyOverrides.map((dep) => dep.name)); | 113 root.dependencyOverrides.map((dep) => dep.name)); |
103 | 114 |
104 var transitive = _getTransitiveDependencies(); | 115 var transitive = _getTransitiveDependencies(); |
105 if (transitive.isEmpty) return; | 116 if (transitive.isEmpty) return; |
106 | 117 |
107 _outputListSection("transitive dependencies", ordered(transitive)); | 118 _outputListSection("transitive dependencies", ordered(transitive)); |
108 } | 119 } |
109 | 120 |
110 /// Outputs one section of packages in the list output. | 121 /// Outputs one section of packages in the list output. |
(...skipping 22 matching lines...) Expand all Loading... |
133 /// depth that it appears at. | 144 /// depth that it appears at. |
134 void _outputTree() { | 145 void _outputTree() { |
135 // The work list for the breadth-first traversal. It contains the package | 146 // The work list for the breadth-first traversal. It contains the package |
136 // being added to the tree, and the parent map that will receive that | 147 // being added to the tree, and the parent map that will receive that |
137 // package. | 148 // package. |
138 var toWalk = new Queue<Pair<Package, Map>>(); | 149 var toWalk = new Queue<Pair<Package, Map>>(); |
139 var visited = new Set<String>.from([entrypoint.root.name]); | 150 var visited = new Set<String>.from([entrypoint.root.name]); |
140 | 151 |
141 // Start with the root dependencies. | 152 // Start with the root dependencies. |
142 var packageTree = {}; | 153 var packageTree = {}; |
143 for (var dep in entrypoint.root.immediateDependencies) { | 154 var immediateDependencies = entrypoint.root.immediateDependencies.toSet(); |
| 155 if (!_includeDev) { |
| 156 immediateDependencies.removeAll(entrypoint.root.devDependencies); |
| 157 } |
| 158 for (var dep in immediateDependenciesr) { |
144 toWalk.add(new Pair(_getPackage(dep.name), packageTree)); | 159 toWalk.add(new Pair(_getPackage(dep.name), packageTree)); |
145 } | 160 } |
146 | 161 |
147 // Do a breadth-first walk to the dependency graph. | 162 // Do a breadth-first walk to the dependency graph. |
148 while (toWalk.isNotEmpty) { | 163 while (toWalk.isNotEmpty) { |
149 var pair = toWalk.removeFirst(); | 164 var pair = toWalk.removeFirst(); |
150 var package = pair.first; | 165 var package = pair.first; |
151 var map = pair.last; | 166 var map = pair.last; |
152 | 167 |
153 if (visited.contains(package.name)) { | 168 if (visited.contains(package.name)) { |
(...skipping 13 matching lines...) Expand all Loading... |
167 } | 182 } |
168 | 183 |
169 _buffer.write(tree.fromMap(packageTree, showAllChildren: true)); | 184 _buffer.write(tree.fromMap(packageTree, showAllChildren: true)); |
170 } | 185 } |
171 | 186 |
172 String _labelPackage(Package package) => | 187 String _labelPackage(Package package) => |
173 "${log.bold(package.name)} ${package.version}"; | 188 "${log.bold(package.name)} ${package.version}"; |
174 | 189 |
175 /// Gets the names of the non-immediate dependencies of the root package. | 190 /// Gets the names of the non-immediate dependencies of the root package. |
176 Set<String> _getTransitiveDependencies() { | 191 Set<String> _getTransitiveDependencies() { |
177 var transitive = entrypoint.packageGraph.packages.keys.toSet(); | 192 var transitive = _getAllDependencies(); |
178 var root = entrypoint.root; | 193 var root = entrypoint.root; |
179 transitive.remove(root.name); | 194 transitive.remove(root.name); |
180 transitive.removeAll(root.dependencies.map((dep) => dep.name)); | 195 transitive.removeAll(root.dependencies.map((dep) => dep.name)); |
181 transitive.removeAll(root.devDependencies.map((dep) => dep.name)); | 196 if (_includeDev) { |
| 197 transitive.removeAll(root.devDependencies.map((dep) => dep.name)); |
| 198 } |
182 transitive.removeAll(root.dependencyOverrides.map((dep) => dep.name)); | 199 transitive.removeAll(root.dependencyOverrides.map((dep) => dep.name)); |
183 return transitive; | 200 return transitive; |
184 } | 201 } |
185 | 202 |
| 203 Set<String> _getAllDependencies() { |
| 204 if (_includeDev) return entrypoint.packageGraph.packages.keys.toSet(); |
| 205 |
| 206 var nonDevDependencies = entrypoint.root.dependencies.toList() |
| 207 ..addAll(entrypoint.root.dependencyOverrides); |
| 208 return nonDevDependencies |
| 209 .expand((dep) => |
| 210 entrypoint.packageGraph.transitiveDependencies(dep.name)) |
| 211 .map((package) => package.name) |
| 212 .toSet(); |
| 213 } |
| 214 |
186 /// Get the package named [name], or throw a [DataError] if it's not | 215 /// Get the package named [name], or throw a [DataError] if it's not |
187 /// available. | 216 /// available. |
188 /// | 217 /// |
189 /// It's very unlikely that the lockfile won't be up-to-date with the pubspec, | 218 /// It's very unlikely that the lockfile won't be up-to-date with the pubspec, |
190 /// but it's possible, since [Entrypoint.assertUpToDate]'s modification time | 219 /// but it's possible, since [Entrypoint.assertUpToDate]'s modification time |
191 /// check can return a false negative. This fails gracefully if that happens. | 220 /// check can return a false negative. This fails gracefully if that happens. |
192 Package _getPackage(String name) { | 221 Package _getPackage(String name) { |
193 var package = entrypoint.packageGraph.packages[name]; | 222 var package = entrypoint.packageGraph.packages[name]; |
194 if (package != null) return package; | 223 if (package != null) return package; |
195 dataError('The pubspec.yaml file has changed since the pubspec.lock file ' | 224 dataError('The pubspec.yaml file has changed since the pubspec.lock file ' |
196 'was generated, please run "pub get" again.'); | 225 'was generated, please run "pub get" again.'); |
197 } | 226 } |
198 } | 227 } |
OLD | NEW |