@@ -23,6 +23,7 @@ import '../package_name.dart';
23
23
import '../pubspec.dart' ;
24
24
import '../pubspec_utils.dart' ;
25
25
import '../solver.dart' ;
26
+ import '../source/git.dart' ;
26
27
import '../system_cache.dart' ;
27
28
import '../utils.dart' ;
28
29
@@ -74,11 +75,11 @@ class DependencyServicesReportCommand extends PubCommand {
74
75
Future <List <Object >> _computeUpgradeSet (
75
76
Pubspec rootPubspec,
76
77
PackageId ? package, {
77
- required UpgradeType upgradeType,
78
+ required _UpgradeType upgradeType,
78
79
}) async {
79
80
if (package == null ) return [];
80
81
final lockFile = entrypoint.lockFile;
81
- final pubspec = upgradeType == UpgradeType .multiBreaking
82
+ final pubspec = upgradeType == _UpgradeType .multiBreaking
82
83
? stripVersionUpperBounds (rootPubspec)
83
84
: Pubspec (
84
85
rootPubspec.name,
@@ -87,7 +88,7 @@ class DependencyServicesReportCommand extends PubCommand {
87
88
sdkConstraints: rootPubspec.sdkConstraints,
88
89
);
89
90
90
- final dependencySet = dependencySetOfPackage (pubspec, package);
91
+ final dependencySet = _dependencySetOfPackage (pubspec, package);
91
92
if (dependencySet != null ) {
92
93
// Force the version to be the new version.
93
94
dependencySet[package.name] =
@@ -110,38 +111,43 @@ class DependencyServicesReportCommand extends PubCommand {
110
111
...resolution.packages.where ((r) {
111
112
if (r.name == rootPubspec.name) return false ;
112
113
final originalVersion = currentPackages[r.name];
113
- return originalVersion == null ||
114
- r.version != originalVersion.version;
114
+ return originalVersion == null || r != originalVersion;
115
115
}).map ((p) {
116
- final depset = dependencySetOfPackage (rootPubspec, p);
116
+ final depset = _dependencySetOfPackage (rootPubspec, p);
117
117
final originalConstraint = depset? [p.name]? .constraint;
118
+ final currentPackage = currentPackages[p.name];
118
119
return {
119
120
'name' : p.name,
120
- 'version' : p.version. toString (),
121
+ 'version' : p.versionOrHash (),
121
122
'kind' : _kindString (pubspec, p.name),
123
+ 'source' : _source (p, containingDir: directory),
122
124
'constraintBumped' : originalConstraint == null
123
125
? null
124
- : upgradeType == UpgradeType .compatible
126
+ : upgradeType == _UpgradeType .compatible
125
127
? originalConstraint.toString ()
126
128
: VersionConstraint .compatibleWith (p.version).toString (),
127
129
'constraintWidened' : originalConstraint == null
128
130
? null
129
- : upgradeType == UpgradeType .compatible
131
+ : upgradeType == _UpgradeType .compatible
130
132
? originalConstraint.toString ()
131
133
: _widenConstraint (originalConstraint, p.version)
132
134
.toString (),
133
135
'constraintBumpedIfNeeded' : originalConstraint == null
134
136
? null
135
- : upgradeType == UpgradeType .compatible
137
+ : upgradeType == _UpgradeType .compatible
136
138
? originalConstraint.toString ()
137
139
: originalConstraint.allows (p.version)
138
140
? originalConstraint.toString ()
139
141
: VersionConstraint .compatibleWith (p.version)
140
142
.toString (),
141
- 'previousVersion' : currentPackages[p.name] ? .version. toString (),
143
+ 'previousVersion' : currentPackage ? . versionOrHash (),
142
144
'previousConstraint' : originalConstraint? .toString (),
145
+ 'previousSource' : currentPackage == null
146
+ ? null
147
+ : _source (currentPackage, containingDir: directory),
143
148
};
144
149
}),
150
+ // Find packages that were removed by the resolution
145
151
for (final oldPackageName in lockFile.packages.keys)
146
152
if (! resolution.packages
147
153
.any ((newPackage) => newPackage.name == oldPackageName))
@@ -154,8 +160,10 @@ class DependencyServicesReportCommand extends PubCommand {
154
160
'constraintWidened' : null ,
155
161
'constraintBumpedIfNeeded' : null ,
156
162
'previousVersion' :
157
- currentPackages[oldPackageName]? .version. toString (),
163
+ currentPackages[oldPackageName]? .versionOrHash (),
158
164
'previousConstraint' : null ,
165
+ 'previous' : _source (currentPackages[oldPackageName]! ,
166
+ containingDir: directory)
159
167
},
160
168
];
161
169
}
@@ -173,7 +181,7 @@ class DependencyServicesReportCommand extends PubCommand {
173
181
devDependencies: compatiblePubspec.devDependencies.values,
174
182
);
175
183
final dependencySet =
176
- dependencySetOfPackage (singleBreakingPubspec, package);
184
+ _dependencySetOfPackage (singleBreakingPubspec, package);
177
185
final kind = _kindString (compatiblePubspec, package.name);
178
186
PackageId ? singleBreakingVersion;
179
187
if (dependencySet != null ) {
@@ -187,25 +195,24 @@ class DependencyServicesReportCommand extends PubCommand {
187
195
}
188
196
dependencies.add ({
189
197
'name' : package.name,
190
- 'version' : package.version. toString (),
198
+ 'version' : package.versionOrHash (),
191
199
'kind' : kind,
200
+ 'source' : _source (package, containingDir: directory),
192
201
'latest' :
193
202
(await cache.getLatest (package.toRef (), version: package.version))
194
- ? .version
195
- .toString (),
203
+ ? .versionOrHash (),
196
204
'constraint' :
197
205
_constraintOf (compatiblePubspec, package.name)? .toString (),
198
- if (compatibleVersion != null )
199
- 'compatible' : await _computeUpgradeSet (
200
- compatiblePubspec, compatibleVersion,
201
- upgradeType: UpgradeType .compatible),
206
+ 'compatible' : await _computeUpgradeSet (
207
+ compatiblePubspec, compatibleVersion,
208
+ upgradeType: _UpgradeType .compatible),
202
209
'singleBreaking' : kind != 'transitive' && singleBreakingVersion == null
203
210
? []
204
211
: await _computeUpgradeSet (compatiblePubspec, singleBreakingVersion,
205
- upgradeType: UpgradeType .singleBreaking),
212
+ upgradeType: _UpgradeType .singleBreaking),
206
213
'multiBreaking' : kind != 'transitive' && multiBreakingVersion != null
207
214
? await _computeUpgradeSet (compatiblePubspec, multiBreakingVersion,
208
- upgradeType: UpgradeType .multiBreaking)
215
+ upgradeType: _UpgradeType .multiBreaking)
209
216
: [],
210
217
});
211
218
}
@@ -227,6 +234,14 @@ String _kindString(Pubspec pubspec, String packageName) {
227
234
: 'transitive' ;
228
235
}
229
236
237
+ Map <String , Object ?> _source (PackageId id, {required String containingDir}) {
238
+ return {
239
+ 'type' : id.source.name,
240
+ 'description' :
241
+ id.description.serializeForLockfile (containingDir: containingDir),
242
+ };
243
+ }
244
+
230
245
/// Try to solve [pubspec] return [PackageId] s in the resolution or `null` if no
231
246
/// resolution was found.
232
247
Future <List <PackageId >?> _tryResolve (Pubspec pubspec, SystemCache cache) async {
@@ -269,16 +284,28 @@ class DependencyServicesListCommand extends PubCommand {
269
284
for (final package in currentPackages) {
270
285
dependencies.add ({
271
286
'name' : package.name,
272
- 'version' : package.version. toString (),
287
+ 'version' : package.versionOrHash (),
273
288
'kind' : _kindString (pubspec, package.name),
274
289
'constraint' : _constraintOf (pubspec, package.name).toString (),
290
+ 'source' : _source (package, containingDir: directory),
275
291
});
276
292
}
277
293
log.message (JsonEncoder .withIndent (' ' ).convert (result));
278
294
}
279
295
}
280
296
281
- enum UpgradeType {
297
+ extension on PackageId {
298
+ String versionOrHash () {
299
+ final description = this .description;
300
+ if (description is GitResolvedDescription ) {
301
+ return description.resolvedRef;
302
+ } else {
303
+ return version.toString ();
304
+ }
305
+ }
306
+ }
307
+
308
+ enum _UpgradeType {
282
309
/// Only upgrade pubspec.lock.
283
310
compatible,
284
311
@@ -315,7 +342,7 @@ class DependencyServicesApplyCommand extends PubCommand {
315
342
toApply.add (
316
343
_PackageVersion (
317
344
change['name' ],
318
- change['version' ] != null ? Version . parse (change[ 'version' ]) : null ,
345
+ change['version' ],
319
346
change['constraint' ] != null
320
347
? VersionConstraint .parse (change['constraint' ])
321
348
: null ,
@@ -334,13 +361,24 @@ class DependencyServicesApplyCommand extends PubCommand {
334
361
final targetPackage = p.name;
335
362
final targetVersion = p.version;
336
363
final targetConstraint = p.constraint;
364
+ final targetRevision = p.gitRevision;
337
365
338
366
if (targetConstraint != null ) {
339
367
final section = pubspec.dependencies[targetPackage] != null
340
368
? 'dependencies'
341
369
: 'dev_dependencies' ;
342
- pubspecEditor
343
- .update ([section, targetPackage], targetConstraint.toString ());
370
+ final packageConfig =
371
+ pubspecEditor.parseAt ([section, targetPackage]).value;
372
+ if (packageConfig == null || packageConfig is String ) {
373
+ pubspecEditor
374
+ .update ([section, targetPackage], targetConstraint.toString ());
375
+ } else if (packageConfig is Map ) {
376
+ pubspecEditor.update (
377
+ [section, targetPackage, 'version' ], targetConstraint.toString ());
378
+ } else {
379
+ fail (
380
+ 'The dependency $targetPackage does not have a map or string as a description' );
381
+ }
344
382
} else if (targetVersion != null ) {
345
383
final constraint = _constraintOf (pubspec, targetPackage);
346
384
if (constraint != null && ! constraint.allows (targetVersion)) {
@@ -351,18 +389,43 @@ class DependencyServicesApplyCommand extends PubCommand {
351
389
VersionConstraint .compatibleWith (targetVersion).toString ());
352
390
}
353
391
}
354
- if (targetVersion != null &&
355
- lockFileEditor != null &&
356
- lockFileYaml['packages' ].containsKey (targetPackage)) {
357
- lockFileEditor.update (
358
- ['packages' , targetPackage, 'version' ], targetVersion.toString ());
359
- }
360
- if (targetVersion == null &&
361
- lockFileEditor != null &&
362
- ! lockFileYaml['packages' ].containsKey (targetPackage)) {
363
- dataError (
364
- 'Trying to remove non-existing transitive dependency $targetPackage .' ,
365
- );
392
+ if (lockFileEditor != null ) {
393
+ if (targetVersion != null &&
394
+ lockFileYaml['packages' ].containsKey (targetPackage)) {
395
+ lockFileEditor.update (
396
+ ['packages' , targetPackage, 'version' ], targetVersion.toString ());
397
+ } else if (targetRevision != null &&
398
+ lockFileYaml['packages' ].containsKey (targetPackage)) {
399
+ final ref = entrypoint.lockFile.packages[targetPackage]! .toRef ();
400
+ final currentDescription = ref.description as GitDescription ;
401
+ final updatedRef = PackageRef (
402
+ targetPackage,
403
+ GitDescription (
404
+ url: currentDescription.url,
405
+ path: currentDescription.path,
406
+ ref: targetRevision,
407
+ containingDir: directory));
408
+ final versions = await cache.getVersions (updatedRef);
409
+ if (versions.isEmpty) {
410
+ dataError (
411
+ 'Found no versions of $targetPackage with git revision `$targetRevision `.' );
412
+ }
413
+ // GitSource can only return a single version.
414
+ assert (versions.length == 1 );
415
+
416
+ lockFileEditor.update (['packages' , targetPackage, 'version' ],
417
+ versions.single.version.toString ());
418
+ lockFileEditor.update (
419
+ ['packages' , targetPackage, 'description' , 'resolved-ref' ],
420
+ targetRevision,
421
+ );
422
+ } else if (targetVersion == null &&
423
+ targetRevision == null &&
424
+ ! lockFileYaml['packages' ].containsKey (targetPackage)) {
425
+ dataError (
426
+ 'Trying to remove non-existing transitive dependency $targetPackage .' ,
427
+ );
428
+ }
366
429
}
367
430
}
368
431
@@ -407,11 +470,31 @@ class DependencyServicesApplyCommand extends PubCommand {
407
470
class _PackageVersion {
408
471
String name;
409
472
Version ? version;
473
+ String ? gitRevision;
410
474
VersionConstraint ? constraint;
411
- _PackageVersion (this .name, this .version, this .constraint);
475
+ _PackageVersion (this .name, String ? versionOrHash, this .constraint)
476
+ : version =
477
+ versionOrHash == null ? null : _tryParseVersion (versionOrHash),
478
+ gitRevision =
479
+ versionOrHash == null ? null : _tryParseHash (versionOrHash);
480
+ }
481
+
482
+ Version ? _tryParseVersion (String v) {
483
+ try {
484
+ return Version .parse (v);
485
+ } on FormatException {
486
+ return null ;
487
+ }
488
+ }
489
+
490
+ String ? _tryParseHash (String v) {
491
+ if (RegExp (r'^[a-fA-F0-9]+$' ).hasMatch (v)) {
492
+ return v;
493
+ }
494
+ return null ;
412
495
}
413
496
414
- Map <String , PackageRange >? dependencySetOfPackage (
497
+ Map <String , PackageRange >? _dependencySetOfPackage (
415
498
Pubspec pubspec, PackageId package) {
416
499
return pubspec.dependencies.containsKey (package.name)
417
500
? pubspec.dependencies
@@ -427,7 +510,7 @@ VersionConstraint _widenConstraint(
427
510
final min = original.min;
428
511
final max = original.max;
429
512
if (max != null && newVersion >= max) {
430
- return compatibleWithIfPossible (
513
+ return _compatibleWithIfPossible (
431
514
VersionRange (
432
515
min: min,
433
516
includeMin: original.includeMin,
@@ -436,7 +519,7 @@ VersionConstraint _widenConstraint(
436
519
);
437
520
}
438
521
if (min != null && newVersion <= min) {
439
- return compatibleWithIfPossible (
522
+ return _compatibleWithIfPossible (
440
523
VersionRange (
441
524
min: newVersion,
442
525
includeMin: true ,
@@ -451,7 +534,7 @@ VersionConstraint _widenConstraint(
451
534
original, 'original' , 'Must be a Version range or empty' );
452
535
}
453
536
454
- VersionConstraint compatibleWithIfPossible (VersionRange versionRange) {
537
+ VersionConstraint _compatibleWithIfPossible (VersionRange versionRange) {
455
538
final min = versionRange.min;
456
539
if (min != null && min.nextBreaking.firstPreRelease == versionRange.max) {
457
540
return VersionConstraint .compatibleWith (min);
0 commit comments