downloadPackage function
Downloads package
and unpacks it into destination
Implementation
Future<void> downloadPackage(
String package,
String? version, {
required String destination,
String? pubHostedUrl,
}) async {
pubHostedUrl ??= 'https://pub-web.flutter-io.cn';
final pubHostedUri = Uri.parse(pubHostedUrl);
final client = http_retry.RetryClient(
http.Client(),
when: (rs) => rs.statusCode >= 500,
);
try {
// Find URI for the package archive
final versionsUri = pubHostedUri.replace(
path: p.join(pubHostedUri.path, '/api/packages/$package'));
final versionsRs = await client.get(versionsUri);
if (versionsRs.statusCode != 200) {
throw Exception(
'Unable to access URL: "$versionsUri" (status code: ${versionsRs.statusCode}).');
}
final versionsJson = json.decode(versionsRs.body);
if (version == null) {
version = versionsJson['latest']['version'] as String;
log.fine('Latest version is: $version');
}
final versions = versionsJson['versions'] as List;
final data = versions
.cast<Map<String, dynamic>>()
.firstWhereOrNull((e) => e['version'] == version);
if (data == null) {
log.info(
'Available versions: ${versions.map((e) => e['version']).join(', ')}');
throw Exception('Version $version not found in version listing');
}
final archiveUrl = data['archive_url'] as String;
var packageUri = Uri.parse(archiveUrl);
if (!packageUri.hasScheme) {
packageUri =
pubHostedUri.replace(path: p.join(pubHostedUri.path, archiveUrl));
}
log.info('Downloading package $package $version from $packageUri');
final rs = await client.get(packageUri);
if (rs.statusCode != 200) {
throw Exception(
'Unable to access URL: "$packageUri" (status code: ${rs.statusCode}).');
}
await _extractTarGz(Stream.value(rs.bodyBytes), destination);
} catch (e, st) {
log.warning('Unable to download $package $version', e, st);
rethrow;
} finally {
client.close();
}
}