Revert "Merge dependency services (#3303)" This reverts commit 0a6252c80bfc599bc7fc1d19798aa62537643193.
diff --git a/analysis_options.yaml b/analysis_options.yaml index 6177eba..f469a93 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml
@@ -1,4 +1,4 @@ -include: package:lints/recommended.yaml +include: package:pedantic/analysis_options.yaml analyzer: errors: @@ -12,27 +12,52 @@ linter: rules: - avoid_catching_errors + - avoid_function_literals_in_foreach_calls - avoid_private_typedef_functions - avoid_redundant_argument_values + - avoid_renaming_method_parameters - avoid_returning_null_for_future + - avoid_returning_null_for_void - avoid_unused_constructor_parameters - avoid_void_async + - await_only_futures + - camel_case_types - cancel_subscriptions + - control_flow_in_finally - directives_ordering + - empty_statements + - file_names + - implementation_imports + - iterable_contains_unrelated_type + - list_remove_unrelated_type - missing_whitespace_between_adjacent_strings - no_adjacent_strings_in_list - no_runtimeType_toString + - non_constant_identifier_names - only_throw_errors + - overridden_fields - package_api_docs + - package_names + - package_prefixed_library_names - prefer_asserts_in_initializer_lists - prefer_const_declarations + - prefer_function_declarations_over_variables + - prefer_initializing_formals + - prefer_inlined_adds + - prefer_is_not_operator + - prefer_null_aware_operators - prefer_relative_imports - - prefer_single_quotes + - prefer_typing_uninitialized_variables + - prefer_void_to_null - sort_pub_dependencies - test_types_in_equals - throw_in_finally - - unawaited_futures + - unnecessary_brace_in_string_interps + - unnecessary_getters_setters - unnecessary_lambdas - unnecessary_null_aware_assignments + - unnecessary_overrides - unnecessary_parenthesis - unnecessary_statements + - unnecessary_string_interpolations + - void_checks
diff --git a/bin/dependency_services.dart b/bin/dependency_services.dart index 1e7b4c1..3b73165 100644 --- a/bin/dependency_services.dart +++ b/bin/dependency_services.dart
@@ -97,7 +97,7 @@ } @override - log.Verbosity get verbosity => log.Verbosity.normal; + log.Verbosity get verbosity => log.Verbosity.NORMAL; } Future<void> main(List<String> arguments) async {
diff --git a/doc/repository-spec-v2.md b/doc/repository-spec-v2.md index 6ddfd0f..6db7763 100644 --- a/doc/repository-spec-v2.md +++ b/doc/repository-spec-v2.md
@@ -227,7 +227,7 @@ "replacedBy": "<package>", /* optional field, if isDiscontinued == true */ "latest": { "version": "<version>", - "retracted": true || false, /* optional field, false if omitted */ + "isRetracted": true || false, /* optional field, false if omitted */ "archive_url": "https://.../archive.tar.gz", "pubspec": { /* pubspec contents as JSON object */ @@ -236,7 +236,7 @@ "versions": [ { "version": "<package>", - "retracted": true || false, /* optional field, false if omitted */ + "isRetracted": true || false, /* optional field, false if omitted */ "archive_url": "https://.../archive.tar.gz", "pubspec": { /* pubspec contents as JSON object */ @@ -371,9 +371,7 @@ archive size, or enforce any other repository specific constraints. This upload flow allows for archives to be uploaded directly to a signed POST -URL for [S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/HTTPPOSTExamples.html), -[GCS](https://cloud.google.com/storage/docs/xml-api/post-object-forms) or -similar blob storage service. Both the +URL for S3, GCS or similar blob storage service. Both the `<multipart-upload-url>` and `<finalize-upload-url>` is allowed to contain query-string parameters, and both of these URLs need only be temporary.
diff --git a/lib/pub.dart b/lib/pub.dart index 71de9d6..5b3054f 100644 --- a/lib/pub.dart +++ b/lib/pub.dart
@@ -18,12 +18,8 @@ /// /// If [analytics] is given, pub will use that analytics instance to send /// statistics about resolutions. -/// -/// [isVerbose] should return `true` (after argument resolution) if the -/// embedding top-level is in verbose mode. -Command<int> pubCommand( - {PubAnalytics? analytics, required bool Function() isVerbose}) => - PubEmbeddableCommand(analytics, isVerbose); +Command<int> pubCommand({PubAnalytics? analytics}) => + PubEmbeddableCommand(analytics); /// Support for the `pub` toplevel command. @Deprecated('Use [pubCommand] instead.')
diff --git a/lib/src/authentication/client.dart b/lib/src/authentication/client.dart index a6001ec..1f37149 100644 --- a/lib/src/authentication/client.dart +++ b/lib/src/authentication/client.dart
@@ -8,6 +8,7 @@ import 'package:http/http.dart' as http; import 'package:http_parser/http_parser.dart'; +import '../exceptions.dart'; import '../http.dart'; import '../log.dart' as log; import '../system_cache.dart'; @@ -21,17 +22,14 @@ /// Constructs Http client wrapper that injects `authorization` header to /// requests and handles authentication errors. /// - /// [_credential] might be `null`. In that case `authorization` header will not + /// [credential] might be `null`. In that case `authorization` header will not /// be injected to requests. - _AuthenticatedClient(this._inner, this._credential); + _AuthenticatedClient(this._inner, this.credential); final http.BaseClient _inner; /// Authentication scheme that could be used for authenticating requests. - final Credential? _credential; - - /// Detected that [_credential] are invalid, happens when server responds 401. - bool _detectInvalidCredentials = false; + final Credential? credential; @override Future<http.StreamedResponse> send(http.BaseRequest request) async { @@ -42,16 +40,15 @@ // to given serverBaseUrl. Otherwise credential leaks might ocurr when // archive_url hosted on 3rd party server that should not receive // credentials of the first party. - if (_credential != null && - _credential!.canAuthenticate(request.url.toString())) { + if (credential != null && + credential!.canAuthenticate(request.url.toString())) { request.headers[HttpHeaders.authorizationHeader] = - await _credential!.getAuthorizationHeaderValue(); + await credential!.getAuthorizationHeaderValue(); } try { final response = await _inner.send(request); if (response.statusCode == 401) { - _detectInvalidCredentials = true; _throwAuthException(response); } return response; @@ -127,17 +124,31 @@ Future<T> Function(http.Client) fn, ) async { final credential = systemCache.tokenStore.findCredential(hostedUrl); - final client = _AuthenticatedClient(httpClient, credential); + final http.Client client = _AuthenticatedClient(httpClient, credential); try { return await fn(client); - } finally { - if (client._detectInvalidCredentials) { - // try to remove the credential, if we detected that it is invalid! - final removed = systemCache.tokenStore.removeCredential(hostedUrl); - if (removed) { + } on AuthenticationException catch (error) { + var message = ''; + + if (error.statusCode == 401) { + if (systemCache.tokenStore.removeCredential(hostedUrl)) { log.warning('Invalid token for $hostedUrl deleted.'); } + message = '$hostedUrl package repository requested authentication! ' + 'You can provide credential using:\n' + ' pub token add $hostedUrl'; } + if (error.statusCode == 403) { + message = 'Insufficient permissions to the resource in $hostedUrl ' + 'package repository. You can modify credential using:\n' + ' pub token add $hostedUrl'; + } + + if (error.serverMessage?.isNotEmpty == true) { + message += '\n${error.serverMessage}'; + } + + throw DataException(message); } }
diff --git a/lib/src/command.dart b/lib/src/command.dart index ee62392..ea3c2d3 100644 --- a/lib/src/command.dart +++ b/lib/src/command.dart
@@ -10,15 +10,16 @@ import 'package:collection/collection.dart' show IterableExtension; import 'package:http/http.dart' as http; import 'package:meta/meta.dart'; -import 'package:path/path.dart' as p; import 'authentication/token_store.dart'; +import 'command_runner.dart'; import 'entrypoint.dart'; import 'exceptions.dart'; import 'exit_codes.dart' as exit_codes; import 'git.dart' as git; import 'global_packages.dart'; import 'http.dart'; +import 'io.dart'; import 'log.dart' as log; import 'pub_embeddable_command.dart'; import 'sdk.dart'; @@ -55,11 +56,7 @@ return a; } - String get directory => - (argResults.options.contains('directory') - ? argResults['directory'] - : null) ?? - _pubTopLevel.directory; + String get directory => argResults['directory'] ?? _pubTopLevel.directory; late final SystemCache cache = SystemCache(isOffline: isOffline); @@ -174,11 +171,12 @@ @nonVirtual FutureOr<int> run() async { computeCommand(_pubTopLevel.argResults); - + if (_pubTopLevel.trace) { + log.recordTranscript(); + } log.verbosity = _pubTopLevel.verbosity; log.fine('Pub ${sdk.version}'); - var crashed = false; try { await captureErrors<void>(() async => runProtected(), captureStackChains: _pubTopLevel.captureStackChains); @@ -190,61 +188,31 @@ log.exception(error, chain); if (_pubTopLevel.trace) { - log.dumpTranscriptToStdErr(); + log.dumpTranscript(); } else if (!isUserFacingException(error)) { - log.error(''' -This is an unexpected error. The full log and other details are collected in: + log.error(""" +This is an unexpected error. Please run - $transcriptPath + dart pub --trace ${_topCommand.name} ${_topCommand.argResults!.arguments.map(protectArgument).join(' ')} -Consider creating an issue on https://github.com/dart-lang/pub/issues/new -and attaching the relevant parts of that log file. -'''); - crashed = true; +and include the logs in an issue on https://github.com/dart-lang/pub/issues/new +"""); } return _chooseExitCode(error); } finally { - final verbose = _pubTopLevel.verbosity == log.Verbosity.all; - - // Write the whole log transcript to file. - if (verbose || crashed) { - // Escape the argument for users to copy-paste in bash. - // Wrap with single quotation, and use '\'' to insert single quote, as - // long as we have no spaces this doesn't create a new argument. - String protectArgument(String x) => - RegExp(r'^[a-zA-Z0-9-_]+$').stringMatch(x) == null - ? "'${x.replaceAll("'", r"'\''")}'" - : x; - - late final Entrypoint? e; - try { - e = entrypoint; - } on ApplicationException { - e = null; - } - log.dumpTranscriptToFile( - transcriptPath, - 'dart pub ${_topCommand.argResults!.arguments.map(protectArgument).join(' ')}', - e, - ); - - if (!crashed) { - log.message('Logs written to $transcriptPath.'); - } - } httpClient.close(); } } /// Returns the appropriate exit code for [exception], falling back on 1 if no /// appropriate exit code could be found. - int _chooseExitCode(Object exception) { + int _chooseExitCode(exception) { if (exception is SolveFailure) { var packageNotFound = exception.packageNotFound; if (packageNotFound != null) exception = packageNotFound; } while (exception is WrappedException && exception.innerError is Exception) { - exception = exception.innerError!; + exception = exception.innerError; } if (exception is HttpException || @@ -314,10 +282,6 @@ } _command = list.join(' '); } - - String get transcriptPath { - return p.join(cache.rootDir, 'log', 'pub_log.txt'); - } } abstract class PubTopLevel {
diff --git a/lib/src/command/add.dart b/lib/src/command/add.dart index 3557104..09cc426 100644 --- a/lib/src/command/add.dart +++ b/lib/src/command/add.dart
@@ -13,7 +13,6 @@ import '../exceptions.dart'; import '../git.dart'; import '../io.dart'; -import '../language_version.dart'; import '../log.dart' as log; import '../package.dart'; import '../package_name.dart'; @@ -34,10 +33,9 @@ @override String get name => 'add'; @override - String get description => 'Add dependencies to pubspec.yaml.'; + String get description => 'Add a dependency to pubspec.yaml.'; @override - String get argumentsDescription => - '<package>[:<constraint>] [<package2>[:<constraint2>]...] [options]'; + String get argumentsDescription => '<package>[:<constraint>] [options]'; @override String get docUrl => 'https://dart.dev/tools/pub/cmd/pub-add'; @override @@ -55,24 +53,19 @@ bool get hasGitOptions => gitUrl != null || gitRef != null || gitPath != null; bool get hasHostOptions => hostUrl != null; - bool get isHosted => !hasGitOptions && path == null && path == null; - AddCommand() { argParser.addFlag('dev', abbr: 'd', negatable: false, - help: 'Adds to the development dependencies instead.'); + help: 'Adds package to the development dependencies instead.'); argParser.addOption('git-url', help: 'Git URL of the package'); argParser.addOption('git-ref', help: 'Git branch or commit to be retrieved'); argParser.addOption('git-path', help: 'Path of git package in repository'); argParser.addOption('hosted-url', help: 'URL of package host server'); - argParser.addOption('path', help: 'Add package from local path'); - argParser.addOption('sdk', - help: 'add package from SDK source', - allowed: ['flutter'], - valueHelp: '[flutter]'); + argParser.addOption('path', help: 'Local path'); + argParser.addOption('sdk', help: 'SDK source for package'); argParser.addFlag( 'example', help: @@ -91,30 +84,23 @@ argParser.addFlag('precompile', help: 'Build executables in immediate dependencies.'); argParser.addOption('directory', - abbr: 'C', help: 'Run this in the directory <dir>.', valueHelp: 'dir'); - argParser.addFlag('legacy-packages-file', - help: 'Generate the legacy ".packages" file', negatable: false); + abbr: 'C', help: 'Run this in the directory<dir>.', valueHelp: 'dir'); } @override Future<void> runProtected() async { if (argResults.rest.isEmpty) { - usageException('Must specify at least one package to be added.'); - } else if (argResults.rest.length > 1 && gitUrl != null) { - usageException('Can only add a single git package at a time.'); - } else if (argResults.rest.length > 1 && path != null) { - usageException('Can only add a single local package at a time.'); + usageException('Must specify a package to be added.'); + } else if (argResults.rest.length > 1) { + usageException('Takes only a single argument.'); } - final languageVersion = entrypoint.root.pubspec.languageVersion; - final updates = - argResults.rest.map((p) => _parsePackage(p, languageVersion)).toList(); - var updatedPubSpec = entrypoint.root.pubspec; - for (final update in updates) { - /// Perform version resolution in-memory. - updatedPubSpec = - await _addPackageToPubspec(updatedPubSpec, update.packageRange); - } + final packageInformation = _parsePackage(argResults.rest.first); + final package = packageInformation.first; + + /// Perform version resolution in-memory. + final updatedPubSpec = + await _addPackageToPubspec(entrypoint.root.pubspec, package); late SolveResult solveResult; @@ -125,11 +111,9 @@ /// that a resolution exists before we update pubspec.yaml. // TODO(sigurdm): We should really use a spinner here. solveResult = await resolveVersions( - SolveType.upgrade, cache, Package.inMemory(updatedPubSpec)); + SolveType.UPGRADE, cache, Package.inMemory(updatedPubSpec)); } on GitException { - final packageRange = updates.first.packageRange; - dataError( - 'Unable to resolve package "${packageRange.name}" with the given ' + dataError('Unable to resolve package "${package.name}" with the given ' 'git parameters.'); } on SolveFailure catch (e) { dataError(e.message); @@ -138,63 +122,59 @@ dataError(e.message); } - /// Verify the results for each package. - for (final update in updates) { - final packageRange = update.packageRange; - final name = packageRange.name; - final resultPackage = solveResult.packages - .firstWhere((packageId) => packageId.name == name); + final resultPackage = solveResult.packages + .firstWhere((packageId) => packageId.name == package.name); - /// Assert that [resultPackage] is within the original user's expectations. - var constraint = packageRange.constraint; - if (!constraint.allows(resultPackage.version)) { - var dependencyOverrides = updatedPubSpec.dependencyOverrides; - if (dependencyOverrides.isNotEmpty) { - dataError('"$name" resolved to "${resultPackage.version}" which ' - 'does not satisfy constraint "$constraint". This could be ' - 'caused by "dependency_overrides".'); - } - dataError('"$name" resolved to "${resultPackage.version}" which ' - 'does not satisfy constraint "$constraint".'); + /// Assert that [resultPackage] is within the original user's expectations. + var constraint = package.constraint; + if (!constraint.allows(resultPackage.version)) { + var dependencyOverrides = updatedPubSpec.dependencyOverrides; + if (dependencyOverrides.isNotEmpty) { + dataError( + '"${package.name}" resolved to "${resultPackage.version}" which ' + 'does not satisfy constraint "${package.constraint}". This could be ' + 'caused by "dependency_overrides".'); } + dataError( + '"${package.name}" resolved to "${resultPackage.version}" which ' + 'does not satisfy constraint "${package.constraint}".'); } + if (isDryRun) { /// Even if it is a dry run, run `acquireDependencies` so that the user /// gets a report on the other packages that might change version due /// to this new dependency. final newRoot = Package.inMemory(updatedPubSpec); - await Entrypoint.inMemory(newRoot, cache, - solveResult: solveResult, lockFile: entrypoint.lockFile) - .acquireDependencies(SolveType.get, + // TODO(jonasfj): Stop abusing Entrypoint.global for dry-run output + await Entrypoint.global(newRoot, entrypoint.lockFile, cache, + solveResult: solveResult) + .acquireDependencies(SolveType.GET, dryRun: true, precompile: argResults['precompile'], - analytics: analytics, - generateDotPackages: false); + analytics: analytics); } else { /// Update the `pubspec.yaml` before calling [acquireDependencies] to /// ensure that the modification timestamp on `pubspec.lock` and /// `.dart_tool/package_config.json` is newer than `pubspec.yaml`, /// ensuring that [entrypoint.assertUptoDate] will pass. - _updatePubspec(solveResult.packages, updates, isDev); + _updatePubspec(resultPackage, packageInformation, isDev); /// Create a new [Entrypoint] since we have to reprocess the updated /// pubspec file. final updatedEntrypoint = Entrypoint(directory, cache); await updatedEntrypoint.acquireDependencies( - SolveType.get, + SolveType.GET, precompile: argResults['precompile'], analytics: analytics, - generateDotPackages: argResults['legacy-packages-file'], ); if (argResults['example'] && entrypoint.example != null) { await entrypoint.example!.acquireDependencies( - SolveType.get, + SolveType.GET, precompile: argResults['precompile'], onlyReportSuccessOrFailure: true, analytics: analytics, - generateDotPackages: argResults['legacy-packages-file'], ); } } @@ -294,7 +274,9 @@ /// /// If any of the other git options are defined when `--git-url` is not /// defined, an error will be thrown. - _ParseResult _parsePackage(String package, LanguageVersion languageVersion) { + Pair<PackageRange, dynamic> _parsePackage(String package) { + ArgumentError.checkNotNull(package, 'package'); + final _conflictingFlagSets = [ ['git-url', 'git-ref', 'git-path'], ['hosted-url'], @@ -398,18 +380,13 @@ .withConstraint(constraint ?? VersionConstraint.any); pubspecInformation = {'sdk': sdk}; } else { - // Hosted - final Object? hostInfo; - if (hasHostOptions) { - hostInfo = languageVersion.supportsShorterHostedSyntax - ? hostUrl - : {'url': hostUrl, 'name': packageName}; - pubspecInformation = { - 'hosted': hostInfo, - }; - } else { - hostInfo = null; + final hostInfo = + hasHostOptions ? {'url': hostUrl, 'name': packageName} : null; + + if (hostInfo == null) { pubspecInformation = constraint?.toString(); + } else { + pubspecInformation = {'hosted': hostInfo}; } packageRange = cache.hosted.source @@ -431,64 +408,66 @@ }; } - return _ParseResult(packageRange, pubspecInformation); + return Pair(packageRange, pubspecInformation); } /// Writes the changes to the pubspec file. - void _updatePubspec(List<PackageId> resultPackages, - List<_ParseResult> updates, bool isDevelopment) { + void _updatePubspec(PackageId resultPackage, + Pair<PackageRange, dynamic> packageInformation, bool isDevelopment) { + ArgumentError.checkNotNull(resultPackage, 'resultPackage'); + ArgumentError.checkNotNull(packageInformation, 'pubspecInformation'); + + final package = packageInformation.first; + var pubspecInformation = packageInformation.last; + + if ((sdk != null || hasHostOptions) && + pubspecInformation is Map && + pubspecInformation['version'] == null) { + /// We cannot simply assign the value of version since it is likely that + /// [pubspecInformation] takes on the type + /// [Map<String, Map<String, String>>] + pubspecInformation = { + ...pubspecInformation, + 'version': '^${resultPackage.version}' + }; + } + + final dependencyKey = isDevelopment ? 'dev_dependencies' : 'dependencies'; + final packagePath = [dependencyKey, package.name]; + final yamlEditor = YamlEditor(readTextFile(entrypoint.pubspecPath)); log.io('Reading ${entrypoint.pubspecPath}.'); log.fine('Contents:\n$yamlEditor'); - for (final update in updates) { - final packageRange = update.packageRange; - final name = packageRange.name; - final resultId = resultPackages.firstWhere((id) => id.name == name); - var description = update.description; + /// Handle situations where the user might not have the dependencies or + /// dev_dependencies map. + if (yamlEditor.parseAt([dependencyKey], + orElse: () => YamlScalar.wrap(null)).value == + null) { + yamlEditor.update([dependencyKey], + {package.name: pubspecInformation ?? '^${resultPackage.version}'}); + } else { + yamlEditor.update( + packagePath, pubspecInformation ?? '^${resultPackage.version}'); + } - if (isHosted) { - final inferredConstraint = - VersionConstraint.compatibleWith(resultId.version).toString(); - if (description == null) { - description = inferredConstraint; - } else if (description is Map && description['version'] == null) { - /// We cannot simply assign the value of version since it is likely that - /// [description] takes on the type - /// [Map<String, Map<String, String>>] - description = {...description, 'version': '^${resultId.version}'}; + log.fine('Added ${package.name} to "$dependencyKey".'); + + /// Remove the package from dev_dependencies if we are adding it to + /// dependencies. Refer to [_addPackageToPubspec] for additional discussion. + if (!isDevelopment) { + final devDependenciesNode = yamlEditor + .parseAt(['dev_dependencies'], orElse: () => YamlScalar.wrap(null)); + + if (devDependenciesNode is YamlMap && + devDependenciesNode.containsKey(package.name)) { + if (devDependenciesNode.length == 1) { + yamlEditor.remove(['dev_dependencies']); + } else { + yamlEditor.remove(['dev_dependencies', package.name]); } - } - final dependencyKey = isDevelopment ? 'dev_dependencies' : 'dependencies'; - final packagePath = [dependencyKey, name]; - - /// Ensure we have a [dependencyKey] map in the `pubspec.yaml`. - if (yamlEditor.parseAt([dependencyKey], - orElse: () => YamlScalar.wrap(null)).value == - null) { - yamlEditor.update([dependencyKey], {}); - } - yamlEditor.update(packagePath, description); - - log.fine('Added ${packageRange.name} to "$dependencyKey".'); - - /// Remove the package from dev_dependencies if we are adding it to - /// dependencies. Refer to [_addPackageToPubspec] for additional discussion. - if (!isDevelopment) { - final devDependenciesNode = yamlEditor - .parseAt(['dev_dependencies'], orElse: () => YamlScalar.wrap(null)); - - if (devDependenciesNode is YamlMap && - devDependenciesNode.containsKey(name)) { - if (devDependenciesNode.length == 1) { - yamlEditor.remove(['dev_dependencies']); - } else { - yamlEditor.remove(['dev_dependencies', name]); - } - - log.fine('Removed $name from "dev_dependencies".'); - } + log.fine('Removed ${package.name} from "dev_dependencies".'); } } @@ -496,9 +475,3 @@ writeTextFile(entrypoint.pubspecPath, yamlEditor.toString()); } } - -class _ParseResult { - PackageRange packageRange; - Object? description; - _ParseResult(this.packageRange, this.description); -}
diff --git a/lib/src/command/cache_repair.dart b/lib/src/command/cache_repair.dart index 74968be..41bae2b 100644 --- a/lib/src/command/cache_repair.dart +++ b/lib/src/command/cache_repair.dart
@@ -23,8 +23,6 @@ @override Future<void> runProtected() async { - // Delete any eventual temp-files left in the cache. - cache.deleteTempDir(); // Repair every cached source. final repairResults = (await Future.wait( cache.sources.all.map(cache.source).map((source) async {
diff --git a/lib/src/command/dependency_services.dart b/lib/src/command/dependency_services.dart index 161a352..ca5c247 100644 --- a/lib/src/command/dependency_services.dart +++ b/lib/src/command/dependency_services.dart
@@ -93,7 +93,7 @@ } final resolution = await tryResolveVersions( - SolveType.get, + SolveType.GET, cache, Package.inMemory(pubspec), lockFile: lockFile, @@ -210,7 +210,7 @@ /// resolution was found. Future<List<PackageId>?> _tryResolve(Pubspec pubspec, SystemCache cache) async { final solveResult = await tryResolveVersions( - SolveType.upgrade, + SolveType.UPGRADE, cache, Package.inMemory(pubspec), ); @@ -346,8 +346,8 @@ await log.warningsOnlyUnlessTerminal( () async { // This will fail if the new configuration does not resolve. - await Entrypoint(directory, cache).acquireDependencies(SolveType.get, - analytics: null, generateDotPackages: false); + await Entrypoint(directory, cache) + .acquireDependencies(SolveType.GET, analytics: null); }, ); // Dummy message.
diff --git a/lib/src/command/downgrade.dart b/lib/src/command/downgrade.dart index fce5ef3..5dd9d41 100644 --- a/lib/src/command/downgrade.dart +++ b/lib/src/command/downgrade.dart
@@ -42,8 +42,6 @@ argParser.addOption('directory', abbr: 'C', help: 'Run this in the directory<dir>.', valueHelp: 'dir'); - argParser.addFlag('legacy-packages-file', - help: 'Generate the legacy ".packages" file', negatable: false); } @override @@ -55,21 +53,19 @@ var dryRun = argResults['dry-run']; await entrypoint.acquireDependencies( - SolveType.downgrade, + SolveType.DOWNGRADE, unlock: argResults.rest, dryRun: dryRun, analytics: analytics, - generateDotPackages: argResults['legacy-packages-file'], ); var example = entrypoint.example; if (argResults['example'] && example != null) { await example.acquireDependencies( - SolveType.get, + SolveType.GET, unlock: argResults.rest, dryRun: dryRun, onlyReportSuccessOrFailure: true, analytics: analytics, - generateDotPackages: argResults['legacy-packages-file'], ); }
diff --git a/lib/src/command/get.dart b/lib/src/command/get.dart index 7b8906c..9255e1e 100644 --- a/lib/src/command/get.dart +++ b/lib/src/command/get.dart
@@ -33,9 +33,6 @@ argParser.addFlag('packages-dir', hide: true); - argParser.addFlag('legacy-packages-file', - help: 'Generate the legacy ".packages" file', negatable: false); - argParser.addFlag( 'example', help: 'Also run in `example/` (if it exists).', @@ -53,23 +50,19 @@ 'The --packages-dir flag is no longer used and does nothing.')); } await entrypoint.acquireDependencies( - SolveType.get, + SolveType.GET, dryRun: argResults['dry-run'], precompile: argResults['precompile'], - generateDotPackages: argResults['legacy-packages-file'], analytics: analytics, ); var example = entrypoint.example; if (argResults['example'] && example != null) { - await example.acquireDependencies( - SolveType.get, - dryRun: argResults['dry-run'], - precompile: argResults['precompile'], - generateDotPackages: argResults['legacy-packages-file'], - analytics: analytics, - onlyReportSuccessOrFailure: true, - ); + await example.acquireDependencies(SolveType.GET, + dryRun: argResults['dry-run'], + precompile: argResults['precompile'], + onlyReportSuccessOrFailure: true, + analytics: analytics); } } }
diff --git a/lib/src/command/lish.dart b/lib/src/command/lish.dart index c927e07..325d482 100644 --- a/lib/src/command/lish.dart +++ b/lib/src/command/lish.dart
@@ -91,7 +91,7 @@ try { await log.progress('Uploading', () async { - var newUri = server.resolve('api/packages/versions/new'); + var newUri = server.resolve('/api/packages/versions/new'); var response = await client.get(newUri, headers: pubApiHeaders); var parameters = parseJsonResponse(response); @@ -120,22 +120,6 @@ handleJsonSuccess( await client.get(Uri.parse(location), headers: pubApiHeaders)); }); - } on AuthenticationException catch (error) { - var msg = ''; - if (error.statusCode == 401) { - msg += '$server package repository requested authentication!\n' - 'You can provide credentials using:\n' - ' pub token add $server\n'; - } - if (error.statusCode == 403) { - msg += 'Insufficient permissions to the resource at the $server ' - 'package repository.\nYou can modify credentials using:\n' - ' pub token add $server\n'; - } - if (error.serverMessage != null) { - msg += '\n' + error.serverMessage! + '\n'; - } - dataError(msg + log.red('Authentication failed!')); } on PubHttpException catch (error) { var url = error.response.request!.url; if (url == cloudStorageUrl) {
diff --git a/lib/src/command/outdated.dart b/lib/src/command/outdated.dart index 0d78c11..4384048 100644 --- a/lib/src/command/outdated.dart +++ b/lib/src/command/outdated.dart
@@ -366,7 +366,7 @@ /// resolution was found. Future<List<PackageId>?> _tryResolve(Pubspec pubspec, SystemCache cache) async { final solveResult = await tryResolveVersions( - SolveType.upgrade, + SolveType.UPGRADE, cache, Package.inMemory(pubspec), ); @@ -807,9 +807,6 @@ _overridden == other._overridden && _id.source == other._id.source && _pubspec.version == other._pubspec.version; - - @override - int get hashCode => Object.hash(_pubspec.version, _id.source, _overridden); } class _PackageDetails implements Comparable<_PackageDetails> {
diff --git a/lib/src/command/remove.dart b/lib/src/command/remove.dart index 82a9547..c7c674a 100644 --- a/lib/src/command/remove.dart +++ b/lib/src/command/remove.dart
@@ -50,9 +50,6 @@ argParser.addOption('directory', abbr: 'C', help: 'Run this in the directory<dir>.', valueHelp: 'dir'); - - argParser.addFlag('legacy-packages-file', - help: 'Generate the legacy ".packages" file', negatable: false); } @override @@ -68,12 +65,11 @@ final newPubspec = _removePackagesFromPubspec(rootPubspec, packages); final newRoot = Package.inMemory(newPubspec); - await Entrypoint.inMemory(newRoot, cache, lockFile: entrypoint.lockFile) - .acquireDependencies(SolveType.get, + await Entrypoint.global(newRoot, entrypoint.lockFile, cache) + .acquireDependencies(SolveType.GET, precompile: argResults['precompile'], dryRun: true, - analytics: null, - generateDotPackages: false); + analytics: null); } else { /// Update the pubspec. _writeRemovalToPubspec(packages); @@ -82,20 +78,18 @@ /// pubspec file. final updatedEntrypoint = Entrypoint(directory, cache); await updatedEntrypoint.acquireDependencies( - SolveType.get, + SolveType.GET, precompile: argResults['precompile'], analytics: analytics, - generateDotPackages: argResults['legacy-packages-file'], ); var example = entrypoint.example; if (argResults['example'] && example != null) { await example.acquireDependencies( - SolveType.get, + SolveType.GET, precompile: argResults['precompile'], onlyReportSuccessOrFailure: true, analytics: analytics, - generateDotPackages: argResults['legacy-packages-file'], ); } }
diff --git a/lib/src/command/token_add.dart b/lib/src/command/token_add.dart index caf3b8b..fddc0cc 100644 --- a/lib/src/command/token_add.dart +++ b/lib/src/command/token_add.dart
@@ -57,11 +57,17 @@ } on FormatException catch (e) { usageException('Invalid [hosted-url]: "$rawHostedUrl"\n' '${e.message}'); + } on TimeoutException catch (_) { + // Timeout is added to readLine call to make sure automated jobs doesn't + // get stuck on noop state if user forget to pipe token to the 'token add' + // command. This behavior might be removed. + throw ApplicationException('Token is not provided within 15 minutes.'); } } Future<void> _addTokenFromStdin(Uri hostedUrl) async { - final token = await stdinPrompt('Enter secret token:', echoMode: false); + final token = await stdinPrompt('Enter secret token:', echoMode: false) + .timeout(const Duration(minutes: 15)); if (token.isEmpty) { usageException('Token is not provided.'); }
diff --git a/lib/src/command/upgrade.dart b/lib/src/command/upgrade.dart index 0dc5fb7..8e44abf 100644 --- a/lib/src/command/upgrade.dart +++ b/lib/src/command/upgrade.dart
@@ -56,9 +56,6 @@ argParser.addFlag('packages-dir', hide: true); - argParser.addFlag('legacy-packages-file', - help: 'Generate the legacy ".packages" file', negatable: false); - argParser.addFlag( 'major-versions', help: 'Upgrades packages to their latest resolvable versions, ' @@ -83,8 +80,6 @@ bool get _precompile => argResults['precompile']; - bool get _packagesFile => argResults['legacy-packages-file']; - bool get _upgradeNullSafety => argResults['nullsafety'] || argResults['null-safety']; @@ -126,12 +121,11 @@ Future<void> _runUpgrade(Entrypoint e, {bool onlySummary = false}) async { await e.acquireDependencies( - SolveType.upgrade, + SolveType.UPGRADE, unlock: argResults.rest, dryRun: _dryRun, precompile: _precompile, onlyReportSuccessOrFailure: onlySummary, - generateDotPackages: _packagesFile, analytics: analytics, ); _showOfflineWarning(); @@ -185,7 +179,7 @@ final resolvedPackages = <String, PackageId>{}; final solveResult = await log.spinner('Resolving dependencies', () async { return await resolveVersions( - SolveType.upgrade, + SolveType.UPGRADE, cache, Package.inMemory(resolvablePubspec), ); @@ -224,37 +218,32 @@ resolvedPackage.version, )); } - final newPubspecText = _updatePubspec(changes); if (_dryRun) { // Even if it is a dry run, run `acquireDependencies` so that the user // gets a report on changes. - await Entrypoint.inMemory( - Package.inMemory( - Pubspec.parse(newPubspecText, cache.sources), - ), + // TODO(jonasfj): Stop abusing Entrypoint.global for dry-run output + await Entrypoint.global( + Package.inMemory(resolvablePubspec), + entrypoint.lockFile, cache, - lockFile: entrypoint.lockFile, solveResult: solveResult, ).acquireDependencies( - SolveType.get, + SolveType.UPGRADE, dryRun: true, precompile: _precompile, analytics: null, // No analytics for dry-run - generateDotPackages: false, ); } else { - if (changes.isNotEmpty) { - writeTextFile(entrypoint.pubspecPath, newPubspecText); - } + await _updatePubspec(changes); + // TODO: Allow Entrypoint to be created with in-memory pubspec, so that // we can show the changes when not in --dry-run mode. For now we only show // the changes made to pubspec.yaml in dry-run mode. await Entrypoint(directory, cache).acquireDependencies( - SolveType.get, + SolveType.UPGRADE, precompile: _precompile, analytics: analytics, - generateDotPackages: argResults['legacy-packages-file'], ); } @@ -287,7 +276,7 @@ final resolvedPackages = <String, PackageId>{}; final solveResult = await log.spinner('Resolving dependencies', () async { return await resolveVersions( - SolveType.upgrade, + SolveType.UPGRADE, cache, Package.inMemory(nullsafetyPubspec), ); @@ -324,35 +313,31 @@ changes[dep] = dep.withConstraint(constraint); } - final newPubspecText = _updatePubspec(changes); if (_dryRun) { // Even if it is a dry run, run `acquireDependencies` so that the user // gets a report on changes. // TODO(jonasfj): Stop abusing Entrypoint.global for dry-run output - await Entrypoint.inMemory( - Package.inMemory(Pubspec.parse(newPubspecText, cache.sources)), + await Entrypoint.global( + Package.inMemory(nullsafetyPubspec), + entrypoint.lockFile, cache, - lockFile: entrypoint.lockFile, solveResult: solveResult, ).acquireDependencies( - SolveType.upgrade, + SolveType.UPGRADE, dryRun: true, precompile: _precompile, analytics: null, - generateDotPackages: false, ); } else { - if (changes.isNotEmpty) { - writeTextFile(entrypoint.pubspecPath, newPubspecText); - } + await _updatePubspec(changes); + // TODO: Allow Entrypoint to be created with in-memory pubspec, so that // we can show the changes in --dry-run mode. For now we only show // the changes made to pubspec.yaml in dry-run mode. await Entrypoint(directory, cache).acquireDependencies( - SolveType.upgrade, + SolveType.UPGRADE, precompile: _precompile, analytics: analytics, - generateDotPackages: argResults['legacy-packages-file'], ); } @@ -396,11 +381,13 @@ } /// Updates `pubspec.yaml` with given [changes]. - String _updatePubspec( + Future<void> _updatePubspec( Map<PackageRange, PackageRange> changes, - ) { + ) async { ArgumentError.checkNotNull(changes, 'changes'); + if (changes.isEmpty) return; + final yamlEditor = YamlEditor(readTextFile(entrypoint.pubspecPath)); final deps = entrypoint.root.pubspec.dependencies.keys; final devDeps = entrypoint.root.pubspec.devDependencies.keys; @@ -420,7 +407,9 @@ ); } } - return yamlEditor.toString(); + + /// Windows line endings are already handled by [yamlEditor] + writeTextFile(entrypoint.pubspecPath, yamlEditor.toString()); } /// Outputs a summary of changes made to `pubspec.yaml`.
diff --git a/lib/src/command_runner.dart b/lib/src/command_runner.dart index 21f568b..4ed33f6 100644 --- a/lib/src/command_runner.dart +++ b/lib/src/command_runner.dart
@@ -58,22 +58,21 @@ Verbosity get verbosity { switch (argResults['verbosity']) { case 'error': - return log.Verbosity.error; + return log.Verbosity.ERROR; case 'warning': - return log.Verbosity.warning; + return log.Verbosity.WARNING; case 'normal': - return log.Verbosity.normal; + return log.Verbosity.NORMAL; case 'io': - return log.Verbosity.io; + return log.Verbosity.IO; case 'solver': - return log.Verbosity.solver; + return log.Verbosity.SOLVER; case 'all': - return log.Verbosity.all; + return log.Verbosity.ALL; default: // No specific verbosity given, so check for the shortcut. - if (argResults['verbose']) return log.Verbosity.all; - if (runningFromTest) return log.Verbosity.testing; - return log.Verbosity.normal; + if (argResults['verbose']) return log.Verbosity.ALL; + return log.Verbosity.NORMAL; } }
diff --git a/lib/src/dart.dart b/lib/src/dart.dart index f4f8686..97219dc 100644 --- a/lib/src/dart.dart +++ b/lib/src/dart.dart
@@ -146,14 +146,11 @@ String toString() => errors.join('\n'); } -/// Precompiles the Dart executable at [executablePath]. +/// Precompiles the Dart executable at [executablePath] to a kernel file at +/// [outputPath]. /// -/// If the compilation succeeds it is saved to a kernel file at [outputPath]. -/// -/// If compilation fails, the output is cached at [incrementalDillOutputPath]. -/// -/// Whichever of [incrementalDillOutputPath] and [outputPath] already exists is -/// used to initialize the compiler run. +/// This file is also cached at [incrementalDillOutputPath] which is used to +/// initialize the compiler on future runs. /// /// The [packageConfigPath] should point at the package config file to be used /// for `package:` uri resolution. @@ -161,65 +158,39 @@ /// The [name] is used to describe the executable in logs and error messages. Future<void> precompile({ required String executablePath, - required String incrementalDillPath, + required String incrementalDillOutputPath, required String name, required String outputPath, required String packageConfigPath, }) async { ensureDir(p.dirname(outputPath)); - ensureDir(p.dirname(incrementalDillPath)); - + ensureDir(p.dirname(incrementalDillOutputPath)); const platformDill = 'lib/_internal/vm_platform_strong.dill'; final sdkRoot = p.relative(p.dirname(p.dirname(Platform.resolvedExecutable))); - String? tempDir; - FrontendServerClient? client; + var client = await FrontendServerClient.start( + executablePath, + incrementalDillOutputPath, + platformDill, + sdkRoot: sdkRoot, + packagesJson: packageConfigPath, + printIncrementalDependencies: false, + ); try { - tempDir = createTempDir(p.dirname(incrementalDillPath), 'tmp'); - // To avoid potential races we copy the incremental data to a temporary file - // for just this compilation. - final temporaryIncrementalDill = - p.join(tempDir, '${p.basename(incrementalDillPath)}.incremental.dill'); - try { - if (fileExists(incrementalDillPath)) { - copyFile(incrementalDillPath, temporaryIncrementalDill); - } else if (fileExists(outputPath)) { - copyFile(outputPath, temporaryIncrementalDill); - } - } on FileSystemException { - // Not able to copy existing file, compilation will start from scratch. - } - - client = await FrontendServerClient.start( - executablePath, - temporaryIncrementalDill, - platformDill, - sdkRoot: sdkRoot, - packagesJson: packageConfigPath, - printIncrementalDependencies: false, - ); - final result = await client.compile(); + var result = await client.compile(); final highlightedName = log.bold(name); if (result?.errorCount == 0) { log.message('Built $highlightedName.'); - // By using rename we ensure atomicity. An external observer will either - // see the old or the new snapshot. - renameFile(temporaryIncrementalDill, outputPath); + await File(incrementalDillOutputPath).copy(outputPath); } else { - // By using rename we ensure atomicity. An external observer will either - // see the old or the new snapshot. - renameFile(temporaryIncrementalDill, incrementalDillPath); - // If compilation failed we don't want to leave an incorrect snapshot. - tryDeleteEntry(outputPath); + // Don't leave partial results. + deleteEntry(outputPath); throw ApplicationException( log.yellow('Failed to build $highlightedName:\n') + (result?.compilerOutputLines.join('\n') ?? '')); } } finally { - client?.kill(); - if (tempDir != null) { - tryDeleteEntry(tempDir); - } + client.kill(); } }
diff --git a/lib/src/entrypoint.dart b/lib/src/entrypoint.dart index 202580c..453ef56 100644 --- a/lib/src/entrypoint.dart +++ b/lib/src/entrypoint.dart
@@ -10,12 +10,12 @@ import 'package:meta/meta.dart'; import 'package:path/path.dart' as p; import 'package:pub_semver/pub_semver.dart'; -import 'package:yaml/yaml.dart'; import 'command_runner.dart'; import 'dart.dart' as dart; import 'exceptions.dart'; import 'executable.dart'; +import 'http.dart' as http; import 'io.dart'; import 'language_version.dart'; import 'lock_file.dart'; @@ -72,14 +72,8 @@ /// but may be the entrypoint when you're running its tests. class Entrypoint { /// The root package this entrypoint is associated with. - /// - /// For a global package, this is the activated package. final Package root; - /// For a global package, this is the directory that the package is installed - /// in. Non-global packages have null. - final String? globalDir; - /// The system-wide cache which caches packages that need to be fetched over /// the network. final SystemCache cache; @@ -88,8 +82,7 @@ bool get isCached => !root.isInMemory && p.isWithin(cache.rootDir, root.dir); /// Whether this is an entrypoint for a globally-activated package. - // final bool isGlobal; - bool get isGlobal => globalDir != null; + final bool isGlobal; /// The lockfile for the entrypoint. /// @@ -129,7 +122,8 @@ /// /// Global packages (except those from path source) /// store these in the global cache. - String? get _configRoot => isCached ? globalDir : root.dir; + String? get _configRoot => + isCached ? p.join(cache.rootDir, 'global_packages', root.name) : root.dir; /// The path to the entrypoint's ".packages" file. /// @@ -158,7 +152,11 @@ /// but the configuration is stored at the package itself. String get cachePath { if (isGlobal) { - return globalDir!; + return p.join( + cache.rootDir, + 'global_packages', + root.name, + ); } else { var newPath = root.path('.dart_tool/pub'); var oldPath = root.path('.pub'); @@ -175,25 +173,15 @@ String get _incrementalDillsPath => p.join(cachePath, 'incremental'); /// Loads the entrypoint from a package at [rootDir]. - Entrypoint( - String rootDir, - this.cache, - ) : root = Package.load(null, rootDir, cache.sources), - globalDir = null; - - Entrypoint.inMemory(this.root, this.cache, - {required LockFile? lockFile, SolveResult? solveResult}) - : _lockFile = lockFile, - globalDir = null { - if (solveResult != null) { - _packageGraph = PackageGraph.fromSolveResult(this, solveResult); - } - } + Entrypoint(String rootDir, this.cache) + : root = Package.load(null, rootDir, cache.sources), + isGlobal = false; /// Creates an entrypoint given package and lockfile objects. /// If a SolveResult is already created it can be passed as an optimization. - Entrypoint.global(this.globalDir, this.root, this._lockFile, this.cache, - {SolveResult? solveResult}) { + Entrypoint.global(this.root, this._lockFile, this.cache, + {SolveResult? solveResult}) + : isGlobal = true { if (solveResult != null) { _packageGraph = PackageGraph.fromSolveResult(this, solveResult); } @@ -213,25 +201,19 @@ Entrypoint? _example; /// Writes .packages and .dart_tool/package_config.json - Future<void> writePackagesFiles({bool generateDotPackages = false}) async { - final entrypointName = isGlobal ? null : root.name; - if (generateDotPackages) { - writeTextFile( - packagesFile, - lockFile.packagesFile(cache, - entrypoint: entrypointName, - relativeFrom: isGlobal ? null : root.dir)); - } else { - tryDeleteEntry(packagesFile); - } + Future<void> writePackagesFiles() async { + writeTextFile( + packagesFile, + lockFile.packagesFile(cache, + entrypoint: root.name, relativeFrom: root.dir)); ensureDir(p.dirname(packageConfigFile)); writeTextFile( packageConfigFile, await lockFile.packageConfigFile(cache, - entrypoint: entrypointName, + entrypoint: root.name, entrypointSdkConstraint: root.pubspec.sdkConstraints[sdk.identifier], - relativeFrom: isGlobal ? null : root.dir)); + relativeFrom: root.dir)); } /// Gets all dependencies of the [root] package. @@ -261,7 +243,6 @@ Iterable<String>? unlock, bool dryRun = false, bool precompile = false, - required bool generateDotPackages, required PubAnalytics? analytics, bool onlyReportSuccessOrFailure = false, }) async { @@ -269,7 +250,8 @@ SolveResult result; try { result = await log.progress('Resolving dependencies$suffix', () async { - _checkSdkConstraint(root.pubspec); + // We require an SDK constraint lower-bound as of Dart 2.12.0 + _checkSdkConstraintIsDefined(root.pubspec); return resolveVersions( type, cache, @@ -312,7 +294,7 @@ await result.showReport(type, cache); } if (!dryRun) { - await result.downloadCachedPackages(cache); + await Future.wait(result.packages.map(_get)); _saveLockFile(result); } if (onlyReportSuccessOrFailure) { @@ -330,7 +312,7 @@ /// have to reload and reparse all the pubspecs. _packageGraph = PackageGraph.fromSolveResult(this, result); - await writePackagesFiles(generateDotPackages: generateDotPackages); + await writePackagesFiles(); try { if (precompile) { @@ -405,11 +387,10 @@ Future<void> _precompileExecutable(Executable executable) async { final package = executable.package; - await dart.precompile( executablePath: resolveExecutable(executable), outputPath: pathOfExecutable(executable), - incrementalDillPath: incrementalDillPathOfExecutable(executable), + incrementalDillOutputPath: incrementalDillPathOfExecutable(executable), packageConfigPath: packageConfigFile, name: '$package:${p.basenameWithoutExtension(executable.relativePath)}'); @@ -489,6 +470,21 @@ } } + /// Makes sure the package at [id] is locally available. + /// + /// This automatically downloads the package to the system-wide cache as well + /// if it requires network access to retrieve (specifically, if the package's + /// source is a [CachedSource]). + Future<void> _get(PackageId id) async { + return await http.withDependencyType(root.dependencyType(id.name), + () async { + if (id.isRoot) return; + + var source = cache.source(id.source); + if (source is CachedSource) await source.downloadToSystemCache(id); + }); + } + /// Throws a [DataError] if the `.dart_tool/package_config.json` file doesn't /// exist or if it's out-of-date relative to the lockfile or the pubspec. /// @@ -876,9 +872,7 @@ } /// We require an SDK constraint lower-bound as of Dart 2.12.0 - /// - /// We don't allow unknown sdks. - void _checkSdkConstraint(Pubspec pubspec) { + void _checkSdkConstraintIsDefined(Pubspec pubspec) { final dartSdkConstraint = pubspec.sdkConstraints['dart']; if (dartSdkConstraint is! VersionRange || dartSdkConstraint.min == null) { // Suggest version range '>=2.10.0 <3.0.0', we avoid using: @@ -908,24 +902,6 @@ See https://dart.dev/go/sdk-constraint '''); } - for (final sdk in pubspec.sdkConstraints.keys) { - if (!sdks.containsKey(sdk)) { - final environment = pubspec.fields.nodes['environment'] as YamlMap; - final keyNode = environment.nodes.entries - .firstWhere((e) => (e.key as YamlNode).value == sdk) - .key as YamlNode; - throw PubspecException(''' -$pubspecPath refers to an unknown sdk '$sdk'. - -Did you mean to add it as a dependency? - -Either remove the constraint, or upgrade to a version of pub that supports the -given sdk. - -See https://dart.dev/go/sdk-constraint -''', keyNode.span); - } - } } }
diff --git a/lib/src/exceptions.dart b/lib/src/exceptions.dart index fcde747..82a5dac 100644 --- a/lib/src/exceptions.dart +++ b/lib/src/exceptions.dart
@@ -11,6 +11,7 @@ import 'package:yaml/yaml.dart'; import 'dart.dart'; +import 'sdk.dart'; /// An exception class for exceptions that are intended to be seen by the user. /// @@ -88,20 +89,18 @@ /// that other code in pub can use this to show a more detailed explanation of /// why the package was being requested. class PackageNotFoundException extends WrappedException { - /// A hint indicating an action the user could take to resolve this problem. - /// - /// This will be printed after the package resolution conflict. - final String? hint; + /// If this failure was caused by an SDK being unavailable, this is that SDK. + final Sdk? missingSdk; PackageNotFoundException( String message, { Object? innerError, StackTrace? innerTrace, - this.hint, + this.missingSdk, }) : super(message, innerError, innerTrace); @override - String toString() => 'Package not available ($message).'; + String toString() => "Package doesn't exist ($message)."; } /// Returns whether [error] is a user-facing error object.
diff --git a/lib/src/executable.dart b/lib/src/executable.dart index 3f8f6a9..2112acc 100644 --- a/lib/src/executable.dart +++ b/lib/src/executable.dart
@@ -306,9 +306,8 @@ try { await warningsOnlyUnlessTerminal( () => entrypoint.acquireDependencies( - SolveType.get, + SolveType.GET, analytics: analytics, - generateDotPackages: false, ), ); } on ApplicationException catch (e) {
diff --git a/lib/src/exit_codes.dart b/lib/src/exit_codes.dart index c6acaf7..e072ef2 100644 --- a/lib/src/exit_codes.dart +++ b/lib/src/exit_codes.dart
@@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -// ignore_for_file: constant_identifier_names - /// Exit code constants. /// /// From [the BSD sysexits manpage][manpage]. Not every constant here is used,
diff --git a/lib/src/global_packages.dart b/lib/src/global_packages.dart index 07e2513..578eca1 100644 --- a/lib/src/global_packages.dart +++ b/lib/src/global_packages.dart
@@ -12,6 +12,7 @@ import 'entrypoint.dart'; import 'exceptions.dart'; import 'executable.dart' as exec; +import 'http.dart' as http; import 'io.dart'; import 'lock_file.dart'; import 'log.dart' as log; @@ -61,8 +62,6 @@ /// The directory where the lockfiles for activated packages are stored. String get _directory => p.join(cache.rootDir, 'global_packages'); - String _packageDir(String packageName) => p.join(_directory, packageName); - /// The directory where binstubs for global package executables are stored. String get _binStubDir => p.join(cache.rootDir, 'bin'); @@ -150,25 +149,28 @@ var entrypoint = Entrypoint(path, cache); // Get the package's dependencies. - await entrypoint.acquireDependencies( - SolveType.get, - analytics: analytics, - generateDotPackages: false, - ); + await entrypoint.acquireDependencies(SolveType.GET, analytics: analytics); var name = entrypoint.root.name; - _describeActive(name, cache); + + try { + var originalLockFile = + LockFile.load(_getLockFilePath(name), cache.sources); + // Call this just to log what the current active package is, if any. + _describeActive(originalLockFile, name); + } on IOException { + // Couldn't read the lock file. It probably doesn't exist. + } // Write a lockfile that points to the local package. var fullPath = canonicalize(entrypoint.root.dir); var id = cache.path.source.idFor(name, entrypoint.root.version, fullPath); - final tempDir = cache.createTempDir(); // TODO(rnystrom): Look in "bin" and display list of binaries that // user can run. - _writeLockFile(tempDir, LockFile([id])); + _writeLockFile(name, LockFile([id])); - tryDeleteEntry(_packageDir(name)); - tryRenameDir(tempDir, _packageDir(name)); + var binDir = p.join(_directory, name, 'bin'); + if (dirExists(binDir)) deleteEntry(binDir); _updateBinStubs(entrypoint, entrypoint.root, executables, overwriteBinStubs: overwriteBinStubs); @@ -176,12 +178,17 @@ } /// Installs the package [dep] and its dependencies into the system cache. - /// - /// If [silent] less logging will be printed. Future<void> _installInCache(PackageRange dep, List<String>? executables, - {required bool overwriteBinStubs, bool silent = false}) async { - final name = dep.name; - LockFile? originalLockFile = _describeActive(name, cache); + {required bool overwriteBinStubs}) async { + LockFile? originalLockFile; + try { + originalLockFile = + LockFile.load(_getLockFilePath(dep.name), cache.sources); + // Call this just to log what the current active package is, if any. + _describeActive(originalLockFile, dep.name); + } on IOException { + // Couldn't read the lock file. It probably doesn't exist. + } // Create a dummy package with just [dep] so we can do resolution on it. var root = Package.inMemory(Pubspec('pub global activate', @@ -193,89 +200,103 @@ // being available, report that as a [dataError]. SolveResult result; try { - result = await log.spinner( - 'Resolving dependencies', - () => resolveVersions(SolveType.get, cache, root), - condition: !silent, - ); + result = await log.progress('Resolving dependencies', + () => resolveVersions(SolveType.GET, cache, root)); } on SolveFailure catch (error) { for (var incompatibility in error.incompatibility.externalIncompatibilities) { if (incompatibility.cause != IncompatibilityCause.noVersions) continue; - if (incompatibility.terms.single.package.name != name) continue; + if (incompatibility.terms.single.package.name != dep.name) continue; dataError(error.toString()); } rethrow; } - // We want the entrypoint to be rooted at 'dep' not the dummy-package. - result.packages.removeWhere((id) => id.name == 'pub global activate'); final sameVersions = originalLockFile != null && originalLockFile.samePackageIds(result.lockFile); - final PackageId id = result.lockFile.packages[name]!; if (sameVersions) { log.message(''' -The package $name is already activated at newest available version. -To recompile executables, first run `$topLevelProgram pub global deactivate $name`. +The package ${dep.name} is already activated at newest available version. +To recompile executables, first run `$topLevelProgram pub global deactivate ${dep.name}`. '''); } else { - // Only precompile binaries if we have a new resolution. - if (!silent) await result.showReport(SolveType.get, cache); - - await result.downloadCachedPackages(cache); - - final lockFile = result.lockFile; - final tempDir = cache.createTempDir(); - _writeLockFile(tempDir, lockFile); - - // Load the package graph from [result] so we don't need to re-parse all - // the pubspecs. - final entrypoint = Entrypoint.global( - tempDir, - cache.loadCached(id), - lockFile, - cache, - solveResult: result, - ); - - await entrypoint.writePackagesFiles(); - - await entrypoint.precompileExecutables(); - - tryDeleteEntry(_packageDir(name)); - tryRenameDir(tempDir, _packageDir(name)); + await result.showReport(SolveType.GET, cache); } + + // Make sure all of the dependencies are locally installed. + await Future.wait(result.packages.map((id) { + return http.withDependencyType(root.dependencyType(id.name), () async { + if (id.isRoot) return; + + var source = cache.source(id.source); + if (source is CachedSource) await source.downloadToSystemCache(id); + }); + })); + + var lockFile = result.lockFile; + _writeLockFile(dep.name, lockFile); + await _writePackageConfigFiles(dep.name, lockFile); + + // We want the entrypoint to be rooted at 'dep' not the dummy-package. + result.packages.removeWhere((id) => id.name == 'pub global activate'); + + var id = lockFile.packages[dep.name]!; + // Load the package graph from [result] so we don't need to re-parse all + // the pubspecs. final entrypoint = Entrypoint.global( - _packageDir(id.name), - cache.loadCached(id), - result.lockFile, + Package( + result.pubspecs[dep.name]!, + (cache.source(dep.source) as CachedSource).getDirectoryInCache(id), + ), + lockFile, cache, solveResult: result, ); + if (!sameVersions) { + // Only precompile binaries if we have a new resolution. + await entrypoint.precompileExecutables(); + } + _updateBinStubs( entrypoint, cache.load(entrypoint.lockFile.packages[dep.name]!), executables, overwriteBinStubs: overwriteBinStubs, ); - if (!silent) log.message('Activated ${_formatPackage(id)}.'); + + log.message('Activated ${_formatPackage(id)}.'); + } + + Future<void> _writePackageConfigFiles( + String package, LockFile lockFile) async { + // TODO(sigurdm): Use [Entrypoint.writePackagesFiles] instead. + final packagesFilePath = _getPackagesFilePath(package); + final packageConfigFilePath = _getPackageConfigFilePath(package); + final dir = p.dirname(packagesFilePath); + writeTextFile( + packagesFilePath, lockFile.packagesFile(cache, relativeFrom: dir)); + ensureDir(p.dirname(packageConfigFilePath)); + writeTextFile(packageConfigFilePath, + await lockFile.packageConfigFile(cache, relativeFrom: dir)); } /// Finishes activating package [package] by saving [lockFile] in the cache. - void _writeLockFile(String dir, LockFile lockFile) { - writeTextFile(p.join(dir, 'pubspec.lock'), lockFile.serialize(null)); + void _writeLockFile(String package, LockFile lockFile) { + ensureDir(p.join(_directory, package)); + + // TODO(nweiz): This cleans up Dart 1.6's old lockfile location. Remove it + // when Dart 1.6 is old enough that we don't think anyone will have these + // lockfiles anymore (issue 20703). + var oldPath = p.join(_directory, '$package.lock'); + if (fileExists(oldPath)) deleteEntry(oldPath); + + writeTextFile(_getLockFilePath(package), + lockFile.serialize(p.join(_directory, package))); } /// Shows the user the currently active package with [name], if any. - LockFile? _describeActive(String name, SystemCache cache) { - late final LockFile lockFile; - try { - lockFile = LockFile.load(_getLockFilePath(name), cache.sources); - } on IOException { - // Couldn't read the lock file. It probably doesn't exist. - return null; - } + void _describeActive(LockFile lockFile, String? name) { var id = lockFile.packages[name]!; var source = id.source; @@ -291,7 +312,6 @@ log.message('Package ${log.bold(name)} is currently active at version ' '${log.bold(id.version)}.'); } - return lockFile; } /// Deactivates a previously-activated package named [name]. @@ -321,8 +341,22 @@ try { lockFile = LockFile.load(lockFilePath, cache.sources); } on IOException { - // If we couldn't read the lock file, it's not activated. - dataError('No active package ${log.bold(name)}.'); + var oldLockFilePath = p.join(_directory, '$name.lock'); + try { + // TODO(nweiz): This looks for Dart 1.6's old lockfile location. + // Remove it when Dart 1.6 is old enough that we don't think anyone + // will have these lockfiles anymore (issue 20703). + lockFile = LockFile.load(oldLockFilePath, cache.sources); + } on IOException { + // If we couldn't read the lock file, it's not activated. + dataError('No active package ${log.bold(name)}.'); + } + + // Move the old lockfile to its new location. + ensureDir(p.dirname(lockFilePath)); + File(oldLockFilePath).renameSync(lockFilePath); + // Just make sure these files are created as well. + await _writePackageConfigFiles(name, lockFile); } // Remove the package itself from the lockfile. We put it in there so we @@ -336,8 +370,7 @@ if (source is CachedSource) { // For cached sources, the package itself is in the cache and the // lockfile is the one we just loaded. - entrypoint = Entrypoint.global( - _packageDir(id.name), cache.loadCached(id), lockFile, cache); + entrypoint = Entrypoint.global(cache.loadCached(id), lockFile, cache); } else { // For uncached sources (i.e. path), the ID just points to the real // directory for the package. @@ -413,6 +446,16 @@ String _getLockFilePath(String name) => p.join(_directory, name, 'pubspec.lock'); + /// Gets the path to the .packages file for an activated cached package with + /// [name]. + String _getPackagesFilePath(String name) => + p.join(_directory, name, '.packages'); + + /// Gets the path to the `package_config.json` file for an + /// activated cached package with [name]. + String _getPackageConfigFilePath(String name) => + p.join(_directory, name, '.dart_tool', 'package_config.json'); + /// Shows the user a formatted list of globally activated packages. void listActivePackages() { if (!dirExists(_directory)) return; @@ -499,24 +542,17 @@ log.message('Reactivating ${log.bold(id.name)} ${id.version}...'); var entrypoint = await find(id.name); - final packageExecutables = executables.remove(id.name) ?? []; - if (entrypoint.isCached) { - deleteEntry(entrypoint.globalDir!); - await _installInCache( - id.toRange(), - packageExecutables, - overwriteBinStubs: true, - silent: true, - ); - } else { - await activatePath( - entrypoint.root.dir, - packageExecutables, - overwriteBinStubs: true, - analytics: null, - ); - } + await _writePackageConfigFiles(id.name, entrypoint.lockFile); + await entrypoint.precompileExecutables(); + var packageExecutables = executables.remove(id.name) ?? []; + _updateBinStubs( + entrypoint, + cache.load(id), + packageExecutables, + overwriteBinStubs: true, + suggestIfNotOnPath: false, + ); successes.add(id.name); } catch (error, stackTrace) { var message = 'Failed to reactivate ' @@ -670,7 +706,10 @@ // Show errors for any missing scripts. // TODO(rnystrom): This can print false positives since a script may be // produced by a transformer. Do something better. - var binFiles = package.executablePaths; + var binFiles = package + .listFiles(beneath: 'bin', recursive: false) + .map(package.relative) + .toList(); for (var executable in installed) { var script = package.pubspec.executables[executable]; var scriptPath = p.join('bin', '$script.dart'); @@ -722,7 +761,6 @@ // If the script was built to a snapshot, just try to invoke that // directly and skip pub global run entirely. String invocation; - late String binstub; if (Platform.isWindows) { if (fileExists(snapshot)) { // We expect absolute paths from the precompiler since relative ones @@ -748,7 +786,7 @@ } else { invocation = 'dart pub global run ${package.name}:$script %*'; } - binstub = ''' + var batch = ''' @echo off rem This file was created by pub v${sdk.version}. rem Package: ${package.name} @@ -757,6 +795,7 @@ rem Script: $script $invocation '''; + writeTextFile(binStubPath, batch); } else { if (fileExists(snapshot)) { // We expect absolute paths from the precompiler since relative ones @@ -779,7 +818,7 @@ } else { invocation = 'dart pub global run ${package.name}:$script "\$@"'; } - binstub = ''' + var bash = ''' #!/usr/bin/env sh # This file was created by pub v${sdk.version}. # Package: ${package.name} @@ -788,31 +827,25 @@ # Script: $script $invocation '''; - } - // Write the binstub to a temporary location, make it executable and move - // it into place afterwards to avoid races. - final tempDir = cache.createTempDir(); - try { - final tmpPath = p.join(tempDir, binStubPath); + // Write this as the system encoding since the system is going to execute + // it and it might contain non-ASCII characters in the pathnames. + writeTextFile(binStubPath, bash, encoding: const SystemEncoding()); - // Write this as the system encoding since the system is going to - // execute it and it might contain non-ASCII characters in the - // pathnames. - writeTextFile(tmpPath, binstub, encoding: const SystemEncoding()); - - if (Platform.isLinux || Platform.isMacOS) { - // Make it executable. - var result = Process.runSync('chmod', ['+x', tmpPath]); - if (result.exitCode != 0) { - // Couldn't make it executable so don't leave it laying around. - fail('Could not make "$tmpPath" executable (exit code ' - '${result.exitCode}):\n${result.stderr}'); + // Make it executable. + var result = Process.runSync('chmod', ['+x', binStubPath]); + if (result.exitCode != 0) { + // Couldn't make it executable so don't leave it laying around. + try { + deleteEntry(binStubPath); + } on IOException catch (err) { + // Do nothing. We're going to fail below anyway. + log.fine('Could not delete binstub:\n$err'); } + + fail('Could not make "$binStubPath" executable (exit code ' + '${result.exitCode}):\n${result.stderr}'); } - File(tmpPath).renameSync(binStubPath); - } finally { - deleteEntry(tempDir); } return previousPackage;
diff --git a/lib/src/http.dart b/lib/src/http.dart index 724962b..fb6e9aa 100644 --- a/lib/src/http.dart +++ b/lib/src/http.dart
@@ -10,6 +10,7 @@ import 'package:http/http.dart' as http; import 'package:http/retry.dart'; +import 'package:pedantic/pedantic.dart'; import 'package:pool/pool.dart'; import 'package:stack_trace/stack_trace.dart';
diff --git a/lib/src/ignore.dart b/lib/src/ignore.dart index ff22dff..fbd93e8 100644 --- a/lib/src/ignore.dart +++ b/lib/src/ignore.dart
@@ -464,9 +464,6 @@ } else { expr += '.*'; } - } else if (peekChar() == '/' || peekChar() == null) { - // /a/* should not match '/a/' - expr += '[^/]+'; } else { // Handle a single '*' expr += '[^/]*'; @@ -523,6 +520,7 @@ expr = '$expr/\$'; } else { expr = '$expr/?\$'; + // expr = '$expr\$'; } try { return _IgnoreParseResult(
diff --git a/lib/src/io.dart b/lib/src/io.dart index acc1a6f..5e9a210 100644 --- a/lib/src/io.dart +++ b/lib/src/io.dart
@@ -8,12 +8,14 @@ import 'dart:convert'; import 'dart:io'; +import 'package:async/async.dart'; import 'package:cli_util/cli_util.dart' show EnvironmentNotFoundException, applicationConfigHome; import 'package:http/http.dart' show ByteStream; import 'package:http_multi_server/http_multi_server.dart'; import 'package:meta/meta.dart'; import 'package:path/path.dart' as path; +import 'package:pedantic/pedantic.dart'; import 'package:pool/pool.dart'; import 'package:stack_trace/stack_trace.dart'; @@ -361,54 +363,52 @@ /// when we try to delete or move something while it's being scanned. To /// mitigate that, on Windows, this will retry the operation a few times if it /// fails. -/// -/// For some operations it makes sense to handle ERROR_DIR_NOT_EMPTY -/// differently. They can pass [ignoreEmptyDir] = `true`. -void _attempt(String description, void Function() operation, - {bool ignoreEmptyDir = false}) { +void _attempt(String description, void Function() operation) { if (!Platform.isWindows) { operation(); return; } String? getErrorReason(FileSystemException error) { - // ERROR_ACCESS_DENIED if (error.osError?.errorCode == 5) { return 'access was denied'; } - // ERROR_SHARING_VIOLATION if (error.osError?.errorCode == 32) { return 'it was in use by another process'; } - // ERROR_DIR_NOT_EMPTY - if (!ignoreEmptyDir && _isDirectoryNotEmptyException(error)) { + if (error.osError?.errorCode == 145) { return 'of dart-lang/sdk#25353'; } return null; } - for (var i = 0; i < 3; i++) { + for (var i = 0; i < 2; i++) { try { operation(); - break; + return; } on FileSystemException catch (error) { var reason = getErrorReason(error); if (reason == null) rethrow; - if (i < 2) { - log.io('Pub failed to $description because $reason. ' - 'Retrying in 50ms.'); - sleep(Duration(milliseconds: 50)); - } else { - fail('Pub failed to $description because $reason.\n' - 'This may be caused by a virus scanner or having a file\n' - 'in the directory open in another application.'); - } + log.io('Pub failed to $description because $reason. ' + 'Retrying in 50ms.'); + sleep(Duration(milliseconds: 50)); } } + + try { + operation(); + } on FileSystemException catch (error) { + var reason = getErrorReason(error); + if (reason == null) rethrow; + + fail('Pub failed to $description because $reason.\n' + 'This may be caused by a virus scanner or having a file\n' + 'in the directory open in another application.'); + } } /// Deletes whatever's at [path], whether it's a file, directory, or symlink. @@ -453,53 +453,14 @@ void renameDir(String from, String to) { _attempt('rename directory', () { log.io('Renaming directory $from to $to.'); - Directory(from).renameSync(to); - }, ignoreEmptyDir: true); -} - -/// Renames directory [from] to [to]. -/// If it fails with "destination not empty" we log and continue, assuming -/// another process got there before us. -void tryRenameDir(String from, String to) { - ensureDir(path.dirname(to)); - try { - renameDir(from, to); - } on FileSystemException catch (e) { - tryDeleteEntry(from); - if (!_isDirectoryNotEmptyException(e)) { + try { + Directory(from).renameSync(to); + } on IOException { + // Ensure that [to] isn't left in an inconsistent state. See issue 12436. + if (entryExists(to)) deleteEntry(to); rethrow; } - log.fine(''' -Destination directory $to already existed. -Assuming a concurrent pub invocation installed it.'''); - } -} - -void copyFile(String from, String to) { - log.io('Copying "$from" to "$to".'); - File(from).copySync(to); -} - -void renameFile(String from, String to) { - log.io('Renaming "$from" to "$to".'); - File(from).renameSync(to); -} - -bool _isDirectoryNotEmptyException(FileSystemException e) { - final errorCode = e.osError?.errorCode; - return - // On Linux rename will fail with ENOTEMPTY if directory exists: - // https://man7.org/linux/man-pages/man2/rename.2.html - // #define ENOTEMPTY 39 /* Directory not empty */ - // https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/asm-generic/errno.h#n20 - (Platform.isLinux && errorCode == 39) || - // On Windows this may fail with ERROR_DIR_NOT_EMPTY - // https://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499- - (Platform.isWindows && errorCode == 145) || - // On MacOS rename will fail with ENOTEMPTY if directory exists. - // #define ENOTEMPTY 66 /* Directory not empty */ - // https://github.com/apple-oss-distributions/xnu/blob/bb611c8fecc755a0d8e56e2fa51513527c5b7a0e/bsd/sys/errno.h#L190 - (Platform.isMacOS && errorCode == 66); + }); } /// Creates a new symlink at path [symlink] that points to [target]. @@ -601,6 +562,10 @@ return path.fromUri(url); })(); +/// A line-by-line stream of standard input. +final StreamQueue<String> _stdinLines = StreamQueue( + ByteStream(stdin).toStringStream().transform(const LineSplitter())); + /// Displays a message and reads a yes/no confirmation from the user. /// /// Returns a [Future] that completes to `true` if the user confirms or `false` @@ -626,14 +591,14 @@ final previousEchoMode = stdin.echoMode; try { stdin.echoMode = echoMode; - final result = stdin.readLineSync() ?? ''; + final result = await _stdinLines.next; stdout.write('\n'); return result; } finally { stdin.echoMode = previousEchoMode; } } else { - return stdin.readLineSync() ?? ''; + return await _stdinLines.next; } } @@ -1007,10 +972,10 @@ log.fine(buffer.toString()); ArgumentError.checkNotNull(baseDir, 'baseDir'); - baseDir = path.normalize(path.absolute(baseDir)); + baseDir = path.absolute(baseDir); final tarContents = Stream.fromIterable(contents.map((entry) { - entry = path.normalize(path.absolute(entry)); + entry = path.absolute(entry); if (!path.isWithin(baseDir, entry)) { throw ArgumentError('Entry $entry is not inside $baseDir.'); }
diff --git a/lib/src/language_version.dart b/lib/src/language_version.dart index ad331b2..e294014 100644 --- a/lib/src/language_version.dart +++ b/lib/src/language_version.dart
@@ -69,21 +69,6 @@ bool get supportsNullSafety => this >= firstVersionWithNullSafety; - /// Minimum language version at which short hosted syntax is supported. - /// - /// This allows `hosted` dependencies to be expressed as: - /// ```yaml - /// dependencies: - /// foo: - /// hosted: https://some-pub.com/path - /// version: ^1.0.0 - /// ``` - /// - /// At older versions, `hosted` dependencies had to be a map with a `url` and - /// a `name` key. - bool get supportsShorterHostedSyntax => - this >= firstVersionWithShorterHostedSyntax; - @override int compareTo(LanguageVersion other) { if (major != other.major) return major.compareTo(other.major); @@ -104,7 +89,6 @@ static const defaultLanguageVersion = LanguageVersion(2, 7); static const firstVersionWithNullSafety = LanguageVersion(2, 12); - static const firstVersionWithShorterHostedSyntax = LanguageVersion(2, 15); /// Transform language version to string that can be parsed with /// [LanguageVersion.parse].
diff --git a/lib/src/lock_file.dart b/lib/src/lock_file.dart index 8f563ab..e2723c7 100644 --- a/lib/src/lock_file.dart +++ b/lib/src/lock_file.dart
@@ -218,7 +218,7 @@ String packagesFile( SystemCache cache, { String? entrypoint, - String? relativeFrom, + required String relativeFrom, }) { var header = ''' This file is deprecated. Tools should instead consume @@ -256,7 +256,7 @@ SystemCache cache, { String? entrypoint, VersionConstraint? entrypointSdkConstraint, - String? relativeFrom, + required String relativeFrom, }) async { final entries = <PackageConfigEntry>[]; for (final name in ordered(packages.keys)) { @@ -306,9 +306,8 @@ /// Returns the serialized YAML text of the lock file. /// /// [packageDir] is the containing directory of the root package, used to - /// serialize relative path package descriptions. If it is null, they will be - /// serialized as absolute. - String serialize(String? packageDir) { + /// properly serialize package descriptions. + String serialize(String packageDir) { // Convert the dependencies to a simple object. var packageMap = {}; packages.forEach((name, package) {
diff --git a/lib/src/log.dart b/lib/src/log.dart index db24d7a..ff7fe29 100644 --- a/lib/src/log.dart +++ b/lib/src/log.dart
@@ -12,11 +12,9 @@ import 'package:source_span/source_span.dart'; import 'package:stack_trace/stack_trace.dart'; -import 'entrypoint.dart'; import 'exceptions.dart'; import 'io.dart'; import 'progress.dart'; -import 'sdk.dart'; import 'transcript.dart'; import 'utils.dart'; @@ -26,7 +24,7 @@ final json = _JsonLogger(); /// The current logging verbosity. -Verbosity verbosity = Verbosity.normal; +Verbosity verbosity = Verbosity.NORMAL; /// In cases where there's a ton of log spew, make sure we don't eat infinite /// memory. @@ -34,11 +32,11 @@ /// This can occur when the backtracking solver stumbles into a pathological /// dependency graph. It generally will find a solution, but it may log /// thousands and thousands of entries to get there. -const _maxTranscript = 10000; +const _MAX_TRANSCRIPT = 10000; /// The list of recorded log messages. Will only be recorded if /// [recordTranscript()] is called. -final Transcript<_Entry> _transcript = Transcript(_maxTranscript); +Transcript<_Entry>? _transcript; /// The currently-animated progress indicator, if any. /// @@ -60,34 +58,34 @@ /// An enum type for defining the different logging levels a given message can /// be associated with. /// -/// By default, [error] and [warning] messages are printed to sterr. [message] +/// By default, [ERROR] and [WARNING] messages are printed to sterr. [MESSAGE] /// messages are printed to stdout, and others are ignored. class Level { /// An error occurred and an operation could not be completed. /// /// Usually shown to the user on stderr. - static const error = Level._('ERR '); + static const ERROR = Level._('ERR '); /// Something unexpected happened, but the program was able to continue, /// though possibly in a degraded fashion. - static const warning = Level._('WARN'); + static const WARNING = Level._('WARN'); /// A message intended specifically to be shown to the user. - static const message = Level._('MSG '); + static const MESSAGE = Level._('MSG '); /// Some interaction with the external world occurred, such as a network /// operation, process spawning, or file IO. - static const io = Level._('IO '); + static const IO = Level._('IO '); /// Incremental output during pub's version constraint solver. - static const solver = Level._('SLVR'); + static const SOLVER = Level._('SLVR'); /// Fine-grained and verbose additional information. /// /// Used to provide program state context for other logs (such as what pub /// was doing when an IO operation occurred) or just more detail for an /// operation. - static const fine = Level._('FINE'); + static const FINE = Level._('FINE'); const Level._(this.name); @@ -101,83 +99,73 @@ /// displayed. class Verbosity { /// Silence all logging. - static const none = Verbosity._('none', { - Level.error: null, - Level.warning: null, - Level.message: null, - Level.io: null, - Level.solver: null, - Level.fine: null + static const NONE = Verbosity._('none', { + Level.ERROR: null, + Level.WARNING: null, + Level.MESSAGE: null, + Level.IO: null, + Level.SOLVER: null, + Level.FINE: null }); /// Shows only errors. - static const error = Verbosity._('error', { - Level.error: _logToStderr, - Level.warning: null, - Level.message: null, - Level.io: null, - Level.solver: null, - Level.fine: null + static const ERROR = Verbosity._('error', { + Level.ERROR: _logToStderr, + Level.WARNING: null, + Level.MESSAGE: null, + Level.IO: null, + Level.SOLVER: null, + Level.FINE: null }); /// Shows only errors and warnings. - static const warning = Verbosity._('warning', { - Level.error: _logToStderr, - Level.warning: _logToStderr, - Level.message: null, - Level.io: null, - Level.solver: null, - Level.fine: null + static const WARNING = Verbosity._('warning', { + Level.ERROR: _logToStderr, + Level.WARNING: _logToStderr, + Level.MESSAGE: null, + Level.IO: null, + Level.SOLVER: null, + Level.FINE: null }); /// The default verbosity which shows errors, warnings, and messages. - static const normal = Verbosity._('normal', { - Level.error: _logToStderr, - Level.warning: _logToStderr, - Level.message: _logToStdout, - Level.io: null, - Level.solver: null, - Level.fine: null + static const NORMAL = Verbosity._('normal', { + Level.ERROR: _logToStderr, + Level.WARNING: _logToStderr, + Level.MESSAGE: _logToStdout, + Level.IO: null, + Level.SOLVER: null, + Level.FINE: null }); /// Shows errors, warnings, messages, and IO event logs. - static const io = Verbosity._('io', { - Level.error: _logToStderrWithLabel, - Level.warning: _logToStderrWithLabel, - Level.message: _logToStdoutWithLabel, - Level.io: _logToStderrWithLabel, - Level.solver: null, - Level.fine: null + static const IO = Verbosity._('io', { + Level.ERROR: _logToStderrWithLabel, + Level.WARNING: _logToStderrWithLabel, + Level.MESSAGE: _logToStdoutWithLabel, + Level.IO: _logToStderrWithLabel, + Level.SOLVER: null, + Level.FINE: null }); /// Shows errors, warnings, messages, and version solver logs. - static const solver = Verbosity._('solver', { - Level.error: _logToStderr, - Level.warning: _logToStderr, - Level.message: _logToStdout, - Level.io: null, - Level.solver: _logToStdout, - Level.fine: null + static const SOLVER = Verbosity._('solver', { + Level.ERROR: _logToStderr, + Level.WARNING: _logToStderr, + Level.MESSAGE: _logToStdout, + Level.IO: null, + Level.SOLVER: _logToStdout, + Level.FINE: null }); /// Shows all logs. - static const all = Verbosity._('all', { - Level.error: _logToStderrWithLabel, - Level.warning: _logToStderrWithLabel, - Level.message: _logToStdoutWithLabel, - Level.io: _logToStderrWithLabel, - Level.solver: _logToStderrWithLabel, - Level.fine: _logToStderrWithLabel - }); - - /// Shows all logs. - static const testing = Verbosity._('testing', { - Level.error: _logToStderrWithLabel, - Level.warning: _logToStderrWithLabel, - Level.message: _logToStdoutWithLabel, - Level.io: _logToStderrWithLabel, - Level.solver: _logToStderrWithLabel, - Level.fine: _logToStderrWithLabel + static const ALL = Verbosity._('all', { + Level.ERROR: _logToStderrWithLabel, + Level.WARNING: _logToStderrWithLabel, + Level.MESSAGE: _logToStdoutWithLabel, + Level.IO: _logToStderrWithLabel, + Level.SOLVER: _logToStderrWithLabel, + Level.FINE: _logToStderrWithLabel }); const Verbosity._(this.name, this._loggers); @@ -200,7 +188,7 @@ _Entry(this.level, this.lines); } -/// Logs [message] at [Level.error]. +/// Logs [message] at [Level.ERROR]. /// /// If [error] is passed, it's appended to [message]. If [trace] is passed, it's /// printed at log level fine. @@ -210,24 +198,24 @@ message = message.isEmpty ? '$error' : '$message: $error'; if (error is Error && trace == null) trace = error.stackTrace; } - write(Level.error, message); - if (trace != null) write(Level.fine, Chain.forTrace(trace)); + write(Level.ERROR, message); + if (trace != null) write(Level.FINE, Chain.forTrace(trace)); } -/// Logs [message] at [Level.warning]. -void warning(message) => write(Level.warning, message); +/// Logs [message] at [Level.WARNING]. +void warning(message) => write(Level.WARNING, message); -/// Logs [message] at [Level.message]. -void message(message) => write(Level.message, message); +/// Logs [message] at [Level.MESSAGE]. +void message(message) => write(Level.MESSAGE, message); -/// Logs [message] at [Level.io]. -void io(message) => write(Level.io, message); +/// Logs [message] at [Level.IO]. +void io(message) => write(Level.IO, message); -/// Logs [message] at [Level.solver]. -void solver(message) => write(Level.solver, message); +/// Logs [message] at [Level.SOLVER]. +void solver(message) => write(Level.SOLVER, message); -/// Logs [message] at [Level.fine]. -void fine(message) => write(Level.fine, message); +/// Logs [message] at [Level.FINE]. +void fine(message) => write(Level.FINE, message); /// Logs [message] at [level]. void write(Level level, message) { @@ -245,10 +233,10 @@ var logFn = verbosity._loggers[level]; if (logFn != null) logFn(entry); - _transcript.add(entry); + if (_transcript != null) _transcript!.add(entry); } -/// Logs the spawning of an [executable] process with [arguments] at [io] +/// Logs the spawning of an [executable] process with [arguments] at [IO] /// level. void process( String executable, List<String> arguments, String workingDirectory) { @@ -325,10 +313,18 @@ } } -/// Prints the recorded log transcript to stderr. -void dumpTranscriptToStdErr() { +/// Enables recording of log entries. +void recordTranscript() { + _transcript = Transcript<_Entry>(_MAX_TRANSCRIPT); +} + +/// If [recordTranscript()] was called, then prints the previously recorded log +/// transcript to stderr. +void dumpTranscript() { + if (_transcript == null) return; + stderr.writeln('---- Log transcript ----'); - _transcript.forEach((entry) { + _transcript!.forEach((entry) { _printToStream(stderr, entry, showLabel: true); }, (discarded) { stderr.writeln('---- ($discarded discarded) ----'); @@ -336,68 +332,6 @@ stderr.writeln('---- End log transcript ----'); } -String _limit(String input, int limit) { - const snip = '[...]'; - if (input.length < limit - snip.length) return input; - return '${input.substring(0, limit ~/ 2 - snip.length)}' - '$snip' - '${input.substring(limit)}'; -} - -/// Prints relevant system information and the log transcript to [path]. -void dumpTranscriptToFile(String path, String command, Entrypoint? entrypoint) { - final buffer = StringBuffer(); - buffer.writeln(''' -Information about the latest pub run. - -If you believe something is not working right, you can go to -https://github.com/dart-lang/pub/issues/new to post a new issue and attach this file. - -Before making this file public, make sure to remove any sensitive information! - -Pub version: ${sdk.version} -Created: ${DateTime.now().toIso8601String()} -FLUTTER_ROOT: ${Platform.environment['FLUTTER_ROOT'] ?? '<not set>'} -PUB_HOSTED_URL: ${Platform.environment['PUB_HOSTED_URL'] ?? '<not set>'} -PUB_CACHE: "${Platform.environment['PUB_CACHE'] ?? '<not set>'}" -Command: $command -Platform: ${Platform.operatingSystem} -'''); - - if (entrypoint != null) { - buffer.writeln('---- ${p.absolute(entrypoint.pubspecPath)} ----'); - if (fileExists(entrypoint.pubspecPath)) { - buffer.writeln(_limit(readTextFile(entrypoint.pubspecPath), 5000)); - } else { - buffer.writeln('<No pubspec.yaml>'); - } - buffer.writeln('---- End pubspec.yaml ----'); - buffer.writeln('---- ${p.absolute(entrypoint.lockFilePath)} ----'); - if (fileExists(entrypoint.lockFilePath)) { - buffer.writeln(_limit(readTextFile(entrypoint.lockFilePath), 5000)); - } else { - buffer.writeln('<No pubspec.lock>'); - } - buffer.writeln('---- End pubspec.lock ----'); - } - - buffer.writeln('---- Log transcript ----'); - - _transcript.forEach((entry) { - _printToStream(buffer, entry, showLabel: true); - }, (discarded) { - buffer.writeln('---- ($discarded entries discarded) ----'); - }); - buffer.writeln('---- End log transcript ----'); - ensureDir(p.dirname(path)); - try { - writeTextFile(path, buffer.toString(), dontLogContents: true); - } on IOException catch (e) { - stderr.writeln('Failed writing log to `$path` ($e), writing it to stderr:'); - dumpTranscriptToStdErr(); - } -} - /// Filter out normal pub output when not attached to a terminal /// /// Unless the user has overriden the verbosity, @@ -405,8 +339,8 @@ /// This is useful to not pollute stdout when the output is piped somewhere. Future<T> warningsOnlyUnlessTerminal<T>(FutureOr<T> Function() callback) async { final oldVerbosity = verbosity; - if (verbosity == Verbosity.normal && !stdout.hasTerminal) { - verbosity = Verbosity.warning; + if (verbosity == Verbosity.NORMAL && !stdout.hasTerminal) { + verbosity = Verbosity.WARNING; } final result = await callback(); verbosity = oldVerbosity; @@ -419,7 +353,7 @@ /// If anything else is logged during this (including another call to /// [progress]) that cancels the progress animation, although the total time /// will still be printed once it finishes. If [fine] is passed, the progress -/// information will only be visible at [Level.fine]. +/// information will only be visible at [Level.FINE]. Future<T> progress<T>(String message, Future<T> Function() callback) { _stopProgress(); @@ -558,7 +492,7 @@ _printToStream(sink, entry, showLabel: showLabel); } -void _printToStream(StringSink sink, _Entry entry, {required bool showLabel}) { +void _printToStream(IOSink sink, _Entry entry, {required bool showLabel}) { _stopProgress(); var firstLine = true;
diff --git a/lib/src/null_safety_analysis.dart b/lib/src/null_safety_analysis.dart index 5b882a8..2ad034d 100644 --- a/lib/src/null_safety_analysis.dart +++ b/lib/src/null_safety_analysis.dart
@@ -109,7 +109,7 @@ SolveResult result; try { result = await resolveVersions( - SolveType.get, + SolveType.GET, _systemCache, fakeRoot, );
diff --git a/lib/src/package.dart b/lib/src/package.dart index d100157..0bc6f89 100644 --- a/lib/src/package.dart +++ b/lib/src/package.dart
@@ -83,12 +83,10 @@ ..addAll(dependencyOverrides); } - /// Returns a list of paths to all Dart executables in this package's bin + /// Returns a list of asset ids for all Dart executables in this package's bin /// directory. List<String> get executablePaths { - final binDir = p.join(dir, 'bin'); - if (!dirExists(binDir)) return <String>[]; - return ordered(listDir(p.join(dir, 'bin'), includeDirs: false)) + return ordered(listFiles(beneath: 'bin', recursive: false)) .where((executable) => p.extension(executable) == '.dart') .map((executable) => p.relative(executable, from: dir)) .toList();
diff --git a/lib/src/package_config.dart b/lib/src/package_config.dart index d64808b..0493dcc 100644 --- a/lib/src/package_config.dart +++ b/lib/src/package_config.dart
@@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'dart:convert'; - import 'package:pub_semver/pub_semver.dart'; import 'language_version.dart'; @@ -162,6 +160,8 @@ /// Given as `<major>.<minor>` version, similar to the `// @dart = X.Y` /// comment. This is derived from the lower-bound on the Dart SDK requirement /// in the `pubspec.yaml` for the given package. + /// + /// `null` if not given. LanguageVersion? languageVersion; /// Additional properties not in the specification for the @@ -173,8 +173,10 @@ required this.rootUri, this.packageUri, this.languageVersion, - this.additionalProperties = const {}, - }); + this.additionalProperties, + }) { + additionalProperties ??= {}; + } /// Create [PackageConfigEntry] from JSON [data]. /// @@ -247,13 +249,7 @@ Map<String, Object?> toJson() => { 'name': name, 'rootUri': rootUri.toString(), - if (packageUri != null) 'packageUri': packageUri.toString(), + if (packageUri != null) 'packageUri': packageUri?.toString(), if (languageVersion != null) 'languageVersion': '$languageVersion', }..addAll(additionalProperties ?? {}); - - @override - String toString() { - // TODO: implement toString - return JsonEncoder.withIndent(' ').convert(toJson()); - } }
diff --git a/lib/src/package_name.dart b/lib/src/package_name.dart index d83f466..50f4bcc 100644 --- a/lib/src/package_name.dart +++ b/lib/src/package_name.dart
@@ -57,10 +57,6 @@ } @override - bool operator ==(Object other) => - throw UnimplementedError('Subclass should implement =='); - - @override int get hashCode { var thisSource = source; if (thisSource == null) return name.hashCode; @@ -108,9 +104,6 @@ @override bool operator ==(other) => other is PackageRef && samePackage(other); - - @override - int get hashCode => super.hashCode ^ 'PackageRef'.hashCode; } /// A reference to a specific version of a package.
diff --git a/lib/src/progress.dart b/lib/src/progress.dart index b9c6931..06ad9e9 100644 --- a/lib/src/progress.dart +++ b/lib/src/progress.dart
@@ -34,7 +34,7 @@ Progress(this._message, {bool fine = false}) { _stopwatch.start(); - var level = fine ? log.Level.fine : log.Level.message; + var level = fine ? log.Level.FINE : log.Level.MESSAGE; // The animation is only shown when it would be meaningful to a human. // That means we're writing a visible message to a TTY at normal log levels @@ -43,7 +43,7 @@ !log.verbosity.isLevelVisible(level) || log.json.enabled || fine || - log.verbosity.isLevelVisible(log.Level.fine)) { + log.verbosity.isLevelVisible(log.Level.FINE)) { // Not animating, so just log the start and wait until the task is // completed. log.write(level, '$_message...');
diff --git a/lib/src/pub_embeddable_command.dart b/lib/src/pub_embeddable_command.dart index b9e59c6..c1fa863 100644 --- a/lib/src/pub_embeddable_command.dart +++ b/lib/src/pub_embeddable_command.dart
@@ -58,13 +58,11 @@ @override final PubAnalytics? analytics; - final bool Function() isVerbose; - - PubEmbeddableCommand(this.analytics, this.isVerbose) : super() { + PubEmbeddableCommand(this.analytics) : super() { argParser.addFlag('trace', help: 'Print debugging information when an error occurs.'); argParser.addFlag('verbose', - abbr: 'v', negatable: false, help: 'Print detailed logging.'); + abbr: 'v', negatable: false, help: 'Shortcut for "--verbosity=all".'); argParser.addOption( 'directory', abbr: 'C', @@ -103,15 +101,12 @@ } @override - bool get captureStackChains => _isVerbose; + bool get captureStackChains => argResults['verbose']; @override - Verbosity get verbosity => _isVerbose ? Verbosity.all : Verbosity.normal; + Verbosity get verbosity => + argResults['verbose'] ? Verbosity.ALL : Verbosity.NORMAL; @override - bool get trace => _isVerbose; - - bool get _isVerbose { - return argResults['verbose'] || isVerbose(); - } + bool get trace => argResults['verbose']; }
diff --git a/lib/src/rate_limited_scheduler.dart b/lib/src/rate_limited_scheduler.dart index 85d73cd..2d301d3 100644 --- a/lib/src/rate_limited_scheduler.dart +++ b/lib/src/rate_limited_scheduler.dart
@@ -5,6 +5,7 @@ import 'dart:async'; import 'dart:collection'; +import 'package:pedantic/pedantic.dart'; import 'package:pool/pool.dart'; /// Handles rate-limited scheduling of tasks.
diff --git a/lib/src/solver/failure.dart b/lib/src/solver/failure.dart index 60f70c5..ba27a3b 100644 --- a/lib/src/solver/failure.dart +++ b/lib/src/solver/failure.dart
@@ -7,6 +7,7 @@ import '../exceptions.dart'; import '../log.dart' as log; import '../package_name.dart'; +import '../sdk.dart'; import '../utils.dart'; import 'incompatibility.dart'; import 'incompatibility_cause.dart'; @@ -92,20 +93,39 @@ String write() { var buffer = StringBuffer(); - // Find all notices from incompatibility causes. This allows an - // [IncompatibilityCause] to provide a notice that is printed before the - // explanation of the conflict. - // Notably, this is used for stating which SDK version is currently - // installed, if an SDK is incompatible with a dependency. - final notices = _root.externalIncompatibilities - .map((c) => c.cause.notice) - .whereNotNull() - .toSet() // Avoid duplicates - .sortedBy((n) => n); // sort for consistency - for (final n in notices) { - buffer.writeln(n); + // SDKs whose version constraints weren't matched. + var sdkConstraintCauses = <Sdk>{}; + + // SDKs implicated in any way in the solve failure. + var sdkCauses = <Sdk>{}; + + for (var incompatibility in _root.externalIncompatibilities) { + var cause = incompatibility.cause; + if (cause is PackageNotFoundCause) { + var sdk = cause.sdk; + if (sdk != null) { + sdkCauses.add(sdk); + } + } else if (cause is SdkCause) { + sdkCauses.add(cause.sdk); + sdkConstraintCauses.add(cause.sdk); + } } - if (notices.isNotEmpty) buffer.writeln(); + + // If the failure was caused in part by unsatisfied SDK constraints, + // indicate the actual versions so we don't have to list them (possibly + // multiple times) in the main body of the error message. + // + // Iterate through [sdks] to ensure that SDKs versions are printed in a + // consistent order + var wroteLine = false; + for (var sdk in sdks.values) { + if (!sdkConstraintCauses.contains(sdk)) continue; + if (!sdk.isAvailable) continue; + wroteLine = true; + buffer.writeln('The current ${sdk.name} SDK version is ${sdk.version}.'); + } + if (wroteLine) buffer.writeln(); if (_root.cause is ConflictCause) { _visit(_root, const {}); @@ -139,21 +159,15 @@ buffer.writeln(wordWrap(message, prefix: ' ' * (padding + 2))); } - // Iterate through all hints, these are intended to be actionable, such as: - // * How to install an SDK, and, - // * How to provide authentication. - // Hence, it makes sense to show these at the end of the explanation, as the - // user will ideally see these before reading the actual conflict and - // understand how to fix the issue. - _root.externalIncompatibilities - .map((c) => c.cause.hint) - .whereNotNull() - .toSet() // avoid duplicates - .sortedBy((hint) => hint) // sort hints for consistent ordering. - .forEach((hint) { + // Iterate through [sdks] to ensure that SDKs versions are printed in a + // consistent order + for (var sdk in sdks.values) { + if (!sdkCauses.contains(sdk)) continue; + if (sdk.isAvailable) continue; + if (sdk.installMessage == null) continue; buffer.writeln(); - buffer.writeln(hint); - }); + buffer.writeln(sdk.installMessage); + } return buffer.toString(); }
diff --git a/lib/src/solver/incompatibility_cause.dart b/lib/src/solver/incompatibility_cause.dart index a2a2327..53dcfe2 100644 --- a/lib/src/solver/incompatibility_cause.dart +++ b/lib/src/solver/incompatibility_cause.dart
@@ -10,8 +10,6 @@ /// The reason an [Incompatibility]'s terms are incompatible. abstract class IncompatibilityCause { - const IncompatibilityCause._(); - /// The incompatibility represents the requirement that the root package /// exists. static const IncompatibilityCause root = _Cause('root'); @@ -29,26 +27,11 @@ /// The incompatibility indicates that the package has an unknown source. static const IncompatibilityCause unknownSource = _Cause('unknown source'); - - /// Human readable notice / information providing context for this - /// incompatibility. - /// - /// This may be multiple lines, and will be printed before the explanation. - /// This is used highlight information that is useful for understanding the - /// why this conflict happened. - String? get notice => null; - - /// Human readable hint indicating how this incompatibility may be resolved. - /// - /// This may be multiple lines, and will be printed after the explanation. - /// This should only be included if it is actionable and likely to resolve the - /// issue for the user. - String? get hint => null; } /// The incompatibility was derived from two existing incompatibilities during /// conflict resolution. -class ConflictCause extends IncompatibilityCause { +class ConflictCause implements IncompatibilityCause { /// The incompatibility that was originally found to be in conflict, from /// which the target incompatibility was derived. final Incompatibility conflict; @@ -57,14 +40,14 @@ /// from which the target incompatibility was derived. final Incompatibility other; - ConflictCause(this.conflict, this.other) : super._(); + ConflictCause(this.conflict, this.other); } /// A class for stateless [IncompatibilityCause]s. -class _Cause extends IncompatibilityCause { +class _Cause implements IncompatibilityCause { final String _name; - const _Cause(this._name) : super._(); + const _Cause(this._name); @override String toString() => _name; @@ -72,7 +55,7 @@ /// The incompatibility represents a package's SDK constraint being /// incompatible with the current SDK. -class SdkCause extends IncompatibilityCause { +class SdkCause implements IncompatibilityCause { /// The union of all the incompatible versions' constraints on the SDK. // TODO(zarah): Investigate if this can be non-nullable final VersionConstraint? constraint; @@ -80,41 +63,20 @@ /// The SDK with which the package was incompatible. final Sdk sdk; - @override - String? get notice { - // If the SDK is not available, then we have an actionable [hint] printed - // after the explanation. So we don't need to state that the SDK is not - // available. - if (!sdk.isAvailable) { - return null; - } - // If the SDK is available and we have an incompatibility, then the user has - // the wrong SDK version (one that is not compatible with any solution). - // Thus, it makes sense to highlight the current SDK version. - return 'The current ${sdk.name} SDK version is ${sdk.version}.'; - } - - @override - String? get hint { - // If the SDK is available, then installing it won't help - if (sdk.isAvailable) { - return null; - } - // Return an install message for the SDK, if there is an install message. - return sdk.installMessage; - } - - SdkCause(this.constraint, this.sdk) : super._(); + SdkCause(this.constraint, this.sdk); } /// The incompatibility represents a package that couldn't be found by its /// source. -class PackageNotFoundCause extends IncompatibilityCause { +class PackageNotFoundCause implements IncompatibilityCause { /// The exception indicating why the package couldn't be found. final PackageNotFoundException exception; - PackageNotFoundCause(this.exception) : super._(); + /// If the incompatibility was caused by an SDK being unavailable, this is + /// that SDK. + /// + /// Otherwise `null`. + Sdk? get sdk => exception.missingSdk; - @override - String? get hint => exception.hint; + PackageNotFoundCause(this.exception); }
diff --git a/lib/src/solver/report.dart b/lib/src/solver/report.dart index e3dd5dc..e345413 100644 --- a/lib/src/solver/report.dart +++ b/lib/src/solver/report.dart
@@ -89,7 +89,7 @@ } } else { if (numChanged == 0) { - if (_type == SolveType.get) { + if (_type == SolveType.GET) { log.message('Got dependencies$suffix!'); } else { log.message('No dependencies changed$suffix.'); @@ -245,7 +245,7 @@ String? message; // See if there are any newer versions of the package that we were // unable to upgrade to. - if (newId != null && _type != SolveType.downgrade) { + if (newId != null && _type != SolveType.DOWNGRADE) { var versions = _result.availableVersions[newId.name]!; var newerStable = false; @@ -292,7 +292,7 @@ } } - if (_type == SolveType.get && + if (_type == SolveType.GET && !(alwaysShow || changed || addedOrRemoved || message != null)) { return; }
diff --git a/lib/src/solver/result.dart b/lib/src/solver/result.dart index bc01162..692b05f 100644 --- a/lib/src/solver/result.dart +++ b/lib/src/solver/result.dart
@@ -5,7 +5,6 @@ import 'package:collection/collection.dart'; import 'package:pub_semver/pub_semver.dart'; -import '../http.dart'; import '../io.dart'; import '../lock_file.dart'; import '../log.dart' as log; @@ -13,7 +12,6 @@ import '../package_name.dart'; import '../pub_embeddable_command.dart'; import '../pubspec.dart'; -import '../source/cached.dart'; import '../source/hosted.dart'; import '../source_registry.dart'; import '../system_cache.dart'; @@ -80,18 +78,6 @@ final LockFile _previousLockFile; - /// Downloads all cached packages in [packages]. - Future<void> downloadCachedPackages(SystemCache cache) async { - await Future.wait(packages.map((id) async { - if (id.source == null) return; - final source = cache.source(id.source); - if (source is! CachedSource) return; - return await withDependencyType(_root.dependencyType(id.name), () async { - await source.downloadToSystemCache(id); - }); - })); - } - /// Returns the names of all packages that were changed. /// /// This includes packages that were added or removed. @@ -136,7 +122,7 @@ final report = SolveReport(type, _sources, _root, _previousLockFile, this, cache); report.summarize(dryRun: dryRun); - if (type == SolveType.upgrade) { + if (type == SolveType.UPGRADE) { await report.reportDiscontinued(); report.reportOutdated(); }
diff --git a/lib/src/solver/type.dart b/lib/src/solver/type.dart index 28a3230..c899e31 100644 --- a/lib/src/solver/type.dart +++ b/lib/src/solver/type.dart
@@ -6,15 +6,15 @@ class SolveType { /// As few changes to the lockfile as possible to be consistent with the /// pubspec. - static const get = SolveType._('get'); + static const GET = SolveType._('get'); /// Upgrade all packages or specific packages to the highest versions /// possible, regardless of the lockfile. - static const upgrade = SolveType._('upgrade'); + static const UPGRADE = SolveType._('upgrade'); /// Downgrade all packages or specific packages to the lowest versions /// possible, regardless of the lockfile. - static const downgrade = SolveType._('downgrade'); + static const DOWNGRADE = SolveType._('downgrade'); final String _name;
diff --git a/lib/src/solver/version_solver.dart b/lib/src/solver/version_solver.dart index d4e3a75..120244a 100644 --- a/lib/src/solver/version_solver.dart +++ b/lib/src/solver/version_solver.dart
@@ -485,7 +485,7 @@ _root.dependencyType(package.name), overridden, _getAllowedRetracted(ref.name), - downgrade: _type == SolveType.downgrade); + downgrade: _type == SolveType.DOWNGRADE); }); } @@ -493,7 +493,7 @@ /// /// Returns `null` if it isn't in the lockfile (or has been unlocked). PackageId? _getLocked(String? package) { - if (_type == SolveType.get) { + if (_type == SolveType.GET) { if (_unlock.contains(package)) { return null; } @@ -503,7 +503,7 @@ // When downgrading, we don't want to force the latest versions of // non-hosted packages, since they don't support multiple versions and thus // can't be downgraded. - if (_type == SolveType.downgrade) { + if (_type == SolveType.DOWNGRADE) { var locked = _lockFile.packages[package]; if (locked != null && !locked.source!.hasMultipleVersions) return locked; }
diff --git a/lib/src/source.dart b/lib/src/source.dart index ecbc5eb..add55fa 100644 --- a/lib/src/source.dart +++ b/lib/src/source.dart
@@ -116,7 +116,7 @@ /// [description] in the right format. /// /// [containingPath] is the containing directory of the root package. - dynamic serializeDescription(String? containingPath, description) { + dynamic serializeDescription(String containingPath, description) { return description; }
diff --git a/lib/src/source/git.dart b/lib/src/source/git.dart index 3be752c..0d98ae9 100644 --- a/lib/src/source/git.dart +++ b/lib/src/source/git.dart
@@ -108,10 +108,10 @@ /// For the descriptions where `relative` attribute is `true`, tries to make /// `url` relative to the specified [containingPath]. @override - dynamic serializeDescription(String? containingPath, description) { + dynamic serializeDescription(String containingPath, description) { final copy = Map.from(description); copy.remove('relative'); - if (description['relative'] == true && containingPath != null) { + if (description['relative'] == true) { copy['url'] = p.url.relative(description['url'], from: Uri.file(containingPath).toString()); }
diff --git a/lib/src/source/hosted.dart b/lib/src/source/hosted.dart index 2cfc52a..def4a98 100644 --- a/lib/src/source/hosted.dart +++ b/lib/src/source/hosted.dart
@@ -10,6 +10,7 @@ show maxBy, IterableNullableExtension; import 'package:http/http.dart' as http; import 'package:path/path.dart' as p; +import 'package:pedantic/pedantic.dart'; import 'package:pub_semver/pub_semver.dart'; import 'package:stack_trace/stack_trace.dart'; @@ -159,7 +160,7 @@ } @override - dynamic serializeDescription(String? containingPath, description) { + dynamic serializeDescription(String containingPath, description) { final desc = _asDescription(description); return _serializedDescriptionFor(desc.packageName, desc.uri); } @@ -232,7 +233,8 @@ return _HostedDescription(packageName, defaultUrl); } - final canUseShorthandSyntax = languageVersion.supportsShorterHostedSyntax; + final canUseShorthandSyntax = + languageVersion >= _minVersionForShorterHostedSyntax; if (description is String) { // Old versions of pub (pre Dart 2.15) interpret `hosted: foo` as @@ -255,7 +257,7 @@ } else { throw FormatException( 'Using `hosted: <url>` is only supported with a minimum SDK ' - 'constraint of ${LanguageVersion.firstVersionWithShorterHostedSyntax}.', + 'constraint of $_minVersionForShorterHostedSyntax.', ); } } @@ -270,7 +272,7 @@ if (name is! String) { throw FormatException("The 'name' key must have a string value without " - 'a minimum Dart SDK constraint of ${LanguageVersion.firstVersionWithShorterHostedSyntax}.0 or higher.'); + 'a minimum Dart SDK constraint of $_minVersionForShorterHostedSyntax.0 or higher.'); } var url = defaultUrl; @@ -285,6 +287,21 @@ return _HostedDescription(name, url); } + /// Minimum language version at which short hosted syntax is supported. + /// + /// This allows `hosted` dependencies to be expressed as: + /// ```yaml + /// dependencies: + /// foo: + /// hosted: https://some-pub.com/path + /// version: ^1.0.0 + /// ``` + /// + /// At older versions, `hosted` dependencies had to be a map with a `url` and + /// a `name` key. + static const LanguageVersion _minVersionForShorterHostedSyntax = + LanguageVersion(2, 15); + static final RegExp _looksLikePackageName = RegExp(r'^[a-zA-Z_]+[a-zA-Z0-9_]*$'); } @@ -389,8 +406,8 @@ body = decoded; result = _versionInfoFromPackageListing(body, ref, url); } on Exception catch (error, stackTrace) { - final packageName = source._asDescription(ref.description).packageName; - _throwFriendlyError(error, stackTrace, packageName, serverUrl); + var parsed = source._asDescription(ref.description); + _throwFriendlyError(error, stackTrace, parsed.packageName, parsed.uri); } // Cache the response on disk. @@ -688,7 +705,6 @@ packages.map((package) async { var id = source.idFor(package.name, package.version, url: url); try { - deleteEntry(package.dir); await _download(id, package.dir); return RepairResult(id, success: true); } catch (error, stackTrace) { @@ -797,74 +813,51 @@ var tempDir = systemCache.createTempDir(); await extractTarGz(readBinaryFileAsSream(archivePath), tempDir); + // Remove the existing directory if it exists. This will happen if + // we're forcing a download to repair the cache. + if (dirExists(destPath)) deleteEntry(destPath); + // Now that the get has succeeded, move it to the real location in the - // cache. - // - // If this fails with a "directory not empty" exception we assume that - // another pub process has installed the same package version while we - // downloaded. - tryRenameDir(tempDir, destPath); + // cache. This ensures that we don't leave half-busted ghost + // directories in the user's pub cache if a get fails. + renameDir(tempDir, destPath); }); } - /// When an error occurs trying to read something about [package] from [hostedUrl], + /// When an error occurs trying to read something about [package] from [url], /// this tries to translate into a more user friendly error message. /// /// Always throws an error, either the original one or a better one. Never _throwFriendlyError( - Exception error, + error, StackTrace stackTrace, String package, - Uri hostedUrl, + Uri url, ) { if (error is PubHttpException) { if (error.response.statusCode == 404) { throw PackageNotFoundException( - 'could not find package $package at $hostedUrl', + 'could not find package $package at $url', innerError: error, innerTrace: stackTrace); } fail( '${error.response.statusCode} ${error.response.reasonPhrase} trying ' - 'to find package $package at $hostedUrl.', + 'to find package $package at $url.', error, stackTrace); } else if (error is io.SocketException) { - fail('Got socket error trying to find package $package at $hostedUrl.', - error, stackTrace); + fail('Got socket error trying to find package $package at $url.', error, + stackTrace); } else if (error is io.TlsException) { - fail('Got TLS error trying to find package $package at $hostedUrl.', - error, stackTrace); - } else if (error is AuthenticationException) { - String? hint; - var message = 'authentication failed'; - - assert(error.statusCode == 401 || error.statusCode == 403); - if (error.statusCode == 401) { - hint = '$hostedUrl package repository requested authentication!\n' - 'You can provide credentials using:\n' - ' pub token add $hostedUrl'; - } - if (error.statusCode == 403) { - hint = 'Insufficient permissions to the resource at the $hostedUrl ' - 'package repository.\nYou can modify credentials using:\n' - ' pub token add $hostedUrl'; - message = 'authorization failed'; - } - - if (error.serverMessage?.isNotEmpty == true && hint != null) { - hint += '\n${error.serverMessage}'; - } - - throw PackageNotFoundException(message, hint: hint); + fail('Got TLS error trying to find package $package at $url.', error, + stackTrace); } else if (error is FormatException) { throw PackageNotFoundException( - 'Got badly formatted response trying to find package $package at $hostedUrl', - innerError: error, - innerTrace: stackTrace, - hint: 'Check that "$hostedUrl" is a valid package repository.', - ); + 'Got badly formatted response trying to find package $package at $url', + innerError: error, + innerTrace: stackTrace); } else { // Otherwise re-throw the original exception. throw error; @@ -982,9 +975,7 @@ // If there are no versions in the cache, report a clearer error. if (versions.isEmpty) { throw PackageNotFoundException( - 'could not find package ${ref.name} in cache', - hint: 'Try again without --offline!', - ); + 'could not find package ${ref.name} in cache'); } return versions; @@ -1000,9 +991,7 @@ @override Future<Pubspec> describeUncached(PackageId id) { throw PackageNotFoundException( - '${id.name} ${id.version} is not available in cache', - hint: 'Try again without --offline!', - ); + '${id.name} ${id.version} is not available in your system cache'); } @override
diff --git a/lib/src/source/path.dart b/lib/src/source/path.dart index 4679f98..0401ebd 100644 --- a/lib/src/source/path.dart +++ b/lib/src/source/path.dart
@@ -130,11 +130,9 @@ /// /// For the descriptions where `relative` attribute is `true`, tries to make /// `path` relative to the specified [containingPath]. - /// - /// If [containingPath] is `null` they are serialized as absolute. @override - dynamic serializeDescription(String? containingPath, description) { - if (description['relative'] == true && containingPath != null) { + dynamic serializeDescription(String containingPath, description) { + if (description['relative']) { return { 'path': relativePathWithPosixSeparators( p.relative(description['path'], from: containingPath)),
diff --git a/lib/src/source/sdk.dart b/lib/src/source/sdk.dart index 1458d1b..f1dde9e 100644 --- a/lib/src/source/sdk.dart +++ b/lib/src/source/sdk.dart
@@ -101,10 +101,8 @@ if (sdk == null) { throw PackageNotFoundException('unknown SDK "$identifier"'); } else if (!sdk.isAvailable) { - throw PackageNotFoundException( - 'the ${sdk.name} SDK is not available', - hint: sdk.installMessage, - ); + throw PackageNotFoundException('the ${sdk.name} SDK is not available', + missingSdk: sdk); } var path = sdk.packagePath(package.name);
diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 2a5768e..39439e9 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart
@@ -375,7 +375,7 @@ // If we're using verbose logging, be more verbose but more accurate when // reporting timing information. - var msString = log.verbosity.isLevelVisible(log.Level.fine) + var msString = log.verbosity.isLevelVisible(log.Level.FINE) ? _padLeft(ms.toString(), 3, '0') : (ms ~/ 100).toString();
diff --git a/lib/src/validator.dart b/lib/src/validator.dart index 1b07560..29392fa 100644 --- a/lib/src/validator.dart +++ b/lib/src/validator.dart
@@ -101,7 +101,7 @@ 'Make sure your SDK constraint excludes old versions:\n' '\n' 'environment:\n' - ' sdk: "$newSdkConstraint"'); + ' sdk: \"$newSdkConstraint\"'); } /// Returns whether [version1] and [version2] are pre-releases of the same version.
diff --git a/lib/src/validator/changelog.dart b/lib/src/validator/changelog.dart index 614eba2..694ace2 100644 --- a/lib/src/validator/changelog.dart +++ b/lib/src/validator/changelog.dart
@@ -21,7 +21,7 @@ final changelog = entrypoint.root.changelogPath; if (changelog == null) { - warnings.add('Please add a `CHANGELOG.md` to your package. ' + warnings.add('Please add a`CHANGELOG.md` to your package. ' 'See https://dart.dev/tools/pub/publishing#important-files.'); return; }
diff --git a/lib/src/validator/gitignore.dart b/lib/src/validator/gitignore.dart index 4fb49b1..7770b57 100644 --- a/lib/src/validator/gitignore.dart +++ b/lib/src/validator/gitignore.dart
@@ -46,10 +46,8 @@ beneath: beneath, listDir: (dir) { var contents = Directory(resolve(dir)).listSync(); - return contents - .where((e) => !(linkExists(e.path) && dirExists(e.path))) - .map((entity) => p.posix - .joinAll(p.split(p.relative(entity.path, from: root)))); + return contents.map((entity) => + p.posix.joinAll(p.split(p.relative(entity.path, from: root)))); }, ignoreForDir: (dir) { final gitIgnore = resolve('$dir/.gitignore'); @@ -71,7 +69,7 @@ if (ignoredFilesCheckedIn.isNotEmpty) { warnings.add(''' -${ignoredFilesCheckedIn.length} checked-in ${pluralize('file', ignoredFilesCheckedIn.length)} ${ignoredFilesCheckedIn.length == 1 ? 'is' : 'are'} ignored by a `.gitignore`. +${ignoredFilesCheckedIn.length} checked in ${pluralize('file', ignoredFilesCheckedIn.length)} ${ignoredFilesCheckedIn.length == 1 ? 'is' : 'are'} ignored by a `.gitignore`. Previous versions of Pub would include those in the published package. Consider adjusting your `.gitignore` files to not ignore those files, and if you do not wish to
diff --git a/lib/src/validator/sdk_constraint.dart b/lib/src/validator/sdk_constraint.dart index ff25e53..063ad7e 100644 --- a/lib/src/validator/sdk_constraint.dart +++ b/lib/src/validator/sdk_constraint.dart
@@ -50,7 +50,7 @@ 'Expand it manually instead:\n' '\n' 'environment:\n' - ' sdk: "$dartConstraintWithoutCaret"'); + ' sdk: \"$dartConstraintWithoutCaret\"'); } if (dartConstraint.max == null) {
diff --git a/lib/src/validator/size.dart b/lib/src/validator/size.dart index e989518..8f258a9 100644 --- a/lib/src/validator/size.dart +++ b/lib/src/validator/size.dart
@@ -10,7 +10,7 @@ import '../validator.dart'; /// The maximum size of the package to upload (100 MB). -const _maxSize = 100 * 1024 * 1024; +const _MAX_SIZE = 100 * 1024 * 1024; /// A validator that validates that a package isn't too big. class SizeValidator extends Validator { @@ -21,7 +21,7 @@ @override Future validate() { return packageSize.then((size) { - if (size <= _maxSize) return; + if (size <= _MAX_SIZE) return; var sizeInMb = (size / math.pow(2, 20)).toStringAsPrecision(4); // Current implementation of Package.listFiles skips hidden files var ignoreExists = fileExists(entrypoint.root.path('.gitignore'));
diff --git a/pubspec.yaml b/pubspec.yaml index a7d9bb4..8c76708 100644 --- a/pubspec.yaml +++ b/pubspec.yaml
@@ -18,6 +18,7 @@ meta: ^1.3.0 oauth2: ^2.0.0 path: ^1.8.0 + pedantic: ^1.11.0 pool: ^1.5.0 pub_semver: ^2.1.0 shelf: ^1.1.1 @@ -28,7 +29,6 @@ yaml_edit: ^2.0.0 dev_dependencies: - lints: ^1.0.1 shelf_test_handler: ^2.0.0 test: ^1.17.3 test_descriptor: ^2.0.0
diff --git a/test/add/common/add_test.dart b/test/add/common/add_test.dart index 82e098b..e124be8 100644 --- a/test/add/common/add_test.dart +++ b/test/add/common/add_test.dart
@@ -13,7 +13,7 @@ void main() { test('URL encodes the package name', () async { - await servePackages(); + await serveNoPackages(); await d.appDir({}).create(); @@ -37,48 +37,49 @@ }); group('normally', () { + test('fails if extra arguments are passed', () async { + await servePackages((builder) { + builder.serve('foo', '1.2.2'); + }); + + await d.dir(appPath, [ + d.pubspec({'name': 'myapp'}) + ]).create(); + + await pubAdd( + args: ['foo', '^1.2.2'], + exitCode: exit_codes.USAGE, + error: contains('Takes only a single argument.')); + + await d.dir(appPath, [ + d.pubspec({ + 'name': 'myapp', + }), + d.nothing('.dart_tool/package_config.json'), + d.nothing('pubspec.lock'), + d.nothing('.packages'), + ]).validate(); + }); + test('adds a package from a pub server', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) => builder.serve('foo', '1.2.3')); await d.appDir({}).create(); await pubAdd(args: ['foo:1.2.3']); await d.cacheDir({'foo': '1.2.3'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); await d.appDir({'foo': '1.2.3'}).validate(); }); - test('adds multiple package from a pub server', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); - server.serve('bar', '1.1.0'); - server.serve('baz', '2.5.3'); - - await d.appDir({}).create(); - - await pubAdd(args: ['foo:1.2.3', 'bar:1.1.0', 'baz:2.5.3']); - - await d.cacheDir( - {'foo': '1.2.3', 'bar': '1.1.0', 'baz': '2.5.3'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - d.packageConfigEntry(name: 'bar', version: '1.1.0'), - d.packageConfigEntry(name: 'baz', version: '2.5.3'), - ]).validate(); - await d - .appDir({'foo': '1.2.3', 'bar': '1.1.0', 'baz': '2.5.3'}).validate(); - }); - test( 'does not remove empty dev_dependencies while adding to normal dependencies', () async { - await servePackages() - ..serve('foo', '1.2.3') - ..serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + builder.serve('foo', '1.2.2'); + }); await d.dir(appPath, [ d.file('pubspec.yaml', ''' @@ -95,9 +96,7 @@ await pubAdd(args: ['foo:1.2.3']); await d.cacheDir({'foo': '1.2.3'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); await d.dir(appPath, [ d.pubspec({ @@ -110,8 +109,7 @@ test('dry run does not actually add the package or modify the pubspec', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) => builder.serve('foo', '1.2.3')); await d.appDir({}).create(); @@ -133,8 +131,7 @@ test( 'adds a package from a pub server even when dependencies key does not exist', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) => builder.serve('foo', '1.2.3')); await d.dir(appPath, [ d.pubspec({'name': 'myapp'}) @@ -143,17 +140,16 @@ await pubAdd(args: ['foo:1.2.3']); await d.cacheDir({'foo': '1.2.3'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); await d.appDir({'foo': '1.2.3'}).validate(); }); group('warns user to use pub upgrade if package exists', () { test('if package is added without a version constraint', () async { - await servePackages() - ..serve('foo', '1.2.3') - ..serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + builder.serve('foo', '1.2.2'); + }); await d.appDir({'foo': '1.2.2'}).create(); @@ -168,9 +164,10 @@ }); test('if package is added with a specific version constraint', () async { - await servePackages() - ..serve('foo', '1.2.3') - ..serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + builder.serve('foo', '1.2.2'); + }); await d.appDir({'foo': '1.2.2'}).create(); @@ -185,9 +182,10 @@ }); test('if package is added with a version constraint range', () async { - await servePackages() - ..serve('foo', '1.2.3') - ..serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + builder.serve('foo', '1.2.2'); + }); await d.appDir({'foo': '1.2.2'}).create(); @@ -203,9 +201,10 @@ }); test('removes dev_dependency and add to normal dependency', () async { - await servePackages() - ..serve('foo', '1.2.3') - ..serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + builder.serve('foo', '1.2.2'); + }); await d.dir(appPath, [ d.file('pubspec.yaml', ''' @@ -226,9 +225,7 @@ 'adding it to dependencies instead.')); await d.cacheDir({'foo': '1.2.3'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); await d.dir(appPath, [ d.pubspec({ @@ -240,9 +237,10 @@ group('dependency override', () { test('passes if package does not specify a range', () async { - await servePackages() - ..serve('foo', '1.2.3') - ..serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + builder.serve('foo', '1.2.2'); + }); await d.dir(appPath, [ d.pubspec({ @@ -255,9 +253,7 @@ await pubAdd(args: ['foo']); await d.cacheDir({'foo': '1.2.2'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.2'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.2'}).validate(); await d.dir(appPath, [ d.pubspec({ 'name': 'myapp', @@ -268,8 +264,9 @@ }); test('passes if constraint matches git dependency override', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + }); await d.git('foo.git', [d.libDir('foo'), d.libPubspec('foo', '1.2.3')]).create(); @@ -298,8 +295,9 @@ }); test('passes if constraint matches path dependency override', () async { - final server = await servePackages(); - server.serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.2'); + }); await d.dir( 'foo', [d.libDir('foo'), d.libPubspec('foo', '1.2.2')]).create(); @@ -327,8 +325,9 @@ }); test('fails with bad version constraint', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + }); await d.dir(appPath, [ d.pubspec({'name': 'myapp', 'dependencies': {}}) @@ -349,9 +348,10 @@ }); test('fails if constraint does not match override', () async { - await servePackages() - ..serve('foo', '1.2.3') - ..serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + builder.serve('foo', '1.2.2'); + }); await d.dir(appPath, [ d.pubspec({ @@ -381,8 +381,9 @@ }); test('fails if constraint matches git dependency override', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + }); await d.git('foo.git', [d.libDir('foo'), d.libPubspec('foo', '1.0.0')]).create(); @@ -420,8 +421,9 @@ test('fails if constraint does not match path dependency override', () async { - final server = await servePackages(); - server.serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.2'); + }); await d.dir( 'foo', [d.libDir('foo'), d.libPubspec('foo', '1.0.0')]).create(); @@ -460,8 +462,7 @@ group('--dev', () { test('--dev adds packages to dev_dependencies instead', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) => builder.serve('foo', '1.2.3')); await d.dir(appPath, [ d.pubspec({'name': 'myapp', 'dev_dependencies': {}}) @@ -469,9 +470,7 @@ await pubAdd(args: ['--dev', 'foo:1.2.3']); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); await d.dir(appPath, [ d.pubspec({ @@ -483,9 +482,10 @@ group('warns user to use pub upgrade if package exists', () { test('if package is added without a version constraint', () async { - await servePackages() - ..serve('foo', '1.2.3') - ..serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + builder.serve('foo', '1.2.2'); + }); await d.dir(appPath, [ d.pubspec({ @@ -510,9 +510,10 @@ }); test('if package is added with a specific version constraint', () async { - await servePackages() - ..serve('foo', '1.2.3') - ..serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + builder.serve('foo', '1.2.2'); + }); await d.dir(appPath, [ d.pubspec({ @@ -537,9 +538,10 @@ }); test('if package is added with a version constraint range', () async { - await servePackages() - ..serve('foo', '1.2.3') - ..serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + builder.serve('foo', '1.2.2'); + }); await d.dir(appPath, [ d.pubspec({ @@ -566,9 +568,10 @@ group('dependency override', () { test('passes if package does not specify a range', () async { - await servePackages() - ..serve('foo', '1.2.3') - ..serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + builder.serve('foo', '1.2.2'); + }); await d.dir(appPath, [ d.pubspec({ @@ -581,9 +584,7 @@ await pubAdd(args: ['foo', '--dev']); await d.cacheDir({'foo': '1.2.2'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.2'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.2'}).validate(); await d.dir(appPath, [ d.pubspec({ 'name': 'myapp', @@ -594,8 +595,10 @@ }); test('passes if constraint is git dependency', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + }); + await d.git('foo.git', [d.libDir('foo'), d.libPubspec('foo', '1.2.3')]).create(); @@ -623,8 +626,9 @@ }); test('passes if constraint matches path dependency override', () async { - final server = await servePackages(); - server.serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.2'); + }); await d.dir( 'foo', [d.libDir('foo'), d.libPubspec('foo', '1.2.2')]).create(); @@ -652,9 +656,10 @@ }); test('fails if constraint does not match override', () async { - await servePackages() - ..serve('foo', '1.2.3') - ..serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + builder.serve('foo', '1.2.2'); + }); await d.dir(appPath, [ d.pubspec({ @@ -684,8 +689,9 @@ }); test('fails if constraint matches git dependency override', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + }); await d.git('foo.git', [d.libDir('foo'), d.libPubspec('foo', '1.0.0')]).create(); @@ -723,9 +729,9 @@ test('fails if constraint does not match path dependency override', () async { - final server = await servePackages(); - server.serve('foo', '1.2.2'); - + await servePackages((builder) { + builder.serve('foo', '1.2.2'); + }); await d.dir( 'foo', [d.libDir('foo'), d.libPubspec('foo', '1.0.0')]).create(); @@ -764,9 +770,10 @@ test( 'prints information saying that package is already a dependency if it ' 'already exists and exits with a usage exception', () async { - await servePackages() - ..serve('foo', '1.2.3') - ..serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + builder.serve('foo', '1.2.2'); + }); await d.dir(appPath, [ d.pubspec({ @@ -798,8 +805,9 @@ /// Differs from the previous test because this tests YAML in flow format. test('adds to empty ', () async { - final server = await servePackages(); - server.serve('bar', '1.0.0'); + await servePackages((builder) { + builder.serve('bar', '1.0.0'); + }); await d.dir(appPath, [ d.file('pubspec.yaml', ''' @@ -817,9 +825,10 @@ }); test('preserves comments', () async { - await servePackages() - ..serve('bar', '1.0.0') - ..serve('foo', '1.0.0'); + await servePackages((builder) { + builder.serve('bar', '1.0.0'); + builder.serve('foo', '1.0.0'); + }); await d.dir(appPath, [ d.file('pubspec.yaml', '''
diff --git a/test/add/common/invalid_options.dart b/test/add/common/invalid_options.dart index f5bf23d..0b60ed8 100644 --- a/test/add/common/invalid_options.dart +++ b/test/add/common/invalid_options.dart
@@ -39,10 +39,12 @@ test('cannot use both --path and --host-<option> flags', () async { // Make the default server serve errors. Only the custom server should // be accessed. - (await servePackages()).serveErrors(); + await serveNoPackages(); + globalPackageServer!.serveErrors(); - final server = await startPackageServer(); - server.serve('foo', '1.2.3'); + final server = await PackageServer.start((builder) { + builder.serve('foo', '1.2.3'); + }); await d .dir('bar', [d.libDir('bar'), d.libPubspec('foo', '0.0.1')]).create(); @@ -74,10 +76,12 @@ test('cannot use both --hosted-url and --git-<option> flags', () async { // Make the default server serve errors. Only the custom server should // be accessed. - (await servePackages()).serveErrors(); + await serveNoPackages(); + globalPackageServer!.serveErrors(); - final server = await startPackageServer(); - server.serve('foo', '1.2.3'); + final server = await PackageServer.start((builder) { + builder.serve('foo', '1.2.3'); + }); ensureGit();
diff --git a/test/add/common/version_constraint_test.dart b/test/add/common/version_constraint_test.dart index f058082..d865727 100644 --- a/test/add/common/version_constraint_test.dart +++ b/test/add/common/version_constraint_test.dart
@@ -10,96 +10,86 @@ void main() { test('allows empty version constraint', () async { - await servePackages() - ..serve('foo', '0.2.3') - ..serve('foo', '1.0.1') - ..serve('foo', '1.2.3') - ..serve('foo', '2.0.0-dev') - ..serve('foo', '1.3.4-dev'); + await servePackages((builder) { + builder.serve('foo', '0.2.3'); + builder.serve('foo', '1.0.1'); + builder.serve('foo', '1.2.3'); + builder.serve('foo', '2.0.0-dev'); + builder.serve('foo', '1.3.4-dev'); + }); await d.appDir({}).create(); await pubAdd(args: ['foo']); await d.cacheDir({'foo': '1.2.3'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); await d.appDir({'foo': '^1.2.3'}).validate(); }); test('allows specific version constraint', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) => builder.serve('foo', '1.2.3')); await d.appDir({}).create(); await pubAdd(args: ['foo:1.2.3']); await d.cacheDir({'foo': '1.2.3'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); await d.appDir({'foo': '1.2.3'}).validate(); }); test('allows specific pre-release version constraint', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3-dev'); + await servePackages((builder) => builder.serve('foo', '1.2.3-dev')); await d.appDir({}).create(); await pubAdd(args: ['foo:1.2.3-dev']); await d.cacheDir({'foo': '1.2.3-dev'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3-dev'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3-dev'}).validate(); await d.appDir({'foo': '1.2.3-dev'}).validate(); }); test('allows the "any" version constraint', () async { - await servePackages() - ..serve('foo', '0.2.3') - ..serve('foo', '1.0.1') - ..serve('foo', '1.2.3') - ..serve('foo', '2.0.0-dev') - ..serve('foo', '1.3.4-dev'); + await servePackages((builder) { + builder.serve('foo', '0.2.3'); + builder.serve('foo', '1.0.1'); + builder.serve('foo', '1.2.3'); + builder.serve('foo', '2.0.0-dev'); + builder.serve('foo', '1.3.4-dev'); + }); await d.appDir({}).create(); await pubAdd(args: ['foo:any']); await d.cacheDir({'foo': '1.2.3'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); await d.appDir({'foo': 'any'}).validate(); }); test('allows version constraint range', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) => builder.serve('foo', '1.2.3')); await d.appDir({}).create(); await pubAdd(args: ['foo:>1.2.0 <2.0.0']); await d.cacheDir({'foo': '1.2.3'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); await d.appDir({'foo': '>1.2.0 <2.0.0'}).validate(); }); test( 'empty constraint allows it to choose the latest version not in conflict', () async { - await servePackages() - ..serve('foo', '0.1.0') - ..serve('foo', '1.2.3', deps: {'bar': '2.0.4'}) - ..serve('bar', '2.0.3') - ..serve('bar', '2.0.4'); + await servePackages((builder) { + builder.serve('foo', '0.1.0'); + builder.serve('foo', '1.2.3', deps: {'bar': '2.0.4'}); + builder.serve('bar', '2.0.3'); + builder.serve('bar', '2.0.4'); + }); await d.appDir({'bar': '2.0.3'}).create(); @@ -108,16 +98,12 @@ await d.appDir({'foo': '^0.1.0', 'bar': '2.0.3'}).validate(); await d.cacheDir({'foo': '0.1.0', 'bar': '2.0.3'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '0.1.0'), - d.packageConfigEntry(name: 'bar', version: '2.0.3'), - ]).validate(); + await d.appPackagesFile({'foo': '0.1.0', 'bar': '2.0.3'}).validate(); }); group('does not update pubspec if no available version found', () { test('simple', () async { - final server = await servePackages(); - server.serve('foo', '1.0.3'); + await servePackages((builder) => builder.serve('foo', '1.0.3')); await d.appDir({}).create(); @@ -138,10 +124,11 @@ }); test('transitive', () async { - await servePackages() - ..serve('foo', '1.2.3', deps: {'bar': '2.0.4'}) - ..serve('bar', '2.0.3') - ..serve('bar', '2.0.4'); + await servePackages((builder) { + builder.serve('foo', '1.2.3', deps: {'bar': '2.0.4'}); + builder.serve('bar', '2.0.3'); + builder.serve('bar', '2.0.4'); + }); await d.appDir({'bar': '2.0.3'}).create();
diff --git a/test/add/common/version_resolution_test.dart b/test/add/common/version_resolution_test.dart index 0f44d2b..4bd355b 100644 --- a/test/add/common/version_resolution_test.dart +++ b/test/add/common/version_resolution_test.dart
@@ -13,10 +13,10 @@ test('unlocks transitive dependencies', () async { /// The server used to only have the foo v3.2.1 as the latest, /// so pub get will create a pubspec.lock to foo 3.2.1 - final server = await servePackages(); - - server.serve('foo', '3.2.1'); - server.serve('bar', '1.0.0', deps: {'foo': '^3.2.1'}); + await servePackages((builder) { + builder.serve('foo', '3.2.1'); + builder.serve('bar', '1.0.0', deps: {'foo': '^3.2.1'}); + }); await d.appDir({'bar': '1.0.0'}).create(); await pubGet(); @@ -24,69 +24,66 @@ /// foo's package creator releases a newer version of foo, and we /// want to test that this is what the user gets when they run /// pub add foo. - server.serve('foo', '3.5.0'); - server.serve('foo', '3.1.0'); - server.serve('foo', '2.5.0'); + globalPackageServer!.add((builder) { + builder.serve('foo', '3.5.0'); + builder.serve('foo', '3.1.0'); + builder.serve('foo', '2.5.0'); + }); await pubAdd(args: ['foo']); await d.appDir({'foo': '^3.5.0', 'bar': '1.0.0'}).validate(); await d.cacheDir({'foo': '3.5.0', 'bar': '1.0.0'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '3.5.0'), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '3.5.0', 'bar': '1.0.0'}).validate(); }); test('chooses the appropriate version to not break other dependencies', () async { /// The server used to only have the foo v3.2.1 as the latest, /// so pub get will create a pubspec.lock to foo 3.2.1 - final server = await servePackages(); - - server.serve('foo', '3.2.1'); - server.serve('bar', '1.0.0', deps: {'foo': '^3.2.1'}); + await servePackages((builder) { + builder.serve('foo', '3.2.1'); + builder.serve('bar', '1.0.0', deps: {'foo': '^3.2.1'}); + }); await d.appDir({'bar': '1.0.0'}).create(); await pubGet(); - server.serve('foo', '4.0.0'); - server.serve('foo', '2.0.0'); + globalPackageServer!.add((builder) { + builder.serve('foo', '4.0.0'); + builder.serve('foo', '2.0.0'); + }); await pubAdd(args: ['foo']); await d.appDir({'foo': '^3.2.1', 'bar': '1.0.0'}).validate(); await d.cacheDir({'foo': '3.2.1', 'bar': '1.0.0'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '3.2.1'), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '3.2.1', 'bar': '1.0.0'}).validate(); }); test('may upgrade other packages if they allow a later version to be chosen', () async { /// The server used to only have the foo v3.2.1 as the latest, /// so pub get will create a pubspec.lock to foo 3.2.1 - final server = await servePackages(); - - server.serve('foo', '3.2.1'); - server.serve('bar', '1.0.0', deps: {'foo': '^3.2.1'}); + await servePackages((builder) { + builder.serve('foo', '3.2.1'); + builder.serve('bar', '1.0.0', deps: {'foo': '^3.2.1'}); + }); await d.appDir({'bar': '^1.0.0'}).create(); await pubGet(); - server.serve('foo', '5.0.0'); - server.serve('foo', '4.0.0'); - server.serve('foo', '2.0.0'); - server.serve('bar', '1.5.0', deps: {'foo': '^4.0.0'}); + globalPackageServer!.add((builder) { + builder.serve('foo', '5.0.0'); + builder.serve('foo', '4.0.0'); + builder.serve('foo', '2.0.0'); + builder.serve('bar', '1.5.0', deps: {'foo': '^4.0.0'}); + }); await pubAdd(args: ['foo']); await d.appDir({'foo': '^4.0.0', 'bar': '^1.0.0'}).validate(); await d.cacheDir({'foo': '4.0.0', 'bar': '1.5.0'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '4.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.5.0'), - ]).validate(); + await d.appPackagesFile({'foo': '4.0.0', 'bar': '1.5.0'}).validate(); }); }
diff --git a/test/add/git/git_test.dart b/test/add/git/git_test.dart index d976172..2577af8 100644 --- a/test/add/git/git_test.dart +++ b/test/add/git/git_test.dart
@@ -156,8 +156,9 @@ }); test('can be overriden by dependency override', () async { - final server = await servePackages(); - server.serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.2'); + }); await d.git( 'foo.git', [d.libDir('foo'), d.libPubspec('foo', '1.0.0')]).create(); @@ -173,9 +174,7 @@ await pubAdd(args: ['foo', '--git-url', '../foo.git']); await d.cacheDir({'foo': '1.2.2'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.2'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.2'}).validate(); await d.dir(appPath, [ d.pubspec({ 'name': 'myapp', @@ -186,18 +185,4 @@ }) ]).validate(); }); - - test('fails if multiple packages passed for git source', () async { - ensureGit(); - - await d.git( - 'foo.git', [d.libDir('foo'), d.libPubspec('foo', '1.0.0')]).create(); - - await d.appDir({}).create(); - - await pubAdd( - args: ['foo', 'bar', 'baz', '--git-url', '../foo.git'], - exitCode: exit_codes.USAGE, - error: contains('Can only add a single git package at a time.')); - }); }
diff --git a/test/add/git/subdir_test.dart b/test/add/git/subdir_test.dart index 8e8c39c..0f78069 100644 --- a/test/add/git/subdir_test.dart +++ b/test/add/git/subdir_test.dart
@@ -30,11 +30,10 @@ ]) ]) ]).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry( - name: 'sub', - path: pathInCache('git/foo-${await repo.revParse('HEAD')}/subdir')), - ]).validate(); + + await d.appPackagesFile({ + 'sub': pathInCache('git/foo-${await repo.revParse('HEAD')}/subdir') + }).validate(); await d.appDir({ 'sub': { @@ -69,11 +68,9 @@ ]) ]).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry( - name: 'sub', - path: pathInCache('git/foo-${await repo.revParse('HEAD')}/sub/dir')), - ]).validate(); + await d.appPackagesFile({ + 'sub': pathInCache('git/foo-${await repo.revParse('HEAD')}/sub/dir') + }).validate(); await d.appDir({ 'sub': {
diff --git a/test/add/hosted/non_default_pub_server_test.dart b/test/add/hosted/non_default_pub_server_test.dart index 60538e3..fbe966e 100644 --- a/test/add/hosted/non_default_pub_server_test.dart +++ b/test/add/hosted/non_default_pub_server_test.dart
@@ -12,12 +12,13 @@ test('adds a package from a non-default pub server', () async { // Make the default server serve errors. Only the custom server should // be accessed. - (await servePackages()).serveErrors(); + await serveErrors(); - final server = await servePackages(); - server.serve('foo', '0.2.5'); - server.serve('foo', '1.1.0'); - server.serve('foo', '1.2.3'); + var server = await PackageServer.start((builder) { + builder.serve('foo', '0.2.5'); + builder.serve('foo', '1.1.0'); + builder.serve('foo', '1.2.3'); + }); await d.appDir({}).create(); @@ -26,9 +27,7 @@ await pubAdd(args: ['foo:1.2.3', '--hosted-url', url]); await d.cacheDir({'foo': '1.2.3'}, port: server.port).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); await d.appDir({ 'foo': { 'version': '1.2.3', @@ -37,49 +36,6 @@ }).validate(); }); - test('adds multiple packages from a non-default pub server', () async { - // Make the default server serve errors. Only the custom server should - // be accessed. - (await servePackages()).serveErrors(); - - final server = await servePackages(); - server.serve('foo', '1.1.0'); - server.serve('foo', '1.2.3'); - server.serve('bar', '0.2.5'); - server.serve('bar', '3.2.3'); - server.serve('baz', '0.1.3'); - server.serve('baz', '1.3.5'); - - await d.appDir({}).create(); - - final url = server.url; - - await pubAdd( - args: ['foo:1.2.3', 'bar:3.2.3', 'baz:1.3.5', '--hosted-url', url]); - - await d.cacheDir({'foo': '1.2.3', 'bar': '3.2.3', 'baz': '1.3.5'}, - port: server.port).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - d.packageConfigEntry(name: 'bar', version: '3.2.3'), - d.packageConfigEntry(name: 'baz', version: '1.3.5'), - ]).validate(); - await d.appDir({ - 'foo': { - 'version': '1.2.3', - 'hosted': {'name': 'foo', 'url': url} - }, - 'bar': { - 'version': '3.2.3', - 'hosted': {'name': 'bar', 'url': url} - }, - 'baz': { - 'version': '1.3.5', - 'hosted': {'name': 'baz', 'url': url} - } - }).validate(); - }); - test('fails when adding from an invalid url', () async { ensureGit(); @@ -108,12 +64,13 @@ () async { // Make the default server serve errors. Only the custom server should // be accessed. - (await servePackages()).serveErrors(); + await serveErrors(); - final server = await servePackages(); - server.serve('foo', '0.2.5'); - server.serve('foo', '1.1.0'); - server.serve('foo', '1.2.3'); + var server = await PackageServer.start((builder) { + builder.serve('foo', '0.2.5'); + builder.serve('foo', '1.1.0'); + builder.serve('foo', '1.2.3'); + }); await d.appDir({}).create(); @@ -122,9 +79,7 @@ await pubAdd(args: ['foo', '--hosted-url', url]); await d.cacheDir({'foo': '1.2.3'}, port: server.port).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); await d.appDir({ 'foo': { 'version': '^1.2.3', @@ -137,12 +92,13 @@ () async { // Make the default server serve errors. Only the custom server should // be accessed. - (await servePackages()).serveErrors(); + await serveErrors(); - final server = await servePackages(); - server.serve('foo', '0.2.5'); - server.serve('foo', '1.1.0'); - server.serve('foo', '1.2.3'); + var server = await PackageServer.start((builder) { + builder.serve('foo', '0.2.5'); + builder.serve('foo', '1.1.0'); + builder.serve('foo', '1.2.3'); + }); await d.appDir({}).create(); @@ -151,9 +107,7 @@ await pubAdd(args: ['foo', '--hosted-url', url]); await d.cacheDir({'foo': '1.2.3'}, port: server.port).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); await d.appDir({ 'foo': { 'version': '^1.2.3', @@ -167,11 +121,13 @@ 'constraint', () async { // Make the default server serve errors. Only the custom server should // be accessed. - (await servePackages()).serveErrors(); - final server = await servePackages(); - server.serve('foo', '0.2.5'); - server.serve('foo', '1.1.0'); - server.serve('foo', '1.2.3'); + await serveErrors(); + + var server = await PackageServer.start((builder) { + builder.serve('foo', '0.2.5'); + builder.serve('foo', '1.1.0'); + builder.serve('foo', '1.2.3'); + }); await d.appDir({}).create(); @@ -180,9 +136,7 @@ await pubAdd(args: ['foo:any', '--hosted-url', url]); await d.cacheDir({'foo': '1.2.3'}, port: server.port).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); await d.appDir({ 'foo': { 'version': 'any',
diff --git a/test/add/path/absolute_path_test.dart b/test/add/path/absolute_path_test.dart index 5e63679..0811bea 100644 --- a/test/add/path/absolute_path_test.dart +++ b/test/add/path/absolute_path_test.dart
@@ -20,9 +20,7 @@ await pubAdd(args: ['foo', '--path', absolutePath]); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: absolutePath), - ]).validate(); + await d.appPackagesFile({'foo': absolutePath}).validate(); await d.appDir({ 'foo': {'path': absolutePath} @@ -43,28 +41,6 @@ }).validate(); }); - test('fails when adding multiple packages through local path', () async { - ensureGit(); - - await d.git( - 'foo.git', [d.libDir('foo'), d.libPubspec('foo', '1.0.0')]).create(); - - await d.appDir({}).create(); - final absolutePath = path.join(d.sandbox, 'foo'); - - await pubAdd( - args: ['foo:2.0.0', 'bar:0.1.3', 'baz:1.3.1', '--path', absolutePath], - error: contains('Can only add a single local package at a time.'), - exitCode: exit_codes.USAGE); - - await d.appDir({}).validate(); - await d.dir(appPath, [ - d.nothing('.dart_tool/package_config.json'), - d.nothing('pubspec.lock'), - d.nothing('.packages'), - ]).validate(); - }); - test('fails when adding with an invalid version constraint', () async { ensureGit(); @@ -112,8 +88,9 @@ }); test('can be overriden by dependency override', () async { - final server = await servePackages(); - server.serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.2'); + }); await d .dir('foo', [d.libDir('foo'), d.libPubspec('foo', '0.0.1')]).create(); @@ -129,9 +106,7 @@ await pubAdd(args: ['foo', '--path', absolutePath]); await d.cacheDir({'foo': '1.2.2'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.2'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.2'}).validate(); await d.dir(appPath, [ d.pubspec({ 'name': 'myapp',
diff --git a/test/add/path/relative_path_test.dart b/test/add/path/relative_path_test.dart index e08ba3c..8fa1932 100644 --- a/test/add/path/relative_path_test.dart +++ b/test/add/path/relative_path_test.dart
@@ -19,9 +19,7 @@ await pubAdd(args: ['foo', '--path', '../foo']); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: '../foo'), - ]).validate(); + await d.appPackagesFile({'foo': '../foo'}).validate(); await d.appDir({ 'foo': {'path': '../foo'} @@ -40,9 +38,7 @@ output: contains('Changed 1 dependency in myapp!'), ); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: '../foo'), - ]).validate(); + await d.appPackagesFile({'foo': '../foo'}).validate(); await d.appDir({ 'foo': {'path': '../foo'} @@ -106,8 +102,9 @@ }); test('can be overriden by dependency override', () async { - final server = await servePackages(); - server.serve('foo', '1.2.2'); + await servePackages((builder) { + builder.serve('foo', '1.2.2'); + }); await d .dir('foo', [d.libDir('foo'), d.libPubspec('foo', '0.0.1')]).create(); @@ -122,9 +119,7 @@ await pubAdd(args: ['foo', '--path', '../foo']); await d.cacheDir({'foo': '1.2.2'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.2'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.2'}).validate(); await d.dir(appPath, [ d.pubspec({ 'name': 'myapp',
diff --git a/test/add/sdk/sdk_test.dart b/test/add/sdk/sdk_test.dart index ff7d442..25995e3 100644 --- a/test/add/sdk/sdk_test.dart +++ b/test/add/sdk/sdk_test.dart
@@ -11,8 +11,9 @@ void main() { setUp(() async { - final server = await servePackages(); - server.serve('bar', '1.0.0'); + await servePackages((builder) { + builder.serve('bar', '1.0.0'); + }); await d.dir('flutter', [ d.dir('packages', [ @@ -42,12 +43,11 @@ 'foo': {'sdk': 'flutter', 'version': '^0.0.1'} } }), - ]).validate(); - - await d.appPackageConfigFile([ - d.packageConfigEntry( - name: 'foo', path: p.join(d.sandbox, 'flutter', 'packages', 'foo')), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), + d.packagesFile({ + 'myapp': '.', + 'foo': p.join(d.sandbox, 'flutter', 'packages', 'foo'), + 'bar': '1.0.0' + }) ]).validate(); }); @@ -66,11 +66,11 @@ 'foo': {'sdk': 'flutter', 'version': '0.0.1'} } }), - ]).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry( - name: 'foo', path: p.join(d.sandbox, 'flutter', 'packages', 'foo')), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), + d.packagesFile({ + 'myapp': '.', + 'foo': p.join(d.sandbox, 'flutter', 'packages', 'foo'), + 'bar': '1.0.0' + }) ]).validate(); }); @@ -80,10 +80,11 @@ args: ['baz', '--sdk', 'flutter'], environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')}); - await d.appPackageConfigFile([ - d.packageConfigEntry( - name: 'baz', - path: p.join(d.sandbox, 'flutter', 'bin', 'cache', 'pkg', 'baz')) + await d.dir(appPath, [ + d.packagesFile({ + 'myapp': '.', + 'baz': p.join(d.sandbox, 'flutter', 'bin', 'cache', 'pkg', 'baz') + }) ]).validate(); });
diff --git a/test/cache/add/adds_latest_matching_version_test.dart b/test/cache/add/adds_latest_matching_version_test.dart index 7bf9625..0e78b12 100644 --- a/test/cache/add/adds_latest_matching_version_test.dart +++ b/test/cache/add/adds_latest_matching_version_test.dart
@@ -13,11 +13,12 @@ test( 'adds the latest version of the package matching the ' 'version constraint', () async { - await servePackages() - ..serve('foo', '1.2.2') - ..serve('foo', '1.2.3') - ..serve('foo', '2.0.0-dev') - ..serve('foo', '2.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.2.2'); + builder.serve('foo', '1.2.3'); + builder.serve('foo', '2.0.0-dev'); + builder.serve('foo', '2.0.0'); + }); await runPub( args: ['cache', 'add', 'foo', '-v', '>=1.0.0 <2.0.0'],
diff --git a/test/cache/add/adds_latest_version_test.dart b/test/cache/add/adds_latest_version_test.dart index cf34857..6e196f6 100644 --- a/test/cache/add/adds_latest_version_test.dart +++ b/test/cache/add/adds_latest_version_test.dart
@@ -9,10 +9,11 @@ void main() { test('adds the latest stable version of the package', () async { - await servePackages() - ..serve('foo', '1.2.2') - ..serve('foo', '1.2.3') - ..serve('foo', '1.2.4-dev'); + await servePackages((builder) { + builder.serve('foo', '1.2.2'); + builder.serve('foo', '1.2.3'); + builder.serve('foo', '1.2.4-dev'); + }); await runPub( args: ['cache', 'add', 'foo'], output: 'Downloading foo 1.2.3...');
diff --git a/test/cache/add/all_adds_all_matching_versions_test.dart b/test/cache/add/all_adds_all_matching_versions_test.dart index a05e8dc..9dfb3c7 100644 --- a/test/cache/add/all_adds_all_matching_versions_test.dart +++ b/test/cache/add/all_adds_all_matching_versions_test.dart
@@ -9,11 +9,12 @@ void main() { test('"--all" adds all matching versions of the package', () async { - await servePackages() - ..serve('foo', '1.2.2') - ..serve('foo', '1.2.3-dev') - ..serve('foo', '1.2.3') - ..serve('foo', '2.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.2.2'); + builder.serve('foo', '1.2.3-dev'); + builder.serve('foo', '1.2.3'); + builder.serve('foo', '2.0.0'); + }); await runPub( args: ['cache', 'add', 'foo', '-v', '>=1.0.0 <2.0.0', '--all'],
diff --git a/test/cache/add/all_with_some_versions_present_test.dart b/test/cache/add/all_with_some_versions_present_test.dart index 7b5b36d..861ac4c 100644 --- a/test/cache/add/all_with_some_versions_present_test.dart +++ b/test/cache/add/all_with_some_versions_present_test.dart
@@ -9,11 +9,12 @@ void main() { test('"--all" adds all non-installed versions of the package', () async { - await servePackages() - ..serve('foo', '1.2.1') - ..serve('foo', '1.2.2') - ..serve('foo', '1.2.3') - ..serve('foo', '2.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.2.1'); + builder.serve('foo', '1.2.2'); + builder.serve('foo', '1.2.3'); + builder.serve('foo', '2.0.0'); + }); // Install a couple of versions first. await runPub(
diff --git a/test/cache/add/already_cached_test.dart b/test/cache/add/already_cached_test.dart index 8c74da9..ac244dc 100644 --- a/test/cache/add/already_cached_test.dart +++ b/test/cache/add/already_cached_test.dart
@@ -9,8 +9,9 @@ void main() { test('does nothing if the package is already cached', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + }); // Run once to put it in the cache. await runPub(
diff --git a/test/cache/add/no_matching_version_test.dart b/test/cache/add/no_matching_version_test.dart index a860294..4b4455c 100644 --- a/test/cache/add/no_matching_version_test.dart +++ b/test/cache/add/no_matching_version_test.dart
@@ -8,9 +8,10 @@ void main() { test('fails if no version matches the version constraint', () async { - await servePackages() - ..serve('foo', '1.2.2') - ..serve('foo', '1.2.3'); + await servePackages((builder) { + builder.serve('foo', '1.2.2'); + builder.serve('foo', '1.2.3'); + }); await runPub( args: ['cache', 'add', 'foo', '-v', '>2.0.0'],
diff --git a/test/cache/add/package_not_found_test.dart b/test/cache/add/package_not_found_test.dart index caf45f4..91f3f3e 100644 --- a/test/cache/add/package_not_found_test.dart +++ b/test/cache/add/package_not_found_test.dart
@@ -9,13 +9,12 @@ void main() { test('fails if the package cound not be found on the source', () async { - await servePackages(); + await serveNoPackages(); await runPub( args: ['cache', 'add', 'foo'], - error: RegExp( - r'Package not available \(could not find package foo at http://.*\)\.', - ), + error: RegExp(r"Package doesn't exist \(could not find package foo at " + r'http://.*\)\.'), exitCode: exit_codes.UNAVAILABLE); }); }
diff --git a/test/cache/clean_test.dart b/test/cache/clean_test.dart index 7a79bc8..b03c0c8 100644 --- a/test/cache/clean_test.dart +++ b/test/cache/clean_test.dart
@@ -17,9 +17,9 @@ }); test('running pub cache clean --force deletes cache', () async { - await servePackages() + await servePackages((b) => b ..serve('foo', '1.1.2') - ..serve('bar', '1.2.3'); + ..serve('bar', '1.2.3')); await d.appDir({'foo': 'any', 'bar': 'any'}).create(); await pubGet(); final cache = path.join(d.sandbox, cachePath); @@ -32,9 +32,9 @@ test('running pub cache clean deletes cache only with confirmation', () async { - await servePackages() + await servePackages((b) => b ..serve('foo', '1.1.2') - ..serve('bar', '1.2.3'); + ..serve('bar', '1.2.3')); await d.appDir({'foo': 'any', 'bar': 'any'}).create(); await pubGet(); final cache = path.join(d.sandbox, cachePath);
diff --git a/test/cache/repair/handles_corrupted_binstub_test.dart b/test/cache/repair/handles_corrupted_binstub_test.dart index 0ca169f..9991ec1 100644 --- a/test/cache/repair/handles_corrupted_binstub_test.dart +++ b/test/cache/repair/handles_corrupted_binstub_test.dart
@@ -9,10 +9,11 @@ void main() { test('handles a corrupted binstub script', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', contents: [ - d.dir('bin', [d.file('script.dart', "main(args) => print('ok');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir('bin', [d.file('script.dart', "main(args) => print('ok');")]) + ]); + }); await runPub(args: ['global', 'activate', 'foo']);
diff --git a/test/cache/repair/handles_failure_test.dart b/test/cache/repair/handles_failure_test.dart index d5637ca..471bcf8 100644 --- a/test/cache/repair/handles_failure_test.dart +++ b/test/cache/repair/handles_failure_test.dart
@@ -11,14 +11,15 @@ void main() { test('handles failure to reinstall some packages', () async { // Only serve two packages so repairing will have a failure. - final server = await servePackages() - ..serve('foo', '1.2.3') - ..serve('foo', '1.2.5'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + builder.serve('foo', '1.2.5'); + }); // Set up a cache with some packages. await d.dir(cachePath, [ d.dir('hosted', [ - d.dir('localhost%58${server.port}', [ + d.dir('localhost%58${globalServer!.port}', [ d.dir('foo-1.2.3', [d.libPubspec('foo', '1.2.3'), d.file('broken.txt')]), d.dir('foo-1.2.4', @@ -38,7 +39,7 @@ expect(pub.stderr, emits(startsWith('Failed to repair foo 1.2.4. Error:'))); expect( pub.stderr, - emits('Package not available ' + emits('Package doesn\'t exist ' '(Package foo has no version 1.2.4).')); expect(pub.stdout, emits('Reinstalled 2 packages.'));
diff --git a/test/cache/repair/handles_orphaned_binstub_test.dart b/test/cache/repair/handles_orphaned_binstub_test.dart index 0754496..9c4e74a 100644 --- a/test/cache/repair/handles_orphaned_binstub_test.dart +++ b/test/cache/repair/handles_orphaned_binstub_test.dart
@@ -7,7 +7,7 @@ import '../../descriptor.dart' as d; import '../../test_pub.dart'; -const _orphanedBinstub = ''' +const _ORPHANED_BINSTUB = ''' #!/usr/bin/env sh # This file was created by pub v0.1.2-3. # Package: foo @@ -20,7 +20,7 @@ void main() { test('handles an orphaned binstub script', () async { await d.dir(cachePath, [ - d.dir('bin', [d.file(binStubName('script'), _orphanedBinstub)]) + d.dir('bin', [d.file(binStubName('script'), _ORPHANED_BINSTUB)]) ]).create(); await runPub(
diff --git a/test/cache/repair/hosted.dart b/test/cache/repair/hosted.dart index ec3786b..97c8167 100644 --- a/test/cache/repair/hosted.dart +++ b/test/cache/repair/hosted.dart
@@ -11,20 +11,21 @@ import '../../test_pub.dart'; void main() { - setUp(() async { - await servePackages() - ..serve('foo', '1.2.3') - ..serve('foo', '1.2.4') - ..serve('foo', '1.2.5') - ..serve('bar', '1.2.3') - ..serve('bar', '1.2.4'); + setUp(() { + return servePackages((builder) { + builder.serve('foo', '1.2.3'); + builder.serve('foo', '1.2.4'); + builder.serve('foo', '1.2.5'); + builder.serve('bar', '1.2.3'); + builder.serve('bar', '1.2.4'); + }); }); test('reinstalls previously cached hosted packages', () async { // Set up a cache with some broken packages. await d.dir(cachePath, [ d.dir('hosted', [ - d.dir('localhost%58${globalServer.port}', [ + d.dir('localhost%58${globalServer!.port}', [ d.dir('foo-1.2.3', [d.libPubspec('foo', '1.2.3'), d.file('broken.txt')]), d.dir('foo-1.2.5', @@ -63,7 +64,7 @@ // Set up a cache with some broken packages. await d.dir(cachePath, [ d.dir('hosted', [ - d.dir('localhost%58${globalServer.port}', [ + d.dir('localhost%58${globalServer!.port}', [ d.dir('bar-1.2.4', [d.file('broken.txt')]), d.dir('foo-1.2.3', [d.file('broken.txt')]), d.dir('foo-1.2.5', [d.file('broken.txt')]), @@ -99,7 +100,7 @@ // Set up a cache with some broken packages. await d.dir(cachePath, [ d.dir('hosted', [ - d.dir('localhost%58${globalServer.port}', [ + d.dir('localhost%58${globalServer!.port}', [ d.dir('bar-1.2.4', [d.file('pubspec.yaml', '{')]), d.dir('foo-1.2.3', [d.file('pubspec.yaml', '{')]), d.dir('foo-1.2.5', [d.file('pubspec.yaml', '{')]),
diff --git a/test/cache/repair/recompiles_snapshots_test.dart b/test/cache/repair/recompiles_snapshots_test.dart index f3c3d6c..89b3575 100644 --- a/test/cache/repair/recompiles_snapshots_test.dart +++ b/test/cache/repair/recompiles_snapshots_test.dart
@@ -9,10 +9,11 @@ void main() { test('recompiles activated executable snapshots', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', contents: [ - d.dir('bin', [d.file('script.dart', "main(args) => print('ok');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir('bin', [d.file('script.dart', "main(args) => print('ok');")]) + ]); + }); await runPub(args: ['global', 'activate', 'foo']);
diff --git a/test/cache/repair/updates_binstubs_test.dart b/test/cache/repair/updates_binstubs_test.dart index e8cbfb4..1cd848b 100644 --- a/test/cache/repair/updates_binstubs_test.dart +++ b/test/cache/repair/updates_binstubs_test.dart
@@ -7,7 +7,7 @@ import '../../descriptor.dart' as d; import '../../test_pub.dart'; -const _outdatedBinstub = ''' +const _OUTDATED_BINSTUB = ''' #!/usr/bin/env sh # This file was created by pub v0.1.2-3. # Package: foo @@ -19,17 +19,19 @@ void main() { test('updates an outdated binstub script', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'executables': {'foo-script': 'script'} - }, contents: [ - d.dir('bin', [d.file('script.dart', "main(args) => print('ok \$args');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'executables': {'foo-script': 'script'} + }, contents: [ + d.dir( + 'bin', [d.file('script.dart', "main(args) => print('ok \$args');")]) + ]); + }); await runPub(args: ['global', 'activate', 'foo']); await d.dir(cachePath, [ - d.dir('bin', [d.file(binStubName('foo-script'), _outdatedBinstub)]) + d.dir('bin', [d.file(binStubName('foo-script'), _OUTDATED_BINSTUB)]) ]).create(); // Repair them.
diff --git a/test/dependency_override_test.dart b/test/dependency_override_test.dart index 59f59e4..2ea5abc 100644 --- a/test/dependency_override_test.dart +++ b/test/dependency_override_test.dart
@@ -12,10 +12,11 @@ void main() { forBothPubGetAndUpgrade((command) { test('chooses best version matching override constraint', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0') - ..serve('foo', '3.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0'); + builder.serve('foo', '3.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -27,14 +28,13 @@ await pubCommand(command); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '2.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '2.0.0'}).validate(); }); test('treats override as implicit dependency', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -45,19 +45,18 @@ await pubCommand(command); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0'}).validate(); }); test('ignores other constraints on overridden package', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0') - ..serve('foo', '3.0.0') - ..serve('bar', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0'); + builder.serve('foo', '3.0.0'); + builder.serve('bar', '1.0.0', pubspec: { 'dependencies': {'foo': '5.0.0-nonexistent'} }); + }); await d.dir(appPath, [ d.pubspec({ @@ -69,16 +68,14 @@ await pubCommand(command); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '2.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '2.0.0', 'bar': '1.0.0'}).validate(); }); test('ignores SDK constraints', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'environment': {'sdk': '5.6.7-fblthp'} + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'environment': {'sdk': '5.6.7-fblthp'} + }); }); await d.dir(appPath, [ @@ -89,15 +86,15 @@ ]).create(); await pubCommand(command); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - ]).validate(); + + await d.appPackagesFile({'foo': '1.0.0'}).validate(); }); test('warns about overridden dependencies', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('bar', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('bar', '1.0.0'); + }); await d .dir('baz', [d.libDir('baz'), d.libPubspec('baz', '0.0.1')]).create();
diff --git a/test/dependency_services/dependency_services_test.dart b/test/dependency_services/dependency_services_test.dart index 58bf303..3bdd224 100644 --- a/test/dependency_services/dependency_services_test.dart +++ b/test/dependency_services/dependency_services_test.dart
@@ -37,7 +37,7 @@ await precompile( executablePath: p.join('bin', 'dependency_services.dart'), outputPath: snapshotFilename, - incrementalDillPath: snapshotIncrementalFilename, + incrementalDillOutputPath: snapshotIncrementalFilename, name: 'bin/pub.dart', packageConfigPath: p.join('.dart_tool', 'package_config.json')); return snapshotFilename; @@ -99,10 +99,10 @@ Future<void> main() async { testWithGolden('Removing transitive', (context) async { - (await servePackages()) + await servePackages((builder) => builder ..serve('foo', '1.2.3', deps: {'transitive': '^1.0.0'}) ..serve('foo', '2.2.3') - ..serve('transitive', '1.0.0'); + ..serve('transitive', '1.0.0')); await d.dir(appPath, [ d.pubspec({ @@ -120,11 +120,11 @@ }); testWithGolden('Compatible', (context) async { - final server = (await servePackages()) + await servePackages((builder) => builder ..serve('foo', '1.2.3') ..serve('foo', '2.2.3') ..serve('bar', '1.2.3') - ..serve('bar', '2.2.3'); + ..serve('bar', '2.2.3')); await d.dir(appPath, [ d.pubspec({ 'name': 'app', @@ -135,7 +135,7 @@ }) ]).create(); await pubGet(); - server.serve('foo', '1.2.4'); + globalPackageServer!.add((b) => b.serve('foo', '1.2.4')); await listReportApply(context, [ _PackageVersion('foo', Version.parse('1.2.3')), _PackageVersion('transitive', null) @@ -143,10 +143,10 @@ }); testWithGolden('Adding transitive', (context) async { - (await servePackages()) + await servePackages((builder) => builder ..serve('foo', '1.2.3') ..serve('foo', '2.2.3', deps: {'transitive': '^1.0.0'}) - ..serve('transitive', '1.0.0'); + ..serve('transitive', '1.0.0')); await d.dir(appPath, [ d.pubspec({ @@ -164,9 +164,9 @@ }); testWithGolden('multibreaking', (context) async { - final server = (await servePackages()) + await servePackages((builder) => builder ..serve('foo', '1.0.0') - ..serve('bar', '1.0.0'); + ..serve('bar', '1.0.0')); await d.dir(appPath, [ d.pubspec({ @@ -178,13 +178,13 @@ }) ]).create(); await pubGet(); - server + globalPackageServer!.add((builder) => builder ..serve('foo', '1.5.0') // compatible ..serve('foo', '2.0.0') // single breaking ..serve('foo', '3.0.0', deps: {'bar': '^2.0.0'}) // multi breaking ..serve('foo', '3.0.1', deps: {'bar': '^2.0.0'}) ..serve('bar', '2.0.0', deps: {'foo': '^3.0.0'}) - ..serve('transitive', '1.0.0'); + ..serve('transitive', '1.0.0')); await listReportApply(context, [ _PackageVersion('foo', Version.parse('3.0.1'), constraint: VersionConstraint.parse('^3.0.0')),
diff --git a/test/deps_test.dart b/test/deps_test.dart index 7336f13..207e8e7 100644 --- a/test/deps_test.dart +++ b/test/deps_test.dart
@@ -10,19 +10,21 @@ void main() { setUp(() async { - await servePackages() - ..serve('normal', '1.2.3', - deps: {'transitive': 'any', 'circular_a': 'any'}) - ..serve('transitive', '1.2.3', deps: {'shared': 'any'}) - ..serve('shared', '1.2.3', deps: {'other': 'any'}) - ..serve('dev_only', '1.2.3') - ..serve('unittest', '1.2.3', deps: {'shared': 'any', 'dev_only': 'any'}) - ..serve('other', '1.0.0', deps: {'myapp': 'any'}) - ..serve('overridden', '1.0.0') - ..serve('overridden', '2.0.0') - ..serve('override_only', '1.2.3') - ..serve('circular_a', '1.2.3', deps: {'circular_b': 'any'}) - ..serve('circular_b', '1.2.3', deps: {'circular_a': 'any'}); + await servePackages((builder) { + builder.serve('normal', '1.2.3', + deps: {'transitive': 'any', 'circular_a': 'any'}); + builder.serve('transitive', '1.2.3', deps: {'shared': 'any'}); + builder.serve('shared', '1.2.3', deps: {'other': 'any'}); + builder.serve('dev_only', '1.2.3'); + builder.serve('unittest', '1.2.3', + deps: {'shared': 'any', 'dev_only': 'any'}); + builder.serve('other', '1.0.0', deps: {'myapp': 'any'}); + builder.serve('overridden', '1.0.0'); + builder.serve('overridden', '2.0.0'); + builder.serve('override_only', '1.2.3'); + builder.serve('circular_a', '1.2.3', deps: {'circular_b': 'any'}); + builder.serve('circular_b', '1.2.3', deps: {'circular_a': 'any'}); + }); await d.dir('from_path', [d.libDir('from_path'), d.libPubspec('from_path', '1.2.3')]).create();
diff --git a/test/descriptor.dart b/test/descriptor.dart index ee50851..7a592db 100644 --- a/test/descriptor.dart +++ b/test/descriptor.dart
@@ -179,7 +179,7 @@ /// that this cache represents. It defaults to [globalServer.port]. Descriptor hostedCache(Iterable<Descriptor> contents, {int? port}) { return dir(cachePath, [ - dir('hosted', [dir('localhost%58${port ?? globalServer.port}', contents)]) + dir('hosted', [dir('localhost%58${port ?? globalServer?.port}', contents)]) ]); } @@ -277,23 +277,6 @@ }) => PackageConfigFileDescriptor(packages, generatorVersion); -Descriptor appPackageConfigFile( - List<PackageConfigEntry> packages, { - String generatorVersion = '0.1.2+3', -}) => - dir( - appPath, - [ - packageConfigFile( - [ - packageConfigEntry(name: 'myapp', path: '.'), - ...packages, - ], - generatorVersion: generatorVersion, - ), - ], - ); - /// Create a [PackageConfigEntry] which assumes package with [name] is either /// a cached package with given [version] or a path dependency at given [path]. PackageConfigEntry packageConfigEntry({ @@ -301,7 +284,6 @@ String? version, String? path, String? languageVersion, - PackageServer? server, }) { if (version != null && path != null) { throw ArgumentError.value( @@ -313,7 +295,7 @@ } Uri rootUri; if (version != null) { - rootUri = p.toUri((server ?? globalServer).pathInCache(name, version)); + rootUri = p.toUri(globalPackageServer!.pathInCache(name, version)); } else { rootUri = p.toUri(p.join('..', path)); }
diff --git a/test/descriptor/packages.dart b/test/descriptor/packages.dart index b670322..de52a80 100644 --- a/test/descriptor/packages.dart +++ b/test/descriptor/packages.dart
@@ -156,20 +156,10 @@ // Compare packages as sets to ignore ordering. expect( - config.packages, - _packages - .map( - (p) => isA<PackageConfigEntry>() - .having((p0) => p0.name, 'name', p.name) - .having( - (p0) => p0.languageVersion, - 'languageVersion', - // If the expected entry has no language-version we don't check it. - p.languageVersion ?? anything) - .having((p0) => p0.rootUri, 'rootUri', p.rootUri) - .having((p0) => p0.packageUri, 'packageUri', p.packageUri), - ) - .toSet(), + config.packages.map((e) => e.toJson()).toSet(), + equals(_packages.map((e) => e.toJson()).toSet()), + reason: + '"packages" property in "$packageConfigFile" does not expected values', ); final expected = PackageConfig.fromJson(_config.toJson());
diff --git a/test/descriptor_server.dart b/test/descriptor_server.dart new file mode 100644 index 0000000..973a49c --- /dev/null +++ b/test/descriptor_server.dart
@@ -0,0 +1,142 @@ +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; + +import 'package:collection/collection.dart' show IterableExtension; +import 'package:path/path.dart' as p; +import 'package:shelf/shelf.dart' as shelf; +import 'package:shelf/shelf_io.dart' as shelf_io; +import 'package:test/test.dart' hide fail; + +import 'descriptor.dart' as d; + +/// The global [DescriptorServer] that's used by default. +/// +/// `null` if there's no global server in use. This can be set to replace the +/// existing global server. +DescriptorServer? get globalServer => _globalServer; +set globalServer(DescriptorServer? value) { + var server = _globalServer; + if (server == null) { + addTearDown(() { + _globalServer = null; + }); + } else { + expect(server.close(), completes); + } + + _globalServer = value; +} + +DescriptorServer? _globalServer; + +/// Creates a global [DescriptorServer] to serve [contents] as static files. +/// +/// This server will exist only for the duration of the pub run. It's accessible +/// via [server]. Subsequent calls to [serve] replace the previous server. +Future serve([List<d.Descriptor> contents = const []]) async { + globalServer = (await DescriptorServer.start())..contents.addAll(contents); +} + +class DescriptorServer { + /// The underlying server. + final shelf.Server _server; + + /// A future that will complete to the port used for the server. + int get port => _server.url.port; + + /// The list of paths that have been requested from this server. + final requestedPaths = <String>[]; + + /// The base directory descriptor of the directories served by [this]. + final d.DirectoryDescriptor _baseDir; + + /// The descriptors served by this server. + /// + /// This can safely be modified between requests. + List<d.Descriptor> get contents => _baseDir.contents; + + /// Handlers for requests not easily described as files. + final Map<Pattern, shelf.Handler> extraHandlers = {}; + + /// Creates an HTTP server to serve [contents] as static files. + /// + /// This server exists only for the duration of the pub run. Subsequent calls + /// to [serve] replace the previous server. + static Future<DescriptorServer> start() async => + DescriptorServer._(await shelf_io.IOServer.bind('localhost', 0)); + + /// Creates a server that reports an error if a request is ever received. + static Future<DescriptorServer> errors() async => + DescriptorServer._(await shelf_io.IOServer.bind('localhost', 0)); + + DescriptorServer._(this._server) : _baseDir = d.dir('serve-dir', []) { + _server.mount((request) async { + final pathWithInitialSlash = '/${request.url.path}'; + final key = extraHandlers.keys.firstWhereOrNull((pattern) { + final match = pattern.matchAsPrefix(pathWithInitialSlash); + return match != null && match.end == pathWithInitialSlash.length; + }); + if (key != null) return extraHandlers[key]!(request); + + var path = p.posix.fromUri(request.url.path); + requestedPaths.add(path); + + try { + var stream = await _validateStream(_baseDir.load(path)); + return shelf.Response.ok(stream); + } catch (_) { + return shelf.Response.notFound('File "$path" not found.'); + } + }); + addTearDown(_server.close); + } + + /// Closes this server. + Future close() => _server.close(); +} + +/// Ensures that [stream] can emit at least one value successfully (or close +/// without any values). +/// +/// For example, reading asynchronously from a non-existent file will return a +/// stream that fails on the first chunk. In order to handle that more +/// gracefully, you may want to check that the stream looks like it's working +/// before you pipe the stream to something else. +/// +/// This lets you do that. It returns a [Future] that completes to a [Stream] +/// emitting the same values and errors as [stream], but only if at least one +/// value can be read successfully. If an error occurs before any values are +/// emitted, the returned Future completes to that error. +Future<Stream<T>> _validateStream<T>(Stream<T> stream) { + var completer = Completer<Stream<T>>(); + var controller = StreamController<T>(sync: true); + + late StreamSubscription subscription; + subscription = stream.listen((value) { + // We got a value, so the stream is valid. + if (!completer.isCompleted) completer.complete(controller.stream); + controller.add(value); + }, onError: (error, [StackTrace? stackTrace]) { + // If the error came after values, it's OK. + if (completer.isCompleted) { + controller.addError(error, stackTrace); + return; + } + + // Otherwise, the error came first and the stream is invalid. + completer.completeError(error, stackTrace); + + // We won't be returning the stream at all in this case, so unsubscribe + // and swallow the error. + subscription.cancel(); + }, onDone: () { + // It closed with no errors, so the stream is valid. + if (!completer.isCompleted) completer.complete(controller.stream); + controller.close(); + }); + + return completer.future; +}
diff --git a/test/dev_dependency_test.dart b/test/dev_dependency_test.dart index b192444..88f321b 100644 --- a/test/dev_dependency_test.dart +++ b/test/dev_dependency_test.dart
@@ -27,10 +27,7 @@ await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: '../foo'), - d.packageConfigEntry(name: 'bar', path: '../bar'), - ]).validate(); + await d.appPackagesFile({'foo': '../foo', 'bar': '../bar'}).validate(); }); test("includes dev dependency's transitive dependencies", () async { @@ -55,10 +52,7 @@ await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: '../foo'), - d.packageConfigEntry(name: 'bar', path: '../bar'), - ]).validate(); + await d.appPackagesFile({'foo': '../foo', 'bar': '../bar'}).validate(); }); test("ignores transitive dependency's dev dependencies", () async { @@ -84,8 +78,6 @@ await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: '../foo'), - ]).validate(); + await d.appPackagesFile({'foo': '../foo'}).validate(); }); }
diff --git a/test/directory_option_test.dart b/test/directory_option_test.dart index 65193bf..2865a69 100644 --- a/test/directory_option_test.dart +++ b/test/directory_option_test.dart
@@ -14,21 +14,20 @@ Future<void> main() async { testWithGolden('commands taking a --directory/-C parameter work', (ctx) async { - await servePackages() + await servePackages((b) => b ..serve('foo', '1.0.0') ..serve('foo', '0.1.2') - ..serve('bar', '1.2.3'); - await credentialsFile(globalServer, 'access token').create(); - globalServer.handle( - RegExp('/api/packages/test_pkg/uploaders'), - (request) { - return shelf.Response.ok( - jsonEncode({ - 'success': {'message': 'Good job!'} - }), - headers: {'content-type': 'application/json'}); - }, - ); + ..serve('bar', '1.2.3')); + await credentialsFile(globalPackageServer!, 'access token').create(); + globalPackageServer! + .extraHandlers[RegExp('/api/packages/test_pkg/uploaders')] = (request) { + return shelf.Response.ok( + jsonEncode({ + 'success': {'message': 'Good job!'} + }), + headers: {'content-type': 'application/json'}, + ); + }; await validPackage.create(); await dir(appPath, [
diff --git a/test/downgrade/does_not_show_other_versions_test.dart b/test/downgrade/does_not_show_other_versions_test.dart index 884bbaf..ca872c8 100644 --- a/test/downgrade/does_not_show_other_versions_test.dart +++ b/test/downgrade/does_not_show_other_versions_test.dart
@@ -9,10 +9,11 @@ void main() { test('does not show how many other versions are available', () async { - await servePackages() - ..serve('downgraded', '1.0.0') - ..serve('downgraded', '2.0.0') - ..serve('downgraded', '3.0.0-dev'); + await servePackages((builder) { + builder.serve('downgraded', '1.0.0'); + builder.serve('downgraded', '2.0.0'); + builder.serve('downgraded', '3.0.0-dev'); + }); await d.appDir({'downgraded': '3.0.0-dev'}).create();
diff --git a/test/downgrade/dry_run_does_not_apply_changes_test.dart b/test/downgrade/dry_run_does_not_apply_changes_test.dart index 38fbebe..ebe2dbf 100644 --- a/test/downgrade/dry_run_does_not_apply_changes_test.dart +++ b/test/downgrade/dry_run_does_not_apply_changes_test.dart
@@ -11,9 +11,10 @@ void main() { test('--dry-run shows report but does not apply changes', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0'); + }); // Create the first lockfile. await d.appDir({'foo': '2.0.0'}).create();
diff --git a/test/downgrade/unlock_if_necessary_test.dart b/test/downgrade/unlock_if_necessary_test.dart index c8b55af..eac39a8 100644 --- a/test/downgrade/unlock_if_necessary_test.dart +++ b/test/downgrade/unlock_if_necessary_test.dart
@@ -11,27 +11,24 @@ test( "downgrades one locked hosted package's dependencies if it's " 'necessary', () async { - final server = await servePackages(); - server.serve('foo', '2.0.0', deps: {'foo_dep': 'any'}); - server.serve('foo_dep', '2.0.0'); + await servePackages((builder) { + builder.serve('foo', '2.0.0', deps: {'foo_dep': 'any'}); + builder.serve('foo_dep', '2.0.0'); + }); await d.appDir({'foo': 'any'}).create(); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '2.0.0'), - d.packageConfigEntry(name: 'foo_dep', version: '2.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '2.0.0', 'foo_dep': '2.0.0'}).validate(); - server.serve('foo', '1.0.0', deps: {'foo_dep': '<2.0.0'}); - server.serve('foo_dep', '1.0.0'); + globalPackageServer!.add((builder) { + builder.serve('foo', '1.0.0', deps: {'foo_dep': '<2.0.0'}); + builder.serve('foo_dep', '1.0.0'); + }); await pubDowngrade(args: ['foo']); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'foo_dep', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0', 'foo_dep': '1.0.0'}).validate(); }); }
diff --git a/test/downgrade/unlock_single_package_test.dart b/test/downgrade/unlock_single_package_test.dart index 1188e41..8997ba2 100644 --- a/test/downgrade/unlock_single_package_test.dart +++ b/test/downgrade/unlock_single_package_test.dart
@@ -9,60 +9,51 @@ void main() { test('can unlock a single package only in downgrade', () async { - final server = await servePackages(); - server.serve('foo', '2.1.0', deps: {'bar': '>1.0.0'}); - server.serve('bar', '2.1.0'); + await servePackages((builder) { + builder.serve('foo', '2.1.0', deps: {'bar': '>1.0.0'}); + builder.serve('bar', '2.1.0'); + }); await d.appDir({'foo': 'any', 'bar': 'any'}).create(); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '2.1.0'), - d.packageConfigEntry(name: 'bar', version: '2.1.0'), - ]).validate(); + await d.appPackagesFile({'foo': '2.1.0', 'bar': '2.1.0'}).validate(); - server.serve('foo', '1.0.0', deps: {'bar': 'any'}); - server.serve('bar', '1.0.0'); + globalPackageServer!.add((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': 'any'}); + builder.serve('bar', '1.0.0'); + }); await pubDowngrade(args: ['bar']); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '2.1.0'), - d.packageConfigEntry(name: 'bar', version: '2.1.0'), - ]).validate(); + await d.appPackagesFile({'foo': '2.1.0', 'bar': '2.1.0'}).validate(); - server.serve('foo', '2.0.0', deps: {'bar': 'any'}); - server.serve('bar', '2.0.0'); + globalPackageServer!.add((builder) { + builder.serve('foo', '2.0.0', deps: {'bar': 'any'}); + builder.serve('bar', '2.0.0'); + }); await pubDowngrade(args: ['bar']); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '2.1.0'), - d.packageConfigEntry(name: 'bar', version: '2.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '2.1.0', 'bar': '2.0.0'}).validate(); await pubDowngrade(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.0.0'}).validate(); }); test('will not downgrade below constraint #2629', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0') - ..serve('foo', '2.1.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0'); + builder.serve('foo', '2.1.0'); + }); await d.appDir({'foo': '^2.0.0'}).create(); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '2.1.0'), - ]).validate(); + + await d.appPackagesFile({'foo': '2.1.0'}).validate(); await pubDowngrade(args: ['foo']); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '2.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '2.0.0'}).validate(); }); }
diff --git a/test/embedding/embedding_test.dart b/test/embedding/embedding_test.dart index a9795ea..20e127e 100644 --- a/test/embedding/embedding_test.dart +++ b/test/embedding/embedding_test.dart
@@ -6,20 +6,16 @@ import 'dart:io'; import 'package:path/path.dart' as path; -import 'package:path/path.dart' as p; import 'package:test/test.dart'; import 'package:test_process/test_process.dart'; - import '../descriptor.dart' as d; import '../golden_file.dart'; import '../test_pub.dart'; -const _commandRunner = 'tool/test-bin/pub_command_runner.dart'; +const _command_runner = 'tool/test-bin/pub_command_runner.dart'; late String snapshot; -final logFile = p.join(d.sandbox, cachePath, 'log', 'pub_log.txt'); - /// Runs `dart tool/test-bin/pub_command_runner.dart [args]` and appends the output to [buffer]. Future<void> runEmbeddingToBuffer( List<String> args, @@ -40,10 +36,13 @@ await process.shouldExit(exitCode); buffer.writeln([ - '\$ $_commandRunner ${args.join(' ')}', - ...await process.stdout.rest.map(_filter).toList(), - ...await process.stderr.rest.map((e) => '[E] ${_filter(e)}').toList(), + '\$ $_command_runner ${args.join(' ')}', + ...await process.stdout.rest.toList(), ].join('\n')); + final stdErr = await process.stderr.rest.toList(); + if (stdErr.isNotEmpty) { + buffer.writeln(stdErr.map((e) => '[E] $e').join('\n')); + } buffer.write('\n'); } @@ -52,7 +51,7 @@ /// next section in golden file. Future<void> runEmbedding( List<String> args, { - String? workingDirectory, + String? workingDirextory, Map<String, String>? environment, dynamic exitCode = 0, }) async { @@ -60,7 +59,7 @@ await runEmbeddingToBuffer( args, buffer, - workingDirectory: workingDirectory, + workingDirectory: workingDirextory, environment: environment, exitCode: exitCode, ); @@ -74,7 +73,7 @@ final tempDir = Directory.systemTemp.createTempSync(); snapshot = path.join(tempDir.path, 'command_runner.dart.snapshot'); final r = Process.runSync( - Platform.resolvedExecutable, ['--snapshot=$snapshot', _commandRunner]); + Platform.resolvedExecutable, ['--snapshot=$snapshot', _command_runner]); expect(r.exitCode, 0, reason: r.stderr); }); @@ -83,7 +82,6 @@ }); testWithGolden('run works, though hidden', (ctx) async { - await servePackages(); await d.dir(appPath, [ d.pubspec({ 'name': 'myapp', @@ -103,60 +101,19 @@ ]).create(); await ctx.runEmbedding( ['pub', 'get'], - workingDirectory: d.path(appPath), + workingDirextory: d.path(appPath), ); await ctx.runEmbedding( ['pub', 'run', 'bin/main.dart'], exitCode: 123, - workingDirectory: d.path(appPath), - ); - }); - - testWithGolden( - 'logfile is written with --verbose and on unexpected exceptions', - (context) async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); - await d.appDir({'foo': 'any'}).create(); - - // TODO(sigurdm) This logs the entire verbose trace to a golden file. - // - // This is fragile, and can break for all sorts of small reasons. We think - // this might be worth while having to have at least minimal testing of the - // verbose stack trace. - // - // But if you, future contributor, think this test is annoying: feel free to - // remove it, or rewrite it to filter out the stack-trace itself, only - // testing for creation of the file. - // - // It is a fragile test, and we acknowledge that it's usefulness can be - // debated... - await context.runEmbedding( - ['pub', '--verbose', 'get'], - workingDirectory: d.path(appPath), - ); - context.expectNextSection( - _filter( - File(logFile).readAsStringSync(), - ), - ); - await d.dir('empty').create(); - await context.runEmbedding( - ['pub', 'fail'], - workingDirectory: d.path('empty'), - exitCode: 1, - ); - context.expectNextSection( - _filter( - File(logFile).readAsStringSync(), - ), + workingDirextory: d.path(appPath), ); }); test('analytics', () async { - await servePackages() + await servePackages((b) => b ..serve('foo', '1.0.0', deps: {'bar': 'any'}) - ..serve('bar', '1.0.0'); + ..serve('bar', '1.0.0')); await d.dir('dep', [ d.pubspec({ 'name': 'dep', @@ -218,113 +175,5 @@ } }, }); - // Don't write the logs to file on a normal run. - expect(File(logFile).existsSync(), isFalse); }); - - test('`embedding --verbose pub` is verbose', () async { - await servePackages(); - final buffer = StringBuffer(); - await runEmbeddingToBuffer(['--verbose', 'pub', 'logout'], buffer); - expect(buffer.toString(), contains('FINE: Pub 0.1.2+3')); - }); -} - -String _filter(String input) { - return input - .replaceAll(p.toUri(d.sandbox).toString(), r'file://$SANDBOX') - .replaceAll(d.sandbox, r'$SANDBOX') - .replaceAll(Platform.pathSeparator, '/') - .replaceAll(Platform.operatingSystem, r'$OS') - .replaceAll(globalServer.port.toString(), r'$PORT') - .replaceAll( - RegExp(r'^Created:(.*)$', multiLine: true), - r'Created: $TIME', - ) - .replaceAll( - RegExp(r'Generated by pub on (.*)$', multiLine: true), - r'Generated by pub on $TIME', - ) - .replaceAll( - RegExp(r'X-Pub-Session-ID(.*)$', multiLine: true), - r'X-Pub-Session-ID: $ID', - ) - .replaceAll( - RegExp(r'took (.*)$', multiLine: true), - r'took: $TIME', - ) - .replaceAll( - RegExp(r'date: (.*)$', multiLine: true), - r'date: $TIME', - ) - .replaceAll( - RegExp(r'Creating (.*) from stream\.$', multiLine: true), - r'Creating $FILE from stream', - ) - .replaceAll( - RegExp(r'Created (.*) from stream\.$', multiLine: true), - r'Created $FILE from stream', - ) - .replaceAll( - RegExp(r'Renaming directory $SANDBOX/cache/_temp/(.*?) to', - multiLine: true), - r'Renaming directory $SANDBOX/cache/_temp/', - ) - .replaceAll( - RegExp(r'Extracting .tar.gz stream to (.*?)$', multiLine: true), - r'Extracting .tar.gz stream to $DIR', - ) - .replaceAll( - RegExp(r'Extracted .tar.gz to (.*?)$', multiLine: true), - r'Extracted .tar.gz to $DIR', - ) - .replaceAll( - RegExp(r'Reading binary file (.*?)$', multiLine: true), - r'Reading binary file $FILE.', - ) - .replaceAll( - RegExp(r'Deleting directory (.*)$', multiLine: true), - r'Deleting directory $DIR', - ) - .replaceAll( - RegExp(r'Deleting directory (.*)$', multiLine: true), - r'Deleting directory $DIR', - ) - .replaceAll( - RegExp(r'Resolving dependencies finished (.*)$', multiLine: true), - r'Resolving dependencies finished ($TIME)', - ) - .replaceAll( - RegExp(r'Created temp directory (.*)$', multiLine: true), - r'Created temp directory $DIR', - ) - .replaceAll( - RegExp(r'Renaming directory (.*)$', multiLine: true), - r'Renaming directory $A to $B', - ) - .replaceAll( - RegExp(r'"_fetchedAt":"(.*)"}$', multiLine: true), - r'"_fetchedAt": "$TIME"}', - ) - .replaceAll( - RegExp(r'"generated": "(.*)",$', multiLine: true), - r'"generated": "$TIME",', - ) - .replaceAll( - RegExp(r'( |^)(/|[A-Z]:)(.*)/tool/test-bin/pub_command_runner.dart', - multiLine: true), - r' tool/test-bin/pub_command_runner.dart', - ) - .replaceAll( - RegExp(r'[ ]{4,}', multiLine: true), - r' ', - ) - .replaceAll( - RegExp(r' [\d]+:[\d]+ ', multiLine: true), - r' $LINE:$COL ', - ) - .replaceAll( - RegExp(r'Writing \d+ characters', multiLine: true), - r'Writing $N characters', - ); }
diff --git a/test/embedding/get_executable_for_command_test.dart b/test/embedding/get_executable_for_command_test.dart index 0edfa72..611f5ef 100644 --- a/test/embedding/get_executable_for_command_test.dart +++ b/test/embedding/get_executable_for_command_test.dart
@@ -25,7 +25,7 @@ }) async { final _cachePath = getPubTestEnvironment()['PUB_CACHE']; final oldVerbosity = log.verbosity; - log.verbosity = log.Verbosity.none; + log.verbosity = log.Verbosity.NONE; if (executable == null) { expect( () => getExecutableForCommand( @@ -129,7 +129,7 @@ ]) ]).create(); - await servePackages(); + await serveNoPackages(); // The solver uses word-wrapping in its error message, so we use \s to // accomodate. await testGetExecutable( @@ -166,7 +166,7 @@ ]) ]).create(); - await servePackages(); + await serveNoPackages(); // The solver uses word-wrapping in its error message, so we use \s to // accomodate. await testGetExecutable( @@ -178,15 +178,15 @@ }); test('Finds files', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'environment': {'sdk': '>=$_currentVersion <3.0.0'} - }, contents: [ - d.dir('bin', [ - d.file('foo.dart', 'main() {print(42);}'), - d.file('tool.dart', 'main() {print(42);}') - ]) - ]); + await servePackages((b) => b + ..serve('foo', '1.0.0', pubspec: { + 'environment': {'sdk': '>=$_currentVersion <3.0.0'} + }, contents: [ + d.dir('bin', [ + d.file('foo.dart', 'main() {print(42);}'), + d.file('tool.dart', 'main() {print(42);}') + ]) + ])); await d.dir(appPath, [ d.pubspec({
diff --git a/test/get/dry_run_does_not_apply_changes_test.dart b/test/get/dry_run_does_not_apply_changes_test.dart index 3e44bf9..27969ae 100644 --- a/test/get/dry_run_does_not_apply_changes_test.dart +++ b/test/get/dry_run_does_not_apply_changes_test.dart
@@ -9,8 +9,9 @@ void main() { test('--dry-run shows but does not apply changes', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + }); await d.appDir({'foo': '1.0.0'}).create();
diff --git a/test/get/git/path_test.dart b/test/get/git/path_test.dart index a323be7..49607a1 100644 --- a/test/get/git/path_test.dart +++ b/test/get/git/path_test.dart
@@ -37,11 +37,9 @@ ]) ]).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry( - name: 'sub', - path: pathInCache('git/foo-${await repo.revParse('HEAD')}/subdir')), - ]).validate(); + await d.appPackagesFile({ + 'sub': pathInCache('git/foo-${await repo.revParse('HEAD')}/subdir') + }).validate(); }); test('depends on a package in a deep subdirectory', () async { @@ -73,12 +71,9 @@ ]) ]).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry( - name: 'sub', - path: - pathInCache('git/foo-${await repo.revParse('HEAD')}/sub/dir%25')), - ]).validate(); + await d.appPackagesFile({ + 'sub': pathInCache('git/foo-${await repo.revParse('HEAD')}/sub/dir%25') + }).validate(); final lockFile = LockFile.load( p.join(d.sandbox, appPath, 'pubspec.lock'), SourceRegistry()); @@ -120,12 +115,9 @@ ]) ]).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry( - name: 'sub', - path: - pathInCache('git/foo-${await repo.revParse('HEAD')}/sub/dir%25')), - ]).validate(); + await d.appPackagesFile({ + 'sub': pathInCache('git/foo-${await repo.revParse('HEAD')}/sub/dir%25') + }).validate(); final lockFile = LockFile.load( p.join(d.sandbox, appPath, 'pubspec.lock'), SourceRegistry()); @@ -166,14 +158,10 @@ ]) ]).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry( - name: 'sub1', - path: pathInCache('git/foo-${await repo.revParse('HEAD')}/subdir1')), - d.packageConfigEntry( - name: 'sub2', - path: pathInCache('git/foo-${await repo.revParse('HEAD')}/subdir2')), - ]).validate(); + await d.appPackagesFile({ + 'sub1': pathInCache('git/foo-${await repo.revParse('HEAD')}/subdir1'), + 'sub2': pathInCache('git/foo-${await repo.revParse('HEAD')}/subdir2') + }).validate(); }); test('depends on packages in the same subdirectory at different revisions', @@ -218,11 +206,9 @@ ]) ]).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry( - name: 'sub1', path: pathInCache('git/foo-$oldRevision/subdir')), - d.packageConfigEntry( - name: 'sub2', path: pathInCache('git/foo-$newRevision/subdir')), - ]).validate(); + await d.appPackagesFile({ + 'sub1': pathInCache('git/foo-$oldRevision/subdir'), + 'sub2': pathInCache('git/foo-$newRevision/subdir') + }).validate(); }); }
diff --git a/test/get/hosted/avoid_network_requests_test.dart b/test/get/hosted/avoid_network_requests_test.dart index c62fa7c..369a187 100644 --- a/test/get/hosted/avoid_network_requests_test.dart +++ b/test/get/hosted/avoid_network_requests_test.dart
@@ -9,13 +9,14 @@ void main() { test('only requests versions that are needed during solving', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '1.1.0') - ..serve('foo', '1.2.0') - ..serve('bar', '1.0.0') - ..serve('bar', '1.1.0') - ..serve('bar', '1.2.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '1.1.0'); + builder.serve('foo', '1.2.0'); + builder.serve('bar', '1.0.0'); + builder.serve('bar', '1.1.0'); + builder.serve('bar', '1.2.0'); + }); await d.appDir({'foo': 'any'}).create(); @@ -24,22 +25,20 @@ // Clear the cache. We don't care about anything that was served during // the initial get. - globalServer.requestedPaths.clear(); + globalServer!.requestedPaths.clear(); // Add "bar" to the dependencies. await d.appDir({'foo': 'any', 'bar': 'any'}).create(); // Run the solver again. await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.0'), - d.packageConfigEntry(name: 'bar', version: '1.2.0'), - ]).validate(); + + await d.appPackagesFile({'foo': '1.2.0', 'bar': '1.2.0'}).validate(); // The get should not have done any network requests since the lock file is // up to date. expect( - globalServer.requestedPaths, + globalServer!.requestedPaths, unorderedEquals([ // Bar should be requested because it's new, but not foo. 'api/packages/bar',
diff --git a/test/get/hosted/cached_pubspec_test.dart b/test/get/hosted/cached_pubspec_test.dart index fa9decc..88551ac 100644 --- a/test/get/hosted/cached_pubspec_test.dart +++ b/test/get/hosted/cached_pubspec_test.dart
@@ -9,8 +9,7 @@ void main() { test('does not request a pubspec for a cached package', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) => builder.serve('foo', '1.2.3')); await d.appDir({'foo': '1.2.3'}).create(); @@ -19,18 +18,16 @@ // Clear the cache. We don't care about anything that was served during // the initial get. - server.requestedPaths.clear(); + globalServer!.requestedPaths.clear(); await d.cacheDir({'foo': '1.2.3'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); // Run the solver again now that it's cached. await pubGet(); // The get should not have requested the pubspec since it's local already. - expect(server.requestedPaths, + expect(globalServer!.requestedPaths, isNot(contains('packages/foo/versions/1.2.3.yaml'))); }); }
diff --git a/test/get/hosted/do_not_upgrade_on_removed_constraints_test.dart b/test/get/hosted/do_not_upgrade_on_removed_constraints_test.dart index 44fe075..30e4a65 100644 --- a/test/get/hosted/do_not_upgrade_on_removed_constraints_test.dart +++ b/test/get/hosted/do_not_upgrade_on_removed_constraints_test.dart
@@ -11,29 +11,24 @@ test( "doesn't upgrade dependencies whose constraints have been " 'removed', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'shared_dep': 'any'}) - ..serve('bar', '1.0.0', deps: {'shared_dep': '<2.0.0'}) - ..serve('shared_dep', '1.0.0') - ..serve('shared_dep', '2.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'shared_dep': 'any'}); + builder.serve('bar', '1.0.0', deps: {'shared_dep': '<2.0.0'}); + builder.serve('shared_dep', '1.0.0'); + builder.serve('shared_dep', '2.0.0'); + }); await d.appDir({'foo': 'any', 'bar': 'any'}).create(); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), - d.packageConfigEntry(name: 'shared_dep', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile( + {'foo': '1.0.0', 'bar': '1.0.0', 'shared_dep': '1.0.0'}).validate(); await d.appDir({'foo': 'any'}).create(); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'shared_dep', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0', 'shared_dep': '1.0.0'}).validate(); }); }
diff --git a/test/get/hosted/does_no_network_requests_when_possible_test.dart b/test/get/hosted/does_no_network_requests_when_possible_test.dart index 4324776..3038624 100644 --- a/test/get/hosted/does_no_network_requests_when_possible_test.dart +++ b/test/get/hosted/does_no_network_requests_when_possible_test.dart
@@ -9,10 +9,11 @@ void main() { test('does not request versions if the lockfile is up to date', () async { - final server = await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '1.1.0') - ..serve('foo', '1.2.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '1.1.0'); + builder.serve('foo', '1.2.0'); + }); await d.appDir({'foo': 'any'}).create(); @@ -21,18 +22,16 @@ // Clear the cache. We don't care about anything that was served during // the initial get. - server.requestedPaths.clear(); + globalServer!.requestedPaths.clear(); // Run the solver again now that it's cached. await pubGet(); await d.cacheDir({'foo': '1.2.0'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.0'}).validate(); // The get should not have done any network requests since the lock file is // up to date. - expect(server.requestedPaths, isEmpty); + expect(globalServer!.requestedPaths, isEmpty); }); }
diff --git a/test/get/hosted/explain_bad_hosted_url_test.dart b/test/get/hosted/explain_bad_hosted_url_test.dart index feebf67..5628ecb 100644 --- a/test/get/hosted/explain_bad_hosted_url_test.dart +++ b/test/get/hosted/explain_bad_hosted_url_test.dart
@@ -32,12 +32,11 @@ }); test('Allows PUB_HOSTED_URL to end with a slash', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((b) => b.serve('foo', '1.0.0')); await d.appDir({'foo': 'any'}).create(); await pubGet( - environment: {'PUB_HOSTED_URL': '${globalServer.url}/'}, + environment: {'PUB_HOSTED_URL': '${globalPackageServer!.url}/'}, ); }); }
diff --git a/test/get/hosted/get_stress_test.dart b/test/get/hosted/get_stress_test.dart index 026c0c1..da45309 100644 --- a/test/get/hosted/get_stress_test.dart +++ b/test/get/hosted/get_stress_test.dart
@@ -9,11 +9,12 @@ void main() { test('gets more than 16 packages from a pub server', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); - for (var i = 0; i < 20; i++) { - server.serve('pkg$i', '1.$i.0'); - } + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + for (var i = 0; i < 20; i++) { + builder.serve('pkg$i', '1.$i.0'); + } + }); await d.appDir({ 'foo': '1.2.3', @@ -26,10 +27,10 @@ 'foo': '1.2.3', for (var i = 0; i < 20; i++) 'pkg$i': '1.$i.0', }).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - for (var i = 0; i < 20; i++) - d.packageConfigEntry(name: 'pkg$i', version: '1.$i.0') - ]).validate(); + + await d.appPackagesFile({ + 'foo': '1.2.3', + for (var i = 0; i < 20; i++) 'pkg$i': '1.$i.0', + }).validate(); }); }
diff --git a/test/get/hosted/get_test.dart b/test/get/hosted/get_test.dart index f0270a3..31c1f2e 100644 --- a/test/get/hosted/get_test.dart +++ b/test/get/hosted/get_test.dart
@@ -13,21 +13,18 @@ void main() { test('gets a package from a pub server', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) => builder.serve('foo', '1.2.3')); await d.appDir({'foo': '1.2.3'}).create(); await pubGet(); await d.cacheDir({'foo': '1.2.3'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); }); test('URL encodes the package name', () async { - await servePackages(); + await serveNoPackages(); await d.appDir({'bad name!': '1.2.3'}).create(); @@ -44,10 +41,11 @@ test('gets a package from a non-default pub server', () async { // Make the default server serve errors. Only the custom server should // be accessed. - (await servePackages()).serveErrors(); + await serveErrors(); - var server = await startPackageServer(); - server.serve('foo', '1.2.3'); + var server = await PackageServer.start((builder) { + builder.serve('foo', '1.2.3'); + }); await d.appDir({ 'foo': { @@ -59,21 +57,18 @@ await pubGet(); await d.cacheDir({'foo': '1.2.3'}, port: server.port).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3', server: server), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); }); group('categorizes dependency types in the lockfile', () { - setUp(() async { - await servePackages() - ..serve('foo', '1.2.3', deps: {'bar': 'any'}) - ..serve('bar', '1.2.3') - ..serve('baz', '1.2.3', deps: {'qux': 'any'}) - ..serve('qux', '1.2.3') - ..serve('zip', '1.2.3', deps: {'zap': 'any'}) - ..serve('zap', '1.2.3'); - }); + setUp(() => servePackages((builder) { + builder.serve('foo', '1.2.3', deps: {'bar': 'any'}); + builder.serve('bar', '1.2.3'); + builder.serve('baz', '1.2.3', deps: {'qux': 'any'}); + builder.serve('qux', '1.2.3'); + builder.serve('zip', '1.2.3', deps: {'zap': 'any'}); + builder.serve('zap', '1.2.3'); + })); test('for main, dev, and overridden dependencies', () async { await d.dir(appPath, [
diff --git a/test/get/hosted/get_transitive_test.dart b/test/get/hosted/get_transitive_test.dart index 0ae18ac..f68006a 100644 --- a/test/get/hosted/get_transitive_test.dart +++ b/test/get/hosted/get_transitive_test.dart
@@ -9,20 +9,18 @@ void main() { test('gets packages transitively from a pub server', () async { - await servePackages() - ..serve('foo', '1.2.3', deps: {'bar': '2.0.4'}) - ..serve('bar', '2.0.3') - ..serve('bar', '2.0.4') - ..serve('bar', '2.0.5'); + await servePackages((builder) { + builder.serve('foo', '1.2.3', deps: {'bar': '2.0.4'}); + builder.serve('bar', '2.0.3'); + builder.serve('bar', '2.0.4'); + builder.serve('bar', '2.0.5'); + }); await d.appDir({'foo': '1.2.3'}).create(); await pubGet(); await d.cacheDir({'foo': '1.2.3', 'bar': '2.0.4'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - d.packageConfigEntry(name: 'bar', version: '2.0.4'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3', 'bar': '2.0.4'}).validate(); }); }
diff --git a/test/get/hosted/gets_a_package_with_busted_dev_dependencies_test.dart b/test/get/hosted/gets_a_package_with_busted_dev_dependencies_test.dart index 585cfba..c53079c 100644 --- a/test/get/hosted/gets_a_package_with_busted_dev_dependencies_test.dart +++ b/test/get/hosted/gets_a_package_with_busted_dev_dependencies_test.dart
@@ -12,11 +12,12 @@ test( 'gets a dependency with broken dev dependencies from a pub ' 'server', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3', pubspec: { - 'dev_dependencies': { - 'busted': {'not a real source': null} - } + await servePackages((builder) { + builder.serve('foo', '1.2.3', pubspec: { + 'dev_dependencies': { + 'busted': {'not a real source': null} + } + }); }); await d.appDir({'foo': '1.2.3'}).create(); @@ -24,8 +25,6 @@ await pubGet(); await d.cacheDir({'foo': '1.2.3'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); }); }
diff --git a/test/get/hosted/resolve_constraints_test.dart b/test/get/hosted/resolve_constraints_test.dart index 466902e..c515c8e 100644 --- a/test/get/hosted/resolve_constraints_test.dart +++ b/test/get/hosted/resolve_constraints_test.dart
@@ -9,12 +9,13 @@ void main() { test('resolves version constraints from a pub server', () async { - await servePackages() - ..serve('foo', '1.2.3', deps: {'baz': '>=2.0.0'}) - ..serve('bar', '2.3.4', deps: {'baz': '<3.0.0'}) - ..serve('baz', '2.0.3') - ..serve('baz', '2.0.4') - ..serve('baz', '3.0.1'); + await servePackages((builder) { + builder.serve('foo', '1.2.3', deps: {'baz': '>=2.0.0'}); + builder.serve('bar', '2.3.4', deps: {'baz': '<3.0.0'}); + builder.serve('baz', '2.0.3'); + builder.serve('baz', '2.0.4'); + builder.serve('baz', '3.0.1'); + }); await d.appDir({'foo': 'any', 'bar': 'any'}).create(); @@ -22,10 +23,8 @@ await d .cacheDir({'foo': '1.2.3', 'bar': '2.3.4', 'baz': '2.0.4'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - d.packageConfigEntry(name: 'bar', version: '2.3.4'), - d.packageConfigEntry(name: 'baz', version: '2.0.4'), - ]).validate(); + + await d.appPackagesFile( + {'foo': '1.2.3', 'bar': '2.3.4', 'baz': '2.0.4'}).validate(); }); }
diff --git a/test/get/hosted/resolve_with_retracted_package_versions_test.dart b/test/get/hosted/resolve_with_retracted_package_versions_test.dart index d9b33a4..033e2a6 100644 --- a/test/get/hosted/resolve_with_retracted_package_versions_test.dart +++ b/test/get/hosted/resolve_with_retracted_package_versions_test.dart
@@ -13,29 +13,28 @@ void main() { test('Do not consider retracted packages', () async { - final server = await servePackages() + await servePackages((builder) => builder ..serve('foo', '1.0.0', deps: {'bar': '^1.0.0'}) ..serve('bar', '1.0.0') - ..serve('bar', '1.1.0'); + ..serve('bar', '1.1.0')); await d.appDir({'foo': '1.0.0'}).create(); - server.retractPackageVersion('bar', '1.1.0'); + globalPackageServer! + .add((builder) => builder..retractPackageVersion('bar', '1.1.0')); await pubGet(); await d.cacheDir({'foo': '1.0.0', 'bar': '1.0.0'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.0.0'}).validate(); }); test('Error when the only available package version is retracted', () async { - final server = await servePackages() + await servePackages((builder) => builder ..serve('foo', '1.0.0', deps: {'bar': '^1.0.0'}) - ..serve('bar', '1.0.0'); + ..serve('bar', '1.0.0')); await d.appDir({'foo': '1.0.0'}).create(); - server.retractPackageVersion('bar', '1.0.0'); + globalPackageServer! + .add((builder) => builder..retractPackageVersion('bar', '1.0.0')); await pubGet( error: '''Because every version of foo depends on bar ^1.0.0 which doesn't match any versions, foo is forbidden. @@ -48,51 +47,39 @@ // In this case we expect a newer version to be published at some point which // will then cause pub upgrade to choose that one. test('Allow retracted version when it was already in pubspec.lock', () async { - final server = await servePackages() + await servePackages((builder) => builder ..serve('foo', '1.0.0', deps: {'bar': '^1.0.0'}) ..serve('bar', '1.0.0') - ..serve('bar', '1.1.0'); + ..serve('bar', '1.1.0')); await d.appDir({'foo': '1.0.0'}).create(); await pubGet(); await d.cacheDir({'foo': '1.0.0', 'bar': '1.1.0'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.1.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.1.0'}).validate(); - server.retractPackageVersion('bar', '1.1.0'); + globalPackageServer! + .add((builder) => builder..retractPackageVersion('bar', '1.1.0')); await pubUpgrade(); await d.cacheDir({'foo': '1.0.0', 'bar': '1.1.0'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.1.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.1.0'}).validate(); - server.serve('bar', '2.0.0'); + globalPackageServer!.add((builder) => builder..serve('bar', '2.0.0')); await pubUpgrade(); await d.cacheDir({'foo': '1.0.0', 'bar': '1.1.0'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.1.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.1.0'}).validate(); - server.serve('bar', '1.2.0'); + globalPackageServer!.add((builder) => builder..serve('bar', '1.2.0')); await pubUpgrade(); await d.cacheDir({'foo': '1.0.0', 'bar': '1.2.0'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.2.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.2.0'}).validate(); }); test('Offline versions of pub commands also handle retracted packages', () async { - final server = await servePackages(); await populateCache({ 'foo': ['1.0.0'], 'bar': ['1.0.0', '1.1.0'] - }, server); + }); await d.cacheDir({ 'foo': '1.0.0', @@ -100,27 +87,25 @@ }).validate(); final barVersionsCache = - p.join(globalServer.cachingPath, '.cache', 'bar-versions.json'); + p.join(globalPackageServer!.cachingPath, '.cache', 'bar-versions.json'); expect(fileExists(barVersionsCache), isTrue); deleteEntry(barVersionsCache); - server.retractPackageVersion('bar', '1.1.0'); + globalPackageServer! + .add((builder) => builder..retractPackageVersion('bar', '1.1.0')); await pubGet(); await d.cacheDir({'bar': '1.1.0'}).validate(); // Now serve only errors - to validate we are truly offline. - server.serveErrors(); + await serveErrors(); await d.appDir({'foo': '1.0.0', 'bar': '^1.0.0'}).create(); await pubUpgrade(args: ['--offline']); // We choose bar 1.1.0 since we already have it in pubspec.lock - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.1.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.1.0'}).validate(); // Delete lockfile so that retracted versions are not considered. final lockFile = p.join(d.sandbox, appPath, 'pubspec.lock'); @@ -128,17 +113,15 @@ deleteEntry(lockFile); await pubGet(args: ['--offline']); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.0.0'}).validate(); }); test('Allow retracted version when pinned in dependency_overrides', () async { - final server = await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0') - ..serve('foo', '3.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0'); + builder.serve('foo', '3.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -148,31 +131,31 @@ }) ]).create(); - server.retractPackageVersion('foo', '2.0.0'); + globalPackageServer! + .add((builder) => builder..retractPackageVersion('foo', '2.0.0')); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '2.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '2.0.0'}).validate(); }); test('Prefer retracted version in dependency_overrides over pubspec.lock', () async { - final server = await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0') - ..serve('foo', '3.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0'); + builder.serve('foo', '3.0.0'); + }); await d.appDir({'foo': 'any'}).create(); await pubGet(); - server.retractPackageVersion('foo', '2.0.0'); - server.retractPackageVersion('foo', '3.0.0'); + globalPackageServer! + .add((builder) => builder..retractPackageVersion('foo', '2.0.0')); + globalPackageServer! + .add((builder) => builder..retractPackageVersion('foo', '3.0.0')); await pubUpgrade(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '3.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '3.0.0'}).validate(); await d.dir(appPath, [ d.pubspec({ @@ -183,8 +166,6 @@ ]).create(); await pubUpgrade(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '2.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '2.0.0'}).validate(); }); }
diff --git a/test/get/hosted/stay_locked_if_compatible_test.dart b/test/get/hosted/stay_locked_if_compatible_test.dart index df04579..52129f2 100644 --- a/test/get/hosted/stay_locked_if_compatible_test.dart +++ b/test/get/hosted/stay_locked_if_compatible_test.dart
@@ -11,24 +11,20 @@ test( "doesn't upgrade a locked pub server package with a new " 'compatible constraint', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((builder) => builder.serve('foo', '1.0.0')); await d.appDir({'foo': 'any'}).create(); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - ]).validate(); - server.serve('foo', '1.0.1'); + await d.appPackagesFile({'foo': '1.0.0'}).validate(); + + globalPackageServer!.add((builder) => builder.serve('foo', '1.0.1')); await d.appDir({'foo': '>=1.0.0'}).create(); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0'}).validate(); }); }
diff --git a/test/get/hosted/stay_locked_if_new_is_satisfied_test.dart b/test/get/hosted/stay_locked_if_new_is_satisfied_test.dart index c75c435..73077b1 100644 --- a/test/get/hosted/stay_locked_if_new_is_satisfied_test.dart +++ b/test/get/hosted/stay_locked_if_new_is_satisfied_test.dart
@@ -11,34 +11,35 @@ test( "doesn't unlock dependencies if a new dependency is already " 'satisfied', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', deps: {'bar': '<2.0.0'}); - server.serve('bar', '1.0.0', deps: {'baz': '<2.0.0'}); - server.serve('baz', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': '<2.0.0'}); + builder.serve('bar', '1.0.0', deps: {'baz': '<2.0.0'}); + builder.serve('baz', '1.0.0'); + }); await d.appDir({'foo': 'any'}).create(); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), - d.packageConfigEntry(name: 'baz', version: '1.0.0'), - ]).validate(); - server.serve('foo', '2.0.0', deps: {'bar': '<3.0.0'}); - server.serve('bar', '2.0.0', deps: {'baz': '<3.0.0'}); - server.serve('baz', '2.0.0'); - server.serve('newdep', '2.0.0', deps: {'baz': '>=1.0.0'}); + await d.appPackagesFile( + {'foo': '1.0.0', 'bar': '1.0.0', 'baz': '1.0.0'}).validate(); + + globalPackageServer!.add((builder) { + builder.serve('foo', '2.0.0', deps: {'bar': '<3.0.0'}); + builder.serve('bar', '2.0.0', deps: {'baz': '<3.0.0'}); + builder.serve('baz', '2.0.0'); + builder.serve('newdep', '2.0.0', deps: {'baz': '>=1.0.0'}); + }); await d.appDir({'foo': 'any', 'newdep': 'any'}).create(); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), - d.packageConfigEntry(name: 'baz', version: '1.0.0'), - d.packageConfigEntry(name: 'newdep', version: '2.0.0'), - ]).validate(); + await d.appPackagesFile({ + 'foo': '1.0.0', + 'bar': '1.0.0', + 'baz': '1.0.0', + 'newdep': '2.0.0' + }).validate(); }); }
diff --git a/test/get/hosted/stay_locked_test.dart b/test/get/hosted/stay_locked_test.dart index 8b819ea..eb26ea8 100644 --- a/test/get/hosted/stay_locked_test.dart +++ b/test/get/hosted/stay_locked_test.dart
@@ -13,28 +13,24 @@ test( 'keeps a hosted package locked to the version in the ' 'lockfile', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((builder) => builder.serve('foo', '1.0.0')); await d.appDir({'foo': 'any'}).create(); // This should lock the foo dependency to version 1.0.0. await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - ]).validate(); + + await d.appPackagesFile({'foo': '1.0.0'}).validate(); // Delete the .dart_tool/package_config.json file to simulate a new checkout of the application. deleteEntry(path.join(d.sandbox, packageConfigFilePath)); // Start serving a newer package as well. - server.serve('foo', '1.0.1'); + globalPackageServer!.add((builder) => builder.serve('foo', '1.0.1')); // This shouldn't upgrade the foo dependency due to the lockfile. await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0'}).validate(); }); }
diff --git a/test/get/hosted/unlock_if_incompatible_test.dart b/test/get/hosted/unlock_if_incompatible_test.dart index 007231e..fad5400 100644 --- a/test/get/hosted/unlock_if_incompatible_test.dart +++ b/test/get/hosted/unlock_if_incompatible_test.dart
@@ -11,23 +11,18 @@ test( 'upgrades a locked pub server package with a new incompatible ' 'constraint', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((builder) => builder.serve('foo', '1.0.0')); await d.appDir({'foo': 'any'}).create(); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - ]).validate(); - server.serve('foo', '1.0.1'); + await d.appPackagesFile({'foo': '1.0.0'}).validate(); + globalPackageServer!.add((builder) => builder.serve('foo', '1.0.1')); await d.appDir({'foo': '>1.0.0'}).create(); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.1'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.1'}).validate(); }); }
diff --git a/test/get/hosted/unlock_if_new_is_unsatisfied_test.dart b/test/get/hosted/unlock_if_new_is_unsatisfied_test.dart index ae6a4e6..aa45b76 100644 --- a/test/get/hosted/unlock_if_new_is_unsatisfied_test.dart +++ b/test/get/hosted/unlock_if_new_is_unsatisfied_test.dart
@@ -11,40 +11,42 @@ test( 'unlocks dependencies if necessary to ensure that a new ' 'dependency is satisfied', () async { - final server = await servePackages(); - - server.serve('foo', '1.0.0', deps: {'bar': '<2.0.0'}); - server.serve('bar', '1.0.0', deps: {'baz': '<2.0.0'}); - server.serve('baz', '1.0.0', deps: {'qux': '<2.0.0'}); - server.serve('qux', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': '<2.0.0'}); + builder.serve('bar', '1.0.0', deps: {'baz': '<2.0.0'}); + builder.serve('baz', '1.0.0', deps: {'qux': '<2.0.0'}); + builder.serve('qux', '1.0.0'); + }); await d.appDir({'foo': 'any'}).create(); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), - d.packageConfigEntry(name: 'baz', version: '1.0.0'), - d.packageConfigEntry(name: 'qux', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({ + 'foo': '1.0.0', + 'bar': '1.0.0', + 'baz': '1.0.0', + 'qux': '1.0.0' + }).validate(); - server.serve('foo', '2.0.0', deps: {'bar': '<3.0.0'}); - server.serve('bar', '2.0.0', deps: {'baz': '<3.0.0'}); - server.serve('baz', '2.0.0', deps: {'qux': '<3.0.0'}); - server.serve('qux', '2.0.0'); - server.serve('newdep', '2.0.0', deps: {'baz': '>=1.5.0'}); + globalPackageServer!.add((builder) { + builder.serve('foo', '2.0.0', deps: {'bar': '<3.0.0'}); + builder.serve('bar', '2.0.0', deps: {'baz': '<3.0.0'}); + builder.serve('baz', '2.0.0', deps: {'qux': '<3.0.0'}); + builder.serve('qux', '2.0.0'); + builder.serve('newdep', '2.0.0', deps: {'baz': '>=1.5.0'}); + }); await d.appDir({'foo': 'any', 'newdep': 'any'}).create(); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '2.0.0'), - d.packageConfigEntry(name: 'bar', version: '2.0.0'), - d.packageConfigEntry(name: 'baz', version: '2.0.0'), - d.packageConfigEntry(name: 'qux', version: '1.0.0'), - d.packageConfigEntry(name: 'newdep', version: '2.0.0'), - ]).validate(); + await d.appPackagesFile({ + 'foo': '2.0.0', + 'bar': '2.0.0', + 'baz': '2.0.0', + 'qux': '1.0.0', + 'newdep': '2.0.0' + }).validate(); }); }
diff --git a/test/get/hosted/unlock_if_version_doesnt_exist_test.dart b/test/get/hosted/unlock_if_version_doesnt_exist_test.dart index e4cc01b..328745e 100644 --- a/test/get/hosted/unlock_if_version_doesnt_exist_test.dart +++ b/test/get/hosted/unlock_if_version_doesnt_exist_test.dart
@@ -12,23 +12,16 @@ void main() { test('upgrades a locked pub server package with a nonexistent version', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((builder) => builder.serve('foo', '1.0.0')); await d.appDir({'foo': 'any'}).create(); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0'}).validate(); deleteEntry(p.join(d.sandbox, cachePath)); - server.clearPackages(); - server.serve('foo', '1.0.1'); - + globalPackageServer!.replace((builder) => builder.serve('foo', '1.0.1')); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.1'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.1'}).validate(); }); }
diff --git a/test/get/hosted/warn_about_discontinued_test.dart b/test/get/hosted/warn_about_discontinued_test.dart index 7057f9b..6df08b8 100644 --- a/test/get/hosted/warn_about_discontinued_test.dart +++ b/test/get/hosted/warn_about_discontinued_test.dart
@@ -6,7 +6,7 @@ import 'package:path/path.dart' as p; import 'package:pub/src/io.dart'; -import 'package:shelf/shelf.dart' as shelf; +import 'package:shelf/shelf.dart'; import 'package:test/test.dart'; import '../../descriptor.dart' as d; @@ -14,22 +14,22 @@ void main() { test('Warns about discontinued dependencies', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3', deps: {'transitive': 'any'}); - server.serve('transitive', '1.0.0'); + await servePackages((builder) => builder + ..serve('foo', '1.2.3', deps: {'transitive': 'any'}) + ..serve('transitive', '1.0.0')); await d.appDir({'foo': '1.2.3'}).create(); await pubGet(); - server + globalPackageServer!.add((builder) => builder ..discontinue('foo') - ..discontinue('transitive'); + ..discontinue('transitive')); // A pub get straight away will not trigger the warning, as we cache // responses for a while. await pubGet(); final fooVersionsCache = - p.join(globalServer.cachingPath, '.cache', 'foo-versions.json'); - final transitiveVersionsCache = - p.join(globalServer.cachingPath, '.cache', 'transitive-versions.json'); + p.join(globalPackageServer!.cachingPath, '.cache', 'foo-versions.json'); + final transitiveVersionsCache = p.join( + globalPackageServer!.cachingPath, '.cache', 'transitive-versions.json'); expect(fileExists(fooVersionsCache), isTrue); expect(fileExists(transitiveVersionsCache), isTrue); deleteEntry(fooVersionsCache); @@ -46,9 +46,8 @@ c['_fetchedAt'] = DateTime.now().subtract(Duration(days: 5)).toIso8601String(); writeTextFile(fooVersionsCache, json.encode(c)); - - server.discontinue('foo', replacementText: 'bar'); - + globalPackageServer! + .add((builder) => builder.discontinue('foo', replacementText: 'bar')); await pubGet(output: ''' Resolving dependencies... foo 1.2.3 (discontinued replaced by bar) @@ -68,7 +67,7 @@ Got dependencies!'''); // Test that --offline won't try to access the server for retrieving the // status. - server.serveErrors(); + await serveErrors(); await pubGet(args: ['--offline'], output: ''' Resolving dependencies... foo 1.2.3 (discontinued replaced by bar) @@ -82,10 +81,9 @@ }); test('Warns about discontinued dev dependencies', () async { - final builder = await servePackages(); - builder + await servePackages((builder) => builder ..serve('foo', '1.2.3', deps: {'transitive': 'any'}) - ..serve('transitive', '1.0.0'); + ..serve('transitive', '1.0.0')); await d.dir(appPath, [ d.file('pubspec.yaml', ''' @@ -100,14 +98,14 @@ ]).create(); await pubGet(); - builder + globalPackageServer!.add((builder) => builder ..discontinue('foo') - ..discontinue('transitive'); + ..discontinue('transitive')); // A pub get straight away will not trigger the warning, as we cache // responses for a while. await pubGet(); final fooVersionsCache = - p.join(globalServer.cachingPath, '.cache', 'foo-versions.json'); + p.join(globalPackageServer!.cachingPath, '.cache', 'foo-versions.json'); expect(fileExists(fooVersionsCache), isTrue); deleteEntry(fooVersionsCache); // We warn only about the direct dependency here: @@ -122,7 +120,8 @@ c['_fetchedAt'] = DateTime.now().subtract(Duration(days: 5)).toIso8601String(); writeTextFile(fooVersionsCache, json.encode(c)); - builder.discontinue('foo', replacementText: 'bar'); + globalPackageServer! + .add((builder) => builder.discontinue('foo', replacementText: 'bar')); await pubGet(output: ''' Resolving dependencies... foo 1.2.3 (discontinued replaced by bar) @@ -142,7 +141,7 @@ Got dependencies!'''); // Test that --offline won't try to access the server for retrieving the // status. - builder.serveErrors(); + await serveErrors(); await pubGet(args: ['--offline'], output: ''' Resolving dependencies... foo 1.2.3 (discontinued replaced by bar) @@ -155,17 +154,17 @@ }); test('get does not fail when status listing fails', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) => builder..serve('foo', '1.2.3')); await d.appDir({'foo': '1.2.3'}).create(); await pubGet(); final fooVersionsCache = - p.join(globalServer.cachingPath, '.cache', 'foo-versions.json'); + p.join(globalPackageServer!.cachingPath, '.cache', 'foo-versions.json'); expect(fileExists(fooVersionsCache), isTrue); deleteEntry(fooVersionsCache); // Serve 400 on all requests. - globalServer.handle(RegExp('.*'), - (shelf.Request request) => shelf.Response.notFound('Not found')); + globalPackageServer!.extraHandlers + ..clear() + ..[RegExp('.*')] = (request) async => Response(400); /// Even if we fail to get status we still report success if versions don't unlock. await pubGet();
diff --git a/test/get/hosted/warn_about_retracted_package_test.dart b/test/get/hosted/warn_about_retracted_package_test.dart index 2336c7f..5031061 100644 --- a/test/get/hosted/warn_about_retracted_package_test.dart +++ b/test/get/hosted/warn_about_retracted_package_test.dart
@@ -11,36 +11,38 @@ void main() { test('Report retracted packages', () async { - final server = await servePackages() + await servePackages((builder) => builder ..serve('foo', '1.0.0', deps: {'bar': 'any'}) - ..serve('bar', '1.0.0'); + ..serve('bar', '1.0.0')); await d.appDir({'foo': '1.0.0'}).create(); await pubGet(); - server.retractPackageVersion('bar', '1.0.0'); + globalPackageServer! + .add((builder) => builder..retractPackageVersion('bar', '1.0.0')); // Delete the cache to trigger the report. final barVersionsCache = - p.join(server.cachingPath, '.cache', 'bar-versions.json'); + p.join(globalPackageServer!.cachingPath, '.cache', 'bar-versions.json'); expect(fileExists(barVersionsCache), isTrue); deleteEntry(barVersionsCache); await pubGet(output: contains('bar 1.0.0 (retracted)')); }); test('Report retracted packages with newer version available', () async { - final server = await servePackages() + await servePackages((builder) => builder ..serve('foo', '1.0.0', deps: {'bar': '^1.0.0'}) ..serve('bar', '1.0.0') ..serve('bar', '2.0.0') - ..serve('bar', '2.0.1-pre'); + ..serve('bar', '2.0.1-pre')); await d.appDir({'foo': '1.0.0'}).create(); await pubGet(); - server.retractPackageVersion('bar', '1.0.0'); + globalPackageServer! + .add((builder) => builder..retractPackageVersion('bar', '1.0.0')); // Delete the cache to trigger the report. final barVersionsCache = - p.join(server.cachingPath, '.cache', 'bar-versions.json'); + p.join(globalPackageServer!.cachingPath, '.cache', 'bar-versions.json'); expect(fileExists(barVersionsCache), isTrue); deleteEntry(barVersionsCache); await pubGet(output: contains('bar 1.0.0 (retracted, 2.0.0 available)')); @@ -48,18 +50,19 @@ test('Report retracted packages with newer prerelease version available', () async { - final server = await servePackages() + await servePackages((builder) => builder ..serve('foo', '1.0.0', deps: {'bar': '^1.0.0-pre'}) ..serve('bar', '1.0.0-pre') - ..serve('bar', '2.0.1-pre'); + ..serve('bar', '2.0.1-pre')); await d.appDir({'foo': '1.0.0'}).create(); await pubGet(); - server.retractPackageVersion('bar', '1.0.0-pre'); + globalPackageServer! + .add((builder) => builder..retractPackageVersion('bar', '1.0.0-pre')); // Delete the cache to trigger the report. final barVersionsCache = - p.join(server.cachingPath, '.cache', 'bar-versions.json'); + p.join(globalPackageServer!.cachingPath, '.cache', 'bar-versions.json'); expect(fileExists(barVersionsCache), isTrue); deleteEntry(barVersionsCache); await pubGet(
diff --git a/test/get/package_name_test.dart b/test/get/package_name_test.dart index b1328cc..46ca386 100644 --- a/test/get/package_name_test.dart +++ b/test/get/package_name_test.dart
@@ -56,8 +56,7 @@ await pubGet(); await d.dir(appPath, [ - d.packageConfigFile( - [d.packageConfigEntry(name: 'foo.bar.baz', path: '.')]) + d.packagesFile({'foo.bar.baz': '.'}), ]).validate(); }); }
diff --git a/test/get/path/absolute_path_test.dart b/test/get/path/absolute_path_test.dart index e1897e9..0fc987a 100644 --- a/test/get/path/absolute_path_test.dart +++ b/test/get/path/absolute_path_test.dart
@@ -21,8 +21,6 @@ await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: path.join(d.sandbox, 'foo')), - ]).validate(); + await d.appPackagesFile({'foo': path.join(d.sandbox, 'foo')}).validate(); }); }
diff --git a/test/get/path/absolute_symlink_test.dart b/test/get/path/absolute_symlink_test.dart index 83d3433..1a2d912 100644 --- a/test/get/path/absolute_symlink_test.dart +++ b/test/get/path/absolute_symlink_test.dart
@@ -24,8 +24,8 @@ await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: fooPath), + await d.dir(appPath, [ + d.packagesFile({'myapp': '.', 'foo': fooPath}) ]).validate(); await d.dir('moved').create(); @@ -35,9 +35,9 @@ renameInSandbox(appPath, path.join('moved', appPath)); await d.dir('moved', [ - d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: fooPath), - ]), + d.dir(appPath, [ + d.packagesFile({'myapp': '.', 'foo': fooPath}) + ]) ]).validate(); }); }
diff --git a/test/get/path/relative_path_test.dart b/test/get/path/relative_path_test.dart index e56a453..4255d49 100644 --- a/test/get/path/relative_path_test.dart +++ b/test/get/path/relative_path_test.dart
@@ -23,9 +23,7 @@ await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: '../foo'), - ]).validate(); + await d.appPackagesFile({'foo': '../foo'}).validate(); }); test('path is relative to containing pubspec', () async { @@ -47,10 +45,8 @@ await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: '../relative/foo'), - d.packageConfigEntry(name: 'bar', path: '../relative/bar'), - ]).validate(); + await d.appPackagesFile( + {'foo': '../relative/foo', 'bar': '../relative/bar'}).validate(); }); test('path is relative to containing pubspec when using --directory', @@ -76,10 +72,9 @@ workingDirectory: d.sandbox, output: contains('Changed 2 dependencies in myapp!')); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: '../relative/foo'), - d.packageConfigEntry(name: 'bar', path: '../relative/bar'), - ]).validate(); + await d.appPackagesFile( + {'foo': '../relative/foo', 'bar': '../relative/bar'}, + ).validate(); }); test('relative path preserved in the lockfile', () async {
diff --git a/test/get/path/relative_symlink_test.dart b/test/get/path/relative_symlink_test.dart index 9136a34..af7185b 100644 --- a/test/get/path/relative_symlink_test.dart +++ b/test/get/path/relative_symlink_test.dart
@@ -28,8 +28,8 @@ await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: '../foo'), + await d.dir(appPath, [ + d.packagesFile({'myapp': '.', 'foo': '../foo'}) ]).validate(); await d.dir('moved').create(); @@ -41,8 +41,8 @@ renameInSandbox(appPath, path.join('moved', appPath)); await d.dir('moved', [ - d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: '../foo'), + d.dir(appPath, [ + d.packagesFile({'myapp': '.', 'foo': '../foo'}) ]) ]).validate(); });
diff --git a/test/get/path/shared_dependency_symlink_test.dart b/test/get/path/shared_dependency_symlink_test.dart index d450838..46a78c6 100644 --- a/test/get/path/shared_dependency_symlink_test.dart +++ b/test/get/path/shared_dependency_symlink_test.dart
@@ -40,10 +40,13 @@ await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: '../foo'), - d.packageConfigEntry(name: 'bar', path: '../bar'), - d.packageConfigEntry(name: 'shared', path: '../shared'), + await d.dir(appPath, [ + d.packagesFile({ + 'myapp': '.', + 'foo': '../foo', + 'bar': '../bar', + 'shared': '../shared' + }) ]).validate(); }); }
diff --git a/test/get/path/shared_dependency_test.dart b/test/get/path/shared_dependency_test.dart index 3ef91ae..7072221 100644 --- a/test/get/path/shared_dependency_test.dart +++ b/test/get/path/shared_dependency_test.dart
@@ -35,11 +35,8 @@ await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: '../foo'), - d.packageConfigEntry(name: 'bar', path: '../bar'), - d.packageConfigEntry(name: 'shared', path: '../shared'), - ]).validate(); + await d.appPackagesFile( + {'foo': '../foo', 'bar': '../bar', 'shared': '../shared'}).validate(); }); test('shared dependency with paths that normalize the same', () async { @@ -69,10 +66,7 @@ await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: '../foo'), - d.packageConfigEntry(name: 'bar', path: '../bar'), - d.packageConfigEntry(name: 'shared', path: '../shared'), - ]).validate(); + await d.appPackagesFile( + {'foo': '../foo', 'bar': '../bar', 'shared': '../shared'}).validate(); }); }
diff --git a/test/get/sdk_constraint_required_test.dart b/test/get/sdk_constraint_required_test.dart index 3f1e5c0..1b6fbc5 100644 --- a/test/get/sdk_constraint_required_test.dart +++ b/test/get/sdk_constraint_required_test.dart
@@ -25,8 +25,8 @@ d.nothing('pubspec.lock'), // The "packages" directory should not have been generated. d.nothing('packages'), - // The package config file should not have been created. - d.nothing('.dart_tool/package_config.json'), + // The ".packages" file should not have been created. + d.nothing('.packages'), ]).validate(); }); }
diff --git a/test/get/switch_source_test.dart b/test/get/switch_source_test.dart index 7e56652..dd8c97d 100644 --- a/test/get/switch_source_test.dart +++ b/test/get/switch_source_test.dart
@@ -9,8 +9,7 @@ void main() { test('re-gets a package if its source has changed', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) => builder.serve('foo', '1.2.3')); await d.dir('foo', [d.libDir('foo', 'foo 0.0.1'), d.libPubspec('foo', '0.0.1')]).create(); @@ -21,15 +20,11 @@ await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: '../foo'), - ]).validate(); + await d.appPackagesFile({'foo': '../foo'}).validate(); await d.appDir({'foo': 'any'}).create(); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); }); }
diff --git a/test/get/unknown_sdk_test.dart b/test/get/unknown_sdk_test.dart deleted file mode 100644 index d0c1de3..0000000 --- a/test/get/unknown_sdk_test.dart +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:pub/src/exit_codes.dart' as exit_codes; -import 'package:test/test.dart'; - -import '../descriptor.dart' as d; -import '../test_pub.dart'; - -void main() { - test('pub get barks at unknown sdk', () async { - await d.dir(appPath, [ - d.pubspec({ - 'environment': {'foo': '>=1.2.4 <2.0.0'} - }) - ]).create(); - - await pubGet( - error: contains( - "Error on line 1, column 40 of pubspec.yaml: pubspec.yaml refers to an unknown sdk 'foo'."), - exitCode: exit_codes.DATA, - ); - }); -}
diff --git a/test/get/with_empty_environment_test.dart b/test/get/with_empty_environment_test.dart index 30768c4..9a9f9e2 100644 --- a/test/get/with_empty_environment_test.dart +++ b/test/get/with_empty_environment_test.dart
@@ -11,8 +11,7 @@ void main() { test(r'runs even with an empty environment (eg. no $HOME)', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) => builder.serve('foo', '1.2.3')); await d.appDir({'foo': 'any'}).create();
diff --git a/test/global/activate/activate_git_after_hosted_test.dart b/test/global/activate/activate_git_after_hosted_test.dart index c553041..75925d3 100644 --- a/test/global/activate/activate_git_after_hosted_test.dart +++ b/test/global/activate/activate_git_after_hosted_test.dart
@@ -11,10 +11,11 @@ test('activating a Git package deactivates the hosted one', () async { ensureGit(); - final server = await servePackages(); - server.serve('foo', '1.0.0', contents: [ - d.dir('bin', [d.file('foo.dart', "main(args) => print('hosted');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir('bin', [d.file('foo.dart', "main(args) => print('hosted');")]) + ]); + }); await d.git('foo.git', [ d.libPubspec('foo', '1.0.0'),
diff --git a/test/global/activate/activate_hosted_after_git_test.dart b/test/global/activate/activate_hosted_after_git_test.dart index 1546280..ba267b6 100644 --- a/test/global/activate/activate_hosted_after_git_test.dart +++ b/test/global/activate/activate_hosted_after_git_test.dart
@@ -2,7 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:path/path.dart' as p; import 'package:test/test.dart'; import '../../descriptor.dart' as d; @@ -10,10 +9,11 @@ void main() { test('activating a hosted package deactivates the Git one', () async { - final server = await servePackages(); - server.serve('foo', '2.0.0', contents: [ - d.dir('bin', [d.file('foo.dart', "main(args) => print('hosted');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '2.0.0', contents: [ + d.dir('bin', [d.file('foo.dart', "main(args) => print('hosted');")]) + ]); + }); await d.git('foo.git', [ d.libPubspec('foo', '1.0.0'), @@ -22,9 +22,8 @@ await runPub(args: ['global', 'activate', '-sgit', '../foo.git']); - final locationUri = p.toUri(p.join(d.sandbox, 'foo.git')); await runPub(args: ['global', 'activate', 'foo'], output: ''' - Package foo is currently active from Git repository "$locationUri". + Package foo is currently active from Git repository "../foo.git". Resolving dependencies... + foo 2.0.0 Downloading foo 2.0.0...
diff --git a/test/global/activate/activate_hosted_after_path_test.dart b/test/global/activate/activate_hosted_after_path_test.dart index 4cd753f..92985bd 100644 --- a/test/global/activate/activate_hosted_after_path_test.dart +++ b/test/global/activate/activate_hosted_after_path_test.dart
@@ -11,10 +11,11 @@ void main() { test('activating a hosted package deactivates the path one', () async { - final server = await servePackages(); - server.serve('foo', '2.0.0', contents: [ - d.dir('bin', [d.file('foo.dart', "main(args) => print('hosted');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '2.0.0', contents: [ + d.dir('bin', [d.file('foo.dart', "main(args) => print('hosted');")]) + ]); + }); await d.dir('foo', [ d.libPubspec('foo', '1.0.0'),
diff --git a/test/global/activate/activate_hosted_twice_test.dart b/test/global/activate/activate_hosted_twice_test.dart index a4d1337..1923641 100644 --- a/test/global/activate/activate_hosted_twice_test.dart +++ b/test/global/activate/activate_hosted_twice_test.dart
@@ -9,8 +9,7 @@ void main() { test('activating a hosted package twice will not precompile', () async { - final server = await servePackages(); - server + await servePackages((builder) => builder ..serve('foo', '1.0.0', deps: { 'bar': 'any' }, contents: [ @@ -22,9 +21,17 @@ ]) ..serve('bar', '1.0.0', contents: [ d.dir('lib', [d.file('bar.dart', 'final version = "1.0.0";')]) - ]); + ])); - await runPub(args: ['global', 'activate', 'foo'], output: anything); + await runPub(args: ['global', 'activate', 'foo'], output: ''' +Resolving dependencies... ++ bar 1.0.0 ++ foo 1.0.0 +Downloading foo 1.0.0... +Downloading bar 1.0.0... +Building package executables... +Built foo:foo. +Activated foo 1.0.0.'''); await runPub(args: ['global', 'activate', 'foo'], output: ''' Package foo is currently active at version 1.0.0. @@ -39,9 +46,10 @@ await runPub(args: ['global', 'activate', 'foo']); - server.serve('bar', '2.0.0', contents: [ - d.dir('lib', [d.file('bar.dart', 'final version = "2.0.0";')]) - ]); + globalPackageServer! + .add((builder) => builder.serve('bar', '2.0.0', contents: [ + d.dir('lib', [d.file('bar.dart', 'final version = "2.0.0";')]) + ])); await runPub(args: ['global', 'activate', 'foo'], output: ''' Package foo is currently active at version 1.0.0.
diff --git a/test/global/activate/activate_path_after_hosted_test.dart b/test/global/activate/activate_path_after_hosted_test.dart index 01d493d..f7cfa95 100644 --- a/test/global/activate/activate_path_after_hosted_test.dart +++ b/test/global/activate/activate_path_after_hosted_test.dart
@@ -10,11 +10,12 @@ import '../../test_pub.dart'; void main() { - test('activating a path package deactivates the hosted one', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', contents: [ - d.dir('bin', [d.file('foo.dart', "main(args) => print('hosted');")]) - ]); + test('activating a hosted package deactivates the path one', () async { + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir('bin', [d.file('foo.dart', "main(args) => print('hosted');")]) + ]); + }); await d.dir('foo', [ d.libPubspec('foo', '2.0.0'),
diff --git a/test/global/activate/cached_package_test.dart b/test/global/activate/cached_package_test.dart index 98db402..2daeaad 100644 --- a/test/global/activate/cached_package_test.dart +++ b/test/global/activate/cached_package_test.dart
@@ -9,10 +9,11 @@ void main() { test('can activate an already cached package', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', contents: [ - d.dir('bin', [d.file('foo.dart', 'main() => print("hi"); ')]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir('bin', [d.file('foo.dart', 'main() => print("hi"); ')]) + ]); + }); await runPub(args: ['cache', 'add', 'foo']);
diff --git a/test/global/activate/constraint_test.dart b/test/global/activate/constraint_test.dart index 23386c0..0a18257 100644 --- a/test/global/activate/constraint_test.dart +++ b/test/global/activate/constraint_test.dart
@@ -9,11 +9,12 @@ void main() { test('chooses the highest version that matches the constraint', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '1.0.1') - ..serve('foo', '1.1.0') - ..serve('foo', '1.2.3'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '1.0.1'); + builder.serve('foo', '1.1.0'); + builder.serve('foo', '1.2.3'); + }); await runPub(args: ['global', 'activate', 'foo', '<1.1.0']);
diff --git a/test/global/activate/custom_hosted_url_test.dart b/test/global/activate/custom_hosted_url_test.dart index 8b2f0fc..54ee463 100644 --- a/test/global/activate/custom_hosted_url_test.dart +++ b/test/global/activate/custom_hosted_url_test.dart
@@ -9,21 +9,22 @@ void main() { test('activating a package from a custom pub server', () async { // The default pub server (i.e. pub.dartlang.org). - final server = await servePackages(); - server.serve('baz', '1.0.0'); + await servePackages((builder) { + builder.serve('baz', '1.0.0'); + }); // The custom pub server. - final customServer = await startPackageServer(); - Map<String, dynamic> hostedDep(String name, String constraint) => { - 'hosted': { - 'url': customServer.url, - 'name': name, - }, - 'version': constraint, - }; - - customServer.serve('foo', '1.0.0', deps: {'bar': hostedDep('bar', 'any')}); - customServer.serve('bar', '1.0.0', deps: {'baz': 'any'}); + final customServer = await PackageServer.start((builder) { + Map<String, dynamic> hostedDep(String name, String constraint) => { + 'hosted': { + 'url': builder.serverUrl, + 'name': name, + }, + 'version': constraint, + }; + builder.serve('foo', '1.0.0', deps: {'bar': hostedDep('bar', 'any')}); + builder.serve('bar', '1.0.0', deps: {'baz': 'any'}); + }); await runPub( args: ['global', 'activate', 'foo', '-u', customServer.url],
diff --git a/test/global/activate/different_version_test.dart b/test/global/activate/different_version_test.dart index 8406b92..dd6cca2 100644 --- a/test/global/activate/different_version_test.dart +++ b/test/global/activate/different_version_test.dart
@@ -11,13 +11,14 @@ test( "discards the previous active version if it doesn't match the " 'constraint', () async { - await servePackages() - ..serve('foo', '1.0.0', contents: [ - d.dir('bin', [d.file('foo.dart', 'main() => print("hi");')]) - ]) - ..serve('foo', '2.0.0', contents: [ - d.dir('bin', [d.file('foo.dart', 'main() => print("hi2");')]) + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir('bin', [d.file('foo.dart', 'main() => print("hi"); ')]) ]); + builder.serve('foo', '2.0.0', contents: [ + d.dir('bin', [d.file('foo.dart', 'main() => print("hi2"); ')]) + ]); + }); // Activate 1.0.0. await runPub(args: ['global', 'activate', 'foo', '1.0.0']);
diff --git a/test/global/activate/empty_constraint_test.dart b/test/global/activate/empty_constraint_test.dart index d893bcd..fe0bd27 100644 --- a/test/global/activate/empty_constraint_test.dart +++ b/test/global/activate/empty_constraint_test.dart
@@ -9,9 +9,10 @@ void main() { test('errors if the constraint matches no versions', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '1.0.1'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '1.0.1'); + }); await runPub( args: ['global', 'activate', 'foo', '>1.1.0'],
diff --git a/test/global/activate/feature_test.dart b/test/global/activate/feature_test.dart index 58119d1..6095aa1 100644 --- a/test/global/activate/feature_test.dart +++ b/test/global/activate/feature_test.dart
@@ -10,8 +10,8 @@ void main() { test('enables default-on features by default', () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'stuff': { 'dependencies': {'bar': '1.0.0'} @@ -21,9 +21,11 @@ 'dependencies': {'baz': '1.0.0'} } } - }) - ..serve('bar', '1.0.0') - ..serve('baz', '1.0.0'); + }); + + builder.serve('bar', '1.0.0'); + builder.serve('baz', '1.0.0'); + }); await runPub(args: ['global', 'activate', 'foo'], output: contains(''' Resolving dependencies... @@ -33,8 +35,8 @@ }); test('can enable default-off features', () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'stuff': { 'dependencies': {'bar': '1.0.0'} @@ -44,9 +46,11 @@ 'dependencies': {'baz': '1.0.0'} } } - }) - ..serve('bar', '1.0.0') - ..serve('baz', '1.0.0'); + }); + + builder.serve('bar', '1.0.0'); + builder.serve('baz', '1.0.0'); + }); await runPub( args: ['global', 'activate', 'foo', '--features', 'things'], @@ -59,8 +63,8 @@ }); test('can disable default-on features', () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'stuff': { 'dependencies': {'bar': '1.0.0'} @@ -70,9 +74,11 @@ 'dependencies': {'baz': '1.0.0'} } } - }) - ..serve('bar', '1.0.0') - ..serve('baz', '1.0.0'); + }); + + builder.serve('bar', '1.0.0'); + builder.serve('baz', '1.0.0'); + }); await runPub( args: ['global', 'activate', 'foo', '--omit-features', 'stuff'], @@ -83,8 +89,8 @@ }); test('supports multiple arguments', () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'stuff': { 'default': false, @@ -95,9 +101,11 @@ 'dependencies': {'baz': '1.0.0'} } } - }) - ..serve('bar', '1.0.0') - ..serve('baz', '1.0.0'); + }); + + builder.serve('bar', '1.0.0'); + builder.serve('baz', '1.0.0'); + }); await runPub( args: ['global', 'activate', 'foo', '--features', 'things,stuff'], @@ -110,8 +118,8 @@ }); test('can both enable and disable', () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'stuff': { 'dependencies': {'bar': '1.0.0'} @@ -121,9 +129,11 @@ 'dependencies': {'baz': '1.0.0'} } } - }) - ..serve('bar', '1.0.0') - ..serve('baz', '1.0.0'); + }); + + builder.serve('bar', '1.0.0'); + builder.serve('baz', '1.0.0'); + }); await runPub(args: [ 'global',
diff --git a/test/global/activate/ignores_active_version_test.dart b/test/global/activate/ignores_active_version_test.dart index 777a631..949456f 100644 --- a/test/global/activate/ignores_active_version_test.dart +++ b/test/global/activate/ignores_active_version_test.dart
@@ -9,14 +9,15 @@ void main() { test('ignores previously activated version', () async { - await servePackages() - ..serve( + await servePackages((builder) { + builder.serve( 'foo', '1.2.3', - ) - ..serve('foo', '1.3.0', contents: [ + ); + builder.serve('foo', '1.3.0', contents: [ d.dir('bin', [d.file('foo.dart', 'main() => print("hi"); ')]) ]); + }); // Activate 1.2.3. await runPub(args: ['global', 'activate', 'foo', '1.2.3']);
diff --git a/test/global/activate/installs_dependencies_for_git_test.dart b/test/global/activate/installs_dependencies_for_git_test.dart index 6018f50..e67fad4 100644 --- a/test/global/activate/installs_dependencies_for_git_test.dart +++ b/test/global/activate/installs_dependencies_for_git_test.dart
@@ -9,9 +9,10 @@ void main() { test('activating a Git package installs its dependencies', () async { - await servePackages() - ..serve('bar', '1.0.0', deps: {'baz': 'any'}) - ..serve('baz', '1.0.0'); + await servePackages((builder) { + builder.serve('bar', '1.0.0', deps: {'baz': 'any'}); + builder.serve('baz', '1.0.0'); + }); await d.git('foo.git', [ d.libPubspec('foo', '1.0.0', deps: {'bar': 'any'}),
diff --git a/test/global/activate/installs_dependencies_for_path_test.dart b/test/global/activate/installs_dependencies_for_path_test.dart index 4688f07..52f3e65 100644 --- a/test/global/activate/installs_dependencies_for_path_test.dart +++ b/test/global/activate/installs_dependencies_for_path_test.dart
@@ -9,9 +9,10 @@ void main() { test('activating a path package installs dependencies', () async { - await servePackages() - ..serve('bar', '1.0.0', deps: {'baz': 'any'}) - ..serve('baz', '2.0.0'); + await servePackages((builder) { + builder.serve('bar', '1.0.0', deps: {'baz': 'any'}); + builder.serve('baz', '2.0.0'); + }); await d.dir('foo', [ d.libPubspec('foo', '0.0.0', deps: {'bar': 'any'}),
diff --git a/test/global/activate/installs_dependencies_test.dart b/test/global/activate/installs_dependencies_test.dart index 770ebcf..7114170 100644 --- a/test/global/activate/installs_dependencies_test.dart +++ b/test/global/activate/installs_dependencies_test.dart
@@ -8,10 +8,11 @@ void main() { test('activating a package installs its dependencies', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': 'any'}) - ..serve('bar', '1.0.0', deps: {'baz': 'any'}) - ..serve('baz', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': 'any'}); + builder.serve('bar', '1.0.0', deps: {'baz': 'any'}); + builder.serve('baz', '1.0.0'); + }); await runPub( args: ['global', 'activate', 'foo'],
diff --git a/test/global/activate/outdated_binstub_test.dart b/test/global/activate/outdated_binstub_test.dart index 6d9e298..5a5a0e6 100644 --- a/test/global/activate/outdated_binstub_test.dart +++ b/test/global/activate/outdated_binstub_test.dart
@@ -7,7 +7,7 @@ import '../../descriptor.dart' as d; import '../../test_pub.dart'; -const _outdatedBinstub = ''' +const _OUTDATED_BINSTUB = ''' #!/usr/bin/env sh # This file was created by pub v0.1.2-3. # Package: foo @@ -19,17 +19,19 @@ void main() { test('an outdated binstub is replaced', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'executables': {'foo-script': 'script'} - }, contents: [ - d.dir('bin', [d.file('script.dart', "main(args) => print('ok \$args');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'executables': {'foo-script': 'script'} + }, contents: [ + d.dir( + 'bin', [d.file('script.dart', "main(args) => print('ok \$args');")]) + ]); + }); await runPub(args: ['global', 'activate', 'foo']); await d.dir(cachePath, [ - d.dir('bin', [d.file(binStubName('foo-script'), _outdatedBinstub)]) + d.dir('bin', [d.file(binStubName('foo-script'), _OUTDATED_BINSTUB)]) ]).create(); await runPub(args: ['global', 'activate', 'foo']);
diff --git a/test/global/activate/path_package_test.dart b/test/global/activate/path_package_test.dart index 514176a..6a08e9c 100644 --- a/test/global/activate/path_package_test.dart +++ b/test/global/activate/path_package_test.dart
@@ -55,13 +55,14 @@ }); test("Doesn't precompile binaries when activating from path", () async { - final server = await servePackages(); - server.serve( - 'bar', - '1.0.0', - contents: [ - d.dir('bin', [d.file('bar.dart', "main() => print('bar');")]) - ], + await servePackages( + (builder) => builder.serve( + 'bar', + '1.0.0', + contents: [ + d.dir('bin', [d.file('bar.dart', "main() => print('bar');")]) + ], + ), ); await d.dir('foo', [
diff --git a/test/global/activate/reactivating_git_upgrades_test.dart b/test/global/activate/reactivating_git_upgrades_test.dart index 68102da..100aaea 100644 --- a/test/global/activate/reactivating_git_upgrades_test.dart +++ b/test/global/activate/reactivating_git_upgrades_test.dart
@@ -2,7 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:path/path.dart' as p; import 'package:test/test.dart'; import '../../descriptor.dart' as d; @@ -30,12 +29,11 @@ await d.git('foo.git', [d.libPubspec('foo', '1.0.1')]).commit(); // Activating it again pulls down the latest commit. - final locationUri = p.toUri(p.join(d.sandbox, 'foo.git')); await runPub( args: ['global', 'activate', '-sgit', '../foo.git'], output: allOf( startsWith('Package foo is currently active from Git repository ' - '"$locationUri".\n' + '"../foo.git".\n' 'Resolving dependencies...\n' '+ foo 1.0.1 from git ../foo.git at '), // Specific revision number goes here.
diff --git a/test/global/activate/removes_old_lockfile_test.dart b/test/global/activate/removes_old_lockfile_test.dart new file mode 100644 index 0000000..a91a153 --- /dev/null +++ b/test/global/activate/removes_old_lockfile_test.dart
@@ -0,0 +1,34 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:test/test.dart'; + +import '../../descriptor.dart' as d; +import '../../test_pub.dart'; + +void main() { + test('removes the 1.6-style lockfile', () async { + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + }); + + await d.dir(cachePath, [ + d.dir('global_packages', [ + d.file( + 'foo.lock', + 'packages: {foo: {description: foo, source: hosted, ' + 'version: "1.0.0"}}}') + ]) + ]).create(); + + await runPub(args: ['global', 'activate', 'foo']); + + await d.dir(cachePath, [ + d.dir('global_packages', [ + d.nothing('foo.lock'), + d.dir('foo', [d.file('pubspec.lock', contains('1.0.0'))]) + ]) + ]).validate(); + }); +}
diff --git a/test/global/activate/snapshots_hosted_executables_test.dart b/test/global/activate/snapshots_hosted_executables_test.dart index bc2b332..c400ec7 100644 --- a/test/global/activate/snapshots_hosted_executables_test.dart +++ b/test/global/activate/snapshots_hosted_executables_test.dart
@@ -9,15 +9,16 @@ void main() { test('snapshots the executables for a hosted package', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', contents: [ - d.dir('bin', [ - d.file('hello.dart', "void main() => print('hello!');"), - d.file('goodbye.dart', "void main() => print('goodbye!');"), - d.file('shell.sh', 'echo shell'), - d.dir('subdir', [d.file('sub.dart', "void main() => print('sub!');")]) - ]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir('bin', [ + d.file('hello.dart', "void main() => print('hello!');"), + d.file('goodbye.dart', "void main() => print('goodbye!');"), + d.file('shell.sh', 'echo shell'), + d.dir('subdir', [d.file('sub.dart', "void main() => print('sub!');")]) + ]) + ]); + }); await runPub( args: ['global', 'activate', 'foo'],
diff --git a/test/global/activate/supports_version_solver_backtracking_test.dart b/test/global/activate/supports_version_solver_backtracking_test.dart index c8c138d..7731bc6 100644 --- a/test/global/activate/supports_version_solver_backtracking_test.dart +++ b/test/global/activate/supports_version_solver_backtracking_test.dart
@@ -9,13 +9,14 @@ void main() { test('performs verison solver backtracking if necessary', () async { - await servePackages() - ..serve('foo', '1.1.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.1.0', pubspec: { 'environment': {'sdk': '>=0.1.2 <0.2.0'} - }) - ..serve('foo', '1.2.0', pubspec: { + }); + builder.serve('foo', '1.2.0', pubspec: { 'environment': {'sdk': '>=0.1.3 <0.2.0'} }); + }); await runPub(args: ['global', 'activate', 'foo']);
diff --git a/test/global/activate/uncached_package_test.dart b/test/global/activate/uncached_package_test.dart index 1a18d70..98b12af 100644 --- a/test/global/activate/uncached_package_test.dart +++ b/test/global/activate/uncached_package_test.dart
@@ -9,16 +9,17 @@ void main() { test('installs and activates the best version of a package', () async { - await servePackages() - ..serve('foo', '1.0.0', contents: [ - d.dir('bin', [d.file('foo.dart', 'main() => print("hi");')]) - ]) - ..serve('foo', '1.2.3', contents: [ - d.dir('bin', [d.file('foo.dart', 'main() => print("hi 1.2.3");')]) - ]) - ..serve('foo', '2.0.0-wildly.unstable', contents: [ - d.dir('bin', [d.file('foo.dart', 'main() => print("hi unstable");')]) + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir('bin', [d.file('foo.dart', 'main() => print("hi"); ')]) ]); + builder.serve('foo', '1.2.3', contents: [ + d.dir('bin', [d.file('foo.dart', 'main() => print("hi 1.2.3"); ')]) + ]); + builder.serve('foo', '2.0.0-wildly.unstable', contents: [ + d.dir('bin', [d.file('foo.dart', 'main() => print("hi unstable"); ')]) + ]); + }); await runPub(args: ['global', 'activate', 'foo'], output: ''' Resolving dependencies...
diff --git a/test/global/activate/unknown_package_test.dart b/test/global/activate/unknown_package_test.dart index 271545d..93a5d3a 100644 --- a/test/global/activate/unknown_package_test.dart +++ b/test/global/activate/unknown_package_test.dart
@@ -9,7 +9,7 @@ void main() { test('errors if the package could not be found', () async { - await servePackages(); + await serveNoPackages(); await runPub( args: ['global', 'activate', 'foo'],
diff --git a/test/global/binstubs/binstub_runs_executable_test.dart b/test/global/binstubs/binstub_runs_executable_test.dart index 98ab53b..c733f47 100644 --- a/test/global/binstubs/binstub_runs_executable_test.dart +++ b/test/global/binstubs/binstub_runs_executable_test.dart
@@ -12,12 +12,14 @@ void main() { test('the generated binstub runs a snapshotted executable', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'executables': {'foo-script': 'script'} - }, contents: [ - d.dir('bin', [d.file('script.dart', "main(args) => print('ok \$args');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'executables': {'foo-script': 'script'} + }, contents: [ + d.dir( + 'bin', [d.file('script.dart', "main(args) => print('ok \$args');")]) + ]); + }); await runPub(args: ['global', 'activate', 'foo']);
diff --git a/test/global/binstubs/binstub_runs_precompiled_snapshot_test.dart b/test/global/binstubs/binstub_runs_precompiled_snapshot_test.dart index cd477db..f66a251 100644 --- a/test/global/binstubs/binstub_runs_precompiled_snapshot_test.dart +++ b/test/global/binstubs/binstub_runs_precompiled_snapshot_test.dart
@@ -9,12 +9,13 @@ void main() { test('the binstubs runs a built snapshot if present', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'executables': {'foo-script': 'script'} - }, contents: [ - d.dir('bin', [d.file('script.dart', "main(args) => print('ok');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'executables': {'foo-script': 'script'} + }, contents: [ + d.dir('bin', [d.file('script.dart', "main(args) => print('ok');")]) + ]); + }); await runPub(args: ['global', 'activate', 'foo']);
diff --git a/test/global/binstubs/creates_executables_in_pubspec_test.dart b/test/global/binstubs/creates_executables_in_pubspec_test.dart index a6604ab..8fe53dc 100644 --- a/test/global/binstubs/creates_executables_in_pubspec_test.dart +++ b/test/global/binstubs/creates_executables_in_pubspec_test.dart
@@ -9,16 +9,17 @@ void main() { test('creates binstubs for each executable in the pubspec', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'executables': {'one': null, 'two-renamed': 'second'} - }, contents: [ - d.dir('bin', [ - d.file('one.dart', "main(args) => print('one');"), - d.file('second.dart', "main(args) => print('two');"), - d.file('nope.dart', "main(args) => print('nope');") - ]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'executables': {'one': null, 'two-renamed': 'second'} + }, contents: [ + d.dir('bin', [ + d.file('one.dart', "main(args) => print('one');"), + d.file('second.dart', "main(args) => print('two');"), + d.file('nope.dart', "main(args) => print('nope');") + ]) + ]); + }); await runPub( args: ['global', 'activate', 'foo'],
diff --git a/test/global/binstubs/does_not_warn_if_no_executables_test.dart b/test/global/binstubs/does_not_warn_if_no_executables_test.dart index 9814f15..b7ca722 100644 --- a/test/global/binstubs/does_not_warn_if_no_executables_test.dart +++ b/test/global/binstubs/does_not_warn_if_no_executables_test.dart
@@ -9,10 +9,12 @@ void main() { test('does not warn if the package has no executables', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', contents: [ - d.dir('bin', [d.file('script.dart', "main(args) => print('ok \$args');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir( + 'bin', [d.file('script.dart', "main(args) => print('ok \$args');")]) + ]); + }); await runPub( args: ['global', 'activate', 'foo'],
diff --git a/test/global/binstubs/does_not_warn_if_on_path_test.dart b/test/global/binstubs/does_not_warn_if_on_path_test.dart index 9b11386..fd0dfa7 100644 --- a/test/global/binstubs/does_not_warn_if_on_path_test.dart +++ b/test/global/binstubs/does_not_warn_if_on_path_test.dart
@@ -12,12 +12,14 @@ void main() { test('does not warn if the binstub directory is on the path', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'executables': {'script': null} - }, contents: [ - d.dir('bin', [d.file('script.dart', "main(args) => print('ok \$args');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'executables': {'script': null} + }, contents: [ + d.dir( + 'bin', [d.file('script.dart', "main(args) => print('ok \$args');")]) + ]); + }); // Add the test's cache bin directory to the path. var binDir = p.dirname(Platform.executable);
diff --git a/test/global/binstubs/outdated_binstub_runs_pub_global_test.dart b/test/global/binstubs/outdated_binstub_runs_pub_global_test.dart index 442dfbc..e86757c 100644 --- a/test/global/binstubs/outdated_binstub_runs_pub_global_test.dart +++ b/test/global/binstubs/outdated_binstub_runs_pub_global_test.dart
@@ -24,22 +24,23 @@ void main() { test("an outdated binstub runs 'pub global run', which replaces old binstub", () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'executables': { - 'foo-script': 'script', - 'foo-script2': 'script', - 'foo-script-not-installed': 'script', - 'foo-another-script': 'another-script', - 'foo-another-script-not-installed': 'another-script' - } - }, contents: [ - d.dir('bin', [ - d.file('script.dart', r"main(args) => print('ok $args');"), - d.file( - 'another-script.dart', r"main(args) => print('not so good $args');") - ]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'executables': { + 'foo-script': 'script', + 'foo-script2': 'script', + 'foo-script-not-installed': 'script', + 'foo-another-script': 'another-script', + 'foo-another-script-not-installed': 'another-script' + } + }, contents: [ + d.dir('bin', [ + d.file('script.dart', r"main(args) => print('ok $args');"), + d.file('another-script.dart', + r"main(args) => print('not so good $args');") + ]) + ]); + }); await runPub(args: [ 'global',
diff --git a/test/global/binstubs/outdated_snapshot_test.dart b/test/global/binstubs/outdated_snapshot_test.dart index 91bfff6..e749a5c 100644 --- a/test/global/binstubs/outdated_snapshot_test.dart +++ b/test/global/binstubs/outdated_snapshot_test.dart
@@ -13,12 +13,14 @@ void main() { test("a binstub runs 'pub global run' for an outdated snapshot", () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'executables': {'foo-script': 'script'} - }, contents: [ - d.dir('bin', [d.file('script.dart', "main(args) => print('ok \$args');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'executables': {'foo-script': 'script'} + }, contents: [ + d.dir( + 'bin', [d.file('script.dart', "main(args) => print('ok \$args');")]) + ]); + }); await runPub(args: ['global', 'activate', 'foo']);
diff --git a/test/global/binstubs/removes_when_deactivated_test.dart b/test/global/binstubs/removes_when_deactivated_test.dart index 975defe..05c8413 100644 --- a/test/global/binstubs/removes_when_deactivated_test.dart +++ b/test/global/binstubs/removes_when_deactivated_test.dart
@@ -9,15 +9,16 @@ void main() { test('removes binstubs when the package is deactivated', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'executables': {'one': null, 'two': null} - }, contents: [ - d.dir('bin', [ - d.file('one.dart', "main(args) => print('one');"), - d.file('two.dart', "main(args) => print('two');") - ]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'executables': {'one': null, 'two': null} + }, contents: [ + d.dir('bin', [ + d.file('one.dart', "main(args) => print('one');"), + d.file('two.dart', "main(args) => print('two');") + ]) + ]); + }); await runPub(args: ['global', 'activate', 'foo']); await runPub(args: ['global', 'deactivate', 'foo']);
diff --git a/test/global/binstubs/runs_once_even_when_dart_is_batch_test.dart b/test/global/binstubs/runs_once_even_when_dart_is_batch_test.dart index 99eeaaf..54f3932 100644 --- a/test/global/binstubs/runs_once_even_when_dart_is_batch_test.dart +++ b/test/global/binstubs/runs_once_even_when_dart_is_batch_test.dart
@@ -14,17 +14,18 @@ test( 'runs only once even when dart on path is a batch file (as in flutter/bin)', () async { - final server = await servePackages(); - server.serve( - 'foo', - '1.0.0', - contents: [ - d.dir('bin', [d.file('script.dart', 'main(args) => print(args);')]), - ], - pubspec: { - 'executables': {'script': 'script'}, - }, - ); + await servePackages((builder) { + builder.serve( + 'foo', + '1.0.0', + contents: [ + d.dir('bin', [d.file('script.dart', 'main(args) => print(args);')]), + ], + pubspec: { + 'executables': {'script': 'script'}, + }, + ); + }); await runPub(args: ['global', 'activate', 'foo']);
diff --git a/test/global/binstubs/warns_if_not_on_path_test.dart b/test/global/binstubs/warns_if_not_on_path_test.dart index d98bf76..d09e698 100644 --- a/test/global/binstubs/warns_if_not_on_path_test.dart +++ b/test/global/binstubs/warns_if_not_on_path_test.dart
@@ -9,12 +9,14 @@ void main() { test('warns if the binstub directory is not on the path', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'executables': {'some-dart-script': 'script'} - }, contents: [ - d.dir('bin', [d.file('script.dart', "main(args) => print('ok \$args');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'executables': {'some-dart-script': 'script'} + }, contents: [ + d.dir( + 'bin', [d.file('script.dart', "main(args) => print('ok \$args');")]) + ]); + }); await runPub( args: ['global', 'activate', 'foo'],
diff --git a/test/global/deactivate/deactivate_and_reactivate_package_test.dart b/test/global/deactivate/deactivate_and_reactivate_package_test.dart index da33486..cc7f597 100644 --- a/test/global/deactivate/deactivate_and_reactivate_package_test.dart +++ b/test/global/deactivate/deactivate_and_reactivate_package_test.dart
@@ -8,9 +8,10 @@ void main() { test('activates a different version after deactivating', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0'); + }); // Activate an old version. await runPub(args: ['global', 'activate', 'foo', '1.0.0']);
diff --git a/test/global/deactivate/git_package_test.dart b/test/global/deactivate/git_package_test.dart index 7fc2855..f06ce53 100644 --- a/test/global/deactivate/git_package_test.dart +++ b/test/global/deactivate/git_package_test.dart
@@ -2,7 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:path/path.dart' as p; import 'package:test/test.dart'; import '../../descriptor.dart' as d; @@ -19,10 +18,9 @@ await runPub(args: ['global', 'activate', '-sgit', '../foo.git']); - final locationUri = p.toUri(p.join(d.sandbox, 'foo.git')); await runPub( args: ['global', 'deactivate', 'foo'], output: - 'Deactivated package foo 1.0.0 from Git repository "$locationUri".'); + 'Deactivated package foo 1.0.0 from Git repository "../foo.git".'); }); }
diff --git a/test/global/deactivate/hosted_package_test.dart b/test/global/deactivate/hosted_package_test.dart index fa91829..854d6a9 100644 --- a/test/global/deactivate/hosted_package_test.dart +++ b/test/global/deactivate/hosted_package_test.dart
@@ -8,8 +8,7 @@ void main() { test('deactivates an active hosted package', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((builder) => builder.serve('foo', '1.0.0')); await runPub(args: ['global', 'activate', 'foo']);
diff --git a/test/global/deactivate/removes_precompiled_snapshots_test.dart b/test/global/deactivate/removes_precompiled_snapshots_test.dart index a7670e2..7ea6d58 100644 --- a/test/global/deactivate/removes_precompiled_snapshots_test.dart +++ b/test/global/deactivate/removes_precompiled_snapshots_test.dart
@@ -9,8 +9,7 @@ void main() { test('removes built snapshots', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((builder) => builder.serve('foo', '1.0.0')); await runPub(args: ['global', 'activate', 'foo']);
diff --git a/test/global/deactivate/unknown_package_test.dart b/test/global/deactivate/unknown_package_test.dart index 35023ad..d67460d 100644 --- a/test/global/deactivate/unknown_package_test.dart +++ b/test/global/deactivate/unknown_package_test.dart
@@ -9,7 +9,7 @@ void main() { test('errors if the package is not activated', () async { - await servePackages(); + await serveNoPackages(); await runPub( args: ['global', 'deactivate', 'foo'],
diff --git a/test/global/list_test.dart b/test/global/list_test.dart index 00ca22c..4b50184 100644 --- a/test/global/list_test.dart +++ b/test/global/list_test.dart
@@ -12,8 +12,9 @@ void main() { test('lists an activated hosted package', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + }); await runPub(args: ['global', 'activate', 'foo']); @@ -30,10 +31,9 @@ await runPub(args: ['global', 'activate', '-sgit', '../foo.git']); - final locationUri = p.toUri(p.join(d.sandbox, 'foo.git')); await runPub( args: ['global', 'list'], - output: 'foo 1.0.0 from Git repository "$locationUri"'); + output: 'foo 1.0.0 from Git repository "../foo.git"'); }); test('lists an activated Path package', () async { @@ -49,10 +49,11 @@ }); test('lists activated packages in alphabetical order', () async { - await servePackages() - ..serve('aaa', '1.0.0') - ..serve('bbb', '1.0.0') - ..serve('ccc', '1.0.0'); + await servePackages((builder) { + builder.serve('aaa', '1.0.0'); + builder.serve('bbb', '1.0.0'); + builder.serve('ccc', '1.0.0'); + }); await runPub(args: ['global', 'activate', 'ccc']); await runPub(args: ['global', 'activate', 'aaa']);
diff --git a/test/global/run/errors_if_outside_bin_test.dart b/test/global/run/errors_if_outside_bin_test.dart index 72bcd4f..098f0bb 100644 --- a/test/global/run/errors_if_outside_bin_test.dart +++ b/test/global/run/errors_if_outside_bin_test.dart
@@ -10,10 +10,11 @@ void main() { test('errors if the script is in a subdirectory.', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', contents: [ - d.dir('example', [d.file('script.dart', "main(args) => print('ok');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir('example', [d.file('script.dart', "main(args) => print('ok');")]) + ]); + }); await runPub(args: ['global', 'activate', 'foo']); await runPub(
diff --git a/test/global/run/fails_if_sdk_constraint_is_unmet_test.dart b/test/global/run/fails_if_sdk_constraint_is_unmet_test.dart index 3bef340..08adbcc 100644 --- a/test/global/run/fails_if_sdk_constraint_is_unmet_test.dart +++ b/test/global/run/fails_if_sdk_constraint_is_unmet_test.dart
@@ -10,10 +10,11 @@ void main() { test("fails if the current SDK doesn't match the constraint", () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', contents: [ - d.dir('bin', [d.file('script.dart', "main(args) => print('ok');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir('bin', [d.file('script.dart', "main(args) => print('ok');")]) + ]); + }); await runPub(args: ['global', 'activate', 'foo']); @@ -40,14 +41,15 @@ }); test('fails if SDK is downgraded below the constraints', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'environment': { - 'sdk': '>=2.0.0 <3.0.0', - }, - }, contents: [ - d.dir('bin', [d.file('script.dart', "main(args) => print('123-OK');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'environment': { + 'sdk': '>=2.0.0 <3.0.0', + }, + }, contents: [ + d.dir('bin', [d.file('script.dart', "main(args) => print('123-OK');")]) + ]); + }); await runPub( environment: {'_PUB_TEST_SDK_VERSION': '2.0.0'}, @@ -67,8 +69,8 @@ }); test('fails if SDK is downgraded below dependency SDK constraints', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: { 'bar': '^1.0.0', }, pubspec: { 'environment': { @@ -76,12 +78,13 @@ }, }, contents: [ d.dir('bin', [d.file('script.dart', "main(args) => print('123-OK');")]) - ]) - ..serve('bar', '1.0.0', pubspec: { + ]); + builder.serve('bar', '1.0.0', pubspec: { 'environment': { 'sdk': '>=2.2.0 <3.0.0', }, }); + }); await runPub( environment: {'_PUB_TEST_SDK_VERSION': '2.2.0'},
diff --git a/test/global/run/implicit_executable_name_test.dart b/test/global/run/implicit_executable_name_test.dart index 9757772..fa7bf51 100644 --- a/test/global/run/implicit_executable_name_test.dart +++ b/test/global/run/implicit_executable_name_test.dart
@@ -9,10 +9,11 @@ void main() { test('defaults to the package name if the script is omitted', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', contents: [ - d.dir('bin', [d.file('foo.dart', "main(args) => print('foo');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir('bin', [d.file('foo.dart', "main(args) => print('foo');")]) + ]); + }); await runPub(args: ['global', 'activate', 'foo']);
diff --git a/test/global/run/nonexistent_script_test.dart b/test/global/run/nonexistent_script_test.dart index 8ff0a42..d4f9577 100644 --- a/test/global/run/nonexistent_script_test.dart +++ b/test/global/run/nonexistent_script_test.dart
@@ -10,10 +10,9 @@ void main() { test('errors if the script does not exist.', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'dev_dependencies': {'bar': '1.0.0'} - }); + await servePackages((builder) => builder.serve('foo', '1.0.0', pubspec: { + 'dev_dependencies': {'bar': '1.0.0'} + })); await runPub(args: ['global', 'activate', 'foo']);
diff --git a/test/global/run/package_api_test.dart b/test/global/run/package_api_test.dart index 5db401b..4ce34ee 100644 --- a/test/global/run/package_api_test.dart +++ b/test/global/run/package_api_test.dart
@@ -10,9 +10,10 @@ void main() { test('an immutable application sees a file: package config', () async { - await servePackages() - ..serve('bar', '1.0.0') - ..serve('foo', '1.0.0', deps: { + await servePackages((builder) { + builder.serve('bar', '1.0.0'); + + builder.serve('foo', '1.0.0', deps: { 'bar': '1.0.0' }, contents: [ d.dir('bin', [ @@ -30,6 +31,7 @@ """) ]) ]); + }); await runPub(args: ['global', 'activate', 'foo']); @@ -41,12 +43,12 @@ 'global_packages/foo/.dart_tool/package_config.json'); expect(pub.stdout, emits(p.toUri(packageConfigPath).toString())); - var fooResourcePath = - p.join(globalServer.pathInCache('foo', '1.0.0'), 'lib/resource.txt'); + var fooResourcePath = p.join( + globalPackageServer!.pathInCache('foo', '1.0.0'), 'lib/resource.txt'); expect(pub.stdout, emits(p.toUri(fooResourcePath).toString())); - var barResourcePath = - p.join(globalServer.pathInCache('bar', '1.0.0'), 'lib/resource.txt'); + var barResourcePath = p.join( + globalPackageServer!.pathInCache('bar', '1.0.0'), 'lib/resource.txt'); expect(pub.stdout, emits(p.toUri(barResourcePath).toString())); await pub.shouldExit(0); });
diff --git a/test/global/run/recompiles_if_snapshot_is_out_of_date_test.dart b/test/global/run/recompiles_if_snapshot_is_out_of_date_test.dart index 24e65bf..97c69f2 100644 --- a/test/global/run/recompiles_if_snapshot_is_out_of_date_test.dart +++ b/test/global/run/recompiles_if_snapshot_is_out_of_date_test.dart
@@ -11,10 +11,11 @@ void main() { test('recompiles a script if the snapshot is out-of-date', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', contents: [ - d.dir('bin', [d.file('script.dart', "main(args) => print('ok');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir('bin', [d.file('script.dart', "main(args) => print('ok');")]) + ]); + }); await runPub(args: ['global', 'activate', 'foo']);
diff --git a/test/global/run/runs_script_in_checked_mode_test.dart b/test/global/run/runs_script_in_checked_mode_test.dart index d0511cf..69cd393 100644 --- a/test/global/run/runs_script_in_checked_mode_test.dart +++ b/test/global/run/runs_script_in_checked_mode_test.dart
@@ -9,10 +9,11 @@ void main() { test('runs a script with assertions enabled', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', contents: [ - d.dir('bin', [d.file('script.dart', 'main() { assert(false); }')]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir('bin', [d.file('script.dart', 'main() { assert(false); }')]) + ]); + }); await runPub(args: ['global', 'activate', 'foo']);
diff --git a/test/global/run/runs_script_in_unchecked_mode_test.dart b/test/global/run/runs_script_in_unchecked_mode_test.dart index ca752b2..d684c27 100644 --- a/test/global/run/runs_script_in_unchecked_mode_test.dart +++ b/test/global/run/runs_script_in_unchecked_mode_test.dart
@@ -7,7 +7,7 @@ import '../../descriptor.dart' as d; import '../../test_pub.dart'; -const _script = ''' +const SCRIPT = ''' main() { assert(false); print("no checks"); @@ -16,10 +16,11 @@ void main() { test('runs a script in unchecked mode by default', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', contents: [ - d.dir('bin', [d.file('script.dart', _script)]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir('bin', [d.file('script.dart', SCRIPT)]) + ]); + }); await runPub(args: ['global', 'activate', 'foo']);
diff --git a/test/global/run/runs_script_test.dart b/test/global/run/runs_script_test.dart index f3f0e99..fe767ef 100644 --- a/test/global/run/runs_script_test.dart +++ b/test/global/run/runs_script_test.dart
@@ -9,10 +9,11 @@ void main() { test('runs a script in an activated package', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', contents: [ - d.dir('bin', [d.file('script.dart', "main(args) => print('ok');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir('bin', [d.file('script.dart', "main(args) => print('ok');")]) + ]); + }); await runPub(args: ['global', 'activate', 'foo']);
diff --git a/test/global/run/runs_script_without_packages_file_test.dart b/test/global/run/runs_script_without_packages_file_test.dart index dc225ba..cb63be2 100644 --- a/test/global/run/runs_script_without_packages_file_test.dart +++ b/test/global/run/runs_script_without_packages_file_test.dart
@@ -12,10 +12,11 @@ void main() { test('runs a snapshotted script without a .dart_tool/package_config file', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', contents: [ - d.dir('bin', [d.file('script.dart', "main(args) => print('ok');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir('bin', [d.file('script.dart', "main(args) => print('ok');")]) + ]); + }); await runPub(args: ['global', 'activate', 'foo']);
diff --git a/test/global/run/unknown_package_test.dart b/test/global/run/unknown_package_test.dart index adcb666..a5fba21 100644 --- a/test/global/run/unknown_package_test.dart +++ b/test/global/run/unknown_package_test.dart
@@ -9,7 +9,7 @@ void main() { test('errors if the package is not activated', () async { - await servePackages(); + await serveNoPackages(); await runPub( args: ['global', 'run', 'foo:bar'],
diff --git a/test/global/run/uses_old_lockfile_test.dart b/test/global/run/uses_old_lockfile_test.dart new file mode 100644 index 0000000..5eb8406 --- /dev/null +++ b/test/global/run/uses_old_lockfile_test.dart
@@ -0,0 +1,55 @@ +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:test/test.dart'; + +import '../../descriptor.dart' as d; +import '../../test_pub.dart'; + +void main() { + test('uses the 1.6-style lockfile if necessary', () async { + await servePackages((builder) { + builder.serve('bar', '1.0.0'); + builder.serve('foo', '1.0.0', deps: { + 'bar': 'any' + }, contents: [ + d.dir('bin', [ + d.file('script.dart', """ + import 'package:bar/bar.dart' as bar; + + main(args) => print(bar.main());""") + ]) + ]); + }); + + await runPub(args: ['cache', 'add', 'foo']); + await runPub(args: ['cache', 'add', 'bar']); + + await d.dir(cachePath, [ + d.dir('global_packages', [ + d.file('foo.lock', ''' +packages: + foo: + description: foo + source: hosted + version: "1.0.0" + bar: + description: bar + source: hosted + version: "1.0.0"''') + ]) + ]).create(); + + var pub = await pubRun(global: true, args: ['foo:script']); + expect(pub.stdout, emitsThrough('bar 1.0.0')); + await pub.shouldExit(); + + await d.dir(cachePath, [ + d.dir('global_packages', [ + d.nothing('foo.lock'), + d.dir('foo', [d.file('pubspec.lock', contains('1.0.0'))]) + ]) + ]).validate(); + }); +}
diff --git a/test/hosted/fail_gracefully_on_bad_version_listing_response_test.dart b/test/hosted/fail_gracefully_on_bad_version_listing_response_test.dart index 7fb22a3..be875a2 100644 --- a/test/hosted/fail_gracefully_on_bad_version_listing_response_test.dart +++ b/test/hosted/fail_gracefully_on_bad_version_listing_response_test.dart
@@ -9,7 +9,6 @@ import 'package:test/test.dart'; import '../descriptor.dart' as d; -import '../golden_file.dart'; import '../test_pub.dart'; void main() { @@ -17,18 +16,15 @@ test( 'fails gracefully if the package server responds with broken package listings', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); - server.expect( - 'GET', - RegExp('/api/packages/.*'), - expectAsync1((request) { - return Response(200, - body: jsonEncode({ - 'notTheRight': {'response': 'type'} - })); - }), - ); + await servePackages((b) => b..serve('foo', '1.2.3')); + globalPackageServer!.extraHandlers[RegExp('/api/packages/.*')] = + expectAsync1((request) { + expect(request.method, 'GET'); + return Response(200, + body: jsonEncode({ + 'notTheRight': {'response': 'type'} + })); + }); await d.appDir({'foo': '1.2.3'}).create(); await pubCommand(command, @@ -40,80 +36,4 @@ exitCode: exit_codes.DATA); }); }); - - testWithGolden('bad_json', (ctx) async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); - server.expect('GET', RegExp('/api/packages/.*'), (request) { - return Response(200, - body: jsonEncode({ - 'notTheRight': {'response': 'type'} - })); - }); - await d.appDir({'foo': '1.2.3'}).create(); - - await ctx.run(['get']); - }); - - testWithGolden('403', (ctx) async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); - server.expect('GET', RegExp('/api/packages/.*'), (request) { - return Response(403, - body: jsonEncode({ - 'notTheRight': {'response': 'type'} - })); - }); - await d.appDir({'foo': '1.2.3'}).create(); - - await ctx.run(['get']); - }); - - testWithGolden('401', (ctx) async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); - server.expect('GET', RegExp('/api/packages/.*'), (request) { - return Response(401, - body: jsonEncode({ - 'notTheRight': {'response': 'type'} - })); - }); - await d.appDir({'foo': '1.2.3'}).create(); - - await ctx.run(['get']); - }); - - testWithGolden('403-with-message', (ctx) async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); - server.expect('GET', RegExp('/api/packages/.*'), (request) { - return Response(403, - headers: { - 'www-authenticate': 'Bearer realm="pub", message="<message>"', - }, - body: jsonEncode({ - 'notTheRight': {'response': 'type'} - })); - }); - await d.appDir({'foo': '1.2.3'}).create(); - - await ctx.run(['get']); - }); - - testWithGolden('401-with-message', (ctx) async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); - server.expect('GET', RegExp('/api/packages/.*'), (request) { - return Response(401, - headers: { - 'www-authenticate': 'Bearer realm="pub", message="<message>"', - }, - body: jsonEncode({ - 'notTheRight': {'response': 'type'} - })); - }); - await d.appDir({'foo': '1.2.3'}).create(); - - await ctx.run(['get']); - }); }
diff --git a/test/hosted/fail_gracefully_on_missing_package_test.dart b/test/hosted/fail_gracefully_on_missing_package_test.dart index 7c6290d..1840f18 100644 --- a/test/hosted/fail_gracefully_on_missing_package_test.dart +++ b/test/hosted/fail_gracefully_on_missing_package_test.dart
@@ -11,7 +11,7 @@ void main() { forBothPubGetAndUpgrade((command) { test('fails gracefully if the package does not exist', () async { - await servePackages(); + await serveNoPackages(); await d.appDir({'foo': '1.2.3'}).create();
diff --git a/test/hosted/fail_gracefully_with_hint_test.dart b/test/hosted/fail_gracefully_with_hint_test.dart deleted file mode 100644 index 4f1a326..0000000 --- a/test/hosted/fail_gracefully_with_hint_test.dart +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:pub/src/exit_codes.dart' as exit_codes; -import 'package:test/test.dart'; - -import '../descriptor.dart' as d; -import '../golden_file.dart'; -import '../test_pub.dart'; - -void main() { - testWithGolden('hint: try without --offline', (ctx) async { - // Run the server so that we know what URL to use in the system cache. - (await servePackages()).serveErrors(); - - await d.appDir({'foo': 'any'}).create(); - - await pubGet( - args: ['--offline'], - exitCode: exit_codes.UNAVAILABLE, - error: contains('Try again without --offline!'), - ); - }); - - testWithGolden('supports two hints', (ctx) async { - // Run the server so that we know what URL to use in the system cache. - (await servePackages()).serveErrors(); - - await d.hostedCache([ - d.dir('foo-1.2.3', [ - d.pubspec({ - 'name': 'foo', - 'version': '1.2.3', - 'environment': { - 'flutter': 'any', // generates hint -> flutter pub get - }, - }), - ]), - d.dir('foo-1.2.4', [ - d.pubspec({ - 'name': 'foo', - 'version': '1.2.4', - 'dependencies': { - 'bar': 'any', // generates hint -> try without --offline - }, - }), - ]), - ]).create(); - - await d.appDir({'foo': 'any'}).create(); - - await pubGet( - args: ['--offline'], - exitCode: exit_codes.UNAVAILABLE, - error: allOf( - contains('Try again without --offline!'), - contains('flutter pub get'), // hint that - ), - ); - - await ctx.run(['get', '--offline']); - }); -}
diff --git a/test/hosted/metadata_test.dart b/test/hosted/metadata_test.dart index c705ac7..7554a0f 100644 --- a/test/hosted/metadata_test.dart +++ b/test/hosted/metadata_test.dart
@@ -12,8 +12,9 @@ void main() { forBothPubGetAndUpgrade((command) { test('sends metadata headers for a direct dependency', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + }); await d.appDir({'foo': '1.0.0'}).create(); @@ -32,8 +33,9 @@ }); test('sends metadata headers for a dev dependency', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -57,8 +59,9 @@ }); test('sends metadata headers for a transitive dependency', () async { - final server = await servePackages(); - server.serve('bar', '1.0.0'); + await servePackages((builder) { + builder.serve('bar', '1.0.0'); + }); await d.appDir({ 'foo': {'path': '../foo'} @@ -79,8 +82,9 @@ }); test("doesn't send metadata headers to a foreign server", () async { - var server = await startPackageServer() - ..serve('foo', '1.0.0'); + var server = await PackageServer.start((builder) { + builder.serve('foo', '1.0.0'); + }); await d.appDir({ 'foo': { @@ -93,7 +97,9 @@ }); test("doesn't send metadata headers when CI=true", () async { - (await servePackages()).serve('foo', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + }); await d.appDir({'foo': '1.0.0'}).create();
diff --git a/test/hosted/offline_test.dart b/test/hosted/offline_test.dart index ca3dc80..713ea3f 100644 --- a/test/hosted/offline_test.dart +++ b/test/hosted/offline_test.dart
@@ -8,13 +8,14 @@ import '../descriptor.dart' as d; import '../test_pub.dart'; -Future<void> populateCache( - Map<String, List<String>> versions, PackageServer server) async { - for (final entry in versions.entries) { - for (final version in entry.value) { - server.serve(entry.key, version); +Future<void> populateCache(Map<String, List<String>> versions) async { + await servePackages((b) { + for (final entry in versions.entries) { + for (final version in entry.value) { + b.serve(entry.key, version); + } } - } + }); for (final entry in versions.entries) { for (final version in entry.value) { await d.appDir({entry.key: version}).create(); @@ -26,14 +27,13 @@ void main() { forBothPubGetAndUpgrade((command) { test('upgrades a package using the cache', () async { - final server = await servePackages(); await populateCache({ 'foo': ['1.2.2', '1.2.3'], 'bar': ['1.2.3'] - }, server); + }); // Now serve only errors - to validate we are truly offline. - server.serveErrors(); + await serveErrors(); await d.appDir({'foo': 'any', 'bar': 'any'}).create(); @@ -44,19 +44,16 @@ } await pubCommand(command, args: ['--offline'], warning: warning); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - d.packageConfigEntry(name: 'bar', version: '1.2.3'), - ]).validate(); + + await d.appPackagesFile({'foo': '1.2.3', 'bar': '1.2.3'}).validate(); }); test('supports prerelease versions', () async { - final server = await servePackages(); await populateCache({ 'foo': ['1.2.3-alpha.1'] - }, server); + }); // Now serve only errors - to validate we are truly offline. - server.serveErrors(); + await serveErrors(); await d.appDir({'foo': 'any'}).create(); @@ -68,15 +65,12 @@ await pubCommand(command, args: ['--offline'], warning: warning); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3-alpha.1'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3-alpha.1'}).validate(); }); test('fails gracefully if a dependency is not cached', () async { // Run the server so that we know what URL to use in the system cache. - final server = await servePackages(); - server.serveErrors(); + await serveErrors(); await d.appDir({'foo': 'any'}).create(); @@ -86,19 +80,16 @@ error: equalsIgnoringWhitespace(""" Because myapp depends on foo any which doesn't exist (could not find package foo in cache), version solving failed. - - Try again without --offline! """)); }); test('fails gracefully if no cached versions match', () async { - final server = await servePackages(); await populateCache({ 'foo': ['1.2.2', '1.2.3'] - }, server); + }); // Run the server so that we know what URL to use in the system cache. - server.serveErrors(); + await serveErrors(); await d.appDir({'foo': '>2.0.0'}).create(); @@ -112,10 +103,8 @@ test( 'fails gracefully if a dependency is not cached and a lockfile ' 'exists', () async { - final server = await servePackages(); - // Run the server so that we know what URL to use in the system cache. - server.serveErrors(); + await serveErrors(); await d.appDir({'foo': 'any'}).create(); @@ -127,19 +116,15 @@ error: equalsIgnoringWhitespace(""" Because myapp depends on foo any which doesn't exist (could not find package foo in cache), version solving failed. - - Try again without --offline! """)); }); test('downgrades to the version in the cache if necessary', () async { - final server = await servePackages(); - await populateCache({ 'foo': ['1.2.2', '1.2.3'] - }, server); + }); // Run the server so that we know what URL to use in the system cache. - server.serveErrors(); + await serveErrors(); await d.appDir({'foo': 'any'}).create(); @@ -147,19 +132,15 @@ await pubCommand(command, args: ['--offline']); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.3'}).validate(); }); test('skips invalid cached versions', () async { - final server = await servePackages(); - await populateCache({ 'foo': ['1.2.2', '1.2.3'] - }, server); + }); // Run the server so that we know what URL to use in the system cache. - server.serveErrors(); + await serveErrors(); await d.hostedCache([ d.dir('foo-1.2.3', [d.file('pubspec.yaml', '{')]), @@ -170,19 +151,15 @@ await pubCommand(command, args: ['--offline']); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.2'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.2'}).validate(); }); test('skips invalid locked versions', () async { - final server = await servePackages(); - await populateCache({ 'foo': ['1.2.2', '1.2.3'] - }, server); + }); // Run the server so that we know what URL to use in the system cache. - server.serveErrors(); + await serveErrors(); await d.hostedCache([ d.dir('foo-1.2.3', [d.file('pubspec.yaml', '{')]) @@ -194,9 +171,7 @@ await pubCommand(command, args: ['--offline']); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.2.2'), - ]).validate(); + await d.appPackagesFile({'foo': '1.2.2'}).validate(); }); }); }
diff --git a/test/hosted/remove_removed_dependency_test.dart b/test/hosted/remove_removed_dependency_test.dart index a0446c0..d326384 100644 --- a/test/hosted/remove_removed_dependency_test.dart +++ b/test/hosted/remove_removed_dependency_test.dart
@@ -10,25 +10,22 @@ void main() { forBothPubGetAndUpgrade((command) { test("removes a dependency that's removed from the pubspec", () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('bar', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('bar', '1.0.0'); + }); await d.appDir({'foo': 'any', 'bar': 'any'}).create(); await pubCommand(command); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), - ]).validate(); + + await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.0.0'}).validate(); await d.appDir({'foo': 'any'}).create(); await pubCommand(command); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0'}).validate(); }); }); }
diff --git a/test/hosted/remove_removed_transitive_dependency_test.dart b/test/hosted/remove_removed_transitive_dependency_test.dart index 182ec3f..50702d7 100644 --- a/test/hosted/remove_removed_transitive_dependency_test.dart +++ b/test/hosted/remove_removed_transitive_dependency_test.dart
@@ -12,30 +12,31 @@ test( "removes a transitive dependency that's no longer depended " 'on', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'shared_dep': 'any'}) - ..serve('bar', '1.0.0', deps: {'shared_dep': 'any', 'bar_dep': 'any'}) - ..serve('shared_dep', '1.0.0') - ..serve('bar_dep', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'shared_dep': 'any'}); + builder.serve('bar', '1.0.0', + deps: {'shared_dep': 'any', 'bar_dep': 'any'}); + builder.serve('shared_dep', '1.0.0'); + builder.serve('bar_dep', '1.0.0'); + }); await d.appDir({'foo': 'any', 'bar': 'any'}).create(); await pubCommand(command); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), - d.packageConfigEntry(name: 'shared_dep', version: '1.0.0'), - d.packageConfigEntry(name: 'bar_dep', version: '1.0.0'), - ]).validate(); + + await d.appPackagesFile({ + 'foo': '1.0.0', + 'bar': '1.0.0', + 'shared_dep': '1.0.0', + 'bar_dep': '1.0.0', + }).validate(); await d.appDir({'foo': 'any'}).create(); await pubCommand(command); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'shared_dep', version: '1.0.0'), - ]).validate(); + await d + .appPackagesFile({'foo': '1.0.0', 'shared_dep': '1.0.0'}).validate(); }); }); }
diff --git a/test/hosted/short_syntax_test.dart b/test/hosted/short_syntax_test.dart index 5d4cf28..70738a9 100644 --- a/test/hosted/short_syntax_test.dart +++ b/test/hosted/short_syntax_test.dart
@@ -12,12 +12,10 @@ import '../test_pub.dart'; void main() { - setUp(() async { - final server = await servePackages(); - server.serve('foo', '1.2.3', pubspec: { - 'environment': {'sdk': '^2.0.0'} - }); - }); + setUp(() => servePackages((b) => b.serve('foo', '1.2.3', pubspec: { + 'environment': {'sdk': '^2.0.0'} + }))); + forBothPubGetAndUpgrade((command) { Future<void> testWith(dynamic dependency) async { await d.dir(appPath, [ @@ -44,19 +42,19 @@ 'source': 'hosted', 'description': { 'name': 'foo', - 'url': globalServer.url, + 'url': globalPackageServer!.url, }, 'version': '1.2.3', }); } test('supports hosted: <url> syntax', () async { - return testWith({'hosted': globalServer.url}); + return testWith({'hosted': globalPackageServer!.url}); }); test('supports hosted map without name', () { return testWith({ - 'hosted': {'url': globalServer.url}, + 'hosted': {'url': globalPackageServer!.url}, }); }); @@ -82,8 +80,8 @@ await File(p.join(d.sandbox, appPath, 'pubspec.lock')).readAsString(), ); - expect( - lockFile['packages']['foo']['description']['url'], globalServer.url); + expect(lockFile['packages']['foo']['description']['url'], + globalPackageServer!.url); }); }); }
diff --git a/test/hosted/version_negotiation_test.dart b/test/hosted/version_negotiation_test.dart index 44dbe7a..ff491cd 100644 --- a/test/hosted/version_negotiation_test.dart +++ b/test/hosted/version_negotiation_test.dart
@@ -16,11 +16,11 @@ await d.appDir({ 'foo': { - 'hosted': {'name': 'foo', 'url': globalServer.url} + 'hosted': {'name': 'foo', 'url': globalPackageServer!.url} } }).create(); - globalServer.expect('GET', '/api/packages/foo', (request) { + globalPackageServer!.expect('GET', '/api/packages/foo', (request) { expect( request.headers['accept'], equals('application/vnd.pub.v2+json')); return shelf.Response(404); @@ -35,14 +35,14 @@ await d.appDir({ 'foo': { - 'hosted': {'name': 'foo', 'url': globalServer.url} + 'hosted': {'name': 'foo', 'url': globalPackageServer!.url} } }).create(); var pub = await startPub(args: [command.name]); - globalServer.expect( - 'GET', '/api/packages/foo', (request) => shelf.Response(406)); + globalPackageServer! + .expect('GET', '/api/packages/foo', (request) => shelf.Response(406)); await pub.shouldExit(1);
diff --git a/test/hosted/will_normalize_hosted_url_test.dart b/test/hosted/will_normalize_hosted_url_test.dart index 6cc3888..38bc574 100644 --- a/test/hosted/will_normalize_hosted_url_test.dart +++ b/test/hosted/will_normalize_hosted_url_test.dart
@@ -13,50 +13,47 @@ void main() { forBothPubGetAndUpgrade((command) { test('does not require slash on bare domain', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); - // All the tests in this file assumes that [globalServer.url] + await servePackages((b) => b..serve('foo', '1.2.3')); + // All the tests in this file assumes that [globalPackageServer.url] // will be on the form: // http://localhost:<port> // In particular, that it doesn't contain anything path segment. - expect(Uri.parse(globalServer.url).path, isEmpty); + expect(Uri.parse(globalPackageServer!.url).path, isEmpty); await d.dir(appPath, [ d.appPubspec({ 'foo': { - 'hosted': {'name': 'foo', 'url': globalServer.url}, + 'hosted': {'name': 'foo', 'url': globalPackageServer!.url}, }, }), ]).create(); await pubCommand( command, - silent: contains('${globalServer.url}/api/packages/foo'), + silent: contains('${globalPackageServer!.url}/api/packages/foo'), ); }); test('normalizes extra slash', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((b) => b..serve('foo', '1.2.3')); await d.dir(appPath, [ d.appPubspec({ 'foo': { - 'hosted': {'name': 'foo', 'url': globalServer.url + '/'}, + 'hosted': {'name': 'foo', 'url': globalPackageServer!.url + '/'}, }, }), ]).create(); await pubCommand( command, - silent: contains('${globalServer.url}/api/packages/foo'), + silent: contains('${globalPackageServer!.url}/api/packages/foo'), ); }); test('cannot normalize double slash', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); - globalServer.expect( + await servePackages((b) => b..serve('foo', '1.2.3')); + globalPackageServer!.expect( 'GET', '//api/packages/foo', (request) => Response.notFound(''), @@ -65,14 +62,15 @@ await d.dir(appPath, [ d.appPubspec({ 'foo': { - 'hosted': {'name': 'foo', 'url': globalServer.url + '//'}, + 'hosted': {'name': 'foo', 'url': globalPackageServer!.url + '//'}, }, }), ]).create(); await pubCommand( command, - error: contains('could not find package foo at ${globalServer.url}//'), + error: contains( + 'could not find package foo at ${globalPackageServer!.url}//'), exitCode: exit_codes.UNAVAILABLE, ); }); @@ -82,31 +80,27 @@ /// This is a bit of a hack, to easily test if hosted pub URLs with a path /// segment works and if the slashes are normalized. void _proxyMyFolderToRoot() { - globalServer.handle( - RegExp('/my-folder/.*'), - (r) async { - if (r.method != 'GET' && r.method != 'HEAD') { - return Response.forbidden(null); - } - final path = r.requestedUri.path.substring('/my-folder/'.length); - final res = await http.get( - Uri.parse(globalServer.url + '/$path'), - ); - return Response(res.statusCode, body: res.bodyBytes, headers: { - 'Content-Type': res.headers['content-type']!, - }); - }, - ); + globalPackageServer!.extraHandlers[RegExp('/my-folder/.*')] = (r) async { + if (r.method != 'GET' && r.method != 'HEAD') { + return Response.forbidden(null); + } + final path = r.requestedUri.path.substring('/my-folder/'.length); + final res = await http.get( + Uri.parse(globalPackageServer!.url + '/$path'), + ); + return Response(res.statusCode, body: res.bodyBytes, headers: { + 'content-type': res.headers['content-type']!, + }); + }; } test('will use normalized url with path', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((b) => b..serve('foo', '1.2.3')); _proxyMyFolderToRoot(); // testing with a normalized URL - final testUrl = globalServer.url + '/my-folder/'; - final normalizedUrl = globalServer.url + '/my-folder/'; + final testUrl = globalPackageServer!.url + '/my-folder/'; + final normalizedUrl = globalPackageServer!.url + '/my-folder/'; await d.dir(appPath, [ d.appPubspec({ @@ -124,13 +118,12 @@ }); test('will normalize url with path by adding slash', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((b) => b..serve('foo', '1.2.3')); _proxyMyFolderToRoot(); // Testing with a URL that is missing the slash. - final testUrl = globalServer.url + '/my-folder'; - final normalizedUrl = globalServer.url + '/my-folder/'; + final testUrl = globalPackageServer!.url + '/my-folder'; + final normalizedUrl = globalPackageServer!.url + '/my-folder/'; await d.dir(appPath, [ d.appPubspec({
diff --git a/test/ignore_test.dart b/test/ignore_test.dart index a8ab8ac..42a189a 100644 --- a/test/ignore_test.dart +++ b/test/ignore_test.dart
@@ -977,13 +977,6 @@ 'folder/a.txt': true, }), - TestData('folder/* does not ignore `folder` itself', { - '.': ['folder/*', '!folder/a.txt'], - }, { - 'folder/a.txt': false, - 'folder/b.txt': true, - }), - // Case sensitivity TestData( 'simple',
diff --git a/test/lish/archives_and_uploads_a_package_test.dart b/test/lish/archives_and_uploads_a_package_test.dart index 88e4862..0fffb5a 100644 --- a/test/lish/archives_and_uploads_a_package_test.dart +++ b/test/lish/archives_and_uploads_a_package_test.dart
@@ -19,44 +19,14 @@ test('archives and uploads a package', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); - handleUploadForm(globalServer); - handleUpload(globalServer); + handleUploadForm(globalPackageServer!); + handleUpload(globalPackageServer!); - globalServer.expect('GET', '/create', (request) { - return shelf.Response.ok(jsonEncode({ - 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} - })); - }); - - expect(pub.stdout, emits(startsWith('Uploading...'))); - expect(pub.stdout, emits('Package test_pkg 1.0.0 uploaded!')); - await pub.shouldExit(exit_codes.SUCCESS); - }); - - test('publishes to hosted-url with path', () async { - await servePackages(); - await d.tokensFile({ - 'version': 1, - 'hosted': [ - {'url': globalServer.url + '/sub/folder', 'env': 'TOKEN'}, - ] - }).create(); - var pub = await startPublish( - globalServer, - path: '/sub/folder', - authMethod: 'token', - environment: {'TOKEN': 'access token'}, - ); - - await confirmPublish(pub); - handleUploadForm(globalServer, path: '/sub/folder'); - handleUpload(globalServer); - - globalServer.expect('GET', '/create', (request) { + globalPackageServer!.expect('GET', '/create', (request) { return shelf.Response.ok(jsonEncode({ 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} })); @@ -83,14 +53,14 @@ await d.dir(p.join(appPath, 'empty')).create(); await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); - handleUploadForm(globalServer); - handleUpload(globalServer); + handleUploadForm(globalPackageServer!); + handleUpload(globalPackageServer!); - globalServer.expect('GET', '/create', (request) { + globalPackageServer!.expect('GET', '/create', (request) { return shelf.Response.ok(jsonEncode({ 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} }));
diff --git a/test/lish/cloud_storage_upload_doesnt_redirect_test.dart b/test/lish/cloud_storage_upload_doesnt_redirect_test.dart index 0f792d5..e4489e4 100644 --- a/test/lish/cloud_storage_upload_doesnt_redirect_test.dart +++ b/test/lish/cloud_storage_upload_doesnt_redirect_test.dart
@@ -14,13 +14,13 @@ test("cloud storage upload doesn't redirect", () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); - handleUploadForm(globalServer); + handleUploadForm(globalPackageServer!); - globalServer.expect('POST', '/upload', (request) async { + globalPackageServer!.expect('POST', '/upload', (request) async { await request.read().drain(); return shelf.Response(200); });
diff --git a/test/lish/cloud_storage_upload_provides_an_error_test.dart b/test/lish/cloud_storage_upload_provides_an_error_test.dart index 5dec03d..ebb463a 100644 --- a/test/lish/cloud_storage_upload_provides_an_error_test.dart +++ b/test/lish/cloud_storage_upload_provides_an_error_test.dart
@@ -14,13 +14,13 @@ test('cloud storage upload provides an error', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); - handleUploadForm(globalServer); + handleUploadForm(globalPackageServer!); - globalServer.expect('POST', '/upload', (request) { + globalPackageServer!.expect('POST', '/upload', (request) { return request.read().drain().then((_) { return shelf.Response.notFound( '<Error><Message>Your request sucked.</Message></Error>',
diff --git a/test/lish/does_not_include_dot_file.dart b/test/lish/does_not_include_dot_file.dart index cec8ab0..9f1b24f 100644 --- a/test/lish/does_not_include_dot_file.dart +++ b/test/lish/does_not_include_dot_file.dart
@@ -30,14 +30,14 @@ test('Check if package doesn\'t include dot-files', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); - handleUploadForm(globalServer); - handleUpload(globalServer); + handleUploadForm(globalPackageServer!); + handleUpload(globalPackageServer!); - globalServer.expect('GET', '/create', (request) { + globalPackageServer!.expect('GET', '/create', (request) { return shelf.Response.ok(jsonEncode({ 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} }));
diff --git a/test/lish/dot_folder_name_test.dart b/test/lish/dot_folder_name_test.dart deleted file mode 100644 index 9f64839..0000000 --- a/test/lish/dot_folder_name_test.dart +++ /dev/null
@@ -1,28 +0,0 @@ -// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'package:pub/src/exit_codes.dart' as exit_codes; -import 'package:test/test.dart'; - -import '../descriptor.dart' as d; -import '../test_pub.dart'; - -void main() { - test('Can publish files in a .folder', () async { - await d.git(appPath).create(); - await d.validPackage.create(); - await d.dir(appPath, [ - d.dir('.vscode', [d.file('a')]), - d.file('.pubignore', '!.vscode/') - ]).create(); - - await runPub( - args: ['lish', '--dry-run'], - output: contains(''' -|-- .vscode -| '-- a'''), - exitCode: exit_codes.SUCCESS, - ); - }); -}
diff --git a/test/lish/force_does_not_publish_if_there_are_errors_test.dart b/test/lish/force_does_not_publish_if_there_are_errors_test.dart index 481f627..58c12fa 100644 --- a/test/lish/force_does_not_publish_if_there_are_errors_test.dart +++ b/test/lish/force_does_not_publish_if_there_are_errors_test.dart
@@ -21,7 +21,7 @@ ]).create(); await servePackages(); - var pub = await startPublish(globalServer, args: ['--force']); + var pub = await startPublish(globalPackageServer!, args: ['--force']); await pub.shouldExit(exit_codes.DATA); expect(
diff --git a/test/lish/force_publishes_if_tests_are_no_warnings_or_errors_test.dart b/test/lish/force_publishes_if_tests_are_no_warnings_or_errors_test.dart index c5d8957..cc05354 100644 --- a/test/lish/force_publishes_if_tests_are_no_warnings_or_errors_test.dart +++ b/test/lish/force_publishes_if_tests_are_no_warnings_or_errors_test.dart
@@ -17,13 +17,13 @@ test('--force publishes if there are no warnings or errors', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer, args: ['--force']); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!, args: ['--force']); - handleUploadForm(globalServer); - handleUpload(globalServer); + handleUploadForm(globalPackageServer!); + handleUpload(globalPackageServer!); - globalServer.expect('GET', '/create', (request) { + globalPackageServer!.expect('GET', '/create', (request) { return shelf.Response.ok(jsonEncode({ 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} }));
diff --git a/test/lish/force_publishes_if_there_are_warnings_test.dart b/test/lish/force_publishes_if_there_are_warnings_test.dart index 9fb3d53..9797e9c 100644 --- a/test/lish/force_publishes_if_there_are_warnings_test.dart +++ b/test/lish/force_publishes_if_there_are_warnings_test.dart
@@ -22,13 +22,13 @@ await d.dir(appPath, [d.pubspec(pkg)]).create(); await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer, args: ['--force']); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!, args: ['--force']); - handleUploadForm(globalServer); - handleUpload(globalServer); + handleUploadForm(globalPackageServer!); + handleUpload(globalPackageServer!); - globalServer.expect('GET', '/create', (request) { + globalPackageServer!.expect('GET', '/create', (request) { return shelf.Response.ok(jsonEncode({ 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} }));
diff --git a/test/lish/many_files_test.dart b/test/lish/many_files_test.dart index 36f4ed7..dfe13f3 100644 --- a/test/lish/many_files_test.dart +++ b/test/lish/many_files_test.dart
@@ -73,14 +73,14 @@ } await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); - handleUploadForm(globalServer); - handleUpload(globalServer); + handleUploadForm(globalPackageServer!); + handleUpload(globalPackageServer!); - globalServer.expect('GET', '/create', (request) { + globalPackageServer!.expect('GET', '/create', (request) { return shelf.Response.ok(jsonEncode({ 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} }));
diff --git a/test/lish/package_creation_provides_a_malformed_error_test.dart b/test/lish/package_creation_provides_a_malformed_error_test.dart index 7ab0bcd..1587165 100644 --- a/test/lish/package_creation_provides_a_malformed_error_test.dart +++ b/test/lish/package_creation_provides_a_malformed_error_test.dart
@@ -16,15 +16,15 @@ test('package creation provides a malformed error', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); - handleUploadForm(globalServer); - handleUpload(globalServer); + handleUploadForm(globalPackageServer!); + handleUpload(globalPackageServer!); var body = {'error': 'Your package was too boring.'}; - globalServer.expect('GET', '/create', (request) { + globalPackageServer!.expect('GET', '/create', (request) { return shelf.Response.notFound(jsonEncode(body)); });
diff --git a/test/lish/package_creation_provides_a_malformed_success_test.dart b/test/lish/package_creation_provides_a_malformed_success_test.dart index 089d09e..b47461f 100644 --- a/test/lish/package_creation_provides_a_malformed_success_test.dart +++ b/test/lish/package_creation_provides_a_malformed_success_test.dart
@@ -16,15 +16,15 @@ test('package creation provides a malformed success', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); - handleUploadForm(globalServer); - handleUpload(globalServer); + handleUploadForm(globalPackageServer!); + handleUpload(globalPackageServer!); var body = {'success': 'Your package was awesome.'}; - globalServer.expect('GET', '/create', (request) { + globalPackageServer!.expect('GET', '/create', (request) { return shelf.Response.ok(jsonEncode(body)); });
diff --git a/test/lish/package_creation_provides_an_error_test.dart b/test/lish/package_creation_provides_an_error_test.dart index f5ff128..a0c7153 100644 --- a/test/lish/package_creation_provides_an_error_test.dart +++ b/test/lish/package_creation_provides_an_error_test.dart
@@ -16,14 +16,14 @@ test('package creation provides an error', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); - handleUploadForm(globalServer); - handleUpload(globalServer); + handleUploadForm(globalPackageServer!); + handleUpload(globalPackageServer!); - globalServer.expect('GET', '/create', (request) { + globalPackageServer!.expect('GET', '/create', (request) { return shelf.Response.notFound(jsonEncode({ 'error': {'message': 'Your package was too boring.'} }));
diff --git a/test/lish/package_creation_provides_invalid_json_test.dart b/test/lish/package_creation_provides_invalid_json_test.dart index 2cd6212..025d8f9 100644 --- a/test/lish/package_creation_provides_invalid_json_test.dart +++ b/test/lish/package_creation_provides_invalid_json_test.dart
@@ -14,14 +14,14 @@ test('package creation provides invalid JSON', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); - handleUploadForm(globalServer); - handleUpload(globalServer); + handleUploadForm(globalPackageServer!); + handleUpload(globalPackageServer!); - globalServer.expect('GET', '/create', (request) { + globalPackageServer!.expect('GET', '/create', (request) { return shelf.Response.ok('{not json'); });
diff --git a/test/lish/package_validation_has_a_warning_and_continues_test.dart b/test/lish/package_validation_has_a_warning_and_continues_test.dart index c39dbc4..15e9185 100644 --- a/test/lish/package_validation_has_a_warning_and_continues_test.dart +++ b/test/lish/package_validation_has_a_warning_and_continues_test.dart
@@ -22,13 +22,13 @@ await d.dir(appPath, [d.pubspec(pkg)]).create(); await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); pub.stdin.writeln('y'); - handleUploadForm(globalServer); - handleUpload(globalServer); + handleUploadForm(globalPackageServer!); + handleUpload(globalPackageServer!); - globalServer.expect('GET', '/create', (request) { + globalPackageServer!.expect('GET', '/create', (request) { return shelf.Response.ok(jsonEncode({ 'success': {'message': 'Package test_pkg 1.0.0 uploaded!'} }));
diff --git a/test/lish/package_validation_has_a_warning_and_is_canceled_test.dart b/test/lish/package_validation_has_a_warning_and_is_canceled_test.dart index 0d5a563..c478b05 100644 --- a/test/lish/package_validation_has_a_warning_and_is_canceled_test.dart +++ b/test/lish/package_validation_has_a_warning_and_is_canceled_test.dart
@@ -18,7 +18,7 @@ await d.dir(appPath, [d.pubspec(pkg)]).create(); await servePackages(); - var pub = await startPublish(globalServer); + var pub = await startPublish(globalPackageServer!); pub.stdin.writeln('n'); await pub.shouldExit(exit_codes.DATA);
diff --git a/test/lish/package_validation_has_an_error_test.dart b/test/lish/package_validation_has_an_error_test.dart index 14c83c0..df747c6 100644 --- a/test/lish/package_validation_has_an_error_test.dart +++ b/test/lish/package_validation_has_an_error_test.dart
@@ -21,7 +21,7 @@ ]).create(); await servePackages(); - var pub = await startPublish(globalServer); + var pub = await startPublish(globalPackageServer!); await pub.shouldExit(exit_codes.DATA); expect(
diff --git a/test/lish/preview_package_validation_has_a_warning_test.dart b/test/lish/preview_package_validation_has_a_warning_test.dart index 69f59af..bbb3967 100644 --- a/test/lish/preview_package_validation_has_a_warning_test.dart +++ b/test/lish/preview_package_validation_has_a_warning_test.dart
@@ -19,7 +19,7 @@ await d.dir(appPath, [d.pubspec(pkg)]).create(); await servePackages(); - var pub = await startPublish(globalServer, args: ['--dry-run']); + var pub = await startPublish(globalPackageServer!, args: ['--dry-run']); await pub.shouldExit(exit_codes.DATA); expect(
diff --git a/test/lish/preview_package_validation_has_no_warnings_test.dart b/test/lish/preview_package_validation_has_no_warnings_test.dart index 179c648..a1bffaf 100644 --- a/test/lish/preview_package_validation_has_no_warnings_test.dart +++ b/test/lish/preview_package_validation_has_no_warnings_test.dart
@@ -17,8 +17,8 @@ packageMap('test_pkg', '1.0.0', null, null, {'sdk': '>=1.8.0 <2.0.0'}); await d.dir(appPath, [d.pubspec(pkg)]).create(); - await servePackages(); - var pub = await startPublish(globalServer, args: ['--dry-run']); + await servePackages((_) {}); + var pub = await startPublish(globalPackageServer!, args: ['--dry-run']); await pub.shouldExit(exit_codes.SUCCESS); expect(pub.stderr, emitsThrough('Package has 0 warnings.'));
diff --git a/test/lish/server_arg_overrides_publish_to_url_test.dart b/test/lish/server_arg_overrides_publish_to_url_test.dart index 1597146..b2d4c14 100644 --- a/test/lish/server_arg_overrides_publish_to_url_test.dart +++ b/test/lish/server_arg_overrides_publish_to_url_test.dart
@@ -13,15 +13,16 @@ test('an explicit --server argument overrides a "publish_to" url', () async { // Create a real server that can reject requests because validators will // try to ping it, and will use multiple retries when doing so. - final packageServer = await startPackageServer(); + final packageServer = await DescriptorServer.start(); + final fakePackageServer = 'http://localhost:${packageServer.port}'; var pkg = packageMap('test_pkg', '1.0.0'); pkg['publish_to'] = 'http://pubspec.com'; await d.dir(appPath, [d.pubspec(pkg)]).create(); await runPub( - args: ['lish', '--dry-run', '--server', packageServer.url], - output: contains(packageServer.url), + args: ['lish', '--dry-run', '--server', fakePackageServer], + output: contains(fakePackageServer), exitCode: exit_codes.DATA); await packageServer.close();
diff --git a/test/lish/upload_form_fields_has_a_non_string_value_test.dart b/test/lish/upload_form_fields_has_a_non_string_value_test.dart index 78a54fa..3be8f4c 100644 --- a/test/lish/upload_form_fields_has_a_non_string_value_test.dart +++ b/test/lish/upload_form_fields_has_a_non_string_value_test.dart
@@ -14,9 +14,9 @@ setUp(d.validPackage.create); test('upload form fields has a non-string value', () async { - await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await servePackages((_) {}); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); @@ -24,7 +24,7 @@ 'url': 'http://example.com/upload', 'fields': {'field': 12} }; - handleUploadForm(globalServer, body: body); + handleUploadForm(globalPackageServer!, body); expect(pub.stderr, emits('Invalid server response:')); expect(pub.stderr, emits(jsonEncode(body))); await pub.shouldExit(1);
diff --git a/test/lish/upload_form_fields_is_not_a_map_test.dart b/test/lish/upload_form_fields_is_not_a_map_test.dart index d18c1ee..53f36da 100644 --- a/test/lish/upload_form_fields_is_not_a_map_test.dart +++ b/test/lish/upload_form_fields_is_not_a_map_test.dart
@@ -15,13 +15,13 @@ test('upload form fields is not a map', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); var body = {'url': 'http://example.com/upload', 'fields': 12}; - handleUploadForm(globalServer, body: body); + handleUploadForm(globalPackageServer!, body); expect(pub.stderr, emits('Invalid server response:')); expect(pub.stderr, emits(jsonEncode(body))); await pub.shouldExit(1);
diff --git a/test/lish/upload_form_is_missing_fields_test.dart b/test/lish/upload_form_is_missing_fields_test.dart index b0032f8..27036f6 100644 --- a/test/lish/upload_form_is_missing_fields_test.dart +++ b/test/lish/upload_form_is_missing_fields_test.dart
@@ -15,13 +15,13 @@ test('upload form is missing fields', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); var body = {'url': 'http://example.com/upload'}; - handleUploadForm(globalServer, body: body); + handleUploadForm(globalPackageServer!, body); expect(pub.stderr, emits('Invalid server response:')); expect(pub.stderr, emits(jsonEncode(body))); await pub.shouldExit(1);
diff --git a/test/lish/upload_form_is_missing_url_test.dart b/test/lish/upload_form_is_missing_url_test.dart index eae43ea..f9f6e8b 100644 --- a/test/lish/upload_form_is_missing_url_test.dart +++ b/test/lish/upload_form_is_missing_url_test.dart
@@ -15,8 +15,8 @@ test('upload form is missing url', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); @@ -24,7 +24,7 @@ 'fields': {'field1': 'value1', 'field2': 'value2'} }; - handleUploadForm(globalServer, body: body); + handleUploadForm(globalPackageServer!, body); expect(pub.stderr, emits('Invalid server response:')); expect(pub.stderr, emits(jsonEncode(body))); await pub.shouldExit(1);
diff --git a/test/lish/upload_form_provides_an_error_test.dart b/test/lish/upload_form_provides_an_error_test.dart index 35932b8..1d9b0c5 100644 --- a/test/lish/upload_form_provides_an_error_test.dart +++ b/test/lish/upload_form_provides_an_error_test.dart
@@ -14,13 +14,15 @@ setUp(d.validPackage.create); test('upload form provides an error', () async { - await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await servePackages((_) {}); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); - globalServer.expect('GET', '/api/packages/versions/new', (request) async { + globalPackageServer!.extraHandlers['/api/packages/versions/new'] = + expectAsync1((request) { + expect(request.method, 'GET'); return shelf.Response.notFound(jsonEncode({ 'error': {'message': 'your request sucked'} }));
diff --git a/test/lish/upload_form_provides_invalid_json_test.dart b/test/lish/upload_form_provides_invalid_json_test.dart index a046755..c0996f9 100644 --- a/test/lish/upload_form_provides_invalid_json_test.dart +++ b/test/lish/upload_form_provides_invalid_json_test.dart
@@ -13,12 +13,12 @@ test('upload form provides invalid JSON', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); - globalServer.expect('GET', '/api/packages/versions/new', + globalPackageServer!.expect('GET', '/api/packages/versions/new', (request) => shelf.Response.ok('{not json')); expect(
diff --git a/test/lish/upload_form_url_is_not_a_string_test.dart b/test/lish/upload_form_url_is_not_a_string_test.dart index f69fd1f..a999537 100644 --- a/test/lish/upload_form_url_is_not_a_string_test.dart +++ b/test/lish/upload_form_url_is_not_a_string_test.dart
@@ -15,8 +15,8 @@ test('upload form url is not a string', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); @@ -25,7 +25,7 @@ 'fields': {'field1': 'value1', 'field2': 'value2'} }; - handleUploadForm(globalServer, body: body); + handleUploadForm(globalPackageServer!, body); expect(pub.stderr, emits('Invalid server response:')); expect(pub.stderr, emits(jsonEncode(body))); await pub.shouldExit(1);
diff --git a/test/lish/utils.dart b/test/lish/utils.dart index f134e4a..8e1ed5f 100644 --- a/test/lish/utils.dart +++ b/test/lish/utils.dart
@@ -9,8 +9,8 @@ import '../test_pub.dart'; -void handleUploadForm(PackageServer server, {Map? body, String path = ''}) { - server.expect('GET', '$path/api/packages/versions/new', (request) { +void handleUploadForm(PackageServer server, [Map? body]) { + server.expect('GET', '/api/packages/versions/new', (request) { expect( request.headers, containsPair('authorization', 'Bearer access token'));
diff --git a/test/list_package_dirs/lists_dependency_directories_test.dart b/test/list_package_dirs/lists_dependency_directories_test.dart index 2cd9664..af019a6 100644 --- a/test/list_package_dirs/lists_dependency_directories_test.dart +++ b/test/list_package_dirs/lists_dependency_directories_test.dart
@@ -12,8 +12,7 @@ void main() { test('prints the local paths to all packages in the lockfile', () async { - final server = await servePackages() - ..serve('bar', '1.0.0'); + await servePackages((builder) => builder.serve('bar', '1.0.0')); await d .dir('foo', [d.libDir('foo'), d.libPubspec('foo', '1.0.0')]).create(); @@ -38,7 +37,7 @@ 'packages': { 'foo': path.join(d.sandbox, 'foo', 'lib'), 'bar': path.join(d.sandbox, cachePath, 'hosted', - 'localhost%58${server.port}', 'bar-1.0.0', 'lib'), + 'localhost%58${globalServer!.port}', 'bar-1.0.0', 'lib'), 'myapp': canonicalize(path.join(d.sandbox, appPath, 'lib')) }, 'input_files': [
diff --git a/test/must_pub_get_test.dart b/test/must_pub_get_test.dart index 71d9c16..3451fc7 100644 --- a/test/must_pub_get_test.dart +++ b/test/must_pub_get_test.dart
@@ -14,14 +14,12 @@ import 'descriptor.dart' as d; import 'test_pub.dart'; -late PackageServer server; - void main() { setUp(() async { - server = await servePackages(); - - server.serve('foo', '1.0.0'); - server.serve('foo', '2.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0'); + }); await d.dir(appPath, [ d.appPubspec(), @@ -213,7 +211,7 @@ d.appPubspec({'foo': '1.0.0'}) ]).create(); - await pubGet(args: ['--legacy-packages-file']); + await pubGet(); deleteEntry(p.join(d.sandbox, cachePath)); @@ -235,7 +233,7 @@ }) ]).create(); - await pubGet(args: ['--legacy-packages-file']); + await pubGet(); await createPackagesFile(appPath); @@ -257,7 +255,7 @@ }) ]).create(); - await pubGet(args: ['--legacy-packages-file']); + await pubGet(); await d.dir(appPath, [ d.file('.packages', ''' @@ -284,7 +282,7 @@ }) ]).create(); - await pubGet(args: ['--legacy-packages-file']); + await pubGet(); await createPackagesFile(appPath, dependenciesInSandBox: ['foo']); @@ -334,8 +332,10 @@ setUp(() async { // Avoid using a path dependency because it triggers the full validation // logic. We want to be sure SDK-validation works without that logic. - server.serve('foo', '3.0.0', pubspec: { - 'environment': {'sdk': '>=1.0.0 <2.0.0'} + globalPackageServer!.add((builder) { + builder.serve('foo', '3.0.0', pubspec: { + 'environment': {'sdk': '>=1.0.0 <2.0.0'} + }); }); await d.dir(appPath, [ @@ -360,8 +360,10 @@ 'current Flutter SDK', () async { // Avoid using a path dependency because it triggers the full validation // logic. We want to be sure SDK-validation works without that logic. - server.serve('foo', '3.0.0', pubspec: { - 'environment': {'flutter': '>=1.0.0 <2.0.0'} + globalPackageServer!.add((builder) { + builder.serve('foo', '3.0.0', pubspec: { + 'environment': {'flutter': '>=1.0.0 <2.0.0'} + }); }); await d.dir('flutter', [d.file('version', '1.2.3')]).create(); @@ -452,7 +454,7 @@ group("doesn't require the user to run pub get first if", () { group( 'the pubspec is older than the lockfile which is older than the ' - 'package-config, even if the contents are wrong', () { + 'packages file, even if the contents are wrong', () { setUp(() async { await d.dir(appPath, [ d.appPubspec({'foo': '1.0.0'}) @@ -461,6 +463,7 @@ await _touch('pubspec.yaml'); await _touch('pubspec.lock'); + await _touch('.packages'); await _touch('.dart_tool/package_config.json'); }); @@ -519,8 +522,10 @@ group("an overridden dependency's SDK constraint is unmatched", () { setUp(() async { - server.serve('bar', '1.0.0', pubspec: { - 'environment': {'sdk': '0.0.0-fake'} + globalPackageServer!.add((builder) { + builder.serve('bar', '1.0.0', pubspec: { + 'environment': {'sdk': '0.0.0-fake'} + }); }); await d.dir(appPath, [ @@ -542,8 +547,10 @@ () async { // Avoid using a path dependency because it triggers the full validation // logic. We want to be sure SDK-validation works without that logic. - server.serve('foo', '3.0.0', pubspec: { - 'environment': {'flutter': '>=1.0.0 <2.0.0'} + globalPackageServer!.add((builder) { + builder.serve('foo', '3.0.0', pubspec: { + 'environment': {'flutter': '>=1.0.0 <2.0.0'} + }); }); await d.dir('flutter', [d.file('version', '1.2.3')]).create(); @@ -599,11 +606,14 @@ File(p.join(d.sandbox, 'myapp/pubspec.yaml')).lastModifiedSync(); var lockFileModified = File(p.join(d.sandbox, 'myapp/pubspec.lock')).lastModifiedSync(); + var packagesModified = + File(p.join(d.sandbox, 'myapp/.packages')).lastModifiedSync(); var packageConfigModified = File(p.join(d.sandbox, 'myapp/.dart_tool/package_config.json')) .lastModifiedSync(); expect(!pubspecModified.isAfter(lockFileModified), isTrue); + expect(!lockFileModified.isAfter(packagesModified), isTrue); expect(!lockFileModified.isAfter(packageConfigModified), isTrue); }); }
diff --git a/test/oauth2/logout_test.dart b/test/oauth2/logout_test.dart index a12a652..7398884 100644 --- a/test/oauth2/logout_test.dart +++ b/test/oauth2/logout_test.dart
@@ -11,7 +11,7 @@ test('with an existing credentials file, deletes it.', () async { await servePackages(); await d - .credentialsFile(globalServer, 'access token', + .credentialsFile(globalPackageServer!, 'access token', refreshToken: 'refresh token', expiration: DateTime.now().add(Duration(hours: 1))) .create(); @@ -28,7 +28,7 @@ await servePackages(); await d .credentialsFile( - globalServer, + globalPackageServer!, 'access token', refreshToken: 'refresh token', expiration: DateTime.now().add(Duration(hours: 1)), @@ -37,7 +37,7 @@ await d .legacyCredentialsFile( - globalServer, + globalPackageServer!, 'access token', refreshToken: 'refresh token', expiration: DateTime.now().add(Duration(hours: 1)),
diff --git a/test/oauth2/with_a_malformed_credentials_authenticates_again_test.dart b/test/oauth2/with_a_malformed_credentials_authenticates_again_test.dart index 75b47ab..79d89a7 100644 --- a/test/oauth2/with_a_malformed_credentials_authenticates_again_test.dart +++ b/test/oauth2/with_a_malformed_credentials_authenticates_again_test.dart
@@ -19,11 +19,11 @@ await d.dir( configPath, [d.file('pub-credentials.json', '{bad json')]).create(); - var pub = await startPublish(globalServer); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); - await authorizePub(pub, globalServer, 'new access token'); + await authorizePub(pub, globalPackageServer!, 'new access token'); - globalServer.expect('GET', '/api/packages/versions/new', (request) { + globalPackageServer!.expect('GET', '/api/packages/versions/new', (request) { expect(request.headers, containsPair('authorization', 'Bearer new access token')); @@ -34,6 +34,8 @@ // do so rather than killing it so it'll write out the credentials file. await pub.shouldExit(1); - await d.credentialsFile(globalServer, 'new access token').validate(); + await d + .credentialsFile(globalPackageServer!, 'new access token') + .validate(); }); }
diff --git a/test/oauth2/with_a_pre_existing_credentials_does_not_authenticate_test.dart b/test/oauth2/with_a_pre_existing_credentials_does_not_authenticate_test.dart index 3c22994..0ecd305 100644 --- a/test/oauth2/with_a_pre_existing_credentials_does_not_authenticate_test.dart +++ b/test/oauth2/with_a_pre_existing_credentials_does_not_authenticate_test.dart
@@ -12,8 +12,8 @@ await d.validPackage.create(); await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub);
diff --git a/test/oauth2/with_a_server_rejected_refresh_token_authenticates_again_test.dart b/test/oauth2/with_a_server_rejected_refresh_token_authenticates_again_test.dart index 624f427..63a91d4 100644 --- a/test/oauth2/with_a_server_rejected_refresh_token_authenticates_again_test.dart +++ b/test/oauth2/with_a_server_rejected_refresh_token_authenticates_again_test.dart
@@ -21,14 +21,14 @@ await servePackages(); await d - .credentialsFile(globalServer, 'access token', + .credentialsFile(globalPackageServer!, 'access token', refreshToken: 'bad refresh token', expiration: DateTime.now().subtract(Duration(hours: 1))) .create(); - var pub = await startPublish(globalServer); + var pub = await startPublish(globalPackageServer!); - globalServer.expect('POST', '/token', (request) { + globalPackageServer!.expect('POST', '/token', (request) { return request.read().drain().then((_) { return shelf.Response(400, body: jsonEncode({'error': 'invalid_request'}), @@ -39,10 +39,11 @@ await confirmPublish(pub); await expectLater(pub.stdout, emits(startsWith('Uploading...'))); - await authorizePub(pub, globalServer, 'new access token'); + await authorizePub(pub, globalPackageServer!, 'new access token'); var done = Completer(); - globalServer.expect('GET', '/api/packages/versions/new', (request) async { + globalPackageServer!.expect('GET', '/api/packages/versions/new', + (request) async { expect(request.headers, containsPair('authorization', 'Bearer new access token'));
diff --git a/test/oauth2/with_an_expired_credentials_refreshes_and_saves_test.dart b/test/oauth2/with_an_expired_credentials_refreshes_and_saves_test.dart index 7fbbb9f..3d303a5 100644 --- a/test/oauth2/with_an_expired_credentials_refreshes_and_saves_test.dart +++ b/test/oauth2/with_an_expired_credentials_refreshes_and_saves_test.dart
@@ -18,15 +18,15 @@ await servePackages(); await d - .credentialsFile(globalServer, 'access token', + .credentialsFile(globalPackageServer!, 'access token', refreshToken: 'refresh token', expiration: DateTime.now().subtract(Duration(hours: 1))) .create(); - var pub = await startPublish(globalServer); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); - globalServer.expect('POST', '/token', (request) { + globalPackageServer!.expect('POST', '/token', (request) { return request.readAsString().then((body) { expect( body, matches(RegExp(r'(^|&)refresh_token=refresh\+token(&|$)'))); @@ -38,7 +38,7 @@ }); }); - globalServer.expect('GET', '/api/packages/versions/new', (request) { + globalPackageServer!.expect('GET', '/api/packages/versions/new', (request) { expect(request.headers, containsPair('authorization', 'Bearer new access token')); @@ -48,7 +48,7 @@ await pub.shouldExit(); await d - .credentialsFile(globalServer, 'new access token', + .credentialsFile(globalPackageServer!, 'new access token', refreshToken: 'refresh token') .validate(); });
diff --git a/test/oauth2/with_an_expired_credentials_without_a_refresh_token_authenticates_again_test.dart b/test/oauth2/with_an_expired_credentials_without_a_refresh_token_authenticates_again_test.dart index 803c529..dbb4280 100644 --- a/test/oauth2/with_an_expired_credentials_without_a_refresh_token_authenticates_again_test.dart +++ b/test/oauth2/with_an_expired_credentials_without_a_refresh_token_authenticates_again_test.dart
@@ -17,20 +17,20 @@ await servePackages(); await d - .credentialsFile(globalServer, 'access token', + .credentialsFile(globalPackageServer!, 'access token', expiration: DateTime.now().subtract(Duration(hours: 1))) .create(); - var pub = await startPublish(globalServer); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); await expectLater( pub.stderr, emits("Pub's authorization to upload packages has expired and " "can't be automatically refreshed.")); - await authorizePub(pub, globalServer, 'new access token'); + await authorizePub(pub, globalPackageServer!, 'new access token'); - globalServer.expect('GET', '/api/packages/versions/new', (request) { + globalPackageServer!.expect('GET', '/api/packages/versions/new', (request) { expect(request.headers, containsPair('authorization', 'Bearer new access token')); @@ -41,6 +41,8 @@ // do so rather than killing it so it'll write out the credentials file. await pub.shouldExit(1); - await d.credentialsFile(globalServer, 'new access token').validate(); + await d + .credentialsFile(globalPackageServer!, 'new access token') + .validate(); }); }
diff --git a/test/oauth2/with_no_credentials_authenticates_and_saves_credentials_test.dart b/test/oauth2/with_no_credentials_authenticates_and_saves_credentials_test.dart index 961a465..fe7bc1b 100644 --- a/test/oauth2/with_no_credentials_authenticates_and_saves_credentials_test.dart +++ b/test/oauth2/with_no_credentials_authenticates_and_saves_credentials_test.dart
@@ -16,11 +16,11 @@ await d.validPackage.create(); await servePackages(); - var pub = await startPublish(globalServer); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); - await authorizePub(pub, globalServer); + await authorizePub(pub, globalPackageServer!); - globalServer.expect('GET', '/api/packages/versions/new', (request) { + globalPackageServer!.expect('GET', '/api/packages/versions/new', (request) { expect(request.headers, containsPair('authorization', 'Bearer access token')); @@ -31,6 +31,6 @@ // do so rather than killing it so it'll write out the credentials file. await pub.shouldExit(1); - await d.credentialsFile(globalServer, 'access token').validate(); + await d.credentialsFile(globalPackageServer!, 'access token').validate(); }); }
diff --git a/test/oauth2/with_server_rejected_credentials_authenticates_again_test.dart b/test/oauth2/with_server_rejected_credentials_authenticates_again_test.dart index 2e3b62f..433a9ed 100644 --- a/test/oauth2/with_server_rejected_credentials_authenticates_again_test.dart +++ b/test/oauth2/with_server_rejected_credentials_authenticates_again_test.dart
@@ -16,12 +16,12 @@ 'credentials.json', () async { await d.validPackage.create(); await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPublish(globalServer); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPublish(globalPackageServer!); await confirmPublish(pub); - globalServer.expect('GET', '/api/packages/versions/new', (request) { + globalPackageServer!.expect('GET', '/api/packages/versions/new', (request) { return shelf.Response(401, body: jsonEncode({ 'error': {'message': 'your token sucks'}
diff --git a/test/outdated/outdated_test.dart b/test/outdated/outdated_test.dart index 31113c7..f2dee0c 100644 --- a/test/outdated/outdated_test.dart +++ b/test/outdated/outdated_test.dart
@@ -45,10 +45,10 @@ testWithGolden('no lockfile', (ctx) async { await d.appDir({'foo': '^1.0.0', 'bar': '^1.0.0'}).create(); - await servePackages() + await servePackages((builder) => builder ..serve('foo', '1.2.3') ..serve('bar', '1.2.3') - ..serve('bar', '2.0.0'); + ..serve('bar', '2.0.0')); await ctx.runOutdatedTests(); }); @@ -61,8 +61,7 @@ }); testWithGolden('newer versions available', (ctx) async { - final builder = await servePackages(); - builder + await servePackages((builder) => builder ..serve('foo', '1.2.3', deps: {'transitive': '^1.0.0'}) ..serve('bar', '1.0.0') ..serve('builder', '1.2.3', deps: { @@ -70,7 +69,7 @@ 'dev_trans': '^1.0.0', }) ..serve('transitive', '1.2.3') - ..serve('dev_trans', '1.0.0'); + ..serve('dev_trans', '1.0.0')); await d.dir('local_package', [ d.libDir('local_package'), @@ -89,7 +88,7 @@ }) ]).create(); await pubGet(); - builder + globalPackageServer!.add((builder) => builder ..serve('foo', '1.3.0', deps: {'transitive': '>=1.0.0<3.0.0'}) ..serve('foo', '2.0.0', deps: {'transitive': '>=1.0.0<3.0.0', 'transitive2': '^1.0.0'}) @@ -105,13 +104,15 @@ ..serve('transitive', '2.0.0') ..serve('transitive2', '1.0.0') ..serve('transitive3', '1.0.0') - ..serve('dev_trans', '2.0.0'); + ..serve('dev_trans', '2.0.0')); + await ctx.runOutdatedTests(); }); testWithGolden('circular dependency on root', (ctx) async { - final server = await servePackages(); - server.serve('foo', '1.2.3', deps: {'app': '^1.0.0'}); + await servePackages( + (builder) => builder..serve('foo', '1.2.3', deps: {'app': '^1.0.0'}), + ); await d.dir(appPath, [ d.pubspec({ @@ -125,7 +126,10 @@ await pubGet(); - server.serve('foo', '1.3.0', deps: {'app': '^1.0.1'}); + globalPackageServer!.add( + (builder) => builder..serve('foo', '1.3.0', deps: {'app': '^1.0.1'}), + ); + await ctx.runOutdatedTests(); }); @@ -141,11 +145,11 @@ }) ]).create(); - await servePackages() + await servePackages((builder) => builder ..serve('foo', '1.0.0', deps: {'bar': '^1.0.0'}) ..serve('bar', '1.0.0', deps: {'foo': '^1.0.0'}) ..serve('foo', '2.0.0', deps: {'bar': '^1.0.0'}) - ..serve('bar', '2.0.0', deps: {'foo': '^1.0.0'}); + ..serve('bar', '2.0.0', deps: {'foo': '^1.0.0'})); await pubGet(); await ctx.runOutdatedTests(); @@ -168,60 +172,62 @@ }), ]).create(); - await servePackages() - ..serve('foo', '1.0.0', deps: { - 'bar': '^1.0.0' - }, pubspec: { - 'environment': {'sdk': '>=2.9.0 < 3.0.0'} - }) - ..serve('bar', '1.0.0', pubspec: { - 'environment': {'sdk': '>=2.9.0 < 3.0.0'} - }) - ..serve('foo', '2.0.0-nullsafety.0', deps: { - 'bar': '^2.0.0' - }, pubspec: { - 'environment': {'sdk': '>=2.12.0 < 3.0.0'} - }) - ..serve('foo', '2.0.0', deps: { - 'bar': '^1.0.0' - }, pubspec: { - 'environment': {'sdk': '>=2.12.0 < 3.0.0'} - }) - ..serve('bar', '2.0.0', pubspec: { - 'environment': {'sdk': '>=2.13.0 < 3.0.0'} - }) - ..serve('file_opts_out', '1.0.0', pubspec: { - 'environment': {'sdk': '>=2.12.0 < 3.0.0'}, - }, contents: [ - d.dir('lib', [d.file('main.dart', '// @dart = 2.9\n')]) - ]) - ..serve('file_opts_out', '2.0.0', pubspec: { - 'environment': {'sdk': '>=2.12.0 < 3.0.0'}, - }) - ..serve('fails_analysis', '1.0.0', pubspec: { - 'environment': {'sdk': '>=2.12.0 < 3.0.0'}, - }, contents: [ - d.dir('lib', [d.file('main.dart', 'syntax error\n')]) - ]) - ..serve('fails_analysis', '2.0.0', pubspec: { - 'environment': {'sdk': '>=2.12.0 < 3.0.0'}, - }) - ..serve('file_in_dependency_opts_out', '1.0.0', deps: { - 'file_opts_out': '^1.0.0' - }, pubspec: { - 'environment': {'sdk': '>=2.12.0 < 3.0.0'}, - }) - ..serve('file_in_dependency_opts_out', '2.0.0', pubspec: { - 'environment': {'sdk': '>=2.12.0 < 3.0.0'}, - }) - ..serve('fails_analysis_in_dependency', '1.0.0', deps: { - 'fails_analysis': '^1.0.0' - }, pubspec: { - 'environment': {'sdk': '>=2.12.0 < 3.0.0'}, - }) - ..serve('fails_analysis_in_dependency', '2.0.0', pubspec: { - 'environment': {'sdk': '>=2.12.0 < 3.0.0'}, - }); + await servePackages( + (builder) => builder + ..serve('foo', '1.0.0', deps: { + 'bar': '^1.0.0' + }, pubspec: { + 'environment': {'sdk': '>=2.9.0 < 3.0.0'} + }) + ..serve('bar', '1.0.0', pubspec: { + 'environment': {'sdk': '>=2.9.0 < 3.0.0'} + }) + ..serve('foo', '2.0.0-nullsafety.0', deps: { + 'bar': '^2.0.0' + }, pubspec: { + 'environment': {'sdk': '>=2.12.0 < 3.0.0'} + }) + ..serve('foo', '2.0.0', deps: { + 'bar': '^1.0.0' + }, pubspec: { + 'environment': {'sdk': '>=2.12.0 < 3.0.0'} + }) + ..serve('bar', '2.0.0', pubspec: { + 'environment': {'sdk': '>=2.13.0 < 3.0.0'} + }) + ..serve('file_opts_out', '1.0.0', pubspec: { + 'environment': {'sdk': '>=2.12.0 < 3.0.0'}, + }, contents: [ + d.dir('lib', [d.file('main.dart', '// @dart = 2.9\n')]) + ]) + ..serve('file_opts_out', '2.0.0', pubspec: { + 'environment': {'sdk': '>=2.12.0 < 3.0.0'}, + }) + ..serve('fails_analysis', '1.0.0', pubspec: { + 'environment': {'sdk': '>=2.12.0 < 3.0.0'}, + }, contents: [ + d.dir('lib', [d.file('main.dart', 'syntax error\n')]) + ]) + ..serve('fails_analysis', '2.0.0', pubspec: { + 'environment': {'sdk': '>=2.12.0 < 3.0.0'}, + }) + ..serve('file_in_dependency_opts_out', '1.0.0', deps: { + 'file_opts_out': '^1.0.0' + }, pubspec: { + 'environment': {'sdk': '>=2.12.0 < 3.0.0'}, + }) + ..serve('file_in_dependency_opts_out', '2.0.0', pubspec: { + 'environment': {'sdk': '>=2.12.0 < 3.0.0'}, + }) + ..serve('fails_analysis_in_dependency', '1.0.0', deps: { + 'fails_analysis': '^1.0.0' + }, pubspec: { + 'environment': {'sdk': '>=2.12.0 < 3.0.0'}, + }) + ..serve('fails_analysis_in_dependency', '2.0.0', pubspec: { + 'environment': {'sdk': '>=2.12.0 < 3.0.0'}, + }), + ); await pubGet(environment: {'_PUB_TEST_SDK_VERSION': '2.13.0'}); await ctx.runOutdatedTests(environment: { @@ -230,7 +236,7 @@ }); testWithGolden('null-safety no resolution', (ctx) async { - await servePackages() + await servePackages((builder) => builder ..serve('foo', '1.0.0', pubspec: { 'environment': {'sdk': '>=2.9.0 < 3.0.0'} }) @@ -246,7 +252,7 @@ 'foo': '^1.0.0' }, pubspec: { 'environment': {'sdk': '>=2.12.0 < 3.0.0'} - }); + })); await d.dir(appPath, [ d.pubspec({ @@ -268,7 +274,7 @@ }); testWithGolden('null-safety already migrated', (ctx) async { - await servePackages() + await servePackages((builder) => builder ..serve('foo', '1.0.0', pubspec: { 'environment': {'sdk': '>=2.9.0 < 3.0.0'} }) @@ -285,7 +291,7 @@ }) ..serve('devTransitive', '1.0.0', pubspec: { 'environment': {'sdk': '>=2.9.0 < 3.0.0'} - }); + })); await d.dir(appPath, [ d.pubspec({ @@ -310,13 +316,15 @@ testWithGolden('overridden dependencies', (ctx) async { ensureGit(); - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0', deps: {'bar': '^1.0.0'}) - ..serve('bar', '1.0.0') - ..serve('bar', '2.0.0') - ..serve('baz', '1.0.0') - ..serve('baz', '2.0.0'); + await servePackages( + (builder) => builder + ..serve('foo', '1.0.0') + ..serve('foo', '2.0.0', deps: {'bar': '^1.0.0'}) + ..serve('bar', '1.0.0') + ..serve('bar', '2.0.0') + ..serve('baz', '1.0.0') + ..serve('baz', '2.0.0'), + ); await d.git('foo.git', [ d.libPubspec('foo', '1.0.1'), @@ -352,11 +360,13 @@ testWithGolden('overridden dependencies - no resolution', (ctx) async { ensureGit(); - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': '^2.0.0'}) - ..serve('foo', '2.0.0', deps: {'bar': '^1.0.0'}) - ..serve('bar', '1.0.0', deps: {'foo': '^1.0.0'}) - ..serve('bar', '2.0.0', deps: {'foo': '^2.0.0'}); + await servePackages( + (builder) => builder + ..serve('foo', '1.0.0', deps: {'bar': '^2.0.0'}) + ..serve('foo', '2.0.0', deps: {'bar': '^1.0.0'}) + ..serve('bar', '1.0.0', deps: {'foo': '^1.0.0'}) + ..serve('bar', '2.0.0', deps: {'foo': '^2.0.0'}), + ); await d.dir(appPath, [ d.pubspec({ @@ -381,7 +391,7 @@ testWithGolden( 'latest version reported while locked on a prerelease can be a prerelease', (ctx) async { - await servePackages() + await servePackages((builder) => builder ..serve('foo', '0.9.0') ..serve('foo', '1.0.0-dev.1') ..serve('foo', '1.0.0-dev.2') @@ -390,7 +400,7 @@ ..serve('bar', '1.0.0-dev.2') ..serve('mop', '0.10.0-dev') ..serve('mop', '0.10.0') - ..serve('mop', '1.0.0-dev'); + ..serve('mop', '1.0.0-dev')); await d.dir(appPath, [ d.pubspec({ 'name': 'app', @@ -409,7 +419,7 @@ }); testWithGolden('Handles SDK dependencies', (ctx) async { - await servePackages() + await servePackages((builder) => builder ..serve('foo', '1.0.0', pubspec: { 'environment': {'sdk': '>=2.10.0 <3.0.0'} }) @@ -418,7 +428,7 @@ }) ..serve('foo', '2.0.0', pubspec: { 'environment': {'sdk': '>=2.12.0 <3.0.0'} - }); + })); await d.dir('flutter-root', [ d.file('version', '1.2.3'),
diff --git a/test/package_config_file_test.dart b/test/package_config_file_test.dart index 763ce42..82882ae 100644 --- a/test/package_config_file_test.dart +++ b/test/package_config_file_test.dart
@@ -12,12 +12,13 @@ void main() { forBothPubGetAndUpgrade((command) { test('package_config.json file is created', () async { - await servePackages() - ..serve('foo', '1.2.3', - deps: {'baz': '2.2.2'}, contents: [d.dir('lib', [])]) - ..serve('bar', '3.2.1', contents: [d.dir('lib', [])]) - ..serve('baz', '2.2.2', + await servePackages((builder) { + builder.serve('foo', '1.2.3', + deps: {'baz': '2.2.2'}, contents: [d.dir('lib', [])]); + builder.serve('bar', '3.2.1', contents: [d.dir('lib', [])]); + builder.serve('baz', '2.2.2', deps: {'bar': '3.2.1'}, contents: [d.dir('lib', [])]); + }); await d.dir(appPath, [ d.appPubspec({'foo': '1.2.3'}), @@ -53,12 +54,13 @@ }); test('package_config.json file is overwritten', () async { - await servePackages() - ..serve('foo', '1.2.3', - deps: {'baz': '2.2.2'}, contents: [d.dir('lib', [])]) - ..serve('bar', '3.2.1', contents: [d.dir('lib', [])]) - ..serve('baz', '2.2.2', + await servePackages((builder) { + builder.serve('foo', '1.2.3', + deps: {'baz': '2.2.2'}, contents: [d.dir('lib', [])]); + builder.serve('bar', '3.2.1', contents: [d.dir('lib', [])]); + builder.serve('baz', '2.2.2', deps: {'bar': '3.2.1'}, contents: [d.dir('lib', [])]); + }); await d.dir(appPath, [ d.appPubspec({'foo': '1.2.3'}), @@ -115,8 +117,6 @@ args: ['--offline'], error: equalsIgnoringWhitespace(""" Because myapp depends on foo any which doesn't exist (could not find package foo in cache), version solving failed. - - Try again without --offline! """), exitCode: exit_codes.UNAVAILABLE); await d.dir(appPath, [ @@ -127,10 +127,11 @@ test( '.dart_tool/package_config.json file has relative path to path dependency', () async { - await servePackages() - ..serve('foo', '1.2.3', - deps: {'baz': 'any'}, contents: [d.dir('lib', [])]) - ..serve('baz', '9.9.9', deps: {}, contents: [d.dir('lib', [])]); + await servePackages((builder) { + builder.serve('foo', '1.2.3', + deps: {'baz': 'any'}, contents: [d.dir('lib', [])]); + builder.serve('baz', '9.9.9', deps: {}, contents: [d.dir('lib', [])]); + }); await d.dir('local_baz', [ d.libDir('baz', 'baz 3.2.1'), @@ -177,17 +178,18 @@ }); test('package_config.json has language version', () async { - final server = await servePackages(); - server.serve( - 'foo', - '1.2.3', - pubspec: { - 'environment': { - 'sdk': '>=0.0.1 <=0.2.2+2', // tests runs with '0.1.2+3' + await servePackages((builder) { + builder.serve( + 'foo', + '1.2.3', + pubspec: { + 'environment': { + 'sdk': '>=0.0.1 <=0.2.2+2', // tests runs with '0.1.2+3' + }, }, - }, - contents: [d.dir('lib', [])], - ); + contents: [d.dir('lib', [])], + ); + }); await d.dir(appPath, [ d.pubspec({ @@ -221,17 +223,18 @@ }); test('package_config.json has 2.7 default language version', () async { - final server = await servePackages(); - server.serve( - 'foo', - '1.2.3', - pubspec: { - 'environment': { - 'sdk': 'any', + await servePackages((builder) { + builder.serve( + 'foo', + '1.2.3', + pubspec: { + 'environment': { + 'sdk': 'any', + }, }, - }, - contents: [d.dir('lib', [])], - ); + contents: [d.dir('lib', [])], + ); + }); await d.dir(appPath, [ d.pubspec({
diff --git a/test/package_server.dart b/test/package_server.dart index 952c189..12b542a 100644 --- a/test/package_server.dart +++ b/test/package_server.dart
@@ -4,156 +4,160 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:io'; import 'package:path/path.dart' as p; -import 'package:pub/src/third_party/tar/tar.dart'; import 'package:pub_semver/pub_semver.dart'; import 'package:shelf/shelf.dart' as shelf; -import 'package:shelf/shelf_io.dart' as shelf_io; import 'package:test/test.dart'; import 'package:test/test.dart' as test show expect; import 'descriptor.dart' as d; import 'test_pub.dart'; +/// The current global [PackageServer]. +PackageServer? get globalPackageServer => _globalPackageServer; +PackageServer? _globalPackageServer; + +/// Creates an HTTP server that replicates the structure of pub.dartlang.org and +/// makes it the current [globalServer]. +/// +/// Calls [callback] with a [PackageServerBuilder] that's used to specify +/// which packages to serve. +Future servePackages([void Function(PackageServerBuilder)? callback]) async { + _globalPackageServer = await PackageServer.start(callback ?? (_) {}); + globalServer = _globalPackageServer!._inner; + + addTearDown(() { + _globalPackageServer = null; + }); +} + +/// Like [servePackages], but instead creates an empty server with no packages +/// registered. +/// +/// This will always replace a previous server. +Future serveNoPackages() => servePackages((_) {}); + +/// Sets up the global package server to report an error on any request. +/// +/// If no server has been set up, an empty server will be started. +Future serveErrors() async { + var packageServer = globalPackageServer; + if (packageServer == null) { + await serveNoPackages(); + } else { + packageServer.serveErrors(); + } +} + class PackageServer { /// The inner [DescriptorServer] that this uses to serve its descriptors. - final shelf.Server _inner; + final DescriptorServer _inner; - /// Handlers of requests. Last matching handler will be used. - final List<_PatternAndHandler> _handlers = []; + /// The [d.DirectoryDescriptor] describing the server layout of + /// `/api/packages` on the test server. + /// + /// This contains metadata for packages that are being served via + /// [servePackages]. + final _servedApiPackageDir = d.dir('packages', []); - // A list of all the requests recieved up till now. - final List<String> requestedPaths = <String>[]; + /// The [d.DirectoryDescriptor] describing the server layout of `/packages` on + /// the test server. + /// + /// This contains the tarballs for packages that are being served via + /// [servePackages]. + final _servedPackageDir = d.dir('packages', []); - PackageServer._(this._inner) { - _inner.mount((request) { - final path = request.url.path; - requestedPaths.add(path); + /// The current [PackageServerBuilder] that a user uses to specify which + /// package to serve. + /// + /// This is preserved so that additional packages can be added. + late final PackageServerBuilder _builder; - final pathWithInitialSlash = '/$path'; - for (final entry in _handlers.reversed) { - final match = entry.pattern.matchAsPrefix(pathWithInitialSlash); - if (match != null && match.end == pathWithInitialSlash.length) { - final a = entry.handler(request); - return a; - } - } - return shelf.Response.notFound('Could not find ${request.url}'); - }); - } + /// The port used for the server. + int get port => _inner.port; - static final _versionInfoPattern = RegExp(r'/api/packages/([a-zA-Z_0-9]*)'); - static final _downloadPattern = - RegExp(r'/packages/([^/]*)/versions/([^/]*).tar.gz'); + /// The URL for the server. + String get url => 'http://localhost:$port'; - static Future<PackageServer> start() async { - final server = - PackageServer._(await shelf_io.IOServer.bind('localhost', 0)); - server.handle( - _versionInfoPattern, - (shelf.Request request) { - final parts = request.url.pathSegments; - assert(parts[0] == 'api'); - assert(parts[1] == 'packages'); - final name = parts[2]; + /// Handlers for requests not easily described as packages. + Map<Pattern, shelf.Handler> get extraHandlers => _inner.extraHandlers; - final package = server._packages[name]; - if (package == null) { - return shelf.Response.notFound('No package named $name'); - } - return shelf.Response.ok(jsonEncode({ - 'name': name, - 'uploaders': ['nweiz@google.com'], - 'versions': package.versions.values - .map((version) => packageVersionApiMap( - server._inner.url.toString(), - version.pubspec, - retracted: version.isRetracted, - )) - .toList(), - if (package.isDiscontinued) 'isDiscontinued': true, - if (package.discontinuedReplacementText != null) - 'replacedBy': package.discontinuedReplacementText, - })); - }, - ); + /// From now on report errors on any request. + void serveErrors() => extraHandlers + ..clear() + ..[RegExp('.*')] = (request) { + fail('The HTTP server received an unexpected request:\n' + '${request.method} ${request.requestedUri}'); + }; - server.handle( - _downloadPattern, - (shelf.Request request) { - final parts = request.url.pathSegments; - assert(parts[0] == 'packages'); - final name = parts[1]; - assert(parts[2] == 'versions'); - final package = server._packages[name]; - if (package == null) { - return shelf.Response.notFound('No package $name'); - } - - final version = Version.parse( - parts[3].substring(0, parts[3].length - '.tar.gz'.length)); - assert(parts[3].endsWith('.tar.gz')); - - for (final packageVersion in package.versions.values) { - if (packageVersion.version == version) { - return shelf.Response.ok(packageVersion.contents()); - } - } - return shelf.Response.notFound('No version $version of $name'); - }, - ); + /// Creates an HTTP server that replicates the structure of pub.dartlang.org. + /// + /// Calls [callback] with a [PackageServerBuilder] that's used to specify + /// which packages to serve. + static Future<PackageServer> start( + void Function(PackageServerBuilder) callback) async { + var descriptorServer = await DescriptorServer.start(); + var server = PackageServer._(descriptorServer); + descriptorServer.contents + ..add(d.dir('api', [server._servedApiPackageDir])) + ..add(server._servedPackageDir); + server.add(callback); return server; } - Future<void> close() async { - await _inner.close(); + PackageServer._(this._inner) { + _builder = PackageServerBuilder._(this); } - /// The port used for the server. - int get port => _inner.url.port; + /// Add to the current set of packages that are being served. + void add(void Function(PackageServerBuilder) callback) { + callback(_builder); - /// The URL for the server. - String get url => _inner.url.toString(); + _servedApiPackageDir.contents.clear(); + _servedPackageDir.contents.clear(); - /// From now on report errors on any request. - void serveErrors() => _handlers - ..clear() - ..add( - _PatternAndHandler( - RegExp('.*'), - (request) { - fail('The HTTP server received an unexpected request:\n' - '${request.method} ${request.requestedUri}'); - }, - ), - ); + _builder._packages.forEach((name, package) { + _servedApiPackageDir.contents.addAll([ + d.file( + name, + jsonEncode({ + 'name': name, + 'uploaders': ['nweiz@google.com'], + 'versions': package.versions.values + .map((version) => packageVersionApiMap(url, version.pubspec, + retracted: version.isRetracted)) + .toList(), + if (package.isDiscontinued) 'isDiscontinued': true, + if (package.discontinuedReplacementText != null) + 'replacedBy': package.discontinuedReplacementText, + })), + d.dir(name, [ + d.dir('versions', package.versions.values.map((version) { + return d.file( + version.version.toString(), + jsonEncode(packageVersionApiMap(url, version.pubspec, + retracted: version.isRetracted, full: true))); + })) + ]) + ]); - void handle(Pattern pattern, shelf.Handler handler) { - _handlers.add( - _PatternAndHandler( - pattern, - handler, - ), - ); + _servedPackageDir.contents.add(d.dir(name, [ + d.dir( + 'versions', + package.versions.values.map((version) => + d.tar('${version.version}.tar.gz', version.contents))) + ])); + }); } // Installs a handler at [pattern] that expects to be called exactly once with // the given [method]. - // - // The handler is installed as the start to give it priority over more general - // handlers. void expect(String method, Pattern pattern, shelf.Handler handler) { - handle( - pattern, - expectAsync1( - (request) { - test.expect(request.method, method); - return handler(request); - }, - ), - ); + extraHandlers[pattern] = expectAsync1((request) { + test.expect(request.method, method); + return handler(request); + }); } /// Returns the path of [package] at [version], installed from this server, in @@ -165,9 +169,26 @@ String get cachingPath => p.join(d.sandbox, cachePath, 'hosted', 'localhost%58$port'); + /// Replace the current set of packages that are being served. + void replace(void Function(PackageServerBuilder) callback) { + _builder._clear(); + add(callback); + } +} + +/// A builder for specifying which packages should be served by [servePackages]. +class PackageServerBuilder { /// A map from package names to the concrete packages to serve. final _packages = <String, _ServedPackage>{}; + /// The package server that this builder is associated with. + final PackageServer _server; + + /// The URL for the server that this builder is associated with. + String get serverUrl => _server.url; + + PackageServerBuilder._(this._server); + /// Specifies that a package named [name] with [version] should be served. /// /// If [deps] is passed, it's used as the "dependencies" field of the pubspec. @@ -187,44 +208,7 @@ contents = [d.file('pubspec.yaml', yaml(pubspecFields)), ...contents]; var package = _packages.putIfAbsent(name, () => _ServedPackage()); - package.versions[version] = _ServedPackageVersion( - pubspecFields, - contents: () { - final entries = <TarEntry>[]; - - void addDescriptor(d.Descriptor descriptor, String path) { - if (descriptor is d.DirectoryDescriptor) { - for (final e in descriptor.contents) { - addDescriptor(e, p.posix.join(path, descriptor.name)); - } - } else { - entries.add( - TarEntry( - TarHeader( - // Ensure paths in tar files use forward slashes - name: p.posix.join(path, descriptor.name), - // We want to keep executable bits, but otherwise use the default - // file mode - mode: 420, - // size: 100, - modified: DateTime.now(), - userName: 'pub', - groupName: 'pub', - ), - (descriptor as d.FileDescriptor).readAsBytes(), - ), - ); - } - } - - for (final e in contents ?? <d.Descriptor>[]) { - addDescriptor(e, ''); - } - return Stream.fromIterable(entries) - .transform(tarWriterWith(format: OutputFormat.gnuLongName)) - .transform(gzip.encoder); - }, - ); + package.versions[version] = _ServedPackageVersion(pubspecFields, contents); } // Mark a package discontinued. @@ -236,7 +220,7 @@ } /// Clears all existing packages from this builder. - void clearPackages() { + void _clear() { _packages.clear(); } @@ -254,17 +238,10 @@ /// A package that's intended to be served. class _ServedPackageVersion { final Map pubspec; - final Stream<List<int>> Function() contents; + final List<d.Descriptor> contents; bool isRetracted = false; Version get version => Version.parse(pubspec['version']); - _ServedPackageVersion(this.pubspec, {required this.contents}); -} - -class _PatternAndHandler { - Pattern pattern; - shelf.Handler handler; - - _PatternAndHandler(this.pattern, this.handler); + _ServedPackageVersion(this.pubspec, this.contents); }
diff --git a/test/packages_file_test.dart b/test/packages_file_test.dart index c245a9a..67ca572 100644 --- a/test/packages_file_test.dart +++ b/test/packages_file_test.dart
@@ -11,20 +11,21 @@ void main() { forBothPubGetAndUpgrade((command) { - test('.packages file is created with flag', () async { - await servePackages() - ..serve('foo', '1.2.3', - deps: {'baz': '2.2.2'}, contents: [d.dir('lib', [])]) - ..serve('bar', '3.2.1', contents: [d.dir('lib', [])]) - ..serve('baz', '2.2.2', + test('.packages file is created', () async { + await servePackages((builder) { + builder.serve('foo', '1.2.3', + deps: {'baz': '2.2.2'}, contents: [d.dir('lib', [])]); + builder.serve('bar', '3.2.1', contents: [d.dir('lib', [])]); + builder.serve('baz', '2.2.2', deps: {'bar': '3.2.1'}, contents: [d.dir('lib', [])]); + }); await d.dir(appPath, [ d.appPubspec({'foo': '1.2.3'}), d.dir('lib') ]).create(); - await pubCommand(command, args: ['--legacy-packages-file']); + await pubCommand(command); await d.dir(appPath, [ d.packagesFile( @@ -32,13 +33,14 @@ ]).validate(); }); - test('.packages file is overwritten with flag', () async { - await servePackages() - ..serve('foo', '1.2.3', - deps: {'baz': '2.2.2'}, contents: [d.dir('lib', [])]) - ..serve('bar', '3.2.1', contents: [d.dir('lib', [])]) - ..serve('baz', '2.2.2', + test('.packages file is overwritten', () async { + await servePackages((builder) { + builder.serve('foo', '1.2.3', + deps: {'baz': '2.2.2'}, contents: [d.dir('lib', [])]); + builder.serve('bar', '3.2.1', contents: [d.dir('lib', [])]); + builder.serve('baz', '2.2.2', deps: {'bar': '3.2.1'}, contents: [d.dir('lib', [])]); + }); await d.dir(appPath, [ d.appPubspec({'foo': '1.2.3'}), @@ -51,7 +53,7 @@ await oldFile.create(); await oldFile.validate(); // Sanity-check that file was created correctly. - await pubCommand(command, args: ['--legacy-packages-file']); + await pubCommand(command); await d.dir(appPath, [ d.packagesFile( @@ -59,32 +61,27 @@ ]).validate(); }); - test('.packages file is not created if pub command fails with flag', - () async { + test('.packages file is not created if pub command fails', () async { await d.dir(appPath, [ d.appPubspec({'foo': '1.2.3'}), d.dir('lib') ]).create(); await pubCommand(command, - args: ['--offline', '--legacy-packages-file'], - error: equalsIgnoringWhitespace(""" + args: ['--offline'], error: equalsIgnoringWhitespace(""" Because myapp depends on foo any which doesn't exist (could not find package foo in cache), version solving failed. - - Try again without --offline! - """), - exitCode: exit_codes.UNAVAILABLE); + """), exitCode: exit_codes.UNAVAILABLE); await d.dir(appPath, [d.nothing('.packages')]).validate(); }); - test('.packages file has relative path to path dependency with flag', - () async { - await servePackages() - ..serve('foo', '1.2.3', - deps: {'baz': 'any'}, contents: [d.dir('lib', [])]) - ..serve('baz', '9.9.9', deps: {}, contents: [d.dir('lib', [])]); + test('.packages file has relative path to path dependency', () async { + await servePackages((builder) { + builder.serve('foo', '1.2.3', + deps: {'baz': 'any'}, contents: [d.dir('lib', [])]); + builder.serve('baz', '9.9.9', deps: {}, contents: [d.dir('lib', [])]); + }); await d.dir('local_baz', [ d.libDir('baz', 'baz 3.2.1'), @@ -104,7 +101,7 @@ d.dir('lib') ]).create(); - await pubCommand(command, args: ['--legacy-packages-file']); + await pubCommand(command); await d.dir(appPath, [ d.packagesFile({'myapp': '.', 'baz': '../local_baz', 'foo': '1.2.3'}),
diff --git a/test/pub_get_and_upgrade_test.dart b/test/pub_get_and_upgrade_test.dart index f64f93b..62004a4 100644 --- a/test/pub_get_and_upgrade_test.dart +++ b/test/pub_get_and_upgrade_test.dart
@@ -45,8 +45,7 @@ await pubCommand(command); await d.dir('myapp', [ - d.packageConfigFile( - [d.packageConfigEntry(name: 'myapp_name', path: '.')]), + d.packagesFile({'myapp_name': '.'}) ]).validate(); });
diff --git a/test/pub_uploader_test.dart b/test/pub_uploader_test.dart index 47d50d3..daec6bc 100644 --- a/test/pub_uploader_test.dart +++ b/test/pub_uploader_test.dart
@@ -40,11 +40,12 @@ test('adds an uploader', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); + await d.credentialsFile(globalPackageServer!, 'access token').create(); var pub = await startPubUploader( - globalServer, ['--package', 'pkg', 'add', 'email']); + globalPackageServer!, ['--package', 'pkg', 'add', 'email']); - globalServer.expect('POST', '/api/packages/pkg/uploaders', (request) { + globalPackageServer!.expect('POST', '/api/packages/pkg/uploaders', + (request) { return request.readAsString().then((body) { expect(body, equals('email=email')); @@ -62,11 +63,11 @@ test('removes an uploader', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); + await d.credentialsFile(globalPackageServer!, 'access token').create(); var pub = await startPubUploader( - globalServer, ['--package', 'pkg', 'remove', 'email']); + globalPackageServer!, ['--package', 'pkg', 'remove', 'email']); - globalServer.expect('DELETE', '/api/packages/pkg/uploaders/email', + globalPackageServer!.expect('DELETE', '/api/packages/pkg/uploaders/email', (request) { return shelf.Response.ok( jsonEncode({ @@ -83,10 +84,11 @@ await d.validPackage.create(); await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); - var pub = await startPubUploader(globalServer, ['add', 'email']); + await d.credentialsFile(globalPackageServer!, 'access token').create(); + var pub = await startPubUploader(globalPackageServer!, ['add', 'email']); - globalServer.expect('POST', '/api/packages/test_pkg/uploaders', (request) { + globalPackageServer!.expect('POST', '/api/packages/test_pkg/uploaders', + (request) { return shelf.Response.ok( jsonEncode({ 'success': {'message': 'Good job!'} @@ -100,11 +102,12 @@ test('add provides an error', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); + await d.credentialsFile(globalPackageServer!, 'access token').create(); var pub = await startPubUploader( - globalServer, ['--package', 'pkg', 'add', 'email']); + globalPackageServer!, ['--package', 'pkg', 'add', 'email']); - globalServer.expect('POST', '/api/packages/pkg/uploaders', (request) { + globalPackageServer!.expect('POST', '/api/packages/pkg/uploaders', + (request) { return shelf.Response(400, body: jsonEncode({ 'error': {'message': 'Bad job!'} @@ -118,12 +121,12 @@ test('remove provides an error', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); + await d.credentialsFile(globalPackageServer!, 'access token').create(); var pub = await startPubUploader( - globalServer, ['--package', 'pkg', 'remove', 'e/mail']); + globalPackageServer!, ['--package', 'pkg', 'remove', 'e/mail']); - globalServer.expect('DELETE', '/api/packages/pkg/uploaders/e%2Fmail', - (request) { + globalPackageServer! + .expect('DELETE', '/api/packages/pkg/uploaders/e%2Fmail', (request) { return shelf.Response(400, body: jsonEncode({ 'error': {'message': 'Bad job!'} @@ -137,11 +140,11 @@ test('add provides invalid JSON', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); + await d.credentialsFile(globalPackageServer!, 'access token').create(); var pub = await startPubUploader( - globalServer, ['--package', 'pkg', 'add', 'email']); + globalPackageServer!, ['--package', 'pkg', 'add', 'email']); - globalServer.expect('POST', '/api/packages/pkg/uploaders', + globalPackageServer!.expect('POST', '/api/packages/pkg/uploaders', (request) => shelf.Response.ok('{not json')); expect( @@ -153,11 +156,11 @@ test('remove provides invalid JSON', () async { await servePackages(); - await d.credentialsFile(globalServer, 'access token').create(); + await d.credentialsFile(globalPackageServer!, 'access token').create(); var pub = await startPubUploader( - globalServer, ['--package', 'pkg', 'remove', 'email']); + globalPackageServer!, ['--package', 'pkg', 'remove', 'email']); - globalServer.expect('DELETE', '/api/packages/pkg/uploaders/email', + globalPackageServer!.expect('DELETE', '/api/packages/pkg/uploaders/email', (request) => shelf.Response.ok('{not json')); expect(
diff --git a/test/rate_limited_scheduler_test.dart b/test/rate_limited_scheduler_test.dart index 8562b07..e94bbc7 100644 --- a/test/rate_limited_scheduler_test.dart +++ b/test/rate_limited_scheduler_test.dart
@@ -4,6 +4,7 @@ import 'dart:async'; +import 'package:pedantic/pedantic.dart'; import 'package:pub/src/rate_limited_scheduler.dart'; import 'package:test/test.dart';
diff --git a/test/remove/remove_test.dart b/test/remove/remove_test.dart index 8c82527..52194c9 100644 --- a/test/remove/remove_test.dart +++ b/test/remove/remove_test.dart
@@ -12,8 +12,7 @@ void main() { test('removes a package from dependencies', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) => builder.serve('foo', '1.2.3')); await d.appDir({'foo': '1.2.3'}).create(); await pubGet(); @@ -21,16 +20,17 @@ await pubRemove(args: ['foo']); await d.cacheDir({}).validate(); - await d.appPackageConfigFile([]).validate(); + await d.appPackagesFile({}).validate(); await d.appDir().validate(); }); test('removing a package from dependencies does not affect dev_dependencies', () async { - await servePackages() - ..serve('foo', '1.2.3') - ..serve('foo', '1.2.2') - ..serve('bar', '2.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + builder.serve('foo', '1.2.2'); + builder.serve('bar', '2.0.0'); + }); await d.dir(appPath, [ d.file('pubspec.yaml', ''' @@ -49,9 +49,7 @@ await pubRemove(args: ['foo']); await d.cacheDir({'bar': '2.0.0'}).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'bar', version: '2.0.0'), - ]).validate(); + await d.appPackagesFile({'bar': '2.0.0'}).validate(); await d.dir(appPath, [ d.pubspec({ @@ -62,8 +60,7 @@ }); test('dry-run does not actually remove dependency', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) => builder.serve('foo', '1.2.3')); await d.appDir({'foo': '1.2.3'}).create(); await pubGet(); @@ -101,8 +98,7 @@ }); test('removes a package from dev_dependencies', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3'); + await servePackages((builder) => builder.serve('foo', '1.2.3')); await d.dir(appPath, [ d.pubspec({ @@ -115,7 +111,7 @@ await pubRemove(args: ['foo']); await d.cacheDir({}).validate(); - await d.appPackageConfigFile([]).validate(); + await d.appPackagesFile({}).validate(); await d.dir(appPath, [ d.pubspec({'name': 'myapp'}) @@ -124,11 +120,12 @@ test('removes multiple packages from dependencies and dev_dependencies', () async { - await servePackages() - ..serve('foo', '1.2.3') - ..serve('bar', '2.3.4') - ..serve('baz', '3.2.1') - ..serve('jfj', '0.2.1'); + await servePackages((builder) { + builder.serve('foo', '1.2.3'); + builder.serve('bar', '2.3.4'); + builder.serve('baz', '3.2.1'); + builder.serve('jfj', '0.2.1'); + }); await d.dir(appPath, [ d.pubspec({ @@ -142,10 +139,7 @@ await pubRemove(args: ['foo', 'bar', 'baz']); await d.cacheDir({'jfj': '0.2.1'}).validate(); - - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'jfj', version: '0.2.1'), - ]).validate(); + await d.appPackagesFile({'jfj': '0.2.1'}).validate(); await d.dir(appPath, [ d.pubspec({ @@ -156,8 +150,7 @@ }); test('removes git dependencies', () async { - final server = await servePackages(); - server.serve('bar', '1.2.3'); + await servePackages((builder) => builder.serve('bar', '1.2.3')); ensureGit(); final repo = d.git('foo.git', [ @@ -175,16 +168,12 @@ await pubGet(); await pubRemove(args: ['foo']); - - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'bar', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'bar': '1.2.3'}).validate(); await d.appDir({'bar': '1.2.3'}).validate(); }); test('removes path dependencies', () async { - final server = await servePackages(); - server.serve('bar', '1.2.3'); + await servePackages((builder) => builder.serve('bar', '1.2.3')); await d .dir('foo', [d.libDir('foo'), d.libPubspec('foo', '0.0.1')]).create(); @@ -196,23 +185,21 @@ await pubGet(); await pubRemove(args: ['foo']); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'bar', version: '1.2.3'), - ]).validate(); + await d.appPackagesFile({'bar': '1.2.3'}).validate(); await d.appDir({'bar': '1.2.3'}).validate(); }); test('removes hosted dependencies', () async { - final server = await servePackages(); - server.serve('bar', '2.0.1'); + await servePackages((builder) => builder.serve('bar', '2.0.1')); - var custom = await startPackageServer(); - custom.serve('foo', '1.2.3'); + var server = await PackageServer.start((builder) { + builder.serve('foo', '1.2.3'); + }); await d.appDir({ 'foo': { 'version': '1.2.3', - 'hosted': {'name': 'foo', 'url': 'http://localhost:${custom.port}'} + 'hosted': {'name': 'foo', 'url': 'http://localhost:${server.port}'} }, 'bar': '2.0.1' }).create(); @@ -220,16 +207,15 @@ await pubGet(); await pubRemove(args: ['foo']); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'bar', version: '2.0.1'), - ]).validate(); + await d.appPackagesFile({'bar': '2.0.1'}).validate(); await d.appDir({'bar': '2.0.1'}).validate(); }); test('preserves comments', () async { - await servePackages() - ..serve('bar', '1.0.0') - ..serve('foo', '1.0.0'); + await servePackages((builder) { + builder.serve('bar', '1.0.0'); + builder.serve('foo', '1.0.0'); + }); await d.dir(appPath, [ d.file('pubspec.yaml', '''
diff --git a/test/run/allows_dart_extension_test.dart b/test/run/allows_dart_extension_test.dart index 962270f..27640fc 100644 --- a/test/run/allows_dart_extension_test.dart +++ b/test/run/allows_dart_extension_test.dart
@@ -7,7 +7,7 @@ import '../descriptor.dart' as d; import '../test_pub.dart'; -const _script = """ +const SCRIPT = """ import 'dart:io'; main() { @@ -21,7 +21,7 @@ test('allows a ".dart" extension on the argument', () async { await d.dir(appPath, [ d.appPubspec(), - d.dir('bin', [d.file('script.dart', _script)]) + d.dir('bin', [d.file('script.dart', SCRIPT)]) ]).create(); await pubGet();
diff --git a/test/run/forwards_signal_posix_test.dart b/test/run/forwards_signal_posix_test.dart index 5205145..1a32be8 100644 --- a/test/run/forwards_signal_posix_test.dart +++ b/test/run/forwards_signal_posix_test.dart
@@ -23,7 +23,7 @@ ProcessSignal.sigwinch, ]; -const _script = """ +const SCRIPT = """ import 'dart:io'; main() { @@ -41,7 +41,7 @@ test('forwards signals to the inner script', () async { await d.dir(appPath, [ d.appPubspec(), - d.dir('bin', [d.file('script.dart', _script)]) + d.dir('bin', [d.file('script.dart', SCRIPT)]) ]).create(); await pubGet();
diff --git a/test/run/includes_parent_directories_of_entrypoint_test.dart b/test/run/includes_parent_directories_of_entrypoint_test.dart index 6bc4e27..d351ac4 100644 --- a/test/run/includes_parent_directories_of_entrypoint_test.dart +++ b/test/run/includes_parent_directories_of_entrypoint_test.dart
@@ -8,7 +8,7 @@ import '../descriptor.dart' as d; import '../test_pub.dart'; -const _script = r""" +const SCRIPT = r""" import '../../a.dart'; import '../b.dart'; main() { @@ -26,7 +26,7 @@ d.file('a.dart', "var a = 'a';"), d.dir('a', [ d.file('b.dart', "var b = 'b';"), - d.dir('b', [d.file('app.dart', _script)]) + d.dir('b', [d.file('app.dart', SCRIPT)]) ]) ]) ]).create();
diff --git a/test/run/package_api_test.dart b/test/run/package_api_test.dart index 4d05408..161cbf9 100644 --- a/test/run/package_api_test.dart +++ b/test/run/package_api_test.dart
@@ -49,10 +49,11 @@ }); test('a snapshotted application sees a file: package root', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', contents: [ - d.dir('bin', [d.file('script.dart', _script)]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', contents: [ + d.dir('bin', [d.file('script.dart', _script)]) + ]); + }); await d.dir(appPath, [ d.appPubspec({'foo': 'any'}) @@ -72,8 +73,8 @@ .toString())); expect(pub.stdout, emits(p.toUri(p.join(d.sandbox, 'myapp/lib/resource.txt')).toString())); - var fooResourcePath = - p.join(globalServer.pathInCache('foo', '1.0.0'), 'lib/resource.txt'); + var fooResourcePath = p.join( + globalPackageServer!.pathInCache('foo', '1.0.0'), 'lib/resource.txt'); expect(pub.stdout, emits(p.toUri(fooResourcePath).toString())); await pub.shouldExit(0); });
diff --git a/test/run/passes_along_arguments_test.dart b/test/run/passes_along_arguments_test.dart index 624d9f2..66a7d53 100644 --- a/test/run/passes_along_arguments_test.dart +++ b/test/run/passes_along_arguments_test.dart
@@ -7,7 +7,7 @@ import '../descriptor.dart' as d; import '../test_pub.dart'; -const _script = ''' +const SCRIPT = ''' main(List<String> args) { print(args.join(" ")); } @@ -17,7 +17,7 @@ test('passes arguments to the spawned script', () async { await d.dir(appPath, [ d.appPubspec(), - d.dir('bin', [d.file('args.dart', _script)]) + d.dir('bin', [d.file('args.dart', SCRIPT)]) ]).create(); await pubGet();
diff --git a/test/run/precompile_test.dart b/test/run/precompile_test.dart index 2d70b4c..ef8787d 100644 --- a/test/run/precompile_test.dart +++ b/test/run/precompile_test.dart
@@ -7,7 +7,7 @@ import '../descriptor.dart' as d; import '../test_pub.dart'; -const _script = r''' +const SCRIPT = r''' import 'dart:io'; main(List<String> args) { @@ -21,11 +21,11 @@ d.appPubspec({'test': '1.0.0'}), ]).create(); - final server = await servePackages(); - server.serve('test', '1.0.0', contents: [ - d.dir('bin', - [d.file('test.dart', 'main(List<String> args) => print("hello");')]) - ]); + await servePackages((server) => server + ..serve('test', '1.0.0', contents: [ + d.dir('bin', + [d.file('test.dart', 'main(List<String> args) => print("hello");')]) + ])); await pubGet(args: ['--no-precompile']); } @@ -57,10 +57,10 @@ d.appPubspec({'test': '1.0.0'}), ]).create(); - final server = await servePackages(); - server.serve('test', '1.0.0', contents: [ - d.dir('bin', [d.file('test.dart', _script)]) - ]); + await servePackages((server) => server + ..serve('test', '1.0.0', contents: [ + d.dir('bin', [d.file('test.dart', SCRIPT)]) + ])); await pubGet( args: ['--no-precompile'], environment: {'PUB_CACHE': '.pub_cache'}); @@ -80,10 +80,10 @@ d.appPubspec({'test': '1.0.0'}), ]).create(); - final server = await servePackages(); - server.serve('test', '1.0.0', contents: [ - d.dir('bin', [d.file('test.dart', _script)]) - ]); + await servePackages((server) => server + ..serve('test', '1.0.0', contents: [ + d.dir('bin', [d.file('test.dart', SCRIPT)]) + ])); await pubGet( args: ['--precompile'], @@ -104,10 +104,10 @@ d.appPubspec({'test': '1.0.0'}), ]).create(); - final server = await servePackages(); - server.serve('test', '1.0.0', contents: [ - d.dir('bin', [d.file('test.dart', _script)]) - ]); + await servePackages((server) => server + ..serve('test', '1.0.0', contents: [ + d.dir('bin', [d.file('test.dart', SCRIPT)]) + ])); await pubGet( args: ['--precompile'],
diff --git a/test/run/runs_app_in_entrypoint_test.dart b/test/run/runs_app_in_entrypoint_test.dart index 6cb932a..27a7381 100644 --- a/test/run/runs_app_in_entrypoint_test.dart +++ b/test/run/runs_app_in_entrypoint_test.dart
@@ -7,7 +7,7 @@ import '../descriptor.dart' as d; import '../test_pub.dart'; -const _script = """ +const SCRIPT = """ import 'dart:io'; main() { @@ -21,7 +21,7 @@ test('runs a Dart application in the entrypoint package', () async { await d.dir(appPath, [ d.appPubspec(), - d.dir('bin', [d.file('script.dart', _script)]) + d.dir('bin', [d.file('script.dart', SCRIPT)]) ]).create(); await pubGet();
diff --git a/test/run/runs_from_a_dependency_override_after_dependency_test.dart b/test/run/runs_from_a_dependency_override_after_dependency_test.dart index c11bacb..f7e7c7a 100644 --- a/test/run/runs_from_a_dependency_override_after_dependency_test.dart +++ b/test/run/runs_from_a_dependency_override_after_dependency_test.dart
@@ -10,13 +10,14 @@ void main() { // Regression test for issue 23113 test('runs a named Dart application in a dependency', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'name': 'foo', - 'version': '1.0.0' - }, contents: [ - d.dir('bin', [d.file('bar.dart', "main() => print('foobar');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'name': 'foo', + 'version': '1.0.0' + }, contents: [ + d.dir('bin', [d.file('bar.dart', "main() => print('foobar');")]) + ]); + }); await d.dir(appPath, [ d.appPubspec({'foo': null})
diff --git a/test/run/runs_the_script_in_unchecked_mode_test.dart b/test/run/runs_the_script_in_unchecked_mode_test.dart index 026a748..2652706 100644 --- a/test/run/runs_the_script_in_unchecked_mode_test.dart +++ b/test/run/runs_the_script_in_unchecked_mode_test.dart
@@ -7,7 +7,7 @@ import '../descriptor.dart' as d; import '../test_pub.dart'; -const _script = ''' +const SCRIPT = ''' main() { assert(false); print("no checks"); @@ -18,7 +18,7 @@ test('runs the script without assertions by default', () async { await d.dir(appPath, [ d.appPubspec(), - d.dir('bin', [d.file('script.dart', _script)]) + d.dir('bin', [d.file('script.dart', SCRIPT)]) ]).create(); await pubGet();
diff --git a/test/sdk_test.dart b/test/sdk_test.dart index 6165cd5..3f3b00b 100644 --- a/test/sdk_test.dart +++ b/test/sdk_test.dart
@@ -13,8 +13,9 @@ void main() { forBothPubGetAndUpgrade((command) { setUp(() async { - final server = await servePackages(); - server.serve('bar', '1.0.0'); + await servePackages((builder) { + builder.serve('bar', '1.0.0'); + }); await d.dir('flutter', [ d.dir('packages', [ @@ -37,10 +38,13 @@ }).create(); await pubCommand(command, environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')}); - await d.appPackageConfigFile([ - d.packageConfigEntry( - name: 'foo', path: p.join(d.sandbox, 'flutter', 'packages', 'foo')), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), + + await d.dir(appPath, [ + d.packagesFile({ + 'myapp': '.', + 'foo': p.join(d.sandbox, 'flutter', 'packages', 'foo'), + 'bar': '1.0.0' + }) ]).validate(); }); @@ -51,10 +55,11 @@ await pubCommand(command, environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')}); - await d.appPackageConfigFile([ - d.packageConfigEntry( - name: 'baz', - path: p.join(d.sandbox, 'flutter', 'bin', 'cache', 'pkg', 'baz')), + await d.dir(appPath, [ + d.packagesFile({ + 'myapp': '.', + 'baz': p.join(d.sandbox, 'flutter', 'bin', 'cache', 'pkg', 'baz') + }) ]).validate(); }); @@ -89,7 +94,10 @@ deleteEntry(p.join(d.sandbox, 'flutter', 'version')); await pubCommand(command, environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')}); - await d.appPackageConfigFile([]).validate(); + + await d.dir(appPath, [ + d.packagesFile({'myapp': '.'}) + ]).validate(); }); group('fails if', () { @@ -162,10 +170,13 @@ }).create(); await pubCommand(command, environment: {'FUCHSIA_DART_SDK_ROOT': p.join(d.sandbox, 'fuchsia')}); - await d.appPackageConfigFile([ - d.packageConfigEntry( - name: 'foo', path: p.join(d.sandbox, 'fuchsia', 'packages', 'foo')), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), + + await d.dir(appPath, [ + d.packagesFile({ + 'myapp': '.', + 'foo': p.join(d.sandbox, 'fuchsia', 'packages', 'foo'), + 'bar': '1.0.0' + }) ]).validate(); }); });
diff --git a/test/snapshot_test.dart b/test/snapshot_test.dart index 8143f7e..215fcdf 100644 --- a/test/snapshot_test.dart +++ b/test/snapshot_test.dart
@@ -11,15 +11,17 @@ void main() { group('creates a snapshot', () { test('for an immediate dependency', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3', contents: [ - d.dir('bin', [ - d.file('hello.dart', "void main() => print('hello!');"), - d.file('goodbye.dart', "void main() => print('goodbye!');"), - d.file('shell.sh', 'echo shell'), - d.dir('subdir', [d.file('sub.dart', "void main() => print('sub!');")]) - ]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.2.3', contents: [ + d.dir('bin', [ + d.file('hello.dart', "void main() => print('hello!');"), + d.file('goodbye.dart', "void main() => print('goodbye!');"), + d.file('shell.sh', 'echo shell'), + d.dir( + 'subdir', [d.file('sub.dart', "void main() => print('sub!');")]) + ]) + ]); + }); await d.appDir({'foo': '1.2.3'}).create(); @@ -47,8 +49,8 @@ }); test("for an immediate dependency that's also transitive", () async { - await servePackages() - ..serve('foo', '1.2.3', contents: [ + await servePackages((builder) { + builder.serve('foo', '1.2.3', contents: [ d.dir('bin', [ d.file('hello.dart', "void main() => print('hello!');"), d.file('goodbye.dart', "void main() => print('goodbye!');"), @@ -56,8 +58,9 @@ d.dir( 'subdir', [d.file('sub.dart', "void main() => print('sub!');")]) ]) - ]) - ..serve('bar', '1.2.3', deps: {'foo': '1.2.3'}); + ]); + builder.serve('bar', '1.2.3', deps: {'foo': '1.2.3'}); + }); await d.appDir({'foo': '1.2.3'}).create(); @@ -86,11 +89,12 @@ group('again if', () { test('its package is updated', () async { - final server = await servePackages(); - server.serve('foo', '1.2.3', contents: [ - d.dir( - 'bin', [d.file('hello.dart', "void main() => print('hello!');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '1.2.3', contents: [ + d.dir('bin', + [d.file('hello.dart', "void main() => print('hello!');")]) + ]); + }); await d.appDir({'foo': 'any'}).create(); @@ -101,10 +105,12 @@ d.file('hello.dart-$versionSuffix.snapshot', contains('hello!')) ]).validate(); - server.serve('foo', '1.2.4', contents: [ - d.dir('bin', - [d.file('hello.dart', "void main() => print('hello 2!');")]) - ]); + globalPackageServer!.add((builder) { + builder.serve('foo', '1.2.4', contents: [ + d.dir('bin', + [d.file('hello.dart', "void main() => print('hello 2!');")]) + ]); + }); await pubUpgrade( args: ['--precompile'], output: contains('Built foo:hello.')); @@ -119,22 +125,22 @@ }); test('a dependency of its package is updated', () async { - final server = await servePackages(); - - server.serve('foo', '1.2.3', pubspec: { - 'dependencies': {'bar': 'any'} - }, contents: [ - d.dir('bin', [ - d.file('hello.dart', """ + await servePackages((builder) { + builder.serve('foo', '1.2.3', pubspec: { + 'dependencies': {'bar': 'any'} + }, contents: [ + d.dir('bin', [ + d.file('hello.dart', """ import 'package:bar/bar.dart'; void main() => print(message); """) - ]) - ]); - server.serve('bar', '1.2.3', contents: [ - d.dir('lib', [d.file('bar.dart', "final message = 'hello!';")]) - ]); + ]) + ]); + builder.serve('bar', '1.2.3', contents: [ + d.dir('lib', [d.file('bar.dart', "final message = 'hello!';")]) + ]); + }); await d.appDir({'foo': 'any'}).create(); @@ -145,9 +151,11 @@ d.file('hello.dart-$versionSuffix.snapshot', contains('hello!')) ]).validate(); - server.serve('bar', '1.2.4', contents: [ - d.dir('lib', [d.file('bar.dart', "final message = 'hello 2!';")]), - ]); + globalPackageServer!.add((builder) { + builder.serve('bar', '1.2.4', contents: [ + d.dir('lib', [d.file('bar.dart', "final message = 'hello 2!';")]), + ]); + }); await pubUpgrade( args: ['--precompile'], output: contains('Built foo:hello.')); @@ -199,11 +207,12 @@ }); test('the SDK is out of date', () async { - final server = await servePackages(); - server.serve('foo', '5.6.7', contents: [ - d.dir( - 'bin', [d.file('hello.dart', "void main() => print('hello!');")]) - ]); + await servePackages((builder) { + builder.serve('foo', '5.6.7', contents: [ + d.dir('bin', + [d.file('hello.dart', "void main() => print('hello!');")]) + ]); + }); await d.appDir({'foo': '5.6.7'}).create();
diff --git a/test/test_pub.dart b/test/test_pub.dart index e30c590..22d8cfa 100644 --- a/test/test_pub.dart +++ b/test/test_pub.dart
@@ -36,9 +36,11 @@ import 'package:test_process/test_process.dart'; import 'descriptor.dart' as d; +import 'descriptor_server.dart'; import 'package_server.dart'; -export 'package_server.dart' show PackageServer; +export 'descriptor_server.dart'; +export 'package_server.dart'; /// A [Matcher] that matches JavaScript generated by dart2js with minification /// enabled. @@ -373,12 +375,11 @@ List<String>? args, String authMethod = 'oauth2', Map<String, String>? environment, - String path = '', }) async { var tokenEndpoint = Uri.parse(server.url).resolve('/token').toString(); args = ['lish', ...?args]; return await startPub(args: args, tokenEndpoint: tokenEndpoint, environment: { - 'PUB_HOSTED_URL': server.url + path, + 'PUB_HOSTED_URL': server.url, '_PUB_TEST_AUTH_METHOD': authMethod, if (environment != null) ...environment, }); @@ -411,19 +412,29 @@ String testVersion = '0.1.2+3'; /// Gets the environment variables used to run pub in a test context. -Map<String, String> getPubTestEnvironment([String? tokenEndpoint]) => { - 'CI': 'false', // unless explicitly given tests don't run pub in CI mode - '_PUB_TESTING': 'true', - '_PUB_TEST_CONFIG_DIR': _pathInSandbox(configPath), - 'PUB_CACHE': _pathInSandbox(cachePath), - 'PUB_ENVIRONMENT': 'test-environment', +Map<String, String> getPubTestEnvironment([String? tokenEndpoint]) { + var environment = { + 'CI': 'false', // unless explicitly given tests don't run pub in CI mode + '_PUB_TESTING': 'true', + '_PUB_TEST_CONFIG_DIR': _pathInSandbox(configPath), + 'PUB_CACHE': _pathInSandbox(cachePath), + 'PUB_ENVIRONMENT': 'test-environment', - // Ensure a known SDK version is set for the tests that rely on that. - '_PUB_TEST_SDK_VERSION': testVersion, - if (tokenEndpoint != null) '_PUB_TEST_TOKEN_ENDPOINT': tokenEndpoint, - if (_globalServer?.port != null) - 'PUB_HOSTED_URL': 'http://localhost:${_globalServer?.port}' - }; + // Ensure a known SDK version is set for the tests that rely on that. + '_PUB_TEST_SDK_VERSION': testVersion + }; + + if (tokenEndpoint != null) { + environment['_PUB_TEST_TOKEN_ENDPOINT'] = tokenEndpoint; + } + + var server = globalServer; + if (server != null) { + environment['PUB_HOSTED_URL'] = 'http://localhost:${server.port}'; + } + + return environment; +} /// The path to the root of pub's sources in the pub repo. final String _pubRoot = (() { @@ -466,7 +477,7 @@ var dartArgs = ['--packages=$dotPackagesPath', '--enable-asserts']; dartArgs - ..addAll([pubPath, if (!verbose) '--verbosity=normal']) + ..addAll([pubPath, if (verbose) '--verbose']) ..addAll(args); final mergedEnvironment = getPubTestEnvironment(tokenEndpoint); @@ -495,8 +506,8 @@ StreamSplitter<Pair<log.Level, String>> createLogSplitter() { return StreamSplitter(StreamGroup.merge([ - _outputToLog(super.stdoutStream(), log.Level.message), - _outputToLog(super.stderrStream(), log.Level.error) + _outputToLog(super.stdoutStream(), log.Level.MESSAGE), + _outputToLog(super.stderrStream(), log.Level.ERROR) ])); } @@ -533,12 +544,12 @@ final _logLineRegExp = RegExp(r'^([A-Z ]{4})[:|] (.*)$'); final Map<String, log.Level> _logLevels = [ - log.Level.error, - log.Level.warning, - log.Level.message, - log.Level.io, - log.Level.solver, - log.Level.fine + log.Level.ERROR, + log.Level.WARNING, + log.Level.MESSAGE, + log.Level.IO, + log.Level.SOLVER, + log.Level.FINE ].fold({}, (levels, level) { levels[level.name] = level; return levels; @@ -560,7 +571,7 @@ @override Stream<String> stdoutStream() { return _logSplitter.split().expand((entry) { - if (entry.first != log.Level.message) return []; + if (entry.first != log.Level.MESSAGE) return []; return [entry.last]; }); } @@ -568,7 +579,7 @@ @override Stream<String> stderrStream() { return _logSplitter.split().expand((entry) { - if (entry.first != log.Level.error && entry.first != log.Level.warning) { + if (entry.first != log.Level.ERROR && entry.first != log.Level.WARNING) { return []; } return [entry.last]; @@ -578,9 +589,9 @@ /// A stream of log messages that are silent by default. Stream<String> silentStream() { return _logSplitter.split().expand((entry) { - if (entry.first == log.Level.message) return []; - if (entry.first == log.Level.error) return []; - if (entry.first == log.Level.warning) return []; + if (entry.first == log.Level.MESSAGE) return []; + if (entry.first == log.Level.ERROR) return []; + if (entry.first == log.Level.WARNING) return []; return [entry.last]; }); } @@ -903,9 +914,9 @@ line = line .replaceAll(d.sandbox, r'$SANDBOX') .replaceAll(Platform.pathSeparator, '/'); - var port = _globalServer?.port; - if (port != null) { - line = line.replaceAll(port.toString(), '\$PORT'); + var packageServer = globalPackageServer; + if (packageServer != null) { + line = line.replaceAll(packageServer.port.toString(), '\$PORT'); } return line; }); @@ -953,28 +964,3 @@ } buffer.write('\n'); } - -/// The current global [PackageServer]. -PackageServer get globalServer => _globalServer!; -PackageServer? _globalServer; - -/// Creates an HTTP server that replicates the structure of pub.dartlang.org and -/// makes it the current [globalServer]. -Future<PackageServer> servePackages() async { - final server = await startPackageServer(); - _globalServer = server; - - addTearDown(() { - _globalServer = null; - }); - return server; -} - -Future<PackageServer> startPackageServer() async { - final server = await PackageServer.start(); - - addTearDown(() async { - await server.close(); - }); - return server; -}
diff --git a/test/testdata/goldens/embedding/embedding_test/logfile is written with --verbose and on unexpected exceptions.txt b/test/testdata/goldens/embedding/embedding_test/logfile is written with --verbose and on unexpected exceptions.txt deleted file mode 100644 index fc69b03..0000000 --- a/test/testdata/goldens/embedding/embedding_test/logfile is written with --verbose and on unexpected exceptions.txt +++ /dev/null
@@ -1,308 +0,0 @@ -# GENERATED BY: test/embedding/embedding_test.dart - -$ tool/test-bin/pub_command_runner.dart pub --verbose get -MSG : Resolving dependencies... -MSG : + foo 1.0.0 -MSG : Downloading foo 1.0.0... -MSG : Changed 1 dependency! -MSG : Logs written to $SANDBOX/cache/log/pub_log.txt. -[E] FINE: Pub 0.1.2+3 -[E] SLVR: fact: myapp is 0.0.0 -[E] SLVR: derived: myapp -[E] SLVR: fact: myapp depends on foo any -[E] SLVR: selecting myapp -[E] SLVR: derived: foo any -[E] IO : Get versions from http://localhost:$PORT/api/packages/foo. -[E] IO : HTTP GET http://localhost:$PORT/api/packages/foo -[E] | Accept: application/vnd.pub.v2+json -[E] | X-Pub-OS: $OS -[E] | X-Pub-Command: get -[E] | X-Pub-Session-ID: $ID -[E] | X-Pub-Environment: test-environment -[E] | X-Pub-Reason: direct -[E] | user-agent: Dart pub 0.1.2+3 -[E] IO : HTTP response 200 OK for GET http://localhost:$PORT/api/packages/foo -[E] | took: $TIME -[E] | date: $TIME -[E] | content-length: 197 -[E] | x-frame-options: SAMEORIGIN -[E] | content-type: text/plain; charset=utf-8 -[E] | x-xss-protection: 1; mode=block -[E] | x-content-type-options: nosniff -[E] | server: dart:io with Shelf -[E] IO : Writing $N characters to text file $SANDBOX/cache/hosted/localhost%58$PORT/.cache/foo-versions.json. -[E] FINE: Contents: -[E] | {"name":"foo","uploaders":["nweiz@google.com"],"versions":[{"pubspec":{"name":"foo","version":"1.0.0"},"version":"1.0.0","archive_url":"http://localhost:$PORT/packages/foo/versions/1.0.0.tar.gz"}],"_fetchedAt": "$TIME"} -[E] SLVR: selecting foo 1.0.0 -[E] SLVR: Version solving took: $TIME -[E] | Tried 1 solutions. -[E] FINE: Resolving dependencies finished ($TIME) -[E] IO : Get package from http://localhost:$PORT/packages/foo/versions/1.0.0.tar.gz. -[E] IO : Created temp directory $DIR -[E] IO : HTTP GET http://localhost:$PORT/packages/foo/versions/1.0.0.tar.gz -[E] | X-Pub-OS: $OS -[E] | X-Pub-Command: get -[E] | X-Pub-Session-ID: $ID -[E] | X-Pub-Environment: test-environment -[E] | X-Pub-Reason: direct -[E] | user-agent: Dart pub 0.1.2+3 -[E] IO : HTTP response 200 OK for GET http://localhost:$PORT/packages/foo/versions/1.0.0.tar.gz -[E] | took: $TIME -[E] | transfer-encoding: chunked -[E] | date: $TIME -[E] | x-frame-options: SAMEORIGIN -[E] | content-type: text/plain; charset=utf-8 -[E] | x-xss-protection: 1; mode=block -[E] | x-content-type-options: nosniff -[E] | server: dart:io with Shelf -[E] IO : Creating $FILE from stream -[E] FINE: Created $FILE from stream -[E] IO : Created temp directory $DIR -[E] IO : Reading binary file $FILE. -[E] FINE: Extracting .tar.gz stream to $DIR -[E] IO : Creating $FILE from stream -[E] FINE: Created $FILE from stream -[E] IO : Creating $FILE from stream -[E] FINE: Created $FILE from stream -[E] FINE: Extracted .tar.gz to $DIR -[E] IO : Renaming directory $A to $B -[E] IO : Deleting directory $DIR -[E] IO : Writing $N characters to text file pubspec.lock. -[E] FINE: Contents: -[E] | # Generated by pub -[E] | # See https://dart.dev/tools/pub/glossary#lockfile -[E] | packages: -[E] | foo: -[E] | dependency: "direct main" -[E] | description: -[E] | name: foo -[E] | url: "http://localhost:$PORT" -[E] | source: hosted -[E] | version: "1.0.0" -[E] | sdks: -[E] | dart: ">=0.1.2 <1.0.0" -[E] IO : Writing $N characters to text file .dart_tool/package_config.json. -[E] FINE: Contents: -[E] | { -[E] | "configVersion": 2, -[E] | "packages": [ -[E] | { -[E] | "name": "foo", -[E] | "rootUri": "file://$SANDBOX/cache/hosted/localhost%2558$PORT/foo-1.0.0", -[E] | "packageUri": "lib/", -[E] | "languageVersion": "2.7" -[E] | }, -[E] | { -[E] | "name": "myapp", -[E] | "rootUri": "../", -[E] | "packageUri": "lib/", -[E] | "languageVersion": "0.1" -[E] | } -[E] | ], -[E] | "generated": "$TIME", -[E] | "generator": "pub", -[E] | "generatorVersion": "0.1.2+3" -[E] | } -[E] IO : Writing $N characters to text file $SANDBOX/cache/log/pub_log.txt. - --------------------------------- END OF OUTPUT --------------------------------- - -Information about the latest pub run. - -If you believe something is not working right, you can go to -https://github.com/dart-lang/pub/issues/new to post a new issue and attach this file. - -Before making this file public, make sure to remove any sensitive information! - -Pub version: 0.1.2+3 -Created: $TIME -FLUTTER_ROOT: <not set> -PUB_HOSTED_URL: http://localhost:$PORT -PUB_CACHE: "$SANDBOX/cache" -Command: dart pub --verbose get -Platform: $OS - ----- $SANDBOX/myapp/pubspec.yaml ---- -{"name":"myapp","environment":{"sdk":">=0.1.2 <1.0.0"},"dependencies":{"foo":"any"}} ----- End pubspec.yaml ---- ----- $SANDBOX/myapp/pubspec.lock ---- -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - foo: - dependency: "direct main" - description: - name: foo - url: "http://localhost:$PORT" - source: hosted - version: "1.0.0" -sdks: - dart: ">=0.1.2 <1.0.0" - ----- End pubspec.lock ---- ----- Log transcript ---- -FINE: Pub 0.1.2+3 -MSG : Resolving dependencies... -SLVR: fact: myapp is 0.0.0 -SLVR: derived: myapp -SLVR: fact: myapp depends on foo any -SLVR: selecting myapp -SLVR: derived: foo any -IO : Get versions from http://localhost:$PORT/api/packages/foo. -IO : HTTP GET http://localhost:$PORT/api/packages/foo - | Accept: application/vnd.pub.v2+json - | X-Pub-OS: $OS - | X-Pub-Command: get - | X-Pub-Session-ID: $ID - | X-Pub-Environment: test-environment - | X-Pub-Reason: direct - | user-agent: Dart pub 0.1.2+3 -IO : HTTP response 200 OK for GET http://localhost:$PORT/api/packages/foo - | took: $TIME - | date: $TIME - | content-length: 197 - | x-frame-options: SAMEORIGIN - | content-type: text/plain; charset=utf-8 - | x-xss-protection: 1; mode=block - | x-content-type-options: nosniff - | server: dart:io with Shelf -IO : Writing $N characters to text file $SANDBOX/cache/hosted/localhost%58$PORT/.cache/foo-versions.json. -FINE: Contents: - | {"name":"foo","uploaders":["nweiz@google.com"],"versions":[{"pubspec":{"name":"foo","version":"1.0.0"},"version":"1.0.0","archive_url":"http://localhost:$PORT/packages/foo/versions/1.0.0.tar.gz"}],"_fetchedAt": "$TIME"} -SLVR: selecting foo 1.0.0 -SLVR: Version solving took: $TIME - | Tried 1 solutions. -FINE: Resolving dependencies finished ($TIME) -MSG : + foo 1.0.0 -IO : Get package from http://localhost:$PORT/packages/foo/versions/1.0.0.tar.gz. -MSG : Downloading foo 1.0.0... -IO : Created temp directory $DIR -IO : HTTP GET http://localhost:$PORT/packages/foo/versions/1.0.0.tar.gz - | X-Pub-OS: $OS - | X-Pub-Command: get - | X-Pub-Session-ID: $ID - | X-Pub-Environment: test-environment - | X-Pub-Reason: direct - | user-agent: Dart pub 0.1.2+3 -IO : HTTP response 200 OK for GET http://localhost:$PORT/packages/foo/versions/1.0.0.tar.gz - | took: $TIME - | transfer-encoding: chunked - | date: $TIME - | x-frame-options: SAMEORIGIN - | content-type: text/plain; charset=utf-8 - | x-xss-protection: 1; mode=block - | x-content-type-options: nosniff - | server: dart:io with Shelf -IO : Creating $FILE from stream -FINE: Created $FILE from stream -IO : Created temp directory $DIR -IO : Reading binary file $FILE. -FINE: Extracting .tar.gz stream to $DIR -IO : Creating $FILE from stream -FINE: Created $FILE from stream -IO : Creating $FILE from stream -FINE: Created $FILE from stream -FINE: Extracted .tar.gz to $DIR -IO : Renaming directory $A to $B -IO : Deleting directory $DIR -IO : Writing $N characters to text file pubspec.lock. -FINE: Contents: - | # Generated by pub - | # See https://dart.dev/tools/pub/glossary#lockfile - | packages: - | foo: - | dependency: "direct main" - | description: - | name: foo - | url: "http://localhost:$PORT" - | source: hosted - | version: "1.0.0" - | sdks: - | dart: ">=0.1.2 <1.0.0" -MSG : Changed 1 dependency! -IO : Writing $N characters to text file .dart_tool/package_config.json. -FINE: Contents: - | { - | "configVersion": 2, - | "packages": [ - | { - | "name": "foo", - | "rootUri": "file://$SANDBOX/cache/hosted/localhost%2558$PORT/foo-1.0.0", - | "packageUri": "lib/", - | "languageVersion": "2.7" - | }, - | { - | "name": "myapp", - | "rootUri": "../", - | "packageUri": "lib/", - | "languageVersion": "0.1" - | } - | ], - | "generated": "$TIME", - | "generator": "pub", - | "generatorVersion": "0.1.2+3" - | } ----- End log transcript ---- --------------------------------- END OF OUTPUT --------------------------------- - -$ tool/test-bin/pub_command_runner.dart pub fail -[E] Bad state: Pub has crashed -[E] tool/test-bin/pub_command_runner.dart $LINE:$COL ThrowingCommand.runProtected -[E] package:pub/src/command.dart $LINE:$COL PubCommand.run.<fn> -[E] package:pub/src/command.dart $LINE:$COL PubCommand.run.<fn> -[E] dart:async new Future.sync -[E] package:pub/src/utils.dart $LINE:$COL captureErrors.wrappedCallback -[E] dart:async runZonedGuarded -[E] package:pub/src/utils.dart $LINE:$COL captureErrors -[E] package:pub/src/command.dart $LINE:$COL PubCommand.run -[E] package:args/command_runner.dart $LINE:$COL CommandRunner.runCommand -[E] tool/test-bin/pub_command_runner.dart $LINE:$COL Runner.runCommand -[E] tool/test-bin/pub_command_runner.dart $LINE:$COL Runner.run -[E] tool/test-bin/pub_command_runner.dart $LINE:$COL main -[E] This is an unexpected error. The full log and other details are collected in: -[E] -[E] $SANDBOX/cache/log/pub_log.txt -[E] -[E] Consider creating an issue on https://github.com/dart-lang/pub/issues/new -[E] and attaching the relevant parts of that log file. - --------------------------------- END OF OUTPUT --------------------------------- - -Information about the latest pub run. - -If you believe something is not working right, you can go to -https://github.com/dart-lang/pub/issues/new to post a new issue and attach this file. - -Before making this file public, make sure to remove any sensitive information! - -Pub version: 0.1.2+3 -Created: $TIME -FLUTTER_ROOT: <not set> -PUB_HOSTED_URL: http://localhost:$PORT -PUB_CACHE: "$SANDBOX/cache" -Command: dart pub fail -Platform: $OS - ----- Log transcript ---- -FINE: Pub 0.1.2+3 -ERR : Bad state: Pub has crashed -FINE: Exception type: StateError -ERR : tool/test-bin/pub_command_runner.dart $LINE:$COL ThrowingCommand.runProtected - | package:pub/src/command.dart $LINE:$COL PubCommand.run.<fn> - | package:pub/src/command.dart $LINE:$COL PubCommand.run.<fn> - | dart:async new Future.sync - | package:pub/src/utils.dart $LINE:$COL captureErrors.wrappedCallback - | dart:async runZonedGuarded - | package:pub/src/utils.dart $LINE:$COL captureErrors - | package:pub/src/command.dart $LINE:$COL PubCommand.run - | package:args/command_runner.dart $LINE:$COL CommandRunner.runCommand - | tool/test-bin/pub_command_runner.dart $LINE:$COL Runner.runCommand - | tool/test-bin/pub_command_runner.dart $LINE:$COL Runner.run - | tool/test-bin/pub_command_runner.dart $LINE:$COL main -ERR : This is an unexpected error. The full log and other details are collected in: - | - | $SANDBOX/cache/log/pub_log.txt - | - | Consider creating an issue on https://github.com/dart-lang/pub/issues/new - | and attaching the relevant parts of that log file. ----- End log transcript ----
diff --git a/test/testdata/goldens/help_test/pub add --help.txt b/test/testdata/goldens/help_test/pub add --help.txt index 3d1f429..5d32e5e 100644 --- a/test/testdata/goldens/help_test/pub add --help.txt +++ b/test/testdata/goldens/help_test/pub add --help.txt
@@ -2,25 +2,22 @@ ## Section 0 $ pub add --help -Add dependencies to pubspec.yaml. +Add a dependency to pubspec.yaml. -Usage: pub add <package>[:<constraint>] [<package2>[:<constraint2>]...] [options] --h, --help Print this usage information. --d, --dev Adds to the development dependencies instead. - --git-url Git URL of the package - --git-ref Git branch or commit to be retrieved - --git-path Path of git package in repository - --hosted-url URL of package host server - --path Add package from local path - --sdk=<[flutter]> add package from SDK source - [flutter] - --[no-]offline Use cached packages instead of accessing the - network. --n, --dry-run Report what dependencies would change but don't - change any. - --[no-]precompile Build executables in immediate dependencies. --C, --directory=<dir> Run this in the directory <dir>. - --legacy-packages-file Generate the legacy ".packages" file +Usage: pub add <package>[:<constraint>] [options] +-h, --help Print this usage information. +-d, --dev Adds package to the development dependencies instead. + --git-url Git URL of the package + --git-ref Git branch or commit to be retrieved + --git-path Path of git package in repository + --hosted-url URL of package host server + --path Local path + --sdk SDK source for package + --[no-]offline Use cached packages instead of accessing the network. +-n, --dry-run Report what dependencies would change but don't change + any. + --[no-]precompile Build executables in immediate dependencies. +-C, --directory=<dir> Run this in the directory<dir>. Run "pub help" to see global options. See https://dart.dev/tools/pub/cmd/pub-add for detailed documentation.
diff --git a/test/testdata/goldens/help_test/pub downgrade --help.txt b/test/testdata/goldens/help_test/pub downgrade --help.txt index ddf71e7..4497da2 100644 --- a/test/testdata/goldens/help_test/pub downgrade --help.txt +++ b/test/testdata/goldens/help_test/pub downgrade --help.txt
@@ -7,13 +7,11 @@ Usage: pub downgrade [dependencies...] --h, --help Print this usage information. - --[no-]offline Use cached packages instead of accessing the - network. --n, --dry-run Report what dependencies would change but don't - change any. --C, --directory=<dir> Run this in the directory<dir>. - --legacy-packages-file Generate the legacy ".packages" file +-h, --help Print this usage information. + --[no-]offline Use cached packages instead of accessing the network. +-n, --dry-run Report what dependencies would change but don't change + any. +-C, --directory=<dir> Run this in the directory<dir>. Run "pub help" to see global options. See https://dart.dev/tools/pub/cmd/pub-downgrade for detailed documentation.
diff --git a/test/testdata/goldens/help_test/pub get --help.txt b/test/testdata/goldens/help_test/pub get --help.txt index 104f69c..74648a2 100644 --- a/test/testdata/goldens/help_test/pub get --help.txt +++ b/test/testdata/goldens/help_test/pub get --help.txt
@@ -5,14 +5,12 @@ Get the current package's dependencies. Usage: pub get <subcommand> [arguments...] --h, --help Print this usage information. - --[no-]offline Use cached packages instead of accessing the - network. --n, --dry-run Report what dependencies would change but don't - change any. - --[no-]precompile Build executables in immediate dependencies. - --legacy-packages-file Generate the legacy ".packages" file --C, --directory=<dir> Run this in the directory<dir>. +-h, --help Print this usage information. + --[no-]offline Use cached packages instead of accessing the network. +-n, --dry-run Report what dependencies would change but don't change + any. + --[no-]precompile Build executables in immediate dependencies. +-C, --directory=<dir> Run this in the directory<dir>. Run "pub help" to see global options. See https://dart.dev/tools/pub/cmd/pub-get for detailed documentation.
diff --git a/test/testdata/goldens/help_test/pub remove --help.txt b/test/testdata/goldens/help_test/pub remove --help.txt index b82f9b6..7d14ed0 100644 --- a/test/testdata/goldens/help_test/pub remove --help.txt +++ b/test/testdata/goldens/help_test/pub remove --help.txt
@@ -5,14 +5,12 @@ Removes a dependency from the current package. Usage: pub remove <package> --h, --help Print this usage information. - --[no-]offline Use cached packages instead of accessing the - network. --n, --dry-run Report what dependencies would change but don't - change any. - --[no-]precompile Precompile executables in immediate dependencies. --C, --directory=<dir> Run this in the directory<dir>. - --legacy-packages-file Generate the legacy ".packages" file +-h, --help Print this usage information. + --[no-]offline Use cached packages instead of accessing the network. +-n, --dry-run Report what dependencies would change but don't change + any. + --[no-]precompile Precompile executables in immediate dependencies. +-C, --directory=<dir> Run this in the directory<dir>. Run "pub help" to see global options. See https://dart.dev/tools/pub/cmd/pub-remove for detailed documentation.
diff --git a/test/testdata/goldens/help_test/pub upgrade --help.txt b/test/testdata/goldens/help_test/pub upgrade --help.txt index c787951..d1a29b9 100644 --- a/test/testdata/goldens/help_test/pub upgrade --help.txt +++ b/test/testdata/goldens/help_test/pub upgrade --help.txt
@@ -5,18 +5,16 @@ Upgrade the current package's dependencies to latest versions. Usage: pub upgrade [dependencies...] --h, --help Print this usage information. - --[no-]offline Use cached packages instead of accessing the - network. --n, --dry-run Report what dependencies would change but don't - change any. - --[no-]precompile Precompile executables in immediate dependencies. - --null-safety Upgrade constraints in pubspec.yaml to null-safety - versions - --legacy-packages-file Generate the legacy ".packages" file - --major-versions Upgrades packages to their latest resolvable - versions, and updates pubspec.yaml. --C, --directory=<dir> Run this in the directory<dir>. +-h, --help Print this usage information. + --[no-]offline Use cached packages instead of accessing the network. +-n, --dry-run Report what dependencies would change but don't change + any. + --[no-]precompile Precompile executables in immediate dependencies. + --null-safety Upgrade constraints in pubspec.yaml to null-safety + versions + --major-versions Upgrades packages to their latest resolvable versions, + and updates pubspec.yaml. +-C, --directory=<dir> Run this in the directory<dir>. Run "pub help" to see global options. See https://dart.dev/tools/pub/cmd/pub-upgrade for detailed documentation.
diff --git a/test/testdata/goldens/hosted/fail_gracefully_on_bad_version_listing_response_test/401-with-message.txt b/test/testdata/goldens/hosted/fail_gracefully_on_bad_version_listing_response_test/401-with-message.txt deleted file mode 100644 index 8dcaaf5..0000000 --- a/test/testdata/goldens/hosted/fail_gracefully_on_bad_version_listing_response_test/401-with-message.txt +++ /dev/null
@@ -1,13 +0,0 @@ -# GENERATED BY: test/hosted/fail_gracefully_on_bad_version_listing_response_test.dart - -## Section 0 -$ pub get -Resolving dependencies... -[STDERR] Because myapp depends on foo any which doesn't exist (authentication failed), version solving failed. -[STDERR] -[STDERR] http://localhost:$PORT package repository requested authentication! -[STDERR] You can provide credentials using: -[STDERR] pub token add http://localhost:$PORT -[STDERR] <message> -[EXIT CODE] 69 -
diff --git a/test/testdata/goldens/hosted/fail_gracefully_on_bad_version_listing_response_test/401.txt b/test/testdata/goldens/hosted/fail_gracefully_on_bad_version_listing_response_test/401.txt deleted file mode 100644 index 68d5bd0..0000000 --- a/test/testdata/goldens/hosted/fail_gracefully_on_bad_version_listing_response_test/401.txt +++ /dev/null
@@ -1,12 +0,0 @@ -# GENERATED BY: test/hosted/fail_gracefully_on_bad_version_listing_response_test.dart - -## Section 0 -$ pub get -Resolving dependencies... -[STDERR] Because myapp depends on foo any which doesn't exist (authentication failed), version solving failed. -[STDERR] -[STDERR] http://localhost:$PORT package repository requested authentication! -[STDERR] You can provide credentials using: -[STDERR] pub token add http://localhost:$PORT -[EXIT CODE] 69 -
diff --git a/test/testdata/goldens/hosted/fail_gracefully_on_bad_version_listing_response_test/403-with-message.txt b/test/testdata/goldens/hosted/fail_gracefully_on_bad_version_listing_response_test/403-with-message.txt deleted file mode 100644 index 882660c..0000000 --- a/test/testdata/goldens/hosted/fail_gracefully_on_bad_version_listing_response_test/403-with-message.txt +++ /dev/null
@@ -1,13 +0,0 @@ -# GENERATED BY: test/hosted/fail_gracefully_on_bad_version_listing_response_test.dart - -## Section 0 -$ pub get -Resolving dependencies... -[STDERR] Because myapp depends on foo any which doesn't exist (authorization failed), version solving failed. -[STDERR] -[STDERR] Insufficient permissions to the resource at the http://localhost:$PORT package repository. -[STDERR] You can modify credentials using: -[STDERR] pub token add http://localhost:$PORT -[STDERR] <message> -[EXIT CODE] 69 -
diff --git a/test/testdata/goldens/hosted/fail_gracefully_on_bad_version_listing_response_test/403.txt b/test/testdata/goldens/hosted/fail_gracefully_on_bad_version_listing_response_test/403.txt deleted file mode 100644 index f8a5af9..0000000 --- a/test/testdata/goldens/hosted/fail_gracefully_on_bad_version_listing_response_test/403.txt +++ /dev/null
@@ -1,12 +0,0 @@ -# GENERATED BY: test/hosted/fail_gracefully_on_bad_version_listing_response_test.dart - -## Section 0 -$ pub get -Resolving dependencies... -[STDERR] Because myapp depends on foo any which doesn't exist (authorization failed), version solving failed. -[STDERR] -[STDERR] Insufficient permissions to the resource at the http://localhost:$PORT package repository. -[STDERR] You can modify credentials using: -[STDERR] pub token add http://localhost:$PORT -[EXIT CODE] 69 -
diff --git a/test/testdata/goldens/hosted/fail_gracefully_on_bad_version_listing_response_test/bad_json.txt b/test/testdata/goldens/hosted/fail_gracefully_on_bad_version_listing_response_test/bad_json.txt deleted file mode 100644 index 8e446c2..0000000 --- a/test/testdata/goldens/hosted/fail_gracefully_on_bad_version_listing_response_test/bad_json.txt +++ /dev/null
@@ -1,10 +0,0 @@ -# GENERATED BY: test/hosted/fail_gracefully_on_bad_version_listing_response_test.dart - -## Section 0 -$ pub get -Resolving dependencies... -[STDERR] Because myapp depends on foo any which doesn't exist (Got badly formatted response trying to find package foo at http://localhost:$PORT), version solving failed. -[STDERR] -[STDERR] Check that "http://localhost:$PORT" is a valid package repository. -[EXIT CODE] 65 -
diff --git a/test/testdata/goldens/hosted/fail_gracefully_with_hint_test/supports two hints.txt b/test/testdata/goldens/hosted/fail_gracefully_with_hint_test/supports two hints.txt deleted file mode 100644 index a45b0f0..0000000 --- a/test/testdata/goldens/hosted/fail_gracefully_with_hint_test/supports two hints.txt +++ /dev/null
@@ -1,13 +0,0 @@ -# GENERATED BY: test/hosted/fail_gracefully_with_hint_test.dart - -## Section 0 -$ pub get --offline -Resolving dependencies... -[STDERR] Because foo <1.2.4 requires the Flutter SDK and foo >=1.2.4 depends on bar any, every version of foo requires bar any. -[STDERR] So, because bar doesn't exist (could not find package bar in cache) and myapp depends on foo any, version solving failed. -[STDERR] -[STDERR] Flutter users should run `flutter pub get` instead of `dart pub get`. -[STDERR] -[STDERR] Try again without --offline! -[EXIT CODE] 69 -
diff --git a/test/testdata/goldens/upgrade/example_warns_about_major_versions_test/pub upgrade --major-versions does not update major versions in example~.txt b/test/testdata/goldens/upgrade/example_warns_about_major_versions_test/pub upgrade --major-versions does not update major versions in example~.txt index ae304ea..2cc96c0 100644 --- a/test/testdata/goldens/upgrade/example_warns_about_major_versions_test/pub upgrade --major-versions does not update major versions in example~.txt +++ b/test/testdata/goldens/upgrade/example_warns_about_major_versions_test/pub upgrade --major-versions does not update major versions in example~.txt
@@ -17,7 +17,9 @@ ## Section 1 $ pub upgrade --major-versions --directory example Resolving dependencies in example... + bar 2.0.0 > foo 2.0.0 (was 1.0.0) + myapp 0.0.0 from path . Changed 1 dependency in example! Changed 1 constraint in pubspec.yaml:
diff --git a/test/token/error_message_test.dart b/test/token/error_message_test.dart index 53431a5..b7bc553 100644 --- a/test/token/error_message_test.dart +++ b/test/token/error_message_test.dart
@@ -9,7 +9,7 @@ import '../test_pub.dart'; void respondWithWwwAuthenticate(String headerValue) { - globalServer.expect('GET', '/api/packages/versions/new', (request) { + globalPackageServer!.expect('GET', '/api/packages/versions/new', (request) { return shelf.Response(403, headers: {'www-authenticate': headerValue}); }); } @@ -18,7 +18,7 @@ return runPub( args: ['lish'], environment: { - 'PUB_HOSTED_URL': globalServer.url, + 'PUB_HOSTED_URL': globalPackageServer!.url, '_PUB_TEST_AUTH_METHOD': 'token', }, exitCode: 65, @@ -34,7 +34,7 @@ await d.tokensFile({ 'version': 1, 'hosted': [ - {'url': globalServer.url, 'token': 'access token'}, + {'url': globalPackageServer!.url, 'token': 'access token'}, ] }).create(); });
diff --git a/test/token/token_authentication_test.dart b/test/token/token_authentication_test.dart index c020ac0..667c47f 100644 --- a/test/token/token_authentication_test.dart +++ b/test/token/token_authentication_test.dart
@@ -16,14 +16,14 @@ await d.tokensFile({ 'version': 1, 'hosted': [ - {'url': globalServer.url, 'env': 'TOKEN'}, + {'url': globalPackageServer!.url, 'env': 'TOKEN'}, ] }).create(); - var pub = await startPublish(globalServer, + var pub = await startPublish(globalPackageServer!, authMethod: 'token', environment: {'TOKEN': 'access token'}); await confirmPublish(pub); - handleUploadForm(globalServer); + handleUploadForm(globalPackageServer!); await pub.shouldExit(1); }); @@ -33,13 +33,13 @@ await d.tokensFile({ 'version': 1, 'hosted': [ - {'url': globalServer.url, 'token': 'access token'}, + {'url': globalPackageServer!.url, 'token': 'access token'}, ] }).create(); - var pub = await startPublish(globalServer, authMethod: 'token'); + var pub = await startPublish(globalPackageServer!, authMethod: 'token'); await confirmPublish(pub); - handleUploadForm(globalServer); + handleUploadForm(globalPackageServer!); await pub.shouldExit(1); });
diff --git a/test/token/when_receives_401_removes_token_test.dart b/test/token/when_receives_401_removes_token_test.dart index 86c0559..b674597 100644 --- a/test/token/when_receives_401_removes_token_test.dart +++ b/test/token/when_receives_401_removes_token_test.dart
@@ -12,17 +12,17 @@ setUp(d.validPackage.create); test('when receives 401 response removes saved token', () async { - final server = await servePackages(); + await servePackages(); await d.tokensFile({ 'version': 1, 'hosted': [ - {'url': server.url, 'token': 'access token'}, + {'url': globalPackageServer!.url, 'token': 'access token'}, ] }).create(); - var pub = await startPublish(server, authMethod: 'token'); + var pub = await startPublish(globalPackageServer!, authMethod: 'token'); await confirmPublish(pub); - server.expect('GET', '/api/packages/versions/new', (request) { + globalPackageServer!.expect('GET', '/api/packages/versions/new', (request) { return shelf.Response(401); });
diff --git a/test/token/when_receives_403_persists_saved_token_test.dart b/test/token/when_receives_403_persists_saved_token_test.dart index 45fc7a4..ffcbab0 100644 --- a/test/token/when_receives_403_persists_saved_token_test.dart +++ b/test/token/when_receives_403_persists_saved_token_test.dart
@@ -12,17 +12,17 @@ setUp(d.validPackage.create); test('when receives 403 response persists saved token', () async { - final server = await servePackages(); + await servePackages(); await d.tokensFile({ 'version': 1, 'hosted': [ - {'url': server.url, 'token': 'access token'}, + {'url': globalPackageServer!.url, 'token': 'access token'}, ] }).create(); - var pub = await startPublish(server, authMethod: 'token'); + var pub = await startPublish(globalPackageServer!, authMethod: 'token'); await confirmPublish(pub); - server.expect('GET', '/api/packages/versions/new', (request) { + globalPackageServer!.expect('GET', '/api/packages/versions/new', (request) { return shelf.Response(403); }); @@ -31,7 +31,7 @@ await d.tokensFile({ 'version': 1, 'hosted': [ - {'url': server.url, 'token': 'access token'}, + {'url': globalPackageServer!.url, 'token': 'access token'}, ] }).validate(); });
diff --git a/test/unknown_source_test.dart b/test/unknown_source_test.dart index 37591d0..fc53621 100644 --- a/test/unknown_source_test.dart +++ b/test/unknown_source_test.dart
@@ -72,9 +72,7 @@ await pubCommand(command); // Should upgrade to the new one. - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', path: '../foo'), - ]).validate(); + await d.appPackagesFile({'foo': '../foo'}).validate(); }); }); }
diff --git a/test/upgrade/dry_run_does_not_apply_changes_test.dart b/test/upgrade/dry_run_does_not_apply_changes_test.dart index 8c942ca..de1e6b5 100644 --- a/test/upgrade/dry_run_does_not_apply_changes_test.dart +++ b/test/upgrade/dry_run_does_not_apply_changes_test.dart
@@ -11,9 +11,10 @@ void main() { test('--dry-run: shows report, changes nothing', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0'); + }); // Create the first lockfile. await d.appDir({'foo': '1.0.0'}).create(); @@ -49,9 +50,10 @@ }); test('--dry-run --major-versions: shows report, changes nothing', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0'); + }); await d.appDir({'foo': '^1.0.0'}).create();
diff --git a/test/upgrade/example_warns_about_major_versions_test.dart b/test/upgrade/example_warns_about_major_versions_test.dart index b5c9a67..a9b2965 100644 --- a/test/upgrade/example_warns_about_major_versions_test.dart +++ b/test/upgrade/example_warns_about_major_versions_test.dart
@@ -10,11 +10,11 @@ testWithGolden( 'pub upgrade --major-versions does not update major versions in example/', (ctx) async { - await servePackages() + await servePackages((b) => b ..serve('foo', '1.0.0') ..serve('foo', '2.0.0') ..serve('bar', '1.0.0') - ..serve('bar', '2.0.0'); + ..serve('bar', '2.0.0')); await d.dir(appPath, [ d.pubspec({ 'name': 'myapp', @@ -39,7 +39,7 @@ testWithGolden( 'pub upgrade --null-safety does not update null-safety of dependencies in example/', (ctx) async { - await servePackages() + await servePackages((b) => b ..serve('foo', '1.0.0', pubspec: { 'environment': {'sdk': '>=2.7.0 <3.0.0'}, }) @@ -51,7 +51,7 @@ }) ..serve('bar', '2.0.0', pubspec: { 'environment': {'sdk': '>=2.12.0 <3.0.0'}, - }); + })); await d.dir(appPath, [ d.pubspec({ 'name': 'myapp',
diff --git a/test/upgrade/hosted/unlock_if_necessary_test.dart b/test/upgrade/hosted/unlock_if_necessary_test.dart index 2707100..5066727 100644 --- a/test/upgrade/hosted/unlock_if_necessary_test.dart +++ b/test/upgrade/hosted/unlock_if_necessary_test.dart
@@ -11,28 +11,24 @@ test( "upgrades one locked pub server package's dependencies if it's " 'necessary', () async { - final server = await servePackages(); - - server.serve('foo', '1.0.0', deps: {'foo_dep': 'any'}); - server.serve('foo_dep', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'foo_dep': 'any'}); + builder.serve('foo_dep', '1.0.0'); + }); await d.appDir({'foo': 'any'}).create(); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'foo_dep', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0', 'foo_dep': '1.0.0'}).validate(); - server.serve('foo', '2.0.0', deps: {'foo_dep': '>1.0.0'}); - server.serve('foo_dep', '2.0.0'); + globalPackageServer!.add((builder) { + builder.serve('foo', '2.0.0', deps: {'foo_dep': '>1.0.0'}); + builder.serve('foo_dep', '2.0.0'); + }); await pubUpgrade(args: ['foo']); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '2.0.0'), - d.packageConfigEntry(name: 'foo_dep', version: '2.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '2.0.0', 'foo_dep': '2.0.0'}).validate(); }); }
diff --git a/test/upgrade/hosted/unlock_single_package_test.dart b/test/upgrade/hosted/unlock_single_package_test.dart index e443a6a..29dabe7 100644 --- a/test/upgrade/hosted/unlock_single_package_test.dart +++ b/test/upgrade/hosted/unlock_single_package_test.dart
@@ -9,43 +9,37 @@ void main() { test('can unlock a single package only in upgrade', () async { - final server = await servePackages(); - - server.serve('foo', '1.0.0', deps: {'bar': '<2.0.0'}); - server.serve('bar', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': '<2.0.0'}); + builder.serve('bar', '1.0.0'); + }); await d.appDir({'foo': 'any', 'bar': 'any'}).create(); await pubGet(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.0.0'}).validate(); - server.serve('foo', '2.0.0', deps: {'bar': '<3.0.0'}); - server.serve('bar', '2.0.0'); + globalPackageServer!.add((builder) { + builder.serve('foo', '2.0.0', deps: {'bar': '<3.0.0'}); + builder.serve('bar', '2.0.0'); + }); // This can't upgrade 'bar' await pubUpgrade(args: ['bar']); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.0.0'}).validate(); + // Introducing foo and bar 1.1.0, to show that only 'bar' will be upgraded - server.serve('foo', '1.1.0', deps: {'bar': '<2.0.0'}); - server.serve('bar', '1.1.0'); + globalPackageServer!.add((builder) { + builder.serve('foo', '1.1.0', deps: {'bar': '<2.0.0'}); + builder.serve('bar', '1.1.0'); + }); await pubUpgrade(args: ['bar']); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.1.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.1.0'}).validate(); + await pubUpgrade(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '2.0.0'), - d.packageConfigEntry(name: 'bar', version: '2.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '2.0.0', 'bar': '2.0.0'}).validate(); }); }
diff --git a/test/upgrade/hosted/upgrade_removed_constraints_test.dart b/test/upgrade/hosted/upgrade_removed_constraints_test.dart index cf72c07..7c20816 100644 --- a/test/upgrade/hosted/upgrade_removed_constraints_test.dart +++ b/test/upgrade/hosted/upgrade_removed_constraints_test.dart
@@ -9,29 +9,24 @@ void main() { test('upgrades dependencies whose constraints have been removed', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'shared_dep': 'any'}) - ..serve('bar', '1.0.0', deps: {'shared_dep': '<2.0.0'}) - ..serve('shared_dep', '1.0.0') - ..serve('shared_dep', '2.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'shared_dep': 'any'}); + builder.serve('bar', '1.0.0', deps: {'shared_dep': '<2.0.0'}); + builder.serve('shared_dep', '1.0.0'); + builder.serve('shared_dep', '2.0.0'); + }); await d.appDir({'foo': 'any', 'bar': 'any'}).create(); await pubUpgrade(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), - d.packageConfigEntry(name: 'shared_dep', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile( + {'foo': '1.0.0', 'bar': '1.0.0', 'shared_dep': '1.0.0'}).validate(); await d.appDir({'foo': 'any'}).create(); await pubUpgrade(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'shared_dep', version: '2.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0', 'shared_dep': '2.0.0'}).validate(); }); }
diff --git a/test/upgrade/hosted/warn_about_discontinued_test.dart b/test/upgrade/hosted/warn_about_discontinued_test.dart index ba7fc57..8444c10 100644 --- a/test/upgrade/hosted/warn_about_discontinued_test.dart +++ b/test/upgrade/hosted/warn_about_discontinued_test.dart
@@ -9,15 +9,15 @@ void main() { test('Warns about discontinued dependencies', () async { - final server = await servePackages() + await servePackages((builder) => builder ..serve('foo', '1.2.3', deps: {'transitive': 'any'}) - ..serve('transitive', '1.0.0'); + ..serve('transitive', '1.0.0')); await d.appDir({'foo': '1.2.3'}).create(); await pubGet(); - server + globalPackageServer!.add((builder) => builder ..discontinue('foo') - ..discontinue('transitive'); + ..discontinue('transitive')); // We warn only about the direct dependency here: await pubUpgrade(output: ''' Resolving dependencies... @@ -26,7 +26,8 @@ No dependencies changed. 1 package is discontinued. '''); - server.discontinue('foo', replacementText: 'bar'); + globalPackageServer! + .add((builder) => builder.discontinue('foo', replacementText: 'bar')); // We warn only about the direct dependency here: await pubUpgrade(output: ''' Resolving dependencies... @@ -38,9 +39,9 @@ }); test('Warns about discontinued dev_dependencies', () async { - final server = await servePackages() + await servePackages((builder) => builder ..serve('foo', '1.2.3', deps: {'transitive': 'any'}) - ..serve('transitive', '1.0.0'); + ..serve('transitive', '1.0.0')); await d.dir(appPath, [ d.file('pubspec.yaml', ''' @@ -55,9 +56,9 @@ ]).create(); await pubGet(); - server + globalPackageServer!.add((builder) => builder ..discontinue('foo') - ..discontinue('transitive'); + ..discontinue('transitive')); // We warn only about the direct dependency here: await pubUpgrade(output: ''' @@ -67,7 +68,8 @@ No dependencies changed. 1 package is discontinued. '''); - server.discontinue('foo', replacementText: 'bar'); + globalPackageServer! + .add((builder) => builder.discontinue('foo', replacementText: 'bar')); // We warn only about the direct dependency here: await pubUpgrade(output: ''' Resolving dependencies...
diff --git a/test/upgrade/renamed_package_circular_dependency.dart b/test/upgrade/renamed_package_circular_dependency.dart index ec10b82..ca033bb 100644 --- a/test/upgrade/renamed_package_circular_dependency.dart +++ b/test/upgrade/renamed_package_circular_dependency.dart
@@ -8,9 +8,10 @@ void main() { test('The upgrade report handles a package becoming root', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'myapp': 'any'}) - ..serve('myapp', '1.0.0', deps: {'foo': 'any'}); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'myapp': 'any'}); + builder.serve('myapp', '1.0.0', deps: {'foo': 'any'}); + }); await d.dir(appPath, [ d.pubspec({
diff --git a/test/upgrade/report/describes_change_test.dart b/test/upgrade/report/describes_change_test.dart index 96410cb..3d93541 100644 --- a/test/upgrade/report/describes_change_test.dart +++ b/test/upgrade/report/describes_change_test.dart
@@ -9,11 +9,11 @@ void main() { test('Shows count of discontinued packages', () async { - final server = await servePackages(); + await servePackages((builder) { + builder.serve('foo', '2.0.0'); + }); - server.serve('foo', '2.0.0'); - - server.discontinue('foo'); + globalPackageServer!.add((builder) => builder..discontinue('foo')); // Create the first lockfile. await d.appDir({'foo': '2.0.0'}).create(); @@ -33,11 +33,12 @@ }); test('shows how package changed from previous lockfile', () async { - await servePackages() - ..serve('unchanged', '1.0.0') - ..serve('version_changed', '1.0.0') - ..serve('version_changed', '2.0.0') - ..serve('source_changed', '1.0.0'); + await servePackages((builder) { + builder.serve('unchanged', '1.0.0'); + builder.serve('version_changed', '1.0.0'); + builder.serve('version_changed', '2.0.0'); + builder.serve('source_changed', '1.0.0'); + }); await d.dir('source_changed', [ d.libDir('source_changed'),
diff --git a/test/upgrade/report/does_not_show_newer_versions_for_locked_packages_test.dart b/test/upgrade/report/does_not_show_newer_versions_for_locked_packages_test.dart index ef987b9..7a232d0 100644 --- a/test/upgrade/report/does_not_show_newer_versions_for_locked_packages_test.dart +++ b/test/upgrade/report/does_not_show_newer_versions_for_locked_packages_test.dart
@@ -11,13 +11,14 @@ test( 'Shows newer versions available for packages that are locked and not being upgraded', () async { - await servePackages() - ..serve('not_upgraded', '1.0.0') - ..serve('not_upgraded', '2.0.0') - ..serve('not_upgraded', '3.0.0-dev') - ..serve('upgraded', '1.0.0') - ..serve('upgraded', '2.0.0') - ..serve('upgraded', '3.0.0-dev'); + await servePackages((builder) { + builder.serve('not_upgraded', '1.0.0'); + builder.serve('not_upgraded', '2.0.0'); + builder.serve('not_upgraded', '3.0.0-dev'); + builder.serve('upgraded', '1.0.0'); + builder.serve('upgraded', '2.0.0'); + builder.serve('upgraded', '3.0.0-dev'); + }); // Constraint everything to the first version. await d.appDir({'not_upgraded': '1.0.0', 'upgraded': '1.0.0'}).create();
diff --git a/test/upgrade/report/highlights_overrides_test.dart b/test/upgrade/report/highlights_overrides_test.dart index 93f9f3b..94608d9 100644 --- a/test/upgrade/report/highlights_overrides_test.dart +++ b/test/upgrade/report/highlights_overrides_test.dart
@@ -9,8 +9,7 @@ void main() { test('highlights overridden packages', () async { - final server = await servePackages(); - server.serve('overridden', '1.0.0'); + await servePackages((builder) => builder.serve('overridden', '1.0.0')); await d.dir(appPath, [ d.pubspec({
diff --git a/test/upgrade/report/leading_character_shows_change_test.dart b/test/upgrade/report/leading_character_shows_change_test.dart index 88f7ed2..d7f870c 100644 --- a/test/upgrade/report/leading_character_shows_change_test.dart +++ b/test/upgrade/report/leading_character_shows_change_test.dart
@@ -9,16 +9,17 @@ void main() { test('the character before each package describes the change', () async { - await servePackages() - ..serve('added', '1.0.0') - ..serve('downgraded', '1.0.0') - ..serve('downgraded', '2.0.0') - ..serve('overridden', '1.0.0') - ..serve('removed', '1.0.0') - ..serve('source_changed', '1.0.0') - ..serve('upgraded', '1.0.0') - ..serve('upgraded', '2.0.0') - ..serve('unchanged', '1.0.0'); + await servePackages((builder) { + builder.serve('added', '1.0.0'); + builder.serve('downgraded', '1.0.0'); + builder.serve('downgraded', '2.0.0'); + builder.serve('overridden', '1.0.0'); + builder.serve('removed', '1.0.0'); + builder.serve('source_changed', '1.0.0'); + builder.serve('upgraded', '1.0.0'); + builder.serve('upgraded', '2.0.0'); + builder.serve('unchanged', '1.0.0'); + }); await d.dir('description_changed_1', [ d.libDir('description_changed'),
diff --git a/test/upgrade/report/shows_newer_available_versions_test.dart b/test/upgrade/report/shows_newer_available_versions_test.dart index 39d4e1a..4c1ca56 100644 --- a/test/upgrade/report/shows_newer_available_versions_test.dart +++ b/test/upgrade/report/shows_newer_available_versions_test.dart
@@ -9,26 +9,28 @@ void main() { test('shows how many newer versions are available', () async { - await servePackages() - ..serve('multiple_newer', '1.0.0') - ..serve('multiple_newer', '1.0.1-unstable.1') - ..serve('multiple_newer', '1.0.1') - ..serve('multiple_newer', '1.0.2-unstable.1') - ..serve('multiple_newer_stable', '1.0.0') - ..serve('multiple_newer_stable', '1.0.1') - ..serve('multiple_newer_stable', '1.0.2') - ..serve('multiple_newer_unstable', '1.0.0') - ..serve('multiple_newer_unstable', '1.0.1-unstable.1') - ..serve('multiple_newer_unstable', '1.0.1-unstable.2') - ..serve('multiple_newer_unstable2', '1.0.1-unstable.1') - ..serve('multiple_newer_unstable2', '1.0.1-unstable.2') - ..serve('no_newer', '1.0.0') - ..serve('one_newer_unstable', '1.0.0') - ..serve('one_newer_unstable', '1.0.1-unstable.1') - ..serve('one_newer_unstable2', '1.0.1-unstable.1') - ..serve('one_newer_unstable2', '1.0.1-unstable.2') - ..serve('one_newer_stable', '1.0.0') - ..serve('one_newer_stable', '1.0.1'); + await servePackages((builder) { + builder.serve('multiple_newer', '1.0.0'); + builder.serve('multiple_newer', '1.0.1-unstable.1'); + builder.serve('multiple_newer', '1.0.1'); + builder.serve('multiple_newer', '1.0.2-unstable.1'); + builder.serve('multiple_newer_stable', '1.0.0'); + builder.serve('multiple_newer_stable', '1.0.1'); + builder.serve('multiple_newer_stable', '1.0.2'); + builder.serve('multiple_newer_unstable', '1.0.0'); + builder.serve('multiple_newer_unstable', '1.0.1-unstable.1'); + builder.serve('multiple_newer_unstable', '1.0.1-unstable.2'); + builder.serve('multiple_newer_unstable2', '1.0.1-unstable.1'); + builder.serve('multiple_newer_unstable2', '1.0.1-unstable.2'); + builder.serve('multiple_newer_unstable2', '1.0.1-unstable.2'); + builder.serve('no_newer', '1.0.0'); + builder.serve('one_newer_unstable', '1.0.0'); + builder.serve('one_newer_unstable', '1.0.1-unstable.1'); + builder.serve('one_newer_unstable2', '1.0.1-unstable.1'); + builder.serve('one_newer_unstable2', '1.0.1-unstable.2'); + builder.serve('one_newer_stable', '1.0.0'); + builder.serve('one_newer_stable', '1.0.1'); + }); // Constraint everything to the first version. await d.appDir({
diff --git a/test/upgrade/report/shows_number_of_changed_dependencies_test.dart b/test/upgrade/report/shows_number_of_changed_dependencies_test.dart index 91ba5aa..5ba3af6 100644 --- a/test/upgrade/report/shows_number_of_changed_dependencies_test.dart +++ b/test/upgrade/report/shows_number_of_changed_dependencies_test.dart
@@ -11,10 +11,11 @@ test( 'does not show how many newer versions are available for ' 'packages that are locked and not being upgraded', () async { - await servePackages() - ..serve('a', '1.0.0') - ..serve('b', '1.0.0') - ..serve('c', '2.0.0'); + await servePackages((builder) { + builder.serve('a', '1.0.0'); + builder.serve('b', '1.0.0'); + builder.serve('c', '2.0.0'); + }); await d.appDir({'a': 'any'}).create();
diff --git a/test/upgrade/report/shows_pub_outdated_test.dart b/test/upgrade/report/shows_pub_outdated_test.dart index 0fdb322..9c0fa3d 100644 --- a/test/upgrade/report/shows_pub_outdated_test.dart +++ b/test/upgrade/report/shows_pub_outdated_test.dart
@@ -9,23 +9,24 @@ void main() { test('shows pub outdated', () async { - await servePackages() - ..serve('multiple_newer', '1.0.0') - ..serve('multiple_newer', '1.0.1-unstable.1') - ..serve('multiple_newer', '1.0.1') - ..serve('multiple_newer', '1.0.2-unstable.1') - ..serve('multiple_newer', '1.0.2-unstable.2') - ..serve('multiple_newer_stable', '1.0.0') - ..serve('multiple_newer_stable', '1.0.1') - ..serve('multiple_newer_stable', '1.0.2') - ..serve('multiple_newer_unstable', '1.0.0') - ..serve('multiple_newer_unstable', '1.0.1-unstable.1') - ..serve('multiple_newer_unstable', '1.0.1-unstable.2') - ..serve('no_newer', '1.0.0') - ..serve('one_newer_unstable', '1.0.0') - ..serve('one_newer_unstable', '1.0.1-unstable.1') - ..serve('one_newer_stable', '1.0.0') - ..serve('one_newer_stable', '1.0.1'); + await servePackages((builder) { + builder.serve('multiple_newer', '1.0.0'); + builder.serve('multiple_newer', '1.0.1-unstable.1'); + builder.serve('multiple_newer', '1.0.1'); + builder.serve('multiple_newer', '1.0.2-unstable.1'); + builder.serve('multiple_newer', '1.0.2-unstable.2'); + builder.serve('multiple_newer_stable', '1.0.0'); + builder.serve('multiple_newer_stable', '1.0.1'); + builder.serve('multiple_newer_stable', '1.0.2'); + builder.serve('multiple_newer_unstable', '1.0.0'); + builder.serve('multiple_newer_unstable', '1.0.1-unstable.1'); + builder.serve('multiple_newer_unstable', '1.0.1-unstable.2'); + builder.serve('no_newer', '1.0.0'); + builder.serve('one_newer_unstable', '1.0.0'); + builder.serve('one_newer_unstable', '1.0.1-unstable.1'); + builder.serve('one_newer_stable', '1.0.0'); + builder.serve('one_newer_stable', '1.0.1'); + }); // Constraint everything to the first version. await d.appDir({
diff --git a/test/upgrade/upgrade_major_versions_test.dart b/test/upgrade/upgrade_major_versions_test.dart index c5f0994..c312717 100644 --- a/test/upgrade/upgrade_major_versions_test.dart +++ b/test/upgrade/upgrade_major_versions_test.dart
@@ -10,13 +10,14 @@ void main() { group('pub upgrade --major-versions', () { test('bumps dependency constraints and shows summary report', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0') - ..serve('bar', '0.1.0') - ..serve('bar', '0.2.0') - ..serve('baz', '1.0.0') - ..serve('baz', '1.0.1'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0'); + builder.serve('bar', '0.1.0'); + builder.serve('bar', '0.2.0'); + builder.serve('baz', '1.0.0'); + builder.serve('baz', '1.0.1'); + }); await d.appDir({ 'foo': '^1.0.0', @@ -41,21 +42,23 @@ 'bar': '^0.2.0', 'baz': '^1.0.0', }).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '2.0.0'), - d.packageConfigEntry(name: 'bar', version: '0.2.0'), - d.packageConfigEntry(name: 'baz', version: '1.0.1'), - ]).validate(); + + await d.appPackagesFile({ + 'foo': '2.0.0', + 'bar': '0.2.0', + 'baz': '1.0.1', + }).validate(); }); test('bumps dev_dependency constraints and shows summary report', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0') - ..serve('bar', '0.1.0') - ..serve('bar', '0.2.0') - ..serve('baz', '1.0.0') - ..serve('baz', '1.0.1'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0'); + builder.serve('bar', '0.1.0'); + builder.serve('bar', '0.2.0'); + builder.serve('baz', '1.0.0'); + builder.serve('baz', '1.0.1'); + }); await d.dir(appPath, [ d.pubspec({ @@ -91,18 +94,20 @@ }), ]).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '2.0.0'), - d.packageConfigEntry(name: 'bar', version: '0.2.0'), - d.packageConfigEntry(name: 'baz', version: '1.0.1'), - ]).validate(); + await d.appPackagesFile({ + 'foo': '2.0.0', + 'bar': '0.2.0', + 'baz': '1.0.1', + }).validate(); }); test('upgrades only the selected package', () async { - final server = await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0') - ..serve('bar', '0.1.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0'); + builder.serve('bar', '0.1.0'); + builder.serve('bar', '0.2.0'); + }); await d.appDir({ 'foo': '^1.0.0', @@ -111,8 +116,6 @@ await pubGet(); - server.serve('bar', '0.1.1'); - // 1 constraint should be updated await pubUpgrade( args: ['--major-versions', 'foo'], @@ -127,17 +130,15 @@ 'bar': '^0.1.0', }).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '2.0.0'), - d.packageConfigEntry(name: 'bar', version: '0.1.0'), - ]).validate(); + await d.appPackagesFile({'foo': '2.0.0', 'bar': '0.1.0'}).validate(); }); test('chooses the latest version where possible', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0') - ..serve('foo', '3.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0'); + builder.serve('foo', '3.0.0'); + }); await d.appDir({'foo': '^1.0.0'}).create(); @@ -161,17 +162,17 @@ d.file('pubspec.lock', contains('3.0.0')) ]).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '3.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '3.0.0'}).validate(); }); test('overridden dependencies - no resolution', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': '^2.0.0'}) - ..serve('foo', '2.0.0', deps: {'bar': '^1.0.0'}) - ..serve('bar', '1.0.0', deps: {'foo': '^1.0.0'}) - ..serve('bar', '2.0.0', deps: {'foo': '^2.0.0'}); + await servePackages( + (builder) => builder + ..serve('foo', '1.0.0', deps: {'bar': '^2.0.0'}) + ..serve('foo', '2.0.0', deps: {'bar': '^1.0.0'}) + ..serve('bar', '1.0.0', deps: {'foo': '^1.0.0'}) + ..serve('bar', '2.0.0', deps: {'foo': '^2.0.0'}), + ); await d.dir(appPath, [ d.pubspec({ @@ -215,25 +216,23 @@ }) ]).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '1.0.0'), - ]).validate(); + await d.appPackagesFile({'foo': '1.0.0', 'bar': '1.0.0'}).validate(); }); test('upgrade should not downgrade any versions', () async { /// The version solver solves the packages with the least number of /// versions remaining, so we add more 'bar' packages to force 'foo' to be /// resolved first - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0', pubspec: { 'dependencies': {'bar': '1.0.0'} - }) - ..serve('bar', '1.0.0') - ..serve('bar', '2.0.0') - ..serve('bar', '3.0.0') - ..serve('bar', '4.0.0'); + }); + builder.serve('bar', '1.0.0'); + builder.serve('bar', '2.0.0'); + builder.serve('bar', '3.0.0'); + builder.serve('bar', '4.0.0'); + }); await d.appDir({ 'foo': '^1.0.0', @@ -256,10 +255,10 @@ 'bar': '^4.0.0', }).validate(); - await d.appPackageConfigFile([ - d.packageConfigEntry(name: 'foo', version: '1.0.0'), - d.packageConfigEntry(name: 'bar', version: '4.0.0'), - ]).validate(); + await d.appPackagesFile({ + 'foo': '1.0.0', + 'bar': '4.0.0', + }).validate(); }); }); }
diff --git a/test/upgrade/upgrade_null_safety_test.dart b/test/upgrade/upgrade_null_safety_test.dart index 557c589..921c737 100644 --- a/test/upgrade/upgrade_null_safety_test.dart +++ b/test/upgrade/upgrade_null_safety_test.dart
@@ -9,28 +9,29 @@ void main() { group('pub upgrade --null-safety', () { setUp(() async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'environment': {'sdk': '>=2.10.0<3.0.0'}, - }) - ..serve('foo', '2.0.0', pubspec: { + }); + builder.serve('foo', '2.0.0', pubspec: { 'environment': {'sdk': '>=2.12.0<3.0.0'}, - }) - ..serve('bar', '1.0.0', pubspec: { + }); + builder.serve('bar', '1.0.0', pubspec: { 'environment': {'sdk': '>=2.9.0<3.0.0'}, - }) - ..serve('bar', '2.0.0-nullsafety.0', pubspec: { + }); + builder.serve('bar', '2.0.0-nullsafety.0', pubspec: { 'environment': {'sdk': '>=2.12.0<3.0.0'}, - }) - ..serve('baz', '1.0.0', pubspec: { + }); + builder.serve('baz', '1.0.0', pubspec: { 'environment': {'sdk': '>=2.9.0<3.0.0'}, - }) - ..serve('has_conflict', '1.0.0', pubspec: { + }); + builder.serve('has_conflict', '1.0.0', pubspec: { 'environment': {'sdk': '>=2.9.0<3.0.0'}, - }) - ..serve('has_conflict', '2.0.0', pubspec: { + }); + builder.serve('has_conflict', '2.0.0', pubspec: { 'environment': {'sdk': '>=2.13.0<3.0.0'}, }); + }); }); test('upgrades to null-safety versions', () async {
diff --git a/test/validator/gitignore_test.dart b/test/validator/gitignore_test.dart index f7b02fe..1112934 100644 --- a/test/validator/gitignore_test.dart +++ b/test/validator/gitignore_test.dart
@@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'dart:io'; - import 'package:path/path.dart' as p; import 'package:pub/src/exit_codes.dart' as exit_codes; import 'package:test/test.dart'; @@ -84,22 +82,4 @@ exit_codes.DATA, workingDirectory: packageRoot); }); - - test('Should not follow symlinks', () async { - await d.git('myapp', [ - ...d.validPackage.contents, - ]).create(); - final packageRoot = p.join(d.sandbox, 'myapp'); - await pubGet( - environment: {'_PUB_TEST_SDK_VERSION': '1.12.0'}, - workingDirectory: packageRoot); - - Link(p.join(packageRoot, '.abc', 'itself')).createSync( - packageRoot, - recursive: true, - ); - - await expectValidation(contains('Package has 0 warnings.'), 0, - workingDirectory: packageRoot); - }); }
diff --git a/test/validator/null_safety_mixed_mode_test.dart b/test/validator/null_safety_mixed_mode_test.dart index d62d051..e2a8dfb 100644 --- a/test/validator/null_safety_mixed_mode_test.dart +++ b/test/validator/null_safety_mixed_mode_test.dart
@@ -45,13 +45,14 @@ group('should consider a package valid if it', () { test('is not opting in to null-safety, but depends on package that is', () async { - final server = await servePackages(); - server.serve( - 'foo', - '0.0.1', - pubspec: { - 'environment': {'sdk': '>=2.12.0<3.0.0'} - }, + await servePackages( + (server) => server.serve( + 'foo', + '0.0.1', + pubspec: { + 'environment': {'sdk': '>=2.12.0<3.0.0'} + }, + ), ); await setup( @@ -60,13 +61,14 @@ }); test('is opting in to null-safety and depends on package that is', () async { - final server = await servePackages(); - server.serve( - 'foo', - '0.0.1', - pubspec: { - 'environment': {'sdk': '>=2.12.0<3.0.0'} - }, + await servePackages( + (server) => server.serve( + 'foo', + '0.0.1', + pubspec: { + 'environment': {'sdk': '>=2.12.0<3.0.0'} + }, + ), ); await setup( @@ -76,13 +78,14 @@ test('is opting in to null-safety has dev_dependency that is not', () async { - final server = await servePackages(); - server.serve( - 'foo', - '0.0.1', - pubspec: { - 'environment': {'sdk': '>=2.9.0<3.0.0'} - }, + await servePackages( + (server) => server.serve( + 'foo', + '0.0.1', + pubspec: { + 'environment': {'sdk': '>=2.9.0<3.0.0'} + }, + ), ); await setup(sdkConstraint: '>=2.12.0 <3.0.0', devDependencies: { @@ -95,13 +98,14 @@ group('should consider a package invalid if it', () { test('is opting in to null-safety, but depends on package that is not', () async { - final server = await servePackages(); - server.serve( - 'foo', - '0.0.1', - pubspec: { - 'environment': {'sdk': '>=2.9.0<3.0.0'} - }, + await servePackages( + (server) => server.serve( + 'foo', + '0.0.1', + pubspec: { + 'environment': {'sdk': '>=2.9.0<3.0.0'} + }, + ), ); await setup( @@ -130,16 +134,17 @@ test( 'is opting in to null-safety, but depends on package has file opting out', () async { - final server = await servePackages(); - server.serve('foo', '0.0.1', pubspec: { - 'environment': {'sdk': '>=2.12.0<3.0.0'} - }, contents: [ - d.dir('lib', [ - d.file('foo.dart', ''' + await servePackages( + (server) => server.serve('foo', '0.0.1', pubspec: { + 'environment': {'sdk': '>=2.12.0<3.0.0'} + }, contents: [ + d.dir('lib', [ + d.file('foo.dart', ''' // @dart = 2.9 ''') - ]) - ]); + ]) + ]), + ); await setup( sdkConstraint: '>=2.12.0 <3.0.0', dependencies: {'foo': '^0.0.1'});
diff --git a/test/validator/relative_version_numbering_test.dart b/test/validator/relative_version_numbering_test.dart index 2f3da5c..07e8dbc 100644 --- a/test/validator/relative_version_numbering_test.dart +++ b/test/validator/relative_version_numbering_test.dart
@@ -13,7 +13,7 @@ Validator validator(Entrypoint entrypoint) => RelativeVersionNumberingValidator( entrypoint, - Uri.parse(globalServer.url), + Uri.parse(globalPackageServer!.url), ); Future<void> setup({required String sdkConstraint}) async { @@ -33,13 +33,14 @@ group('should consider a package valid if it', () { test('is not opting in to null-safety with previous non-null-safe version', () async { - final server = await servePackages(); - server.serve( - 'test_pkg', - '0.0.1', - pubspec: { - 'environment': {'sdk': '>=2.9.0<3.0.0'} - }, + await servePackages( + (server) => server.serve( + 'test_pkg', + '0.0.1', + pubspec: { + 'environment': {'sdk': '>=2.9.0<3.0.0'} + }, + ), ); await setup(sdkConstraint: '>=2.9.0 <3.0.0'); @@ -49,21 +50,23 @@ test( 'is not opting in to null-safety with previous non-null-safe version. ' 'Even with a later null-safe version', () async { - await servePackages() - ..serve( - 'test_pkg', - '0.0.1', - pubspec: { - 'environment': {'sdk': '>=2.9.0<3.0.0'} - }, - ) - ..serve( - 'test_pkg', - '2.0.0', - pubspec: { - 'environment': {'sdk': '>=2.12.0<3.0.0'} - }, - ); + await servePackages( + (server) => server + ..serve( + 'test_pkg', + '0.0.1', + pubspec: { + 'environment': {'sdk': '>=2.9.0<3.0.0'} + }, + ) + ..serve( + 'test_pkg', + '2.0.0', + pubspec: { + 'environment': {'sdk': '>=2.12.0<3.0.0'} + }, + ), + ); await setup(sdkConstraint: '>=2.9.0 <3.0.0'); await expectValidation(validator); @@ -71,13 +74,14 @@ test('is opting in to null-safety with previous null-safe version', () async { - final server = await servePackages(); - server.serve( - 'test_pkg', - '0.0.1', - pubspec: { - 'environment': {'sdk': '>=2.12.0<3.0.0'} - }, + await servePackages( + (server) => server.serve( + 'test_pkg', + '0.0.1', + pubspec: { + 'environment': {'sdk': '>=2.12.0<3.0.0'} + }, + ), ); await setup(sdkConstraint: '>=2.12.0 <3.0.0'); @@ -87,13 +91,14 @@ test( 'is opting in to null-safety using a pre-release of 2.12.0 ' 'with previous null-safe version', () async { - final server = await servePackages(); - server.serve( - 'test_pkg', - '0.0.1', - pubspec: { - 'environment': {'sdk': '>=2.12.0<3.0.0'} - }, + await servePackages( + (server) => server.serve( + 'test_pkg', + '0.0.1', + pubspec: { + 'environment': {'sdk': '>=2.12.0<3.0.0'} + }, + ), ); await setup(sdkConstraint: '>=2.12.0-dev <3.0.0'); @@ -103,21 +108,23 @@ test( 'is opting in to null-safety with previous null-safe version. ' 'Even with a later non-null-safe version', () async { - await servePackages() - ..serve( - 'test_pkg', - '0.0.1', - pubspec: { - 'environment': {'sdk': '>=2.12.0<3.0.0'} - }, - ) - ..serve( - 'test_pkg', - '2.0.1', - pubspec: { - 'environment': {'sdk': '>=2.9.0<3.0.0'} - }, - ); + await servePackages( + (server) => server + ..serve( + 'test_pkg', + '0.0.1', + pubspec: { + 'environment': {'sdk': '>=2.12.0<3.0.0'} + }, + ) + ..serve( + 'test_pkg', + '2.0.1', + pubspec: { + 'environment': {'sdk': '>=2.9.0<3.0.0'} + }, + ), + ); await setup(sdkConstraint: '>=2.12.0 <3.0.0'); await expectValidation(validator); @@ -125,13 +132,13 @@ test('is opting in to null-safety with no existing versions', () async { await setup(sdkConstraint: '>=2.12.0 <3.0.0'); - await servePackages(); + await servePackages((x) => x); await expectValidation(validator); }); test('is not opting in to null-safety with no existing versions', () async { await setup(sdkConstraint: '>=2.9.0 <3.0.0'); - await servePackages(); + await servePackages((x) => x); await expectValidation(validator); }); @@ -139,21 +146,23 @@ test( 'is not opting in to null-safety with previous null-safe stable version. ' 'With an in-between not null-safe prerelease', () async { - await servePackages() - ..serve( - 'test_pkg', - '0.0.1', - pubspec: { - 'environment': {'sdk': '>=2.12.0<3.0.0'} - }, - ) - ..serve( - 'test_pkg', - '0.0.2-dev', - pubspec: { - 'environment': {'sdk': '>=2.9.0<3.0.0'} - }, - ); + await servePackages( + (server) => server + ..serve( + 'test_pkg', + '0.0.1', + pubspec: { + 'environment': {'sdk': '>=2.12.0<3.0.0'} + }, + ) + ..serve( + 'test_pkg', + '0.0.2-dev', + pubspec: { + 'environment': {'sdk': '>=2.9.0<3.0.0'} + }, + ), + ); await setup(sdkConstraint: '>=2.9.0 <3.0.0'); await expectValidation(validator); @@ -162,21 +171,23 @@ test( 'opts in to null-safety, with previous stable version not-null-safe. ' 'With an in-between non-null-safe prerelease', () async { - await servePackages() - ..serve( - 'test_pkg', - '0.0.1', - pubspec: { - 'environment': {'sdk': '>=2.9.0<3.0.0'} - }, - ) - ..serve( - 'test_pkg', - '0.0.2-dev', - pubspec: { - 'environment': {'sdk': '>=2.12.0<3.0.0'} - }, - ); + await servePackages( + (server) => server + ..serve( + 'test_pkg', + '0.0.1', + pubspec: { + 'environment': {'sdk': '>=2.9.0<3.0.0'} + }, + ) + ..serve( + 'test_pkg', + '0.0.2-dev', + pubspec: { + 'environment': {'sdk': '>=2.12.0<3.0.0'} + }, + ), + ); await setup(sdkConstraint: '>=2.12.0 <3.0.0'); await expectValidation(validator); @@ -186,13 +197,14 @@ group('should warn if ', () { test('opts in to null-safety, with previous version not-null-safe', () async { - final server = await servePackages(); - server.serve( - 'test_pkg', - '0.0.1', - pubspec: { - 'environment': {'sdk': '>=2.9.0<3.0.0'} - }, + await servePackages( + (server) => server.serve( + 'test_pkg', + '0.0.1', + pubspec: { + 'environment': {'sdk': '>=2.9.0<3.0.0'} + }, + ), ); await setup(sdkConstraint: '>=2.12.0 <3.0.0'); @@ -203,13 +215,14 @@ 'is not opting in to null-safety with no existing stable versions. ' 'With a previous in-between null-safe prerelease', () async { await setup(sdkConstraint: '>=2.9.0 <3.0.0'); - final server = await servePackages(); - server.serve( - 'test_pkg', - '0.0.2-dev', - pubspec: { - 'environment': {'sdk': '>=2.12.0<3.0.0'} - }, + await servePackages( + (server) => server.serve( + 'test_pkg', + '0.0.2-dev', + pubspec: { + 'environment': {'sdk': '>=2.12.0<3.0.0'} + }, + ), ); await expectValidation(validator, hints: isNotEmpty); @@ -217,21 +230,23 @@ test( 'is not opting in to null-safety with previous non-null-safe stable version. ' 'With an in-between null-safe prerelease', () async { - await servePackages() - ..serve( - 'test_pkg', - '0.0.1', - pubspec: { - 'environment': {'sdk': '>=2.9.0<3.0.0'} - }, - ) - ..serve( - 'test_pkg', - '0.0.2-dev', - pubspec: { - 'environment': {'sdk': '>=2.12.0<3.0.0'} - }, - ); + await servePackages( + (server) => server + ..serve( + 'test_pkg', + '0.0.1', + pubspec: { + 'environment': {'sdk': '>=2.9.0<3.0.0'} + }, + ) + ..serve( + 'test_pkg', + '0.0.2-dev', + pubspec: { + 'environment': {'sdk': '>=2.12.0<3.0.0'} + }, + ), + ); await setup(sdkConstraint: '>=2.9.0 <3.0.0'); await expectValidation(validator, hints: isNotEmpty); @@ -240,21 +255,23 @@ test( 'opts in to null-safety, with previous version not-null-safe. ' 'Even with a later null-safe version', () async { - await servePackages() - ..serve( - 'test_pkg', - '0.0.1', - pubspec: { - 'environment': {'sdk': '>=2.9.0<3.0.0'} - }, - ) - ..serve( - 'test_pkg', - '2.0.0', - pubspec: { - 'environment': {'sdk': '>=2.12.0<3.0.0'} - }, - ); + await servePackages( + (server) => server + ..serve( + 'test_pkg', + '0.0.1', + pubspec: { + 'environment': {'sdk': '>=2.9.0<3.0.0'} + }, + ) + ..serve( + 'test_pkg', + '2.0.0', + pubspec: { + 'environment': {'sdk': '>=2.12.0<3.0.0'} + }, + ), + ); await setup(sdkConstraint: '>=2.12.0 <3.0.0'); await expectValidation(validator, hints: isNotEmpty); @@ -262,13 +279,14 @@ test('is not opting in to null-safety with previous null-safe version', () async { - final server = await servePackages(); - server.serve( - 'test_pkg', - '0.0.1', - pubspec: { - 'environment': {'sdk': '>=2.12.0<3.0.0'} - }, + await servePackages( + (server) => server.serve( + 'test_pkg', + '0.0.1', + pubspec: { + 'environment': {'sdk': '>=2.12.0<3.0.0'} + }, + ), ); await setup(sdkConstraint: '>=2.9.0 <3.0.0'); @@ -278,21 +296,23 @@ test( 'is not opting in to null-safety with previous null-safe version. ' 'Even with a later non-null-safe version', () async { - await servePackages() - ..serve( - 'test_pkg', - '0.0.1', - pubspec: { - 'environment': {'sdk': '>=2.12.0<3.0.0'} - }, - ) - ..serve( - 'test_pkg', - '2.0.0', - pubspec: { - 'environment': {'sdk': '>=2.9.0<3.0.0'} - }, - ); + await servePackages( + (server) => server + ..serve( + 'test_pkg', + '0.0.1', + pubspec: { + 'environment': {'sdk': '>=2.12.0<3.0.0'} + }, + ) + ..serve( + 'test_pkg', + '2.0.0', + pubspec: { + 'environment': {'sdk': '>=2.9.0<3.0.0'} + }, + ), + ); await setup(sdkConstraint: '>=2.9.0 <3.0.0'); await expectValidation(validator, hints: isNotEmpty); @@ -301,21 +321,23 @@ test( 'is opting in to null-safety with previous null-safe stable version. ' 'with an in-between non-null-safe prerelease', () async { - await servePackages() - ..serve( - 'test_pkg', - '0.0.1', - pubspec: { - 'environment': {'sdk': '>=2.12.0<3.0.0'} - }, - ) - ..serve( - 'test_pkg', - '0.0.2-dev', - pubspec: { - 'environment': {'sdk': '>=2.9.0<3.0.0'} - }, - ); + await servePackages( + (server) => server + ..serve( + 'test_pkg', + '0.0.1', + pubspec: { + 'environment': {'sdk': '>=2.12.0<3.0.0'} + }, + ) + ..serve( + 'test_pkg', + '0.0.2-dev', + pubspec: { + 'environment': {'sdk': '>=2.9.0<3.0.0'} + }, + ), + ); await setup(sdkConstraint: '>=2.12.0 <3.0.0'); await expectValidation(validator, hints: isNotEmpty); @@ -325,13 +347,14 @@ 'is opting in to null-safety with no existing stable versions. ' 'With a previous non-null-safe prerelease', () async { await setup(sdkConstraint: '>=2.12.0 <3.0.0'); - final server = await servePackages(); - server.serve( - 'test_pkg', - '0.0.2-dev', - pubspec: { - 'environment': {'sdk': '>=2.9.0<3.0.0'} - }, + await servePackages( + (server) => server.serve( + 'test_pkg', + '0.0.2-dev', + pubspec: { + 'environment': {'sdk': '>=2.9.0<3.0.0'} + }, + ), ); await expectValidation(validator, hints: isNotEmpty); });
diff --git a/test/version_solver_test.dart b/test/version_solver_test.dart index d36a16f..261c493 100644 --- a/test/version_solver_test.dart +++ b/test/version_solver_test.dart
@@ -40,13 +40,14 @@ }); test('simple dependency tree', () async { - await servePackages() - ..serve('a', '1.0.0', deps: {'aa': '1.0.0', 'ab': '1.0.0'}) - ..serve('aa', '1.0.0') - ..serve('ab', '1.0.0') - ..serve('b', '1.0.0', deps: {'ba': '1.0.0', 'bb': '1.0.0'}) - ..serve('ba', '1.0.0') - ..serve('bb', '1.0.0'); + await servePackages((builder) { + builder.serve('a', '1.0.0', deps: {'aa': '1.0.0', 'ab': '1.0.0'}); + builder.serve('aa', '1.0.0'); + builder.serve('ab', '1.0.0'); + builder.serve('b', '1.0.0', deps: {'ba': '1.0.0', 'bb': '1.0.0'}); + builder.serve('ba', '1.0.0'); + builder.serve('bb', '1.0.0'); + }); await d.appDir({'a': '1.0.0', 'b': '1.0.0'}).create(); await expectResolves(result: { @@ -60,14 +61,15 @@ }); test('shared dependency with overlapping constraints', () async { - await servePackages() - ..serve('a', '1.0.0', deps: {'shared': '>=2.0.0 <4.0.0'}) - ..serve('b', '1.0.0', deps: {'shared': '>=3.0.0 <5.0.0'}) - ..serve('shared', '2.0.0') - ..serve('shared', '3.0.0') - ..serve('shared', '3.6.9') - ..serve('shared', '4.0.0') - ..serve('shared', '5.0.0'); + await servePackages((builder) { + builder.serve('a', '1.0.0', deps: {'shared': '>=2.0.0 <4.0.0'}); + builder.serve('b', '1.0.0', deps: {'shared': '>=3.0.0 <5.0.0'}); + builder.serve('shared', '2.0.0'); + builder.serve('shared', '3.0.0'); + builder.serve('shared', '3.6.9'); + builder.serve('shared', '4.0.0'); + builder.serve('shared', '5.0.0'); + }); await d.appDir({'a': '1.0.0', 'b': '1.0.0'}).create(); await expectResolves( @@ -77,15 +79,16 @@ test( 'shared dependency where dependent version in turn affects other ' 'dependencies', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '1.0.1', deps: {'bang': '1.0.0'}) - ..serve('foo', '1.0.2', deps: {'whoop': '1.0.0'}) - ..serve('foo', '1.0.3', deps: {'zoop': '1.0.0'}) - ..serve('bar', '1.0.0', deps: {'foo': '<=1.0.1'}) - ..serve('bang', '1.0.0') - ..serve('whoop', '1.0.0') - ..serve('zoop', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '1.0.1', deps: {'bang': '1.0.0'}); + builder.serve('foo', '1.0.2', deps: {'whoop': '1.0.0'}); + builder.serve('foo', '1.0.3', deps: {'zoop': '1.0.0'}); + builder.serve('bar', '1.0.0', deps: {'foo': '<=1.0.1'}); + builder.serve('bang', '1.0.0'); + builder.serve('whoop', '1.0.0'); + builder.serve('zoop', '1.0.0'); + }); await d.appDir({'foo': '<=1.0.2', 'bar': '1.0.0'}).create(); await expectResolves( @@ -93,21 +96,23 @@ }); test('circular dependency', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': '1.0.0'}) - ..serve('bar', '1.0.0', deps: {'foo': '1.0.0'}); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': '1.0.0'}); + builder.serve('bar', '1.0.0', deps: {'foo': '1.0.0'}); + }); await d.appDir({'foo': '1.0.0'}).create(); await expectResolves(result: {'foo': '1.0.0', 'bar': '1.0.0'}); }); test('removed dependency', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0') - ..serve('bar', '1.0.0') - ..serve('bar', '2.0.0', deps: {'baz': '1.0.0'}) - ..serve('baz', '1.0.0', deps: {'foo': '2.0.0'}); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0'); + builder.serve('bar', '1.0.0'); + builder.serve('bar', '2.0.0', deps: {'baz': '1.0.0'}); + builder.serve('baz', '1.0.0', deps: {'foo': '2.0.0'}); + }); await d.appDir({'foo': '1.0.0', 'bar': 'any'}).create(); await expectResolves(result: {'foo': '1.0.0', 'bar': '1.0.0'}, tries: 2); @@ -116,13 +121,14 @@ void withLockFile() { test('with compatible locked dependency', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': '1.0.0'}) - ..serve('foo', '1.0.1', deps: {'bar': '1.0.1'}) - ..serve('foo', '1.0.2', deps: {'bar': '1.0.2'}) - ..serve('bar', '1.0.0') - ..serve('bar', '1.0.1') - ..serve('bar', '1.0.2'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': '1.0.0'}); + builder.serve('foo', '1.0.1', deps: {'bar': '1.0.1'}); + builder.serve('foo', '1.0.2', deps: {'bar': '1.0.2'}); + builder.serve('bar', '1.0.0'); + builder.serve('bar', '1.0.1'); + builder.serve('bar', '1.0.2'); + }); await d.appDir({'foo': '1.0.1'}).create(); await expectResolves(result: {'foo': '1.0.1', 'bar': '1.0.1'}); @@ -132,13 +138,14 @@ }); test('with incompatible locked dependency', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': '1.0.0'}) - ..serve('foo', '1.0.1', deps: {'bar': '1.0.1'}) - ..serve('foo', '1.0.2', deps: {'bar': '1.0.2'}) - ..serve('bar', '1.0.0') - ..serve('bar', '1.0.1') - ..serve('bar', '1.0.2'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': '1.0.0'}); + builder.serve('foo', '1.0.1', deps: {'bar': '1.0.1'}); + builder.serve('foo', '1.0.2', deps: {'bar': '1.0.2'}); + builder.serve('bar', '1.0.0'); + builder.serve('bar', '1.0.1'); + builder.serve('bar', '1.0.2'); + }); await d.appDir({'foo': '1.0.1'}).create(); await expectResolves(result: {'foo': '1.0.1', 'bar': '1.0.1'}); @@ -148,14 +155,15 @@ }); test('with unrelated locked dependency', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': '1.0.0'}) - ..serve('foo', '1.0.1', deps: {'bar': '1.0.1'}) - ..serve('foo', '1.0.2', deps: {'bar': '1.0.2'}) - ..serve('bar', '1.0.0') - ..serve('bar', '1.0.1') - ..serve('bar', '1.0.2') - ..serve('baz', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': '1.0.0'}); + builder.serve('foo', '1.0.1', deps: {'bar': '1.0.1'}); + builder.serve('foo', '1.0.2', deps: {'bar': '1.0.2'}); + builder.serve('bar', '1.0.0'); + builder.serve('bar', '1.0.1'); + builder.serve('bar', '1.0.2'); + builder.serve('baz', '1.0.0'); + }); await d.appDir({'baz': '1.0.0'}).create(); await expectResolves(result: {'baz': '1.0.0'}); @@ -167,16 +175,17 @@ test( 'unlocks dependencies if necessary to ensure that a new ' 'dependency is satisfied', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': '<2.0.0'}) - ..serve('bar', '1.0.0', deps: {'baz': '<2.0.0'}) - ..serve('baz', '1.0.0', deps: {'qux': '<2.0.0'}) - ..serve('qux', '1.0.0') - ..serve('foo', '2.0.0', deps: {'bar': '<3.0.0'}) - ..serve('bar', '2.0.0', deps: {'baz': '<3.0.0'}) - ..serve('baz', '2.0.0', deps: {'qux': '<3.0.0'}) - ..serve('qux', '2.0.0') - ..serve('newdep', '2.0.0', deps: {'baz': '>=1.5.0'}); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': '<2.0.0'}); + builder.serve('bar', '1.0.0', deps: {'baz': '<2.0.0'}); + builder.serve('baz', '1.0.0', deps: {'qux': '<2.0.0'}); + builder.serve('qux', '1.0.0'); + builder.serve('foo', '2.0.0', deps: {'bar': '<3.0.0'}); + builder.serve('bar', '2.0.0', deps: {'baz': '<3.0.0'}); + builder.serve('baz', '2.0.0', deps: {'qux': '<3.0.0'}); + builder.serve('qux', '2.0.0'); + builder.serve('newdep', '2.0.0', deps: {'baz': '>=1.5.0'}); + }); await d.appDir({'foo': '1.0.0'}).create(); await expectResolves(result: { @@ -200,10 +209,11 @@ test( "produces a nice message for a locked dependency that's the only " 'version of its package', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': '>=2.0.0'}) - ..serve('bar', '1.0.0') - ..serve('bar', '2.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': '>=2.0.0'}); + builder.serve('bar', '1.0.0'); + builder.serve('bar', '2.0.0'); + }); await d.appDir({'foo': 'any'}).create(); await expectResolves(result: {'foo': '1.0.0', 'bar': '2.0.0'}); @@ -219,27 +229,30 @@ void rootDependency() { test('with root source', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', deps: {'myapp': 'any'}); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'myapp': 'any'}); + }); await d.appDir({'foo': '1.0.0'}).create(); await expectResolves(result: {'foo': '1.0.0'}); }); test('with mismatched sources', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'myapp': 'any'}) - ..serve('bar', '1.0.0', deps: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'myapp': 'any'}); + builder.serve('bar', '1.0.0', deps: { 'myapp': {'git': 'http://nowhere.com/'} }); + }); await d.appDir({'foo': '1.0.0', 'bar': '1.0.0'}).create(); await expectResolves(result: {'foo': '1.0.0', 'bar': '1.0.0'}); }); test('with wrong version', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', deps: {'myapp': '>0.0.0'}); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'myapp': '>0.0.0'}); + }); await d.appDir({'foo': '1.0.0'}).create(); await expectResolves(error: equalsIgnoringWhitespace(''' @@ -252,9 +265,10 @@ void devDependency() { test("includes root package's dev dependencies", () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('bar', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('bar', '1.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -267,9 +281,10 @@ }); test("includes dev dependency's transitive dependencies", () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': '1.0.0'}) - ..serve('bar', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': '1.0.0'}); + builder.serve('bar', '1.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -282,9 +297,10 @@ }); test("ignores transitive dependency's dev dependencies", () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'dev_dependencies': {'bar': '1.0.0'} + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'dev_dependencies': {'bar': '1.0.0'} + }); }); await d.appDir({'foo': '1.0.0'}).create(); @@ -293,10 +309,11 @@ group('with both a dev and regular dependency', () { test('succeeds when both are satisfied', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0') - ..serve('foo', '3.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0'); + builder.serve('foo', '3.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -310,8 +327,9 @@ }); test("fails when main dependency isn't satisfied", () async { - final server = await servePackages(); - server.serve('foo', '3.0.0'); + await servePackages((builder) { + builder.serve('foo', '3.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -329,8 +347,9 @@ }); test("fails when dev dependency isn't satisfied", () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -348,8 +367,9 @@ }); test('fails when dev and main constraints are incompatible', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -366,8 +386,9 @@ }); test('fails when dev and main sources are incompatible', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -386,8 +407,9 @@ }); test('fails when dev and main descriptions are incompatible', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -411,9 +433,10 @@ void unsolvable() { test('no version that matches constraint', () async { - await servePackages() - ..serve('foo', '2.0.0') - ..serve('foo', '2.1.3'); + await servePackages((builder) { + builder.serve('foo', '2.0.0'); + builder.serve('foo', '2.1.3'); + }); await d.appDir({'foo': '>=1.0.0 <2.0.0'}).create(); await expectResolves(error: equalsIgnoringWhitespace(""" @@ -423,11 +446,12 @@ }); test('no version that matches combined constraint', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'shared': '>=2.0.0 <3.0.0'}) - ..serve('bar', '1.0.0', deps: {'shared': '>=2.9.0 <4.0.0'}) - ..serve('shared', '2.5.0') - ..serve('shared', '3.5.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'shared': '>=2.0.0 <3.0.0'}); + builder.serve('bar', '1.0.0', deps: {'shared': '>=2.9.0 <4.0.0'}); + builder.serve('shared', '2.5.0'); + builder.serve('shared', '3.5.0'); + }); await d.appDir({'foo': '1.0.0', 'bar': '1.0.0'}).create(); await expectResolves(error: equalsIgnoringWhitespace(''' @@ -442,11 +466,12 @@ }); test('disjoint constraints', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'shared': '<=2.0.0'}) - ..serve('bar', '1.0.0', deps: {'shared': '>3.0.0'}) - ..serve('shared', '2.0.0') - ..serve('shared', '4.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'shared': '<=2.0.0'}); + builder.serve('bar', '1.0.0', deps: {'shared': '>3.0.0'}); + builder.serve('shared', '2.0.0'); + builder.serve('shared', '4.0.0'); + }); await d.appDir({'foo': '1.0.0', 'bar': '1.0.0'}).create(); await expectResolves(error: equalsIgnoringWhitespace(''' @@ -458,18 +483,20 @@ }); test('mismatched descriptions', () async { - var otherServer = await startPackageServer(); - otherServer.serve('shared', '1.0.0'); + var otherServer = await PackageServer.start((builder) { + builder.serve('shared', '1.0.0'); + }); - await servePackages() - ..serve('foo', '1.0.0', deps: {'shared': '1.0.0'}) - ..serve('bar', '1.0.0', deps: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'shared': '1.0.0'}); + builder.serve('bar', '1.0.0', deps: { 'shared': { 'hosted': {'name': 'shared', 'url': otherServer.url}, 'version': '1.0.0' } - }) - ..serve('shared', '1.0.0'); + }); + builder.serve('shared', '1.0.0'); + }); await d.appDir({'foo': '1.0.0', 'bar': '1.0.0'}).create(); @@ -488,12 +515,13 @@ test('mismatched sources', () async { await d.dir('shared', [d.libPubspec('shared', '1.0.0')]).create(); - await servePackages() - ..serve('foo', '1.0.0', deps: {'shared': '1.0.0'}) - ..serve('bar', '1.0.0', deps: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'shared': '1.0.0'}); + builder.serve('bar', '1.0.0', deps: { 'shared': {'path': p.join(d.sandbox, 'shared')} - }) - ..serve('shared', '1.0.0'); + }); + builder.serve('shared', '1.0.0'); + }); await d.appDir({'foo': '1.0.0', 'bar': '1.0.0'}).create(); await expectResolves(error: equalsIgnoringWhitespace(''' @@ -506,11 +534,12 @@ }); test('no valid solution', () async { - await servePackages() - ..serve('a', '1.0.0', deps: {'b': '1.0.0'}) - ..serve('a', '2.0.0', deps: {'b': '2.0.0'}) - ..serve('b', '1.0.0', deps: {'a': '2.0.0'}) - ..serve('b', '2.0.0', deps: {'a': '1.0.0'}); + await servePackages((builder) { + builder.serve('a', '1.0.0', deps: {'b': '1.0.0'}); + builder.serve('a', '2.0.0', deps: {'b': '2.0.0'}); + builder.serve('b', '1.0.0', deps: {'a': '2.0.0'}); + builder.serve('b', '2.0.0', deps: {'a': '1.0.0'}); + }); await d.appDir({'a': 'any', 'b': 'any'}).create(); await expectResolves(error: equalsIgnoringWhitespace(''' @@ -525,9 +554,10 @@ // This is a regression test for #15550. test('no version that matches while backtracking', () async { - await servePackages() - ..serve('a', '1.0.0') - ..serve('b', '1.0.0'); + await servePackages((builder) { + builder.serve('a', '1.0.0'); + builder.serve('b', '1.0.0'); + }); await d.appDir({'a': 'any', 'b': '>1.0.0'}).create(); await expectResolves(error: equalsIgnoringWhitespace(""" @@ -538,18 +568,19 @@ // This is a regression test for #18300. test('issue 18300', () async { - await servePackages() - ..serve('analyzer', '0.12.2') - ..serve('angular', '0.10.0', - deps: {'di': '>=0.0.32 <0.1.0', 'collection': '>=0.9.1 <1.0.0'}) - ..serve('angular', '0.9.11', - deps: {'di': '>=0.0.32 <0.1.0', 'collection': '>=0.9.1 <1.0.0'}) - ..serve('angular', '0.9.10', - deps: {'di': '>=0.0.32 <0.1.0', 'collection': '>=0.9.1 <1.0.0'}) - ..serve('collection', '0.9.0') - ..serve('collection', '0.9.1') - ..serve('di', '0.0.37', deps: {'analyzer': '>=0.13.0 <0.14.0'}) - ..serve('di', '0.0.36', deps: {'analyzer': '>=0.13.0 <0.14.0'}); + await servePackages((builder) { + builder.serve('analyzer', '0.12.2'); + builder.serve('angular', '0.10.0', + deps: {'di': '>=0.0.32 <0.1.0', 'collection': '>=0.9.1 <1.0.0'}); + builder.serve('angular', '0.9.11', + deps: {'di': '>=0.0.32 <0.1.0', 'collection': '>=0.9.1 <1.0.0'}); + builder.serve('angular', '0.9.10', + deps: {'di': '>=0.0.32 <0.1.0', 'collection': '>=0.9.1 <1.0.0'}); + builder.serve('collection', '0.9.0'); + builder.serve('collection', '0.9.1'); + builder.serve('di', '0.0.37', deps: {'analyzer': '>=0.13.0 <0.14.0'}); + builder.serve('di', '0.0.36', deps: {'analyzer': '>=0.13.0 <0.14.0'}); + }); await d.appDir({'angular': 'any', 'collection': 'any'}).create(); await expectResolves(error: equalsIgnoringWhitespace(''' @@ -589,16 +620,17 @@ }); test('fail if all versions have bad source in dep', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: { 'bar': {'bad': 'any'} - }) - ..serve('foo', '1.0.1', deps: { + }); + builder.serve('foo', '1.0.1', deps: { 'baz': {'bad': 'any'} - }) - ..serve('foo', '1.0.2', deps: { + }); + builder.serve('foo', '1.0.2', deps: { 'bang': {'bad': 'any'} }); + }); await d.appDir({'foo': 'any'}).create(); await expectResolves(error: equalsIgnoringWhitespace(''' @@ -614,15 +646,16 @@ }); test('ignore versions with bad source in dep', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': 'any'}) - ..serve('foo', '1.0.1', deps: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': 'any'}); + builder.serve('foo', '1.0.1', deps: { 'bar': {'bad': 'any'} - }) - ..serve('foo', '1.0.2', deps: { + }); + builder.serve('foo', '1.0.2', deps: { 'bar': {'bad': 'any'} - }) - ..serve('bar', '1.0.0'); + }); + builder.serve('bar', '1.0.0'); + }); await d.appDir({'foo': 'any'}).create(); await expectResolves(result: {'foo': '1.0.0', 'bar': '1.0.0'}, tries: 2); @@ -630,10 +663,11 @@ // Issue 1853 test('reports a nice error across a collapsed cause', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': 'any'}) - ..serve('bar', '1.0.0', deps: {'baz': 'any'}) - ..serve('baz', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': 'any'}); + builder.serve('bar', '1.0.0', deps: {'baz': 'any'}); + builder.serve('baz', '1.0.0'); + }); await d.dir('baz', [d.libPubspec('baz', '1.0.0')]).create(); await d.appDir({ @@ -651,24 +685,28 @@ void backtracking() { test('circular dependency on older version', () async { - await servePackages() - ..serve('a', '1.0.0') - ..serve('a', '2.0.0', deps: {'b': '1.0.0'}) - ..serve('b', '1.0.0', deps: {'a': '1.0.0'}); + await servePackages((builder) { + builder.serve('a', '1.0.0'); + builder.serve('a', '2.0.0', deps: {'b': '1.0.0'}); + builder.serve('b', '1.0.0', deps: {'a': '1.0.0'}); + }); await d.appDir({'a': '>=1.0.0'}).create(); await expectResolves(result: {'a': '1.0.0'}, tries: 2); }); test('diamond dependency graph', () async { - await servePackages() - ..serve('a', '2.0.0', deps: {'c': '^1.0.0'}) - ..serve('a', '1.0.0') - ..serve('b', '2.0.0', deps: {'c': '^3.0.0'}) - ..serve('b', '1.0.0', deps: {'c': '^2.0.0'}) - ..serve('c', '3.0.0') - ..serve('c', '2.0.0') - ..serve('c', '1.0.0'); + await servePackages((builder) { + builder.serve('a', '2.0.0', deps: {'c': '^1.0.0'}); + builder.serve('a', '1.0.0'); + + builder.serve('b', '2.0.0', deps: {'c': '^3.0.0'}); + builder.serve('b', '1.0.0', deps: {'c': '^2.0.0'}); + + builder.serve('c', '3.0.0'); + builder.serve('c', '2.0.0'); + builder.serve('c', '1.0.0'); + }); await d.appDir({'a': 'any', 'b': 'any'}).create(); await expectResolves(result: {'a': '1.0.0', 'b': '2.0.0', 'c': '3.0.0'}); @@ -678,16 +716,20 @@ // requirement only exists because of both a and b. The solver should be able // to deduce c 2.0.0's incompatibility and select c 1.0.0 instead. test('backjumps after a partial satisfier', () async { - await servePackages() - ..serve('a', '1.0.0', deps: {'x': '>=1.0.0'}) - ..serve('b', '1.0.0', deps: {'x': '<2.0.0'}) - ..serve('c', '1.0.0') - ..serve('c', '2.0.0', deps: {'a': 'any', 'b': 'any'}) - ..serve('x', '0.0.0') - ..serve('x', '1.0.0', deps: {'y': '1.0.0'}) - ..serve('x', '2.0.0') - ..serve('y', '1.0.0') - ..serve('y', '2.0.0'); + await servePackages((builder) { + builder.serve('a', '1.0.0', deps: {'x': '>=1.0.0'}); + builder.serve('b', '1.0.0', deps: {'x': '<2.0.0'}); + + builder.serve('c', '1.0.0'); + builder.serve('c', '2.0.0', deps: {'a': 'any', 'b': 'any'}); + + builder.serve('x', '0.0.0'); + builder.serve('x', '1.0.0', deps: {'y': '1.0.0'}); + builder.serve('x', '2.0.0'); + + builder.serve('y', '1.0.0'); + builder.serve('y', '2.0.0'); + }); await d.appDir({'c': 'any', 'y': '^2.0.0'}).create(); await expectResolves(result: {'c': '1.0.0', 'y': '2.0.0'}, tries: 2); @@ -696,15 +738,16 @@ // This matches the Branching Error Reporting example in the version solver // documentation, and tests that we display line numbers correctly. test('branching error reporting', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'a': '^1.0.0', 'b': '^1.0.0'}) - ..serve('foo', '1.1.0', deps: {'x': '^1.0.0', 'y': '^1.0.0'}) - ..serve('a', '1.0.0', deps: {'b': '^2.0.0'}) - ..serve('b', '1.0.0') - ..serve('b', '2.0.0') - ..serve('x', '1.0.0', deps: {'y': '^2.0.0'}) - ..serve('y', '1.0.0') - ..serve('y', '2.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'a': '^1.0.0', 'b': '^1.0.0'}); + builder.serve('foo', '1.1.0', deps: {'x': '^1.0.0', 'y': '^1.0.0'}); + builder.serve('a', '1.0.0', deps: {'b': '^2.0.0'}); + builder.serve('b', '1.0.0'); + builder.serve('b', '2.0.0'); + builder.serve('x', '1.0.0', deps: {'y': '^2.0.0'}); + builder.serve('y', '1.0.0'); + builder.serve('y', '2.0.0'); + }); await d.appDir({'foo': '^1.0.0'}).create(); await expectResolves( @@ -729,13 +772,14 @@ // will resolve the problem. This test validates that b, which is farther // in the dependency graph from myapp is downgraded first. test('rolls back leaf versions first', () async { - await servePackages() - ..serve('a', '1.0.0', deps: {'b': 'any'}) - ..serve('a', '2.0.0', deps: {'b': 'any', 'c': '2.0.0'}) - ..serve('b', '1.0.0') - ..serve('b', '2.0.0', deps: {'c': '1.0.0'}) - ..serve('c', '1.0.0') - ..serve('c', '2.0.0'); + await servePackages((builder) { + builder.serve('a', '1.0.0', deps: {'b': 'any'}); + builder.serve('a', '2.0.0', deps: {'b': 'any', 'c': '2.0.0'}); + builder.serve('b', '1.0.0'); + builder.serve('b', '2.0.0', deps: {'c': '1.0.0'}); + builder.serve('c', '1.0.0'); + builder.serve('c', '2.0.0'); + }); await d.appDir({'a': 'any'}).create(); await expectResolves(result: {'a': '2.0.0', 'b': '1.0.0', 'c': '2.0.0'}); @@ -744,14 +788,15 @@ // Only one version of baz, so foo and bar will have to downgrade until they // reach it. test('simple transitive', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': '1.0.0'}) - ..serve('foo', '2.0.0', deps: {'bar': '2.0.0'}) - ..serve('foo', '3.0.0', deps: {'bar': '3.0.0'}) - ..serve('bar', '1.0.0', deps: {'baz': 'any'}) - ..serve('bar', '2.0.0', deps: {'baz': '2.0.0'}) - ..serve('bar', '3.0.0', deps: {'baz': '3.0.0'}) - ..serve('baz', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': '1.0.0'}); + builder.serve('foo', '2.0.0', deps: {'bar': '2.0.0'}); + builder.serve('foo', '3.0.0', deps: {'bar': '3.0.0'}); + builder.serve('bar', '1.0.0', deps: {'baz': 'any'}); + builder.serve('bar', '2.0.0', deps: {'baz': '2.0.0'}); + builder.serve('bar', '3.0.0', deps: {'baz': '3.0.0'}); + builder.serve('baz', '1.0.0'); + }); await d.appDir({'foo': 'any'}).create(); await expectResolves( @@ -763,13 +808,14 @@ // make sure b has more versions than a so that the solver tries a first // since it sorts sibling dependencies by number of versions. test('backjump to nearer unsatisfied package', () async { - await servePackages() - ..serve('a', '1.0.0', deps: {'c': '1.0.0'}) - ..serve('a', '2.0.0', deps: {'c': '2.0.0-nonexistent'}) - ..serve('b', '1.0.0') - ..serve('b', '2.0.0') - ..serve('b', '3.0.0') - ..serve('c', '1.0.0'); + await servePackages((builder) { + builder.serve('a', '1.0.0', deps: {'c': '1.0.0'}); + builder.serve('a', '2.0.0', deps: {'c': '2.0.0-nonexistent'}); + builder.serve('b', '1.0.0'); + builder.serve('b', '2.0.0'); + builder.serve('b', '3.0.0'); + builder.serve('c', '1.0.0'); + }); await d.appDir({'a': 'any', 'b': 'any'}).create(); await expectResolves( @@ -793,17 +839,18 @@ test('successful backjump to conflicting source', () async { await d.dir('a', [d.libPubspec('a', '1.0.0')]).create(); - await servePackages() - ..serve('a', '1.0.0') - ..serve('b', '1.0.0', deps: {'a': 'any'}) - ..serve('b', '2.0.0', deps: { + await servePackages((builder) { + builder.serve('a', '1.0.0'); + builder.serve('b', '1.0.0', deps: {'a': 'any'}); + builder.serve('b', '2.0.0', deps: { 'a': {'path': p.join(d.sandbox, 'a')} - }) - ..serve('c', '1.0.0') - ..serve('c', '2.0.0') - ..serve('c', '3.0.0') - ..serve('c', '4.0.0') - ..serve('c', '5.0.0'); + }); + builder.serve('c', '1.0.0'); + builder.serve('c', '2.0.0'); + builder.serve('c', '3.0.0'); + builder.serve('c', '4.0.0'); + builder.serve('c', '5.0.0'); + }); await d.appDir({'a': 'any', 'b': 'any', 'c': 'any'}).create(); await expectResolves(result: {'a': '1.0.0', 'b': '1.0.0', 'c': '5.0.0'}); @@ -811,22 +858,24 @@ // Like the above test, but for a conflicting description. test('successful backjump to conflicting description', () async { - var otherServer = await startPackageServer(); - otherServer.serve('a', '1.0.0'); + var otherServer = await PackageServer.start((builder) { + builder.serve('a', '1.0.0'); + }); - await servePackages() - ..serve('a', '1.0.0') - ..serve('b', '1.0.0', deps: {'a': 'any'}) - ..serve('b', '2.0.0', deps: { + await servePackages((builder) { + builder.serve('a', '1.0.0'); + builder.serve('b', '1.0.0', deps: {'a': 'any'}); + builder.serve('b', '2.0.0', deps: { 'a': { 'hosted': {'name': 'a', 'url': otherServer.url} } - }) - ..serve('c', '1.0.0') - ..serve('c', '2.0.0') - ..serve('c', '3.0.0') - ..serve('c', '4.0.0') - ..serve('c', '5.0.0'); + }); + builder.serve('c', '1.0.0'); + builder.serve('c', '2.0.0'); + builder.serve('c', '3.0.0'); + builder.serve('c', '4.0.0'); + builder.serve('c', '5.0.0'); + }); await d.appDir({'a': 'any', 'b': 'any', 'c': 'any'}).create(); await expectResolves(result: {'a': '1.0.0', 'b': '1.0.0', 'c': '5.0.0'}); @@ -837,16 +886,17 @@ test('failing backjump to conflicting source', () async { await d.dir('a', [d.libPubspec('a', '1.0.0')]).create(); - await servePackages() - ..serve('a', '1.0.0') - ..serve('b', '1.0.0', deps: { + await servePackages((builder) { + builder.serve('a', '1.0.0'); + builder.serve('b', '1.0.0', deps: { 'a': {'path': p.join(d.sandbox, 'shared')} - }) - ..serve('c', '1.0.0') - ..serve('c', '2.0.0') - ..serve('c', '3.0.0') - ..serve('c', '4.0.0') - ..serve('c', '5.0.0'); + }); + builder.serve('c', '1.0.0'); + builder.serve('c', '2.0.0'); + builder.serve('c', '3.0.0'); + builder.serve('c', '4.0.0'); + builder.serve('c', '5.0.0'); + }); await d.appDir({'a': 'any', 'b': 'any', 'c': 'any'}).create(); await expectResolves(error: equalsIgnoringWhitespace(''' @@ -857,21 +907,23 @@ }); test('failing backjump to conflicting description', () async { - var otherServer = await startPackageServer(); - otherServer.serve('a', '1.0.0'); + var otherServer = await PackageServer.start((builder) { + builder.serve('a', '1.0.0'); + }); - await servePackages() - ..serve('a', '1.0.0') - ..serve('b', '1.0.0', deps: { + await servePackages((builder) { + builder.serve('a', '1.0.0'); + builder.serve('b', '1.0.0', deps: { 'a': { 'hosted': {'name': 'a', 'url': otherServer.url} } - }) - ..serve('c', '1.0.0') - ..serve('c', '2.0.0') - ..serve('c', '3.0.0') - ..serve('c', '4.0.0') - ..serve('c', '5.0.0'); + }); + builder.serve('c', '1.0.0'); + builder.serve('c', '2.0.0'); + builder.serve('c', '3.0.0'); + builder.serve('c', '4.0.0'); + builder.serve('c', '5.0.0'); + }); await d.appDir({'a': 'any', 'b': 'any', 'c': 'any'}).create(); await expectResolves( @@ -890,37 +942,39 @@ // Since b has fewer versions, it will be traversed first, which means a will // come later. Since later selections are revised first, a gets downgraded. test('traverse into package with fewer versions first', () async { - await servePackages() - ..serve('a', '1.0.0', deps: {'c': 'any'}) - ..serve('a', '2.0.0', deps: {'c': 'any'}) - ..serve('a', '3.0.0', deps: {'c': 'any'}) - ..serve('a', '4.0.0', deps: {'c': 'any'}) - ..serve('a', '5.0.0', deps: {'c': '1.0.0'}) - ..serve('b', '1.0.0', deps: {'c': 'any'}) - ..serve('b', '2.0.0', deps: {'c': 'any'}) - ..serve('b', '3.0.0', deps: {'c': 'any'}) - ..serve('b', '4.0.0', deps: {'c': '2.0.0'}) - ..serve('c', '1.0.0') - ..serve('c', '2.0.0'); + await servePackages((builder) { + builder.serve('a', '1.0.0', deps: {'c': 'any'}); + builder.serve('a', '2.0.0', deps: {'c': 'any'}); + builder.serve('a', '3.0.0', deps: {'c': 'any'}); + builder.serve('a', '4.0.0', deps: {'c': 'any'}); + builder.serve('a', '5.0.0', deps: {'c': '1.0.0'}); + builder.serve('b', '1.0.0', deps: {'c': 'any'}); + builder.serve('b', '2.0.0', deps: {'c': 'any'}); + builder.serve('b', '3.0.0', deps: {'c': 'any'}); + builder.serve('b', '4.0.0', deps: {'c': '2.0.0'}); + builder.serve('c', '1.0.0'); + builder.serve('c', '2.0.0'); + }); await d.appDir({'a': 'any', 'b': 'any'}).create(); await expectResolves(result: {'a': '4.0.0', 'b': '4.0.0', 'c': '2.0.0'}); }); test('complex backtrack', () async { - final server = await servePackages(); - // This sets up a hundred versions of foo and bar, 0.0.0 through 9.9.0. Each - // version of foo depends on a baz with the same major version. Each version - // of bar depends on a baz with the same minor version. There is only one - // version of baz, 0.0.0, so only older versions of foo and bar will - // satisfy it. - server.serve('baz', '0.0.0'); - for (var i = 0; i < 10; i++) { - for (var j = 0; j < 10; j++) { - server.serve('foo', '$i.$j.0', deps: {'baz': '$i.0.0'}); - server.serve('bar', '$i.$j.0', deps: {'baz': '0.$j.0'}); + await servePackages((builder) { + // This sets up a hundred versions of foo and bar, 0.0.0 through 9.9.0. Each + // version of foo depends on a baz with the same major version. Each version + // of bar depends on a baz with the same minor version. There is only one + // version of baz, 0.0.0, so only older versions of foo and bar will + // satisfy it. + builder.serve('baz', '0.0.0'); + for (var i = 0; i < 10; i++) { + for (var j = 0; j < 10; j++) { + builder.serve('foo', '$i.$j.0', deps: {'baz': '$i.0.0'}); + builder.serve('bar', '$i.$j.0', deps: {'baz': '0.$j.0'}); + } } - } + }); await d.appDir({'foo': 'any', 'bar': 'any'}).create(); await expectResolves( @@ -931,18 +985,19 @@ // versions of it is a waste of time: no possible versions can match. We need // to jump past it to the most recent package that affected the constraint. test('backjump past failed package on disjoint constraint', () async { - await servePackages() - ..serve('a', '1.0.0', deps: { + await servePackages((builder) { + builder.serve('a', '1.0.0', deps: { 'foo': 'any' // ok - }) - ..serve('a', '2.0.0', deps: { + }); + builder.serve('a', '2.0.0', deps: { 'foo': '<1.0.0' // disjoint with myapp's constraint on foo - }) - ..serve('foo', '2.0.0') - ..serve('foo', '2.0.1') - ..serve('foo', '2.0.2') - ..serve('foo', '2.0.3') - ..serve('foo', '2.0.4'); + }); + builder.serve('foo', '2.0.0'); + builder.serve('foo', '2.0.1'); + builder.serve('foo', '2.0.2'); + builder.serve('foo', '2.0.3'); + builder.serve('foo', '2.0.4'); + }); await d.appDir({'a': 'any', 'foo': '>2.0.0'}).create(); await expectResolves(result: {'a': '1.0.0', 'foo': '2.0.4'}); @@ -953,13 +1008,14 @@ // would backtrack over the failed package instead of trying different // versions of it. test('finds solution with less strict constraint', () async { - await servePackages() - ..serve('a', '2.0.0') - ..serve('a', '1.0.0') - ..serve('b', '1.0.0', deps: {'a': '1.0.0'}) - ..serve('c', '1.0.0', deps: {'b': 'any'}) - ..serve('d', '2.0.0', deps: {'myapp': 'any'}) - ..serve('d', '1.0.0', deps: {'myapp': '<1.0.0'}); + await servePackages((builder) { + builder.serve('a', '2.0.0'); + builder.serve('a', '1.0.0'); + builder.serve('b', '1.0.0', deps: {'a': '1.0.0'}); + builder.serve('c', '1.0.0', deps: {'b': 'any'}); + builder.serve('d', '2.0.0', deps: {'myapp': 'any'}); + builder.serve('d', '1.0.0', deps: {'myapp': '<1.0.0'}); + }); await d.appDir({'a': 'any', 'c': 'any', 'd': 'any'}).create(); await expectResolves( @@ -995,9 +1051,10 @@ }); test('dependency does not match SDK', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'environment': {'sdk': '0.0.0'} + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'environment': {'sdk': '0.0.0'} + }); }); await d.appDir({'foo': 'any'}).create(); @@ -1010,11 +1067,12 @@ }); test('transitive dependency does not match SDK', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': 'any'}) - ..serve('bar', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': 'any'}); + builder.serve('bar', '1.0.0', pubspec: { 'environment': {'sdk': '0.0.0'} }); + }); await d.appDir({'foo': 'any'}).create(); await expectResolves(error: equalsIgnoringWhitespace(''' @@ -1027,39 +1085,41 @@ }); test('selects a dependency version that allows the SDK', () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'environment': {'sdk': '0.1.2+3'} - }) - ..serve('foo', '2.0.0', pubspec: { + }); + builder.serve('foo', '2.0.0', pubspec: { 'environment': {'sdk': '0.1.2+3'} - }) - ..serve('foo', '3.0.0', pubspec: { - 'environment': {'sdk': '0.0.0'} - }) - ..serve('foo', '4.0.0', pubspec: { + }); + builder.serve('foo', '3.0.0', pubspec: { 'environment': {'sdk': '0.0.0'} }); + builder.serve('foo', '4.0.0', pubspec: { + 'environment': {'sdk': '0.0.0'} + }); + }); await d.appDir({'foo': 'any'}).create(); await expectResolves(result: {'foo': '2.0.0'}); }); test('selects a transitive dependency version that allows the SDK', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': 'any'}) - ..serve('bar', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': 'any'}); + builder.serve('bar', '1.0.0', pubspec: { 'environment': {'sdk': '0.1.2+3'} - }) - ..serve('bar', '2.0.0', pubspec: { + }); + builder.serve('bar', '2.0.0', pubspec: { 'environment': {'sdk': '0.1.2+3'} - }) - ..serve('bar', '3.0.0', pubspec: { - 'environment': {'sdk': '0.0.0'} - }) - ..serve('bar', '4.0.0', pubspec: { + }); + builder.serve('bar', '3.0.0', pubspec: { 'environment': {'sdk': '0.0.0'} }); + builder.serve('bar', '4.0.0', pubspec: { + 'environment': {'sdk': '0.0.0'} + }); + }); await d.appDir({'foo': 'any'}).create(); await expectResolves(result: {'foo': '1.0.0', 'bar': '2.0.0'}); @@ -1068,23 +1128,24 @@ test( 'selects a dependency version that allows a transitive ' 'dependency that allows the SDK', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': '1.0.0'}) - ..serve('foo', '2.0.0', deps: {'bar': '2.0.0'}) - ..serve('foo', '3.0.0', deps: {'bar': '3.0.0'}) - ..serve('foo', '4.0.0', deps: {'bar': '4.0.0'}) - ..serve('bar', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': '1.0.0'}); + builder.serve('foo', '2.0.0', deps: {'bar': '2.0.0'}); + builder.serve('foo', '3.0.0', deps: {'bar': '3.0.0'}); + builder.serve('foo', '4.0.0', deps: {'bar': '4.0.0'}); + builder.serve('bar', '1.0.0', pubspec: { 'environment': {'sdk': '0.1.2+3'} - }) - ..serve('bar', '2.0.0', pubspec: { + }); + builder.serve('bar', '2.0.0', pubspec: { 'environment': {'sdk': '0.1.2+3'} - }) - ..serve('bar', '3.0.0', pubspec: { - 'environment': {'sdk': '0.0.0'} - }) - ..serve('bar', '4.0.0', pubspec: { + }); + builder.serve('bar', '3.0.0', pubspec: { 'environment': {'sdk': '0.0.0'} }); + builder.serve('bar', '4.0.0', pubspec: { + 'environment': {'sdk': '0.0.0'} + }); + }); await d.appDir({'foo': 'any'}).create(); await expectResolves(result: {'foo': '2.0.0', 'bar': '2.0.0'}, tries: 2); @@ -1402,9 +1463,10 @@ }); test('fails for a dependency', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'environment': {'flutter': '0.0.0'} + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'environment': {'flutter': '0.0.0'} + }); }); await d.appDir({'foo': 'any'}).create(); @@ -1417,12 +1479,13 @@ }); test("chooses a version that doesn't need Flutter", () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0') - ..serve('foo', '3.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0'); + builder.serve('foo', '3.0.0', pubspec: { 'environment': {'flutter': '0.0.0'} }); + }); await d.appDir({'foo': 'any'}).create(); await expectResolves(result: {'foo': '2.0.0'}); @@ -1549,16 +1612,17 @@ }); test('selects the latest dependency with a matching constraint', () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'environment': {'flutter': '^0.0.0'} - }) - ..serve('foo', '2.0.0', pubspec: { + }); + builder.serve('foo', '2.0.0', pubspec: { 'environment': {'flutter': '^1.0.0'} - }) - ..serve('foo', '3.0.0', pubspec: { + }); + builder.serve('foo', '3.0.0', pubspec: { 'environment': {'flutter': '^2.0.0'} }); + }); await d.appDir({'foo': 'any'}).create(); await expectResolves( @@ -1570,33 +1634,36 @@ void prerelease() { test('prefer stable versions over unstable', () async { - await servePackages() - ..serve('a', '1.0.0') - ..serve('a', '1.1.0-dev') - ..serve('a', '2.0.0-dev') - ..serve('a', '3.0.0-dev'); + await servePackages((builder) { + builder.serve('a', '1.0.0'); + builder.serve('a', '1.1.0-dev'); + builder.serve('a', '2.0.0-dev'); + builder.serve('a', '3.0.0-dev'); + }); await d.appDir({'a': 'any'}).create(); await expectResolves(result: {'a': '1.0.0'}); }); test('use latest allowed prerelease if no stable versions match', () async { - await servePackages() - ..serve('a', '1.0.0-dev') - ..serve('a', '1.1.0-dev') - ..serve('a', '1.9.0-dev') - ..serve('a', '3.0.0'); + await servePackages((builder) { + builder.serve('a', '1.0.0-dev'); + builder.serve('a', '1.1.0-dev'); + builder.serve('a', '1.9.0-dev'); + builder.serve('a', '3.0.0'); + }); await d.appDir({'a': '<2.0.0'}).create(); await expectResolves(result: {'a': '1.9.0-dev'}); }); test('use an earlier stable version on a < constraint', () async { - await servePackages() - ..serve('a', '1.0.0') - ..serve('a', '1.1.0') - ..serve('a', '2.0.0-dev') - ..serve('a', '2.0.0'); + await servePackages((builder) { + builder.serve('a', '1.0.0'); + builder.serve('a', '1.1.0'); + builder.serve('a', '2.0.0-dev'); + builder.serve('a', '2.0.0'); + }); await d.appDir({'a': '<2.0.0'}).create(); await expectResolves(result: {'a': '1.1.0'}); @@ -1604,30 +1671,33 @@ test('prefer a stable version even if constraint mentions unstable', () async { - await servePackages() - ..serve('a', '1.0.0') - ..serve('a', '1.1.0') - ..serve('a', '2.0.0-dev') - ..serve('a', '2.0.0'); + await servePackages((builder) { + builder.serve('a', '1.0.0'); + builder.serve('a', '1.1.0'); + builder.serve('a', '2.0.0-dev'); + builder.serve('a', '2.0.0'); + }); await d.appDir({'a': '<=2.0.0-dev'}).create(); await expectResolves(result: {'a': '1.1.0'}); }); test('use pre-release when desired', () async { - await servePackages() - ..serve('a', '1.0.0') - ..serve('a', '1.1.0-dev'); + await servePackages((builder) { + builder.serve('a', '1.0.0'); + builder.serve('a', '1.1.0-dev'); + }); await d.appDir({'a': '^1.1.0-dev'}).create(); await expectResolves(result: {'a': '1.1.0-dev'}); }); test('can upgrade from pre-release', () async { - await servePackages() - ..serve('a', '1.0.0') - ..serve('a', '1.1.0-dev') - ..serve('a', '1.1.0'); + await servePackages((builder) { + builder.serve('a', '1.0.0'); + builder.serve('a', '1.1.0-dev'); + builder.serve('a', '1.1.0'); + }); await d.appDir({'a': '^1.1.0-dev'}).create(); await expectResolves(result: {'a': '1.1.0'}); @@ -1636,11 +1706,12 @@ test('will use pre-release if depended on in stable release', () async { // This behavior is desired because a stable package has dependency on a // pre-release. - await servePackages() - ..serve('a', '1.0.0', deps: {'b': '^1.0.0'}) - ..serve('a', '1.1.0', deps: {'b': '^1.1.0-dev'}) - ..serve('b', '1.0.0') - ..serve('b', '1.1.0-dev'); + await servePackages((builder) { + builder.serve('a', '1.0.0', deps: {'b': '^1.0.0'}); + builder.serve('a', '1.1.0', deps: {'b': '^1.1.0-dev'}); + builder.serve('b', '1.0.0'); + builder.serve('b', '1.1.0-dev'); + }); await d.appDir({'a': '^1.0.0'}).create(); await expectResolves(result: { @@ -1650,11 +1721,12 @@ }); test('backtracks pre-release choice with direct dependency', () async { - await servePackages() - ..serve('a', '1.0.0', deps: {'b': '^1.0.0'}) - ..serve('a', '1.1.0', deps: {'b': '^1.1.0-dev'}) - ..serve('b', '1.0.0') - ..serve('b', '1.1.0-dev'); + await servePackages((builder) { + builder.serve('a', '1.0.0', deps: {'b': '^1.0.0'}); + builder.serve('a', '1.1.0', deps: {'b': '^1.1.0-dev'}); + builder.serve('b', '1.0.0'); + builder.serve('b', '1.1.0-dev'); + }); await d.appDir({ 'a': '^1.0.0', @@ -1669,12 +1741,13 @@ test('backtracking pre-release fails with indirect dependency', () async { // NOTE: This behavior is not necessarily desired. // If feasible it might worth changing this behavior in the future. - await servePackages() - ..serve('a', '1.0.0', deps: {'b': '^1.0.0'}) - ..serve('a', '1.1.0', deps: {'b': '^1.1.0-dev'}) - ..serve('b', '1.0.0') - ..serve('b', '1.1.0-dev') - ..serve('c', '1.0.0', deps: {'b': '^1.0.0'}); + await servePackages((builder) { + builder.serve('a', '1.0.0', deps: {'b': '^1.0.0'}); + builder.serve('a', '1.1.0', deps: {'b': '^1.1.0-dev'}); + builder.serve('b', '1.0.0'); + builder.serve('b', '1.1.0-dev'); + builder.serve('c', '1.0.0', deps: {'b': '^1.0.0'}); + }); await d.appDir({ 'a': '^1.0.0', @@ -1689,13 +1762,14 @@ test('https://github.com/dart-lang/pub/issues/3057 regression', () async { // This used to cause an infinite loop. - await servePackages() - ..serve('a', '0.12.0', deps: {}) - ..serve('b', '0.1.0', deps: {'c': '2.0.0'}) - ..serve('b', '0.9.0-1', deps: {'c': '^1.6.0'}) - ..serve('b', '0.10.0', deps: {'a': '1.0.0'}) - ..serve('b', '0.17.0', deps: {'a': '1.0.0'}) - ..serve('c', '2.0.1', deps: {}); + await servePackages((builder) { + builder.serve('a', '0.12.0', deps: {}); + builder.serve('b', '0.1.0', deps: {'c': '2.0.0'}); + builder.serve('b', '0.9.0-1', deps: {'c': '^1.6.0'}); + builder.serve('b', '0.10.0', deps: {'a': '1.0.0'}); + builder.serve('b', '0.17.0', deps: {'a': '1.0.0'}); + builder.serve('c', '2.0.1', deps: {}); + }); await d.appDir( { @@ -1710,12 +1784,13 @@ }); test('https://github.com/dart-lang/pub/pull/3038 regression', () async { - await servePackages() - ..serve('a', '1.1.0', deps: {'b': '^1.0.0'}) - ..serve('b', '1.0.0', deps: {'c': '^1.0.0'}) - ..serve('c', '0.9.0') - ..serve('b', '1.1.0-alpha') - ..serve('a', '1.0.0', deps: {'b': '^1.1.0-alpha'}); + await servePackages((builder) { + builder.serve('a', '1.1.0', deps: {'b': '^1.0.0'}); + builder.serve('b', '1.0.0', deps: {'c': '^1.0.0'}); + builder.serve('c', '0.9.0'); + builder.serve('b', '1.1.0-alpha'); + builder.serve('a', '1.0.0', deps: {'b': '^1.1.0-alpha'}); + }); await d.appDir({ 'a': '^1.0.0', @@ -1726,10 +1801,11 @@ void override() { test('chooses best version matching override constraint', () async { - await servePackages() - ..serve('a', '1.0.0') - ..serve('a', '2.0.0') - ..serve('a', '3.0.0'); + await servePackages((builder) { + builder.serve('a', '1.0.0'); + builder.serve('a', '2.0.0'); + builder.serve('a', '3.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -1743,10 +1819,11 @@ }); test('uses override as dependency', () async { - await servePackages() - ..serve('a', '1.0.0') - ..serve('a', '2.0.0') - ..serve('a', '3.0.0'); + await servePackages((builder) { + builder.serve('a', '1.0.0'); + builder.serve('a', '2.0.0'); + builder.serve('a', '3.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -1759,12 +1836,13 @@ }); test('ignores other constraints on overridden package', () async { - await servePackages() - ..serve('a', '1.0.0') - ..serve('a', '2.0.0') - ..serve('a', '3.0.0') - ..serve('b', '1.0.0', deps: {'a': '1.0.0'}) - ..serve('c', '1.0.0', deps: {'a': '3.0.0'}); + await servePackages((builder) { + builder.serve('a', '1.0.0'); + builder.serve('a', '2.0.0'); + builder.serve('a', '3.0.0'); + builder.serve('b', '1.0.0', deps: {'a': '1.0.0'}); + builder.serve('c', '1.0.0', deps: {'a': '3.0.0'}); + }); await d.dir(appPath, [ d.pubspec({ @@ -1778,11 +1856,12 @@ }); test('backtracks on overidden package for its constraints', () async { - await servePackages() - ..serve('a', '1.0.0', deps: {'shared': 'any'}) - ..serve('a', '2.0.0', deps: {'shared': '1.0.0'}) - ..serve('shared', '1.0.0') - ..serve('shared', '2.0.0'); + await servePackages((builder) { + builder.serve('a', '1.0.0', deps: {'shared': 'any'}); + builder.serve('a', '2.0.0', deps: {'shared': '1.0.0'}); + builder.serve('shared', '1.0.0'); + builder.serve('shared', '2.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -1796,13 +1875,14 @@ }); test('override compatible with locked dependency', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': '1.0.0'}) - ..serve('foo', '1.0.1', deps: {'bar': '1.0.1'}) - ..serve('foo', '1.0.2', deps: {'bar': '1.0.2'}) - ..serve('bar', '1.0.0') - ..serve('bar', '1.0.1') - ..serve('bar', '1.0.2'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': '1.0.0'}); + builder.serve('foo', '1.0.1', deps: {'bar': '1.0.1'}); + builder.serve('foo', '1.0.2', deps: {'bar': '1.0.2'}); + builder.serve('bar', '1.0.0'); + builder.serve('bar', '1.0.1'); + builder.serve('bar', '1.0.2'); + }); await d.appDir({'foo': '1.0.1'}).create(); await expectResolves(result: {'foo': '1.0.1', 'bar': '1.0.1'}); @@ -1818,13 +1898,14 @@ }); test('override incompatible with locked dependency', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'bar': '1.0.0'}) - ..serve('foo', '1.0.1', deps: {'bar': '1.0.1'}) - ..serve('foo', '1.0.2', deps: {'bar': '1.0.2'}) - ..serve('bar', '1.0.0') - ..serve('bar', '1.0.1') - ..serve('bar', '1.0.2'); + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'bar': '1.0.0'}); + builder.serve('foo', '1.0.1', deps: {'bar': '1.0.1'}); + builder.serve('foo', '1.0.2', deps: {'bar': '1.0.2'}); + builder.serve('bar', '1.0.0'); + builder.serve('bar', '1.0.1'); + builder.serve('bar', '1.0.2'); + }); await d.appDir({'foo': '1.0.1'}).create(); await expectResolves(result: {'foo': '1.0.1', 'bar': '1.0.1'}); @@ -1840,9 +1921,10 @@ }); test('no version that matches override', () async { - await servePackages() - ..serve('foo', '2.0.0') - ..serve('foo', '2.1.3'); + await servePackages((builder) { + builder.serve('foo', '2.0.0'); + builder.serve('foo', '2.1.3'); + }); await d.dir(appPath, [ d.pubspec({ @@ -1858,8 +1940,9 @@ }); test('overrides a bad source without error', () async { - final server = await servePackages(); - server.serve('foo', '0.0.0'); + await servePackages((builder) { + builder.serve('foo', '0.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -1875,9 +1958,10 @@ }); test('overrides an unmatched SDK constraint', () async { - final server = await servePackages(); - server.serve('foo', '0.0.0', pubspec: { - 'environment': {'sdk': '0.0.0'} + await servePackages((builder) { + builder.serve('foo', '0.0.0', pubspec: { + 'environment': {'sdk': '0.0.0'} + }); }); await d.dir(appPath, [ @@ -1891,8 +1975,9 @@ }); test('overrides an unmatched root dependency', () async { - final server = await servePackages(); - server.serve('foo', '0.0.0', deps: {'myapp': '1.0.0'}); + await servePackages((builder) { + builder.serve('foo', '0.0.0', deps: {'myapp': '1.0.0'}); + }); await d.dir(appPath, [ d.pubspec({ @@ -1907,10 +1992,11 @@ // Regression test for #1853 test("overrides a locked package's dependency", () async { - await servePackages() - ..serve('foo', '1.2.3', deps: {'bar': '1.2.3'}) - ..serve('bar', '1.2.3') - ..serve('bar', '0.0.1'); + await servePackages((builder) { + builder.serve('foo', '1.2.3', deps: {'bar': '1.2.3'}); + builder.serve('bar', '1.2.3'); + builder.serve('bar', '0.0.1'); + }); await d.appDir({'foo': 'any'}).create(); @@ -1930,11 +2016,12 @@ void downgrade() { test('downgrades a dependency to the lowest matching version', () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '2.0.0-dev') - ..serve('foo', '2.0.0') - ..serve('foo', '2.1.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '2.0.0-dev'); + builder.serve('foo', '2.0.0'); + builder.serve('foo', '2.1.0'); + }); await d.appDir({'foo': '2.1.0'}).create(); await expectResolves(result: {'foo': '2.1.0'}); @@ -1946,11 +2033,12 @@ test( 'use earliest allowed prerelease if no stable versions match ' 'while downgrading', () async { - await servePackages() - ..serve('a', '1.0.0') - ..serve('a', '2.0.0-dev.1') - ..serve('a', '2.0.0-dev.2') - ..serve('a', '2.0.0-dev.3'); + await servePackages((builder) { + builder.serve('a', '1.0.0'); + builder.serve('a', '2.0.0-dev.1'); + builder.serve('a', '2.0.0-dev.2'); + builder.serve('a', '2.0.0-dev.3'); + }); await d.appDir({'a': '>=2.0.0-dev.1 <3.0.0'}).create(); await expectResolves(result: {'a': '2.0.0-dev.1'}, downgrade: true); @@ -1959,63 +2047,67 @@ void features() { test("doesn't enable an opt-in feature by default", () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'stuff': { 'default': false, 'dependencies': {'bar': '1.0.0'} } } - }) - ..serve('bar', '1.0.0'); + }); + builder.serve('bar', '1.0.0'); + }); await d.appDir({'foo': '1.0.0'}).create(); await expectResolves(result: {'foo': '1.0.0'}); }); test('enables an opt-out feature by default', () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'stuff': { 'default': true, 'dependencies': {'bar': '1.0.0'} } } - }) - ..serve('bar', '1.0.0'); + }); + builder.serve('bar', '1.0.0'); + }); await d.appDir({'foo': '1.0.0'}).create(); await expectResolves(result: {'foo': '1.0.0', 'bar': '1.0.0'}); }); test('features are opt-out by default', () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'stuff': { 'dependencies': {'bar': '1.0.0'} } } - }) - ..serve('bar', '1.0.0'); + }); + builder.serve('bar', '1.0.0'); + }); await d.appDir({'foo': '1.0.0'}).create(); await expectResolves(result: {'foo': '1.0.0', 'bar': '1.0.0'}); }); test("enables an opt-in feature if it's required", () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'stuff': { 'default': false, 'dependencies': {'bar': '1.0.0'} } } - }) - ..serve('bar', '1.0.0'); + }); + builder.serve('bar', '1.0.0'); + }); await d.appDir({ 'foo': { @@ -2027,15 +2119,16 @@ }); test("doesn't enable an opt-out feature if it's disabled", () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'stuff': { 'dependencies': {'bar': '1.0.0'} } } - }) - ..serve('bar', '1.0.0'); + }); + builder.serve('bar', '1.0.0'); + }); await d.appDir({ 'foo': { @@ -2047,21 +2140,22 @@ }); test('opting in takes precedence over opting out', () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'stuff': { 'dependencies': {'bar': '1.0.0'} } } - }) - ..serve('bar', '1.0.0') - ..serve('baz', '1.0.0', deps: { + }); + builder.serve('bar', '1.0.0'); + builder.serve('baz', '1.0.0', deps: { 'foo': { 'version': '1.0.0', 'features': {'stuff': true} } }); + }); await d.appDir({ 'foo': { @@ -2075,20 +2169,21 @@ }); test('implicitly opting in takes precedence over opting out', () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'stuff': { 'dependencies': {'bar': '1.0.0'} } } - }) - ..serve('bar', '1.0.0') - ..serve('baz', '1.0.0', deps: { + }); + builder.serve('bar', '1.0.0'); + builder.serve('baz', '1.0.0', deps: { 'foo': { 'version': '1.0.0', } }); + }); await d.appDir({ 'foo': { @@ -2102,17 +2197,18 @@ }); test("doesn't select a version with an unavailable feature", () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'stuff': { 'default': false, 'dependencies': {'bar': '1.0.0'} } } - }) - ..serve('foo', '1.1.0') - ..serve('bar', '1.0.0'); + }); + builder.serve('foo', '1.1.0'); + builder.serve('bar', '1.0.0'); + }); await d.appDir({ 'foo': { @@ -2124,25 +2220,26 @@ }); test("doesn't select a version with an incompatible feature", () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'stuff': { 'default': false, 'dependencies': {'bar': '1.0.0'} } } - }) - ..serve('foo', '1.1.0', pubspec: { + }); + builder.serve('foo', '1.1.0', pubspec: { 'features': { 'stuff': { 'default': false, 'dependencies': {'bar': '2.0.0'} } } - }) - ..serve('bar', '1.0.0') - ..serve('bar', '2.0.0'); + }); + builder.serve('bar', '1.0.0'); + builder.serve('bar', '2.0.0'); + }); await d.appDir({ 'foo': { @@ -2157,8 +2254,8 @@ test( 'backtracks if a feature is transitively incompatible with another ' 'feature', () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'stuff': { 'default': false, @@ -2170,24 +2267,27 @@ } } } - }) - ..serve('foo', '1.1.0', pubspec: { + }); + builder.serve('foo', '1.1.0', pubspec: { 'features': { 'stuff': { 'default': false, 'dependencies': {'bar': '1.0.0'} } } - }) - ..serve('bar', '1.0.0', pubspec: { + }); + + builder.serve('bar', '1.0.0', pubspec: { 'features': { 'stuff': { 'dependencies': {'baz': '1.0.0'} } } - }) - ..serve('baz', '1.0.0') - ..serve('baz', '2.0.0'); + }); + + builder.serve('baz', '1.0.0'); + builder.serve('baz', '2.0.0'); + }); await d.appDir({ 'foo': { @@ -2202,27 +2302,30 @@ test("backtracks if a feature's dependencies are transitively incompatible", () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'stuff': { 'default': false, 'dependencies': {'bar': '1.0.0'} } } - }) - ..serve('foo', '1.1.0', pubspec: { + }); + builder.serve('foo', '1.1.0', pubspec: { 'features': { 'stuff': { 'default': false, 'dependencies': {'bar': '2.0.0'} } } - }) - ..serve('bar', '1.0.0', deps: {'baz': '1.0.0'}) - ..serve('bar', '2.0.0', deps: {'baz': '2.0.0'}) - ..serve('baz', '1.0.0') - ..serve('baz', '2.0.0'); + }); + + builder.serve('bar', '1.0.0', deps: {'baz': '1.0.0'}); + builder.serve('bar', '2.0.0', deps: {'baz': '2.0.0'}); + + builder.serve('baz', '1.0.0'); + builder.serve('baz', '2.0.0'); + }); await d.appDir({ 'foo': { @@ -2236,9 +2339,9 @@ }); test('disables a feature when it backtracks', () async { - await servePackages() - ..serve('foo', '1.0.0', deps: {'myapp': '0.0.0'}) - ..serve('foo', '1.1.0', deps: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: {'myapp': '0.0.0'}); + builder.serve('foo', '1.1.0', deps: { // This is a transitively incompatible dependency with myapp, which will // force the solver to backtrack and unselect foo 1.1.0. 'bar': '1.0.0', @@ -2246,11 +2349,15 @@ 'version': '0.0.0', 'features': {'stuff': true} } - }) - ..serve('bar', '1.0.0', deps: {'baz': '2.0.0'}) - ..serve('baz', '1.0.0') - ..serve('baz', '2.0.0') - ..serve('qux', '1.0.0'); + }); + + builder.serve('bar', '1.0.0', deps: {'baz': '2.0.0'}); + + builder.serve('baz', '1.0.0'); + builder.serve('baz', '2.0.0'); + + builder.serve('qux', '1.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -2268,9 +2375,10 @@ }); test("the root package's features are opt-out by default", () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('bar', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('bar', '1.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -2287,9 +2395,10 @@ }); test("the root package's features can be made opt-in", () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('bar', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('bar', '1.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -2312,13 +2421,14 @@ // increases the total number of dependencies. test("the root package's features can't be disabled by dependencies", () async { - await servePackages() - ..serve('foo', '1.0.0', deps: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: { 'myapp': { 'features': {'stuff': false} } - }) - ..serve('bar', '1.0.0'); + }); + builder.serve('bar', '1.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -2335,13 +2445,14 @@ }); test("the root package's features can be enabled by dependencies", () async { - await servePackages() - ..serve('foo', '1.0.0', deps: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', deps: { 'myapp': { 'features': {'stuff': true} } - }) - ..serve('bar', '1.0.0'); + }); + builder.serve('bar', '1.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -2359,8 +2470,9 @@ }); test("resolution fails because a feature doesn't exist", () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + }); await d.dir(appPath, [ d.pubspec({ @@ -2380,16 +2492,17 @@ group('an "if available" dependency', () { test('enables an opt-in feature', () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'stuff': { 'default': false, 'dependencies': {'bar': '1.0.0'} } } - }) - ..serve('bar', '1.0.0'); + }); + builder.serve('bar', '1.0.0'); + }); await d.appDir({ 'foo': { @@ -2401,8 +2514,9 @@ }); test("is compatible with a feature that doesn't exist", () async { - final server = await servePackages(); - server.serve('foo', '1.0.0'); + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + }); await d.appDir({ 'foo': { @@ -2421,13 +2535,14 @@ group('succeeds when', () { test('a Dart SDK constraint is matched', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'features': { - 'stuff': { - 'environment': {'sdk': '^0.1.0'} + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'features': { + 'stuff': { + 'environment': {'sdk': '^0.1.0'} + } } - } + }); }); await d.dir(appPath, [ @@ -2441,13 +2556,14 @@ }); test('a Flutter SDK constraint is matched', () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'features': { - 'stuff': { - 'environment': {'flutter': '^1.0.0'} + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'features': { + 'stuff': { + 'environment': {'flutter': '^1.0.0'} + } } - } + }); }); await d.dir(appPath, [ @@ -2465,15 +2581,16 @@ group("doesn't choose a version because", () { test("a Dart SDK constraint isn't matched", () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '1.1.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '1.1.0', pubspec: { 'features': { 'stuff': { 'environment': {'sdk': '0.0.1'} } } }); + }); await d.dir(appPath, [ d.pubspec({ @@ -2486,15 +2603,16 @@ }); test("Flutter isn't available", () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '1.1.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '1.1.0', pubspec: { 'features': { 'stuff': { 'environment': {'flutter': '1.0.0'} } } }); + }); await d.dir(appPath, [ d.pubspec({ @@ -2507,15 +2625,16 @@ }); test("a Flutter SDK constraint isn't matched", () async { - await servePackages() - ..serve('foo', '1.0.0') - ..serve('foo', '1.1.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0'); + builder.serve('foo', '1.1.0', pubspec: { 'features': { 'stuff': { 'environment': {'flutter': '^2.0.0'} } } }); + }); await d.dir(appPath, [ d.pubspec({ @@ -2532,13 +2651,14 @@ group('resolution fails because', () { test("a Dart SDK constraint isn't matched", () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'features': { - 'stuff': { - 'environment': {'sdk': '0.0.1'} + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'features': { + 'stuff': { + 'environment': {'sdk': '0.0.1'} + } } - } + }); }); await d.dir(appPath, [ @@ -2555,13 +2675,14 @@ }); test("Flutter isn't available", () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'features': { - 'stuff': { - 'environment': {'flutter': '1.0.0'} + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'features': { + 'stuff': { + 'environment': {'flutter': '1.0.0'} + } } - } + }); }); await d.dir(appPath, [ @@ -2577,13 +2698,14 @@ }); test("a Flutter SDK constraint isn't matched", () async { - final server = await servePackages(); - server.serve('foo', '1.0.0', pubspec: { - 'features': { - 'stuff': { - 'environment': {'flutter': '^2.0.0'} + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { + 'features': { + 'stuff': { + 'environment': {'flutter': '^2.0.0'} + } } - } + }); }); await d.dir(appPath, [ @@ -2603,8 +2725,8 @@ group('with overlapping dependencies', () { test('can enable extra features', () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'dependencies': {'bar': '1.0.0'}, 'features': { 'stuff': { @@ -2616,16 +2738,19 @@ } } } - }) - ..serve('bar', '1.0.0', pubspec: { + }); + + builder.serve('bar', '1.0.0', pubspec: { 'features': { 'stuff': { 'default': false, 'dependencies': {'baz': '1.0.0'} } } - }) - ..serve('baz', '1.0.0'); + }); + + builder.serve('baz', '1.0.0'); + }); await d.appDir({ 'foo': {'version': '1.0.0'} @@ -2643,8 +2768,8 @@ }); test("can't disable features", () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'dependencies': { 'bar': { 'version': '1.0.0', @@ -2661,16 +2786,19 @@ } } } - }) - ..serve('bar', '1.0.0', pubspec: { + }); + + builder.serve('bar', '1.0.0', pubspec: { 'features': { 'stuff': { 'default': true, 'dependencies': {'baz': '1.0.0'} } } - }) - ..serve('baz', '1.0.0'); + }); + + builder.serve('baz', '1.0.0'); + }); await d.appDir({ 'foo': { @@ -2685,8 +2813,8 @@ group('with required features', () { test('enables those features', () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'main': { 'default': false, @@ -2701,9 +2829,10 @@ 'dependencies': {'baz': '1.0.0'} } } - }) - ..serve('bar', '1.0.0') - ..serve('baz', '1.0.0'); + }); + builder.serve('bar', '1.0.0'); + builder.serve('baz', '1.0.0'); + }); await d.appDir({ 'foo': { @@ -2716,8 +2845,8 @@ }); test('enables those features by default', () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'main': { 'requires': ['required1', 'required2'] @@ -2731,9 +2860,10 @@ 'dependencies': {'baz': '1.0.0'} } } - }) - ..serve('bar', '1.0.0') - ..serve('baz', '1.0.0'); + }); + builder.serve('bar', '1.0.0'); + builder.serve('baz', '1.0.0'); + }); await d.appDir({'foo': '1.0.0'}).create(); await expectResolves( @@ -2741,8 +2871,8 @@ }); test("doesn't enable those features if it's disabled", () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'main': { 'requires': ['required'] @@ -2752,8 +2882,9 @@ 'dependencies': {'bar': '1.0.0'} } } - }) - ..serve('bar', '1.0.0'); + }); + builder.serve('bar', '1.0.0'); + }); await d.appDir({ 'foo': { @@ -2766,8 +2897,8 @@ test("enables those features even if they'd otherwise be disabled", () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'main': { 'requires': ['required'] @@ -2777,8 +2908,9 @@ 'dependencies': {'bar': '1.0.0'} } } - }) - ..serve('bar', '1.0.0'); + }); + builder.serve('bar', '1.0.0'); + }); await d.appDir({ 'foo': { @@ -2790,8 +2922,8 @@ }); test('enables features transitively', () async { - await servePackages() - ..serve('foo', '1.0.0', pubspec: { + await servePackages((builder) { + builder.serve('foo', '1.0.0', pubspec: { 'features': { 'main': { 'requires': ['required1'] @@ -2805,8 +2937,9 @@ 'dependencies': {'bar': '1.0.0'} } } - }) - ..serve('bar', '1.0.0'); + }); + builder.serve('bar', '1.0.0'); + }); await d.appDir({ 'foo': { @@ -2874,7 +3007,7 @@ // If the dep uses the default hosted source, grab it from the test // package server rather than pub.dartlang.org. dep = registry.hosted - .refFor(dep.name, url: Uri.parse(globalServer.url)) + .refFor(dep.name, url: Uri.parse(globalPackageServer!.url)) .withConstraint(dep.constraint); } expect(dep.allows(id), isTrue, reason: 'Expected $id to match $dep.'); @@ -2885,12 +3018,14 @@ void regressions() { test('reformatRanges with a build', () async { - await servePackages() - ..serve('integration_test', '1.0.1', - deps: {'vm_service': '>= 4.2.0 <6.0.0'}) - ..serve('integration_test', '1.0.2+2', - deps: {'vm_service': '>= 4.2.0 <7.0.0'}) - ..serve('vm_service', '7.3.0'); + await servePackages((b) { + b.serve('integration_test', '1.0.1', + deps: {'vm_service': '>= 4.2.0 <6.0.0'}); + b.serve('integration_test', '1.0.2+2', + deps: {'vm_service': '>= 4.2.0 <7.0.0'}); + + b.serve('vm_service', '7.3.0'); + }); await d.appDir({'integration_test': '^1.0.2'}).create(); await expectResolves( error: contains(
diff --git a/tool/test-bin/pub_command_runner.dart b/tool/test-bin/pub_command_runner.dart index e438aae..2be51e8 100644 --- a/tool/test-bin/pub_command_runner.dart +++ b/tool/test-bin/pub_command_runner.dart
@@ -9,30 +9,12 @@ import 'package:args/args.dart'; import 'package:args/command_runner.dart'; import 'package:pub/pub.dart'; -import 'package:pub/src/command.dart'; import 'package:pub/src/exit_codes.dart' as exit_codes; import 'package:pub/src/log.dart' as log; import 'package:usage/usage.dart'; final _LoggingAnalytics loggingAnalytics = _LoggingAnalytics(); -// A command for explicitly throwing an exception, to test the handling of -// unexpected eceptions. -class ThrowingCommand extends PubCommand { - @override - String get name => 'fail'; - - @override - String get description => 'Throws an exception'; - - bool get hide => true; - - @override - Future<int> runProtected() async { - throw StateError('Pub has crashed'); - } -} - class Runner extends CommandRunner<int> { late ArgResults _options; @@ -41,10 +23,7 @@ ? PubAnalytics(() => loggingAnalytics, dependencyKindCustomDimensionName: 'cd1') : null; - addCommand( - pubCommand(analytics: analytics, isVerbose: () => _options['verbose']) - ..addSubcommand(ThrowingCommand())); - argParser.addFlag('verbose'); + addCommand(pubCommand(analytics: analytics)); } @override
diff --git a/tool/test.dart b/tool/test.dart index 7d98156..e7877a2 100755 --- a/tool/test.dart +++ b/tool/test.dart
@@ -29,7 +29,7 @@ await precompile( executablePath: path.join('bin', 'pub.dart'), outputPath: pubSnapshotFilename, - incrementalDillPath: pubSnapshotIncrementalFilename, + incrementalDillOutputPath: pubSnapshotIncrementalFilename, name: 'bin/pub.dart', packageConfigPath: path.join('.dart_tool', 'package_config.json')); testProcess = await Process.start(