@@ -2,23 +2,19 @@ import 'package:collection/collection.dart';
2
2
import 'package:pub_semver/pub_semver.dart' ;
3
3
import 'package:string_scanner/string_scanner.dart' ;
4
4
5
- class DepsList extends VersionedEntry {
5
+ class DepsList {
6
6
static final _sdkLine = RegExp (r'(\w+) SDK (.+)\n' );
7
- static final _sourcePackageLine = RegExp ('($_pkgName ) (.+)\n ' );
8
- static final _emptyLine = RegExp (r'\n' );
9
7
10
8
final Map <String , Version > sdks;
11
- final Map <String , Map <VersionedEntry , Map <String , VersionConstraint >>>
12
- sections;
13
-
14
- Map <VersionedEntry , Map <String , VersionConstraint >> get allEntries =>
15
- CombinedMapView (sections.values);
9
+ final Map <String , DepsPackageEntry > packages;
10
+ final Map <VersionedEntry , Map <String , VersionConstraint >>
11
+ transitiveDependencies;
16
12
17
- DepsList ._(
18
- super . entry,
19
- this .sdks,
20
- this .sections,
21
- ) : super . copy ();
13
+ DepsList ._(this .sdks, this .packages, { required this .transitiveDependencies}) {
14
+ for ( var entry in packages.values) {
15
+ entry._parent = this ;
16
+ }
17
+ }
22
18
23
19
factory DepsList .parse (String input) {
24
20
final scanner = StringScanner (input);
@@ -36,32 +32,77 @@ class DepsList extends VersionedEntry {
36
32
scanSdk ();
37
33
} while (scanner.matches (_sdkLine));
38
34
39
- scanner.expect (_sourcePackageLine, name: 'Source package' );
35
+ final pkgs = < String , DepsPackageEntry > {};
36
+ while (scanner.matches (_packageLine)) {
37
+ final entry = DepsPackageEntry ._parse (scanner);
38
+ pkgs[entry.name] = entry;
39
+ }
40
+
41
+ final section = scanner.matches (_transitiveDepsHeaderLine)
42
+ ? _scanSection (scanner, headerPattern: _transitiveDepsHeaderLine)
43
+ .entries
44
+ : < VersionedEntry , Map <String , VersionConstraint >> {};
45
+
46
+ return DepsList ._(
47
+ sdks,
48
+ pkgs,
49
+ transitiveDependencies: section,
50
+ );
51
+ }
52
+
53
+ Map <String , dynamic > toJson () => {
54
+ 'sdks' : sdks,
55
+ 'packages' : packages,
56
+ 'transitiveDependencies' :
57
+ transitiveDependencies.map ((k, v) => MapEntry (k.toString (), v)),
58
+ };
59
+ }
60
+
61
+ class DepsPackageEntry extends VersionedEntry {
62
+ static final _emptyLine = RegExp (r'\n' );
63
+
64
+ final Map <String , Map <VersionedEntry , Map <String , VersionConstraint >>>
65
+ sections;
66
+
67
+ late final DepsList _parent;
68
+
69
+ Map <VersionedEntry , Map <String , VersionConstraint >> get allEntries =>
70
+ CombinedMapView ([
71
+ ..._parent.packages.values.expand ((e) => e.sections.values),
72
+ _parent.transitiveDependencies,
73
+ ]);
74
+
75
+ DepsPackageEntry ._(
76
+ super .entry,
77
+ this .sections,
78
+ ) : super .copy ();
79
+
80
+ factory DepsPackageEntry ._parse (StringScanner scanner) {
81
+ scanner.expect (_packageLine, name: 'Source package' );
82
+
40
83
final sourcePackage = VersionedEntry .fromMatch (scanner.lastMatch! );
41
84
42
85
final sections =
43
86
< String , Map <VersionedEntry , Map <String , VersionConstraint >>> {};
44
87
45
88
while (scanner.scan (_emptyLine)) {
46
- final section = _scanSection ( scanner);
47
- sections[section.key] = section.value ;
48
- }
89
+ if ( ! scanner. matches (_sectionHeaderLine)) {
90
+ break ;
91
+ }
49
92
50
- assert (scanner.isDone, '${scanner .position } of ${input .length }' );
93
+ final section = _scanSection (scanner, headerPattern: _sectionHeaderLine);
94
+ sections[section.name] = section.entries;
95
+ }
51
96
52
- return DepsList ._(
97
+ return DepsPackageEntry ._(
53
98
sourcePackage,
54
- sdks,
55
99
sections,
56
100
);
57
101
}
58
102
59
103
Map <String , dynamic > toJson () => {
60
104
'name' : name,
61
105
'version' : version.toString (),
62
- 'sdks' : {
63
- for (var sdk in sdks.entries) sdk.key: sdk.value.toString (),
64
- },
65
106
'sections' : {
66
107
for (var section in sections.entries)
67
108
section.key: {
@@ -87,13 +128,15 @@ const _identifierRegExp = r'[a-zA-Z_]\w*';
87
128
/// when publishing a package to pub.dev.
88
129
const _pkgName = '$_identifierRegExp (?:\\ .$_identifierRegExp )*' ;
89
130
90
- final _sectionHeaderLine = RegExp (r'([a-zA-Z ]+):\n' );
131
+ final _sectionHeaderLine = RegExp (r'(dependencies|dev dependencies):\n' );
132
+ final _transitiveDepsHeaderLine = RegExp (r'(transitive dependencies):\n' );
133
+ final _packageLine = RegExp ('($_pkgName ) (\\ d.+)\n ' );
91
134
final _usageLine = RegExp ('- ($_pkgName ) (.+)\n ' );
92
135
final _depLine = RegExp (' - ($_pkgName ) (.+)\n ' );
93
136
94
- MapEntry < String , Map <VersionedEntry , Map <String , VersionConstraint >>>
95
- _scanSection (StringScanner scanner) {
96
- scanner.expect (_sectionHeaderLine , name: 'section header' );
137
+ ({ String name , Map <VersionedEntry , Map <String , VersionConstraint >> entries})
138
+ _scanSection (StringScanner scanner, { required Pattern headerPattern} ) {
139
+ scanner.expect (headerPattern , name: 'section header' );
97
140
final header = scanner.lastMatch! [1 ]! ;
98
141
99
142
final entries = < VersionedEntry , Map <String , VersionConstraint >> {};
@@ -115,7 +158,7 @@ MapEntry<String, Map<VersionedEntry, Map<String, VersionConstraint>>>
115
158
scanUsage ();
116
159
} while (scanner.matches (_usageLine));
117
160
118
- return MapEntry ( header, entries);
161
+ return (name : header, entries : entries);
119
162
}
120
163
121
164
class VersionedEntry {
0 commit comments