OLD | NEW |
| (Empty) |
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 | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library lock_file; | |
6 | |
7 import 'dart:json' as json; | |
8 | |
9 import 'package:yaml/yaml.dart'; | |
10 | |
11 import 'io.dart'; | |
12 import 'package.dart'; | |
13 import 'source_registry.dart'; | |
14 import 'utils.dart'; | |
15 import 'version.dart'; | |
16 | |
17 /// A parsed and validated `pubspec.lock` file. | |
18 class LockFile { | |
19 /// The packages this lockfile pins. | |
20 Map<String, PackageId> packages; | |
21 | |
22 LockFile._(this.packages); | |
23 | |
24 LockFile.empty() | |
25 : packages = <String, PackageId>{}; | |
26 | |
27 /// Loads a lockfile from [filePath]. | |
28 factory LockFile.load(String filePath, SourceRegistry sources) { | |
29 return LockFile._parse(filePath, readTextFile(filePath), sources); | |
30 } | |
31 | |
32 /// Parses a lockfile whose text is [contents]. | |
33 factory LockFile.parse(String contents, SourceRegistry sources) { | |
34 return LockFile._parse(null, contents, sources); | |
35 } | |
36 | |
37 /// Parses the lockfile whose text is [contents]. | |
38 static LockFile _parse(String filePath, String contents, | |
39 SourceRegistry sources) { | |
40 var packages = <String, PackageId>{}; | |
41 | |
42 if (contents.trim() == '') return new LockFile.empty(); | |
43 var parsed = loadYaml(contents); | |
44 | |
45 if (parsed.containsKey('packages')) { | |
46 var packageEntries = parsed['packages']; | |
47 | |
48 packageEntries.forEach((name, spec) { | |
49 // Parse the version. | |
50 if (!spec.containsKey('version')) { | |
51 throw new FormatException('Package $name is missing a version.'); | |
52 } | |
53 var version = new Version.parse(spec['version']); | |
54 | |
55 // Parse the source. | |
56 if (!spec.containsKey('source')) { | |
57 throw new FormatException('Package $name is missing a source.'); | |
58 } | |
59 var sourceName = spec['source']; | |
60 if (!sources.contains(sourceName)) { | |
61 throw new FormatException( | |
62 'Could not find a source named $sourceName.'); | |
63 } | |
64 var source = sources[sourceName]; | |
65 | |
66 // Parse the description. | |
67 if (!spec.containsKey('description')) { | |
68 throw new FormatException('Package $name is missing a description.'); | |
69 } | |
70 var description = spec['description']; | |
71 description = source.parseDescription(filePath, description, | |
72 fromLockFile: true); | |
73 | |
74 var id = new PackageId(name, source, version, description); | |
75 | |
76 // Validate the name. | |
77 if (name != id.name) { | |
78 throw new FormatException( | |
79 "Package name $name doesn't match ${id.name}."); | |
80 } | |
81 | |
82 packages[name] = id; | |
83 }); | |
84 } | |
85 | |
86 return new LockFile._(packages); | |
87 } | |
88 | |
89 /// Returns the serialized YAML text of the lock file. | |
90 String serialize() { | |
91 var packagesObj = <String, Map>{}; | |
92 packages.forEach((name, id) { | |
93 packagesObj[name] = { | |
94 'version': id.version.toString(), | |
95 'source': id.source.name, | |
96 'description': id.description | |
97 }; | |
98 }); | |
99 | |
100 // TODO(nweiz): Serialize using the YAML library once it supports | |
101 // serialization. For now, we use JSON, since it's a subset of YAML anyway. | |
102 return | |
103 '# Generated by pub\n' | |
104 '# See http://pub.dartlang.org/doc/glossary.html#lockfile\n' | |
105 '\n' | |
106 '${json.stringify({'packages': packagesObj})}\n'; | |
107 } | |
108 } | |
OLD | NEW |