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

Side by Side Diff: lib/src/lock_file.dart

Issue 2165423002: Add support for Flutter SDK constraints. (Closed) Base URL: git@github.com:dart-lang/pub.git@master
Patch Set: Code review changes Created 4 years, 5 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 unified diff | Download patch
« no previous file with comments | « lib/src/global_packages.dart ('k') | lib/src/pubspec.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 import 'dart:collection'; 5 import 'dart:collection';
6 6
7 import 'package:path/path.dart' as p; 7 import 'package:path/path.dart' as p;
8 import 'package:package_config/packages_file.dart' as packages_file; 8 import 'package:package_config/packages_file.dart' as packages_file;
9 import 'package:pub_semver/pub_semver.dart'; 9 import 'package:pub_semver/pub_semver.dart';
10 import 'package:source_span/source_span.dart'; 10 import 'package:source_span/source_span.dart';
11 import 'package:yaml/yaml.dart'; 11 import 'package:yaml/yaml.dart';
12 12
13 import 'io.dart'; 13 import 'io.dart';
14 import 'package.dart'; 14 import 'package.dart';
15 import 'source_registry.dart'; 15 import 'source_registry.dart';
16 import 'system_cache.dart'; 16 import 'system_cache.dart';
17 import 'utils.dart'; 17 import 'utils.dart';
18 18
19 /// A parsed and validated `pubspec.lock` file. 19 /// A parsed and validated `pubspec.lock` file.
20 class LockFile { 20 class LockFile {
21 /// The packages this lockfile pins. 21 /// The packages this lockfile pins.
22 final Map<String, PackageId> packages; 22 final Map<String, PackageId> packages;
23 23
24 /// The intersection of all SDK constraints for all locked packages. 24 /// The intersection of all Dart SDK constraints for all locked packages.
25 final VersionConstraint sdkConstraint; 25 final VersionConstraint dartSdkConstraint;
26
27 /// The intersection of all Flutter SDK constraints for all locked packages,
28 /// or `null` if no packages require the Flutter SDK.
29 final VersionConstraint flutterSdkConstraint;
26 30
27 /// Creates a new lockfile containing [ids]. 31 /// Creates a new lockfile containing [ids].
28 /// 32 ///
29 /// If passed, [sdkConstraint] represents the intersection of all SKD 33 /// If passed, [dartSdkConstraint] represents the intersection of all Dart SDK
30 /// constraints for all locked packages. It defaults to 34 /// constraints for all locked packages. It defaults to
31 /// [VersionConstraint.any]. 35 /// [VersionConstraint.any]. Similarly, [flutterSdkConstraint] represents the
32 LockFile(Iterable<PackageId> ids, {VersionConstraint sdkConstraint}) 36 /// intersection of all Flutter SDK constraints; however, it defaults to
37 /// `null`.
38 LockFile(Iterable<PackageId> ids, {VersionConstraint dartSdkConstraint,
39 VersionConstraint flutterSdkConstraint})
33 : this._( 40 : this._(
34 new Map.fromIterable( 41 new Map.fromIterable(
35 ids.where((id) => !id.isRoot), 42 ids.where((id) => !id.isRoot),
36 key: (id) => id.name), 43 key: (id) => id.name),
37 sdkConstraint ?? VersionConstraint.any); 44 dartSdkConstraint ?? VersionConstraint.any,
45 flutterSdkConstraint);
38 46
39 LockFile._(Map<String, PackageId> packages, this.sdkConstraint) 47 LockFile._(Map<String, PackageId> packages, this.dartSdkConstraint,
48 this.flutterSdkConstraint)
40 : packages = new UnmodifiableMapView(packages); 49 : packages = new UnmodifiableMapView(packages);
41 50
42 LockFile.empty() 51 LockFile.empty()
43 : packages = const {}, 52 : packages = const {},
44 sdkConstraint = VersionConstraint.any; 53 dartSdkConstraint = VersionConstraint.any,
54 flutterSdkConstraint = null;
45 55
46 /// Loads a lockfile from [filePath]. 56 /// Loads a lockfile from [filePath].
47 factory LockFile.load(String filePath, SourceRegistry sources) { 57 factory LockFile.load(String filePath, SourceRegistry sources) {
48 return LockFile._parse(filePath, readTextFile(filePath), sources); 58 return LockFile._parse(filePath, readTextFile(filePath), sources);
49 } 59 }
50 60
51 /// Parses a lockfile whose text is [contents]. 61 /// Parses a lockfile whose text is [contents].
52 factory LockFile.parse(String contents, SourceRegistry sources) { 62 factory LockFile.parse(String contents, SourceRegistry sources) {
53 return LockFile._parse(null, contents, sources); 63 return LockFile._parse(null, contents, sources);
54 } 64 }
55 65
56 /// Parses the lockfile whose text is [contents]. 66 /// Parses the lockfile whose text is [contents].
57 /// 67 ///
58 /// [filePath] is the system-native path to the lockfile on disc. It may be 68 /// [filePath] is the system-native path to the lockfile on disc. It may be
59 /// `null`. 69 /// `null`.
60 static LockFile _parse(String filePath, String contents, 70 static LockFile _parse(String filePath, String contents,
61 SourceRegistry sources) { 71 SourceRegistry sources) {
62 if (contents.trim() == '') return new LockFile.empty(); 72 if (contents.trim() == '') return new LockFile.empty();
63 73
64 var sourceUrl; 74 var sourceUrl;
65 if (filePath != null) sourceUrl = p.toUri(filePath); 75 if (filePath != null) sourceUrl = p.toUri(filePath);
66 var parsed = loadYamlNode(contents, sourceUrl: sourceUrl); 76 var parsed = loadYamlNode(contents, sourceUrl: sourceUrl);
67 77
68 _validate(parsed is Map, 'The lockfile must be a YAML mapping.', parsed); 78 _validate(parsed is Map, 'The lockfile must be a YAML mapping.', parsed);
69 79
70 var sdkConstraint = VersionConstraint.any; 80 var dartSdkConstraint = VersionConstraint.any;
71 var sdkConstraintText = parsed['sdk']; 81 VersionConstraint flutterSdkConstraint;
72 if (sdkConstraintText != null) { 82 var sdkNode = parsed.nodes['sdk'];
83 if (sdkNode != null) {
84 // Lockfiles produced by pub versions from 1.14.0 through 1.18.0 included
85 // a top-level "sdk" field which encoded the unified constraint on the
86 // Dart SDK. They had no way of specifying constraints on other SDKs.
87 dartSdkConstraint = _parseVersionConstraint(sdkNode);
88 } else if ((parsed as Map).containsKey('sdks')) {
89 var sdksField = parsed['sdks'];
73 _validate( 90 _validate(
74 sdkConstraintText is String, 91 sdksField is Map,
75 'The "sdk" field must be a string.', 92 'The "sdks" field must be a mapping.',
76 parsed.nodes['sdk']); 93 parsed.nodes['sdks']);
77 94
78 sdkConstraint = _wrapFormatException( 95 dartSdkConstraint = _parseVersionConstraint(sdksField.nodes['dart']);
79 'version constraint', 96 flutterSdkConstraint =
80 parsed.nodes['sdk'].span, 97 _parseVersionConstraint(sdksField.nodes['flutter']);
81 () => new VersionConstraint.parse(sdkConstraintText));
82 } 98 }
83 99
84 var packages = {}; 100 var packages = {};
85 var packageEntries = parsed['packages']; 101 var packageEntries = parsed['packages'];
86 if (packageEntries != null) { 102 if (packageEntries != null) {
87 _validate(packageEntries is Map, 'The "packages" field must be a map.', 103 _validate(packageEntries is Map, 'The "packages" field must be a map.',
88 parsed.nodes['packages']); 104 parsed.nodes['packages']);
89 105
90 packageEntries.forEach((name, spec) { 106 packageEntries.forEach((name, spec) {
91 // Parse the version. 107 // Parse the version.
(...skipping 21 matching lines...) Expand all
113 } 129 }
114 130
115 // Validate the name. 131 // Validate the name.
116 _validate(name == id.name, 132 _validate(name == id.name,
117 "Package name $name doesn't match ${id.name}.", spec); 133 "Package name $name doesn't match ${id.name}.", spec);
118 134
119 packages[name] = id; 135 packages[name] = id;
120 }); 136 });
121 } 137 }
122 138
123 return new LockFile._(packages, sdkConstraint); 139 return new LockFile._(packages, dartSdkConstraint, flutterSdkConstraint);
140 }
141
142 /// Asserts that [node] is a version constraint, and parses it.
143 static VersionConstraint _parseVersionConstraint(YamlNode node) {
144 if (node == null) return null;
145
146 _validate(
147 node.value is String,
148 'Invalid version constraint: must be a string.',
149 node);
150
151 return _wrapFormatException(
152 'version constraint',
153 node.span,
154 () => new VersionConstraint.parse(node.value));
124 } 155 }
125 156
126 /// Runs [fn] and wraps any [FormatException] it throws in a 157 /// Runs [fn] and wraps any [FormatException] it throws in a
127 /// [SourceSpanFormatException]. 158 /// [SourceSpanFormatException].
128 /// 159 ///
129 /// [description] should be a noun phrase that describes whatever's being 160 /// [description] should be a noun phrase that describes whatever's being
130 /// parsed or processed by [fn]. [span] should be the location of whatever's 161 /// parsed or processed by [fn]. [span] should be the location of whatever's
131 /// being processed within the pubspec. 162 /// being processed within the pubspec.
132 static _wrapFormatException(String description, SourceSpan span, fn()) { 163 static _wrapFormatException(String description, SourceSpan span, fn()) {
133 try { 164 try {
(...skipping 12 matching lines...) Expand all
146 177
147 /// Returns a copy of this LockFile with [id] added. 178 /// Returns a copy of this LockFile with [id] added.
148 /// 179 ///
149 /// If there's already an ID with the same name as [id] in the LockFile, it's 180 /// If there's already an ID with the same name as [id] in the LockFile, it's
150 /// overwritten. 181 /// overwritten.
151 LockFile setPackage(PackageId id) { 182 LockFile setPackage(PackageId id) {
152 if (id.isRoot) return this; 183 if (id.isRoot) return this;
153 184
154 var packages = new Map.from(this.packages); 185 var packages = new Map.from(this.packages);
155 packages[id.name] = id; 186 packages[id.name] = id;
156 return new LockFile._(packages, sdkConstraint); 187 return new LockFile._(packages, dartSdkConstraint, flutterSdkConstraint);
157 } 188 }
158 189
159 /// Returns a copy of this LockFile with a package named [name] removed. 190 /// Returns a copy of this LockFile with a package named [name] removed.
160 /// 191 ///
161 /// Returns an identical [LockFile] if there's no package named [name]. 192 /// Returns an identical [LockFile] if there's no package named [name].
162 LockFile removePackage(String name) { 193 LockFile removePackage(String name) {
163 if (!this.packages.containsKey(name)) return this; 194 if (!this.packages.containsKey(name)) return this;
164 195
165 var packages = new Map.from(this.packages); 196 var packages = new Map.from(this.packages);
166 packages.remove(name); 197 packages.remove(name);
167 return new LockFile._(packages, sdkConstraint); 198 return new LockFile._(packages, dartSdkConstraint, flutterSdkConstraint);
168 } 199 }
169 200
170 /// Returns the contents of the `.packages` file generated from this lockfile. 201 /// Returns the contents of the `.packages` file generated from this lockfile.
171 /// 202 ///
172 /// If [entrypoint] is passed, a relative entry is added for its "lib/" 203 /// If [entrypoint] is passed, a relative entry is added for its "lib/"
173 /// directory. 204 /// directory.
174 String packagesFile(SystemCache cache, [String entrypoint]) { 205 String packagesFile(SystemCache cache, [String entrypoint]) {
175 var header = "Generated by pub on ${new DateTime.now()}."; 206 var header = "Generated by pub on ${new DateTime.now()}.";
176 207
177 var map = new Map.fromIterable(ordered(packages.keys), value: (name) { 208 var map = new Map.fromIterable(ordered(packages.keys), value: (name) {
(...skipping 20 matching lines...) Expand all
198 var description = package.source 229 var description = package.source
199 .serializeDescription(packageDir, package.description); 230 .serializeDescription(packageDir, package.description);
200 231
201 packageMap[name] = { 232 packageMap[name] = {
202 'version': package.version.toString(), 233 'version': package.version.toString(),
203 'source': package.source.name, 234 'source': package.source.name,
204 'description': description 235 'description': description
205 }; 236 };
206 }); 237 });
207 238
208 var data = {'sdk': sdkConstraint.toString(), 'packages': packageMap}; 239 var sdks = {
240 'dart': dartSdkConstraint.toString()
241 };
242 if (flutterSdkConstraint != null) {
243 sdks['flutter'] = flutterSdkConstraint.toString();
244 }
245
246 var data = {'sdks': sdks, 'packages': packageMap};
209 return """ 247 return """
210 # Generated by pub 248 # Generated by pub
211 # See http://pub.dartlang.org/doc/glossary.html#lockfile 249 # See http://pub.dartlang.org/doc/glossary.html#lockfile
212 ${yamlToString(data)} 250 ${yamlToString(data)}
213 """; 251 """;
214 } 252 }
215 } 253 }
OLDNEW
« no previous file with comments | « lib/src/global_packages.dart ('k') | lib/src/pubspec.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698