Normalize pub.dartlang.org to pub.dev when reading lockfile (#3754)
Cherry-pick of 3ce46a32e14b76555de70afa9dc1281ab999159c
diff --git a/lib/src/command/global_activate.dart b/lib/src/command/global_activate.dart
index 53353ae..505ebe4 100644
--- a/lib/src/command/global_activate.dart
+++ b/lib/src/command/global_activate.dart
@@ -7,7 +7,7 @@
import 'package:pub_semver/pub_semver.dart';
import '../command.dart';
-import '../source/hosted.dart';
+import '../package_name.dart';
import '../utils.dart';
/// Handles the `global activate` pub command.
@@ -69,14 +69,6 @@
}
final overwrite = argResults['overwrite'] as bool;
- Uri? hostedUrl;
- if (argResults.wasParsed('hosted-url')) {
- try {
- hostedUrl = validateAndNormalizeHostedUrl(argResults['hosted-url']);
- } on FormatException catch (e) {
- usageException('Invalid hosted-url: $e');
- }
- }
Iterable<String> args = argResults.rest;
@@ -115,6 +107,13 @@
case 'hosted':
var package = readArg('No package to activate given.');
+ PackageRef ref;
+ try {
+ ref = cache.hosted.refFor(package, url: argResults['hosted-url']);
+ } on FormatException catch (e) {
+ usageException('Invalid hosted-url: $e');
+ }
+
// Parse the version constraint, if there is one.
var constraint = VersionConstraint.any;
if (args.isNotEmpty) {
@@ -127,11 +126,9 @@
validateNoExtraArgs();
return globals.activateHosted(
- package,
- constraint,
+ ref.withConstraint(constraint),
executables,
overwriteBinStubs: overwrite,
- url: hostedUrl?.toString(),
);
case 'path':
diff --git a/lib/src/global_packages.dart b/lib/src/global_packages.dart
index 089016a..27c46ec 100644
--- a/lib/src/global_packages.dart
+++ b/lib/src/global_packages.dart
@@ -139,16 +139,16 @@
/// [url] is an optional custom pub server URL. If not null, the package to be
/// activated will be fetched from this URL instead of the default pub URL.
Future<void> activateHosted(
- String name,
- VersionConstraint constraint,
+ PackageRange range,
List<String>? executables, {
required bool overwriteBinStubs,
String? url,
}) async {
await _installInCache(
- cache.hosted.refFor(name, url: url).withConstraint(constraint),
- executables,
- overwriteBinStubs: overwriteBinStubs);
+ range,
+ executables,
+ overwriteBinStubs: overwriteBinStubs,
+ );
}
/// Makes the local package at [path] globally active.
diff --git a/lib/src/source/hosted.dart b/lib/src/source/hosted.dart
index 2d481e4..6f590e1 100644
--- a/lib/src/source/hosted.dart
+++ b/lib/src/source/hosted.dart
@@ -51,7 +51,7 @@
/// backwards compatibility with `pubspec.lock`-files which contain
/// `https://pub.dartlang.org`.
///
-/// Throws [FormatException] if there is anything wrong [hostedUrl].
+/// Throws [FormatException] if there is anything wrong with [hostedUrl].
///
/// [1]: ../../../doc/repository-spec-v2.md
Uri validateAndNormalizeHostedUrl(String hostedUrl) {
@@ -194,8 +194,8 @@
/// Returns a reference to a hosted package named [name].
///
/// If [url] is passed, it's the URL of the pub server from which the package
- /// should be downloaded. [url] most be normalized and validated using
- /// [validateAndNormalizeHostedUrl].
+ /// should be downloaded. [url] will be normalized and validated using
+ /// [validateAndNormalizeHostedUrl]. This can throw a [FormatException].
PackageRef refFor(String name, {String? url}) {
final d = HostedDescription(name, url ?? defaultUrl);
return PackageRef(name, d);
@@ -258,7 +258,7 @@
name,
version,
ResolvedHostedDescription(
- HostedDescription(name, Uri.parse(url).toString()),
+ HostedDescription(name, url),
sha256: sha256 == null ? null : hexDecode(sha256),
),
);
@@ -291,8 +291,7 @@
// environment, we throw an error if something that looks like a URI is
// used as a package name.
if (canUseShorthandSyntax) {
- return HostedDescription(
- packageName, validateAndNormalizeHostedUrl(description).toString());
+ return HostedDescription(packageName, description);
} else {
if (_looksLikePackageName.hasMatch(description)) {
// Valid use of `hosted: package` dependency with an old SDK
@@ -319,14 +318,11 @@
'a minimum Dart SDK constraint of ${LanguageVersion.firstVersionWithShorterHostedSyntax}.0 or higher.');
}
- var url = defaultUrl;
final u = description['url'];
- if (u != null) {
- if (u is! String) {
- throw FormatException("The 'url' key must be a string value.");
- }
- url = validateAndNormalizeHostedUrl(u).toString();
+ if (u != null && u is! String) {
+ throw FormatException("The 'url' key must be a string value.");
}
+ final url = u ?? defaultUrl;
return HostedDescription(name, url);
}
@@ -915,7 +911,7 @@
package.name,
package.version,
ResolvedHostedDescription(
- HostedDescription(package.name, url),
+ HostedDescription._(package.name, url),
sha256: null,
),
);
@@ -1178,10 +1174,7 @@
pubspec.name,
pubspec.version,
ResolvedHostedDescription(
- HostedDescription(
- pubspec.name,
- validateAndNormalizeHostedUrl(cache.hosted.defaultUrl).toString(),
- ),
+ HostedDescription(pubspec.name, defaultUrl),
sha256: contentHash,
),
);
@@ -1283,7 +1276,12 @@
final String packageName;
final String url;
- HostedDescription(this.packageName, this.url);
+ HostedDescription._(this.packageName, this.url);
+ factory HostedDescription(String packageName, String url) =>
+ HostedDescription._(
+ packageName,
+ validateAndNormalizeHostedUrl(url).toString(),
+ );
@override
int get hashCode => Object.hash(packageName, url);
diff --git a/test/lock_file_test.dart b/test/lock_file_test.dart
index 20e3976..7e01e7f 100644
--- a/test/lock_file_test.dart
+++ b/test/lock_file_test.dart
@@ -205,6 +205,41 @@
}, throwsFormatException);
});
+ test('Reads pub.dartlang.org as pub.dev in hosted descriptions', () {
+ final lockfile = LockFile.parse(
+ '''
+packages:
+ characters:
+ dependency: transitive
+ description:
+ name: characters
+ url: "https://pub.dartlang.org"
+ source: hosted
+ version: "1.2.1"
+ retry:
+ dependency: transitive
+ description:
+ name: retry
+ url: "https://pub.dev"
+ sha256:
+ source: hosted
+ version: "1.0.0"
+''',
+ sources,
+ );
+ void expectComesFromPubDev(String name) {
+ final description = lockfile.packages[name]!.description.description
+ as HostedDescription;
+ expect(
+ description.url,
+ 'https://pub.dev',
+ );
+ }
+
+ expectComesFromPubDev('characters');
+ expectComesFromPubDev('retry');
+ });
+
test('ignores extra stuff in file', () {
LockFile.parse('''
extra: