Index: lib/src/lock_file.dart |
diff --git a/lib/src/lock_file.dart b/lib/src/lock_file.dart |
index 94c574b2ae1de6bbc2e663d6a702e165b93a3c87..9726a105cc14d807b420df22f1e33eb742c50d91 100644 |
--- a/lib/src/lock_file.dart |
+++ b/lib/src/lock_file.dart |
@@ -25,19 +25,29 @@ class LockFile { |
/// The packages this lockfile pins. |
final Map<String, PackageId> packages; |
- /// Creates a new lockfile containing [ids]. |
- factory LockFile(Iterable<PackageId> ids, SourceRegistry sources) { |
- var packages = new Map.fromIterable( |
- ids.where((id) => !id.isRoot), |
- key: (id) => id.name); |
- return new LockFile._(packages, sources); |
- } |
+ /// The intersection of all SDK constraints for all locked packages. |
+ final VersionConstraint sdkConstraint; |
- LockFile._(Map<String, PackageId> packages, this._sources) |
+ /// Creates a new lockfile containing [ids]. |
+ /// |
+ /// If passed, [sdkConstraint] represents the intersection of all SKD |
+ /// constraints for all locked packages. It defaults to |
+ /// [VersionConstraint.any]. |
+ LockFile(Iterable<PackageId> ids, SourceRegistry sources, |
+ {VersionConstraint sdkConstraint}) |
+ : this._( |
+ new Map.fromIterable( |
+ ids.where((id) => !id.isRoot), |
+ key: (id) => id.name), |
+ sdkConstraint ?? VersionConstraint.any, |
+ sources); |
+ |
+ LockFile._(Map<String, PackageId> packages, this.sdkConstraint, this._sources) |
: packages = new UnmodifiableMapView(packages); |
LockFile.empty(this._sources) |
- : packages = const {}; |
+ : packages = const {}, |
+ sdkConstraint = VersionConstraint.any; |
/// Loads a lockfile from [filePath]. |
factory LockFile.load(String filePath, SourceRegistry sources) { |
@@ -55,8 +65,6 @@ class LockFile { |
/// `null`. |
static LockFile _parse(String filePath, String contents, |
SourceRegistry sources) { |
- var packages = {}; |
- |
if (contents.trim() == '') return new LockFile.empty(sources); |
var sourceUrl; |
@@ -65,6 +73,19 @@ class LockFile { |
_validate(parsed is Map, 'The lockfile must be a YAML mapping.', parsed); |
+ var sdkConstraint = VersionConstraint.any; |
+ var sdkConstraintText = parsed['sdk']; |
+ if (sdkConstraintText != null) { |
+ _validate(sdkConstraintText is String, 'The "sdk" field must be a string.', |
Bob Nystrom
2015/12/21 20:55:03
Long line.
nweiz
2016/01/04 23:27:29
Done.
|
+ parsed.nodes['sdk']); |
+ |
+ sdkConstraint = _wrapFormatException( |
+ 'version constraint', |
+ parsed.nodes['sdk'], |
+ () => new VersionConstraint.parse(sdkConstraintText)); |
+ } |
+ |
+ var packages = {}; |
var packageEntries = parsed['packages']; |
if (packageEntries != null) { |
_validate(packageEntries is Map, 'The "packages" field must be a map.', |
@@ -103,7 +124,22 @@ class LockFile { |
}); |
} |
- return new LockFile._(packages, sources); |
+ return new LockFile._(packages, sdkConstraint, sources); |
+ } |
+ |
+ /// Runs [fn] and wraps any [FormatException] it throws in a |
+ /// [SourceSpanFormatException]. |
+ /// |
+ /// [description] should be a noun phrase that describes whatever's being |
+ /// parsed or processed by [fn]. [span] should be the location of whatever's |
+ /// being processed within the pubspec. |
+ static _wrapFormatException(String description, SourceSpan span, fn()) { |
+ try { |
+ return fn(); |
+ } on FormatException catch (e) { |
+ throw new SourceSpanFormatException( |
+ 'Invalid $description: ${e.message}', span); |
+ } |
} |
Bob Nystrom
2015/12/21 20:55:03
Do we do this elsewhere? Maybe move it into utils?
nweiz
2016/01/04 23:27:29
We do something similar in pubspec.dart, but it th
|
/// If [condition] is `false` throws a format error with [message] for [node]. |
@@ -121,7 +157,7 @@ class LockFile { |
var packages = new Map.from(this.packages); |
packages[id.name] = id; |
- return new LockFile._(packages, _sources); |
+ return new LockFile._(packages, sdkConstraint, _sources); |
} |
/// Returns a copy of this LockFile with a package named [name] removed. |
@@ -132,7 +168,7 @@ class LockFile { |
var packages = new Map.from(this.packages); |
packages.remove(name); |
- return new LockFile._(packages, _sources); |
+ return new LockFile._(packages, sdkConstraint, _sources); |
} |
/// Returns the contents of the `.packages` file generated from this lockfile. |
@@ -161,22 +197,23 @@ class LockFile { |
/// properly serialize package descriptions. |
String serialize(String packageDir) { |
// Convert the dependencies to a simple object. |
- var data = {}; |
+ var packageMap = {}; |
packages.forEach((name, package) { |
var description = _sources[package.source] |
.serializeDescription(packageDir, package.description); |
- data[name] = { |
+ packageMap[name] = { |
'version': package.version.toString(), |
'source': package.source, |
'description': description |
}; |
}); |
+ var data = {'sdk': sdkConstraint.toString(), 'packages': packageMap}; |
return """ |
# Generated by pub |
# See http://pub.dartlang.org/doc/glossary.html#lockfile |
-${yamlToString({'packages': data})} |
+${yamlToString(data)} |
"""; |
} |
} |