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/pubspec.dart b/lib/src/pubspec.dart index 8ac8023..f14133e 100644 --- a/lib/src/pubspec.dart +++ b/lib/src/pubspec.dart
@@ -13,6 +13,7 @@ import 'language_version.dart'; import 'package_name.dart'; import 'pubspec_parse.dart'; +import 'sdk.dart'; import 'system_cache.dart'; export 'pubspec_parse.dart' hide PubspecBase; @@ -156,7 +157,10 @@ // If a package is null safe it should also be compatible with dart 3. // Therefore we rewrite a null-safety enabled constraint with the upper // bound <3.0.0 to be have upper bound <4.0.0 - if (constraint is VersionRange && + // + // Only do this rewrite after dart 3. + if (sdk.version.major >= 3 && + constraint is VersionRange && LanguageVersion.fromSdkConstraint(constraint) >= LanguageVersion.firstVersionWithNullSafety && // <3.0.0 is parsed into a max of 3.0.0-0, so that is what we look for
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/dart3_sdk_constraint_hack_test.dart b/test/dart3_sdk_constraint_hack_test.dart index 7df3ee8..1a03ce5 100644 --- a/test/dart3_sdk_constraint_hack_test.dart +++ b/test/dart3_sdk_constraint_hack_test.dart
@@ -108,4 +108,19 @@ ), ); }); + test('Rewrite only happens after Dart 3', () async { + await d.dir(appPath, [ + d.pubspec({ + 'name': 'myapp', + 'environment': {'sdk': '>=2.19.1 <3.0.0'} + }), + ]).create(); + + await pubGet( + error: contains( + 'Because myapp requires SDK version >=2.19.1 <3.0.0, version solving failed.', + ), + environment: {'_PUB_TEST_SDK_VERSION': '2.19.0'}, + ); + }); }
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: