[tool] version-check publish-check commands can check against pub (#3840)

Add a PubVersionFinder class to easily fetch the version from pub.

Add an against-pub flag to check-version command, which allows it to check the version against pub server

Make the 'publish-check' command to check against pub to determine if the specific versions of packages need to be published.
Add a log-status flag, which allows the publish-check command to log the final status of the result. This helps other ci tools to easily grab the results and use it to determine what to do next. See option 3 in flutter/flutter#81444

This PR also fixes some tests.

partially flutter/flutter#81444
This commit is contained in:
Chris Yang
2021-05-11 12:48:30 -07:00
committed by GitHub
parent ce899a3151
commit 87cfd6ab03
8 changed files with 902 additions and 104 deletions

View File

@ -11,6 +11,7 @@ import 'package:args/command_runner.dart';
import 'package:colorize/colorize.dart';
import 'package:file/file.dart';
import 'package:git/git.dart';
import 'package:http/http.dart' as http;
import 'package:meta/meta.dart';
import 'package:path/path.dart' as p;
import 'package:pub_semver/pub_semver.dart';
@ -563,6 +564,98 @@ class ProcessRunner {
}
}
/// Finding version of [package] that is published on pub.
class PubVersionFinder {
/// Constructor.
///
/// Note: you should manually close the [httpClient] when done using the finder.
PubVersionFinder({this.pubHost = defaultPubHost, @required this.httpClient});
/// The default pub host to use.
static const String defaultPubHost = 'https://pub.dev';
/// The pub host url, defaults to `https://pub.dev`.
final String pubHost;
/// The http client.
///
/// You should manually close this client when done using this finder.
final http.Client httpClient;
/// Get the package version on pub.
Future<PubVersionFinderResponse> getPackageVersion(
{@required String package}) async {
assert(package != null && package.isNotEmpty);
final Uri pubHostUri = Uri.parse(pubHost);
final Uri url = pubHostUri.replace(path: '/packages/$package.json');
final http.Response response = await httpClient.get(url);
if (response.statusCode == 404) {
return PubVersionFinderResponse(
versions: null,
result: PubVersionFinderResult.noPackageFound,
httpResponse: response);
} else if (response.statusCode != 200) {
return PubVersionFinderResponse(
versions: null,
result: PubVersionFinderResult.fail,
httpResponse: response);
}
final List<Version> versions =
(json.decode(response.body)['versions'] as List<dynamic>)
.map<Version>((final dynamic versionString) =>
Version.parse(versionString as String))
.toList();
return PubVersionFinderResponse(
versions: versions,
result: PubVersionFinderResult.success,
httpResponse: response);
}
}
/// Represents a response for [PubVersionFinder].
class PubVersionFinderResponse {
/// Constructor.
PubVersionFinderResponse({this.versions, this.result, this.httpResponse}) {
if (versions != null && versions.isNotEmpty) {
versions.sort((Version a, Version b) {
// TODO(cyanglaz): Think about how to handle pre-release version with [Version.prioritize].
// https://github.com/flutter/flutter/issues/82222
return b.compareTo(a);
});
}
}
/// The versions found in [PubVersionFinder].
///
/// This is sorted by largest to smallest, so the first element in the list is the largest version.
/// Might be `null` if the [result] is not [PubVersionFinderResult.success].
final List<Version> versions;
/// The result of the version finder.
final PubVersionFinderResult result;
/// The response object of the http request.
final http.Response httpResponse;
}
/// An enum representing the result of [PubVersionFinder].
enum PubVersionFinderResult {
/// The version finder successfully found a version.
success,
/// The version finder failed to find a valid version.
///
/// This might due to http connection errors or user errors.
fail,
/// The version finder failed to locate the package.
///
/// This indicates the package is new.
noPackageFound,
}
/// Finding diffs based on `baseGitDir` and `baseSha`.
class GitVersionFinder {
/// Constructor