Skip to content

Commit 73433d1

Browse files
committed
Represent Pubspec.dependencies as a map (#1743)
This cleans up some existing code, but more importantly it makes some algorithms for the new version solver more efficient.
1 parent c698e5c commit 73433d1

18 files changed

+100
-108
lines changed

lib/src/barback/dependency_computer.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ class DependencyComputer {
194194
packageName == _graph.entrypoint.root.name
195195
? package.immediateDependencies
196196
: package.dependencies;
197-
for (var dep in dependencies) {
197+
for (var dep in dependencies.values) {
198198
try {
199199
traversePackage(dep.name);
200200
} on CycleException catch (error) {
@@ -355,7 +355,7 @@ class _PackageDependencyComputer {
355355
return _applicableTransformers
356356
.map((config) => config.id)
357357
.toSet()
358-
.union(unionAll(dependencies.map((dep) {
358+
.union(unionAll(dependencies.values.map((dep) {
359359
try {
360360
return _dependencyComputer._transformersNeededByPackage(dep.name);
361361
} on CycleException catch (error) {

lib/src/cached_package.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,10 @@ class _CachedPubspec implements Pubspec {
8282
YamlMap get fields => _inner.fields;
8383
String get name => _inner.name;
8484
Version get version => _inner.version;
85-
List<PackageRange> get dependencies => _inner.dependencies;
86-
List<PackageRange> get devDependencies => _inner.devDependencies;
87-
List<PackageRange> get dependencyOverrides => _inner.dependencyOverrides;
85+
Map<String, PackageRange> get dependencies => _inner.dependencies;
86+
Map<String, PackageRange> get devDependencies => _inner.devDependencies;
87+
Map<String, PackageRange> get dependencyOverrides =>
88+
_inner.dependencyOverrides;
8889
Map<String, Feature> get features => _inner.features;
8990
VersionConstraint get dartSdkConstraint => _inner.dartSdkConstraint;
9091
VersionConstraint get originalDartSdkConstraint =>

lib/src/command/build.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,8 @@ class BuildCommand extends BarbackCommand {
223223
/// directories next to each entrypoint in [entrypoints].
224224
Future _copyBrowserJsFiles(Iterable<AssetId> entrypoints, AssetSet assets) {
225225
// Must depend on the browser package.
226-
if (!entrypoint.root.immediateDependencies
227-
.any((dep) => dep.name == 'browser' && dep.source is HostedSource)) {
226+
var browser = entrypoint.root.immediateDependencies['browser'];
227+
if (browser == null || browser.source is! HostedSource) {
228228
return new Future.value();
229229
}
230230

lib/src/command/deps.dart

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,12 @@ class DepsCommand extends PubCommand {
9090
/// line.
9191
void _outputCompact() {
9292
var root = entrypoint.root;
93-
_outputCompactPackages(
94-
"dependencies", root.dependencies.map((dep) => dep.name));
93+
_outputCompactPackages("dependencies", root.dependencies.keys);
9594
if (_includeDev) {
96-
_outputCompactPackages(
97-
"dev dependencies", root.devDependencies.map((dep) => dep.name));
95+
_outputCompactPackages("dev dependencies", root.devDependencies.keys);
9896
}
99-
_outputCompactPackages("dependency overrides",
100-
root.dependencyOverrides.map((dep) => dep.name));
97+
_outputCompactPackages(
98+
"dependency overrides", root.dependencyOverrides.keys);
10199

102100
var transitive = _getTransitiveDependencies();
103101
_outputCompactPackages("transitive dependencies", transitive);
@@ -116,7 +114,7 @@ class DepsCommand extends PubCommand {
116114
if (package.dependencies.isEmpty) {
117115
_buffer.writeln();
118116
} else {
119-
var depNames = package.dependencies.map((dep) => dep.name);
117+
var depNames = package.dependencies.keys;
120118
var depsList = "[${depNames.join(' ')}]";
121119
_buffer.writeln(" ${log.gray(depsList)}");
122120
}
@@ -130,14 +128,11 @@ class DepsCommand extends PubCommand {
130128
/// shown.
131129
void _outputList() {
132130
var root = entrypoint.root;
133-
_outputListSection(
134-
"dependencies", root.dependencies.map((dep) => dep.name));
131+
_outputListSection("dependencies", root.dependencies.keys);
135132
if (_includeDev) {
136-
_outputListSection(
137-
"dev dependencies", root.devDependencies.map((dep) => dep.name));
133+
_outputListSection("dev dependencies", root.devDependencies.keys);
138134
}
139-
_outputListSection("dependency overrides",
140-
root.dependencyOverrides.map((dep) => dep.name));
135+
_outputListSection("dependency overrides", root.dependencyOverrides.keys);
141136

142137
var transitive = _getTransitiveDependencies();
143138
if (transitive.isEmpty) return;
@@ -156,7 +151,7 @@ class DepsCommand extends PubCommand {
156151
var package = _getPackage(name);
157152
_buffer.writeln("- ${_labelPackage(package)}");
158153

159-
for (var dep in package.dependencies) {
154+
for (var dep in package.dependencies.values) {
160155
_buffer
161156
.writeln(" - ${log.bold(dep.name)} ${log.gray(dep.constraint)}");
162157
}
@@ -178,12 +173,13 @@ class DepsCommand extends PubCommand {
178173

179174
// Start with the root dependencies.
180175
var packageTree = <String, Map>{};
181-
var immediateDependencies = entrypoint.root.immediateDependencies.toSet();
176+
var immediateDependencies =
177+
entrypoint.root.immediateDependencies.keys.toSet();
182178
if (!_includeDev) {
183-
immediateDependencies.removeAll(entrypoint.root.devDependencies);
179+
immediateDependencies.removeAll(entrypoint.root.devDependencies.keys);
184180
}
185-
for (var dep in immediateDependencies) {
186-
toWalk.add(new Pair(_getPackage(dep.name), packageTree));
181+
for (var name in immediateDependencies) {
182+
toWalk.add(new Pair(_getPackage(name), packageTree));
187183
}
188184

189185
// Do a breadth-first walk to the dependency graph.
@@ -203,7 +199,7 @@ class DepsCommand extends PubCommand {
203199
var childMap = <String, Map>{};
204200
map[_labelPackage(package)] = childMap;
205201

206-
for (var dep in package.dependencies) {
202+
for (var dep in package.dependencies.values) {
207203
toWalk.add(new Pair(_getPackage(dep.name), childMap));
208204
}
209205
}
@@ -219,22 +215,21 @@ class DepsCommand extends PubCommand {
219215
var transitive = _getAllDependencies();
220216
var root = entrypoint.root;
221217
transitive.remove(root.name);
222-
transitive.removeAll(root.dependencies.map((dep) => dep.name));
218+
transitive.removeAll(root.dependencies.keys);
223219
if (_includeDev) {
224-
transitive.removeAll(root.devDependencies.map((dep) => dep.name));
220+
transitive.removeAll(root.devDependencies.keys);
225221
}
226-
transitive.removeAll(root.dependencyOverrides.map((dep) => dep.name));
222+
transitive.removeAll(root.dependencyOverrides.keys);
227223
return transitive;
228224
}
229225

230226
Set<String> _getAllDependencies() {
231227
if (_includeDev) return entrypoint.packageGraph.packages.keys.toSet();
232228

233-
var nonDevDependencies = entrypoint.root.dependencies.toList()
234-
..addAll(entrypoint.root.dependencyOverrides);
229+
var nonDevDependencies = entrypoint.root.dependencies.keys.toList()
230+
..addAll(entrypoint.root.dependencyOverrides.keys);
235231
return nonDevDependencies
236-
.expand(
237-
(dep) => entrypoint.packageGraph.transitiveDependencies(dep.name))
232+
.expand((name) => entrypoint.packageGraph.transitiveDependencies(name))
238233
.map((package) => package.name)
239234
.toSet();
240235
}
@@ -260,7 +255,8 @@ class DepsCommand extends PubCommand {
260255
..addAll((_includeDev
261256
? entrypoint.root.immediateDependencies
262257
: entrypoint.root.dependencies)
263-
.map((dep) => entrypoint.packageGraph.packages[dep.name]));
258+
.keys
259+
.map((name) => entrypoint.packageGraph.packages[name]));
264260

265261
for (var package in packages) {
266262
var executables = _getExecutablesFor(package);

lib/src/entrypoint.dart

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'dart:async';
66
import 'dart:io';
77

88
import 'package:barback/barback.dart';
9+
import 'package:collection/collection.dart';
910
import 'package:package_config/packages_file.dart' as packages_file;
1011
import 'package:path/path.dart' as p;
1112
import 'package:pub_semver/pub_semver.dart';
@@ -372,10 +373,8 @@ class Entrypoint {
372373
Future precompileExecutables({Iterable<String> changed}) async {
373374
_deleteExecutableSnapshots(changed: changed);
374375

375-
var executables = new Map<String, List<AssetId>>.fromIterable(
376-
root.immediateDependencies,
377-
key: (dep) => dep.name,
378-
value: (dep) => _executablesForPackage(dep.name));
376+
var executables = mapMap(root.immediateDependencies,
377+
value: (name, _) => _executablesForPackage(name));
379378

380379
for (var package in executables.keys.toList()) {
381380
if (executables[package].isEmpty) executables.remove(package);
@@ -609,12 +608,12 @@ class Entrypoint {
609608
/// or that don't match what's in there, this will throw a [DataError]
610609
/// describing the issue.
611610
void _assertLockFileUpToDate() {
612-
if (!root.immediateDependencies.every(_isDependencyUpToDate)) {
611+
if (!root.immediateDependencies.values.every(_isDependencyUpToDate)) {
613612
dataError('The pubspec.yaml file has changed since the pubspec.lock '
614613
'file was generated, please run "pub get" again.');
615614
}
616615

617-
var overrides = root.dependencyOverrides.map((dep) => dep.name).toSet();
616+
var overrides = new MapKeySet(root.dependencyOverrides);
618617

619618
// Check that uncached dependencies' pubspecs are also still satisfied,
620619
// since they're mutable and may have changed since the last get.
@@ -623,7 +622,7 @@ class Entrypoint {
623622
if (source is CachedSource) continue;
624623

625624
try {
626-
if (cache.load(id).dependencies.every((dep) =>
625+
if (cache.load(id).dependencies.values.every((dep) =>
627626
overrides.contains(dep.name) || _isDependencyUpToDate(dep))) {
628627
continue;
629628
}

lib/src/executable.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@ Future<int> runExecutable(Entrypoint entrypoint, String package,
3939
// Make sure the package is an immediate dependency of the entrypoint or the
4040
// entrypoint itself.
4141
if (entrypoint.root.name != package &&
42-
!entrypoint.root.immediateDependencies
43-
.any((dep) => dep.name == package)) {
42+
!entrypoint.root.immediateDependencies.containsKey(package)) {
4443
if (entrypoint.packageGraph.packages.containsKey(package)) {
4544
dataError('Package "$package" is not an immediate dependency.\n'
4645
'Cannot run executables in transitive dependencies.');

lib/src/package.dart

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,31 +49,24 @@ class Package {
4949
final Pubspec pubspec;
5050

5151
/// The immediate dependencies this package specifies in its pubspec.
52-
List<PackageRange> get dependencies => pubspec.dependencies;
52+
Map<String, PackageRange> get dependencies => pubspec.dependencies;
5353

5454
/// The immediate dev dependencies this package specifies in its pubspec.
55-
List<PackageRange> get devDependencies => pubspec.devDependencies;
55+
Map<String, PackageRange> get devDependencies => pubspec.devDependencies;
5656

5757
/// The dependency overrides this package specifies in its pubspec.
58-
List<PackageRange> get dependencyOverrides => pubspec.dependencyOverrides;
58+
Map<String, PackageRange> get dependencyOverrides =>
59+
pubspec.dependencyOverrides;
5960

6061
/// All immediate dependencies this package specifies.
6162
///
6263
/// This includes regular, dev dependencies, and overrides.
63-
List<PackageRange> get immediateDependencies {
64-
var deps = <String, PackageRange>{};
65-
66-
addToMap(dep) {
67-
deps[dep.name] = dep;
68-
}
69-
70-
dependencies.forEach(addToMap);
71-
devDependencies.forEach(addToMap);
72-
73-
// Make sure to add these last so they replace normal dependencies.
74-
dependencyOverrides.forEach(addToMap);
75-
76-
return deps.values.toList();
64+
Map<String, PackageRange> get immediateDependencies {
65+
// Make sure to add overrides last so they replace normal dependencies.
66+
return {}
67+
..addAll(dependencies)
68+
..addAll(devDependencies)
69+
..addAll(dependencyOverrides);
7770
}
7871

7972
/// Returns a list of asset ids for all Dart executables in this package's bin

lib/src/package_graph.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,7 @@ class PackageGraph {
8282
if (_transitiveDependencies == null) {
8383
var closure = transitiveClosure(
8484
mapMap<String, Package, String, Iterable<String>>(packages,
85-
value: (_, package) =>
86-
package.dependencies.map((dep) => dep.name)));
85+
value: (_, package) => package.dependencies.keys));
8786
_transitiveDependencies =
8887
mapMap<String, Set<String>, String, Set<Package>>(closure,
8988
value: (depender, names) {

lib/src/pubspec.dart

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -163,38 +163,38 @@ class Pubspec {
163163
Version _version;
164164

165165
/// The additional packages this package depends on.
166-
List<PackageRange> get dependencies {
166+
Map<String, PackageRange> get dependencies {
167167
if (_dependencies != null) return _dependencies;
168168
_dependencies =
169169
_parseDependencies('dependencies', fields.nodes['dependencies']);
170170
return _dependencies;
171171
}
172172

173-
List<PackageRange> _dependencies;
173+
Map<String, PackageRange> _dependencies;
174174

175175
/// The packages this package depends on when it is the root package.
176-
List<PackageRange> get devDependencies {
176+
Map<String, PackageRange> get devDependencies {
177177
if (_devDependencies != null) return _devDependencies;
178178
_devDependencies = _parseDependencies(
179179
'dev_dependencies', fields.nodes['dev_dependencies']);
180180
return _devDependencies;
181181
}
182182

183-
List<PackageRange> _devDependencies;
183+
Map<String, PackageRange> _devDependencies;
184184

185185
/// The dependency constraints that this package overrides when it is the
186186
/// root package.
187187
///
188188
/// Dependencies here will replace any dependency on a package with the same
189189
/// name anywhere in the dependency graph.
190-
List<PackageRange> get dependencyOverrides {
190+
Map<String, PackageRange> get dependencyOverrides {
191191
if (_dependencyOverrides != null) return _dependencyOverrides;
192192
_dependencyOverrides = _parseDependencies(
193193
'dependency_overrides', fields.nodes['dependency_overrides']);
194194
return _dependencyOverrides;
195195
}
196196

197-
List<PackageRange> _dependencyOverrides;
197+
Map<String, PackageRange> _dependencyOverrides;
198198

199199
Map<String, Feature> get features {
200200
if (_features != null) return _features;
@@ -235,7 +235,7 @@ class Pubspec {
235235

236236
var sdkConstraints = _parseEnvironment(specNode);
237237

238-
return new Feature(nameNode.value, dependencies,
238+
return new Feature(nameNode.value, dependencies.values,
239239
requires: requires,
240240
dartSdkConstraint: sdkConstraints.first,
241241
flutterSdkConstraint: sdkConstraints.last,
@@ -597,11 +597,16 @@ class Pubspec {
597597
Map fields,
598598
SourceRegistry sources})
599599
: _version = version,
600-
_dependencies = dependencies == null ? null : dependencies.toList(),
601-
_devDependencies =
602-
devDependencies == null ? null : devDependencies.toList(),
603-
_dependencyOverrides =
604-
dependencyOverrides == null ? null : dependencyOverrides.toList(),
600+
_dependencies = dependencies == null
601+
? null
602+
: new Map.fromIterable(dependencies, key: (range) => range.name),
603+
_devDependencies = devDependencies == null
604+
? null
605+
: new Map.fromIterable(devDependencies, key: (range) => range.name),
606+
_dependencyOverrides = dependencyOverrides == null
607+
? null
608+
: new Map.fromIterable(dependencyOverrides,
609+
key: (range) => range.name),
605610
_dartSdkConstraint =
606611
dartSdkConstraint ?? includeDefaultSdkConstraint == true
607612
? _defaultUpperBoundSdkConstraint
@@ -618,8 +623,8 @@ class Pubspec {
618623
: _sources = null,
619624
_name = null,
620625
_version = Version.none,
621-
_dependencies = <PackageRange>[],
622-
_devDependencies = <PackageRange>[],
626+
_dependencies = {},
627+
_devDependencies = {},
623628
_dartSdkConstraint = VersionConstraint.any,
624629
_flutterSdkConstraint = null,
625630
_includeDefaultSdkConstraint = false,
@@ -704,9 +709,9 @@ class Pubspec {
704709
}
705710

706711
/// Parses the dependency field named [field], and returns the corresponding
707-
/// list of dependencies.
708-
List<PackageRange> _parseDependencies(String field, YamlNode node) {
709-
var dependencies = <PackageRange>[];
712+
/// map of dependency names to dependencies.
713+
Map<String, PackageRange> _parseDependencies(String field, YamlNode node) {
714+
var dependencies = <String, PackageRange>{};
710715

711716
// Allow an empty dependencies key.
712717
if (node == null || node.value == null) return dependencies;
@@ -788,8 +793,8 @@ class Pubspec {
788793
containingPath: pubspecPath);
789794
});
790795

791-
dependencies
792-
.add(ref.withConstraint(versionConstraint).withFeatures(features));
796+
dependencies[name] =
797+
ref.withConstraint(versionConstraint).withFeatures(features);
793798
});
794799

795800
return dependencies;

0 commit comments

Comments
 (0)