
Context: https://github.com/flutter/flutter/issues/131862 This PR injects a "realm" component to the storage base URL when the contents of the file `bin/internal/engine.realm` is non-empty. As documented in the PR, when the realm is `flutter_archives_v2`, and `bin/internal/engine.version` contains the commit hash for a commit in a `flutter/engine` PR, then the artifacts pulled by the tool will be the artifacts built by the presubmit checks for the PR. This works for everything but the following two cases: 1. Fuchsia artifacts are not uploaded to CIPD by the Fuchsia presubmit builds. 2. Web artifacts are not uploaded to gstatic by the web engine presubmit builds. For (1), the flutter/flutter presubmit `fuchsia_precache` is driven by a shell script outside of the repo. It will fail when the `engine.version` and `engine.realm` don't point to a post-submit engine commit. For (2), the flutter/flutter web presubmit tests that refer to artifacts in gstatic hang when the artifacts aren't found, so this PR skips them.
98 lines
3.8 KiB
Dart
98 lines
3.8 KiB
Dart
// Copyright 2014 The Flutter Authors. 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 'dart:math';
|
|
|
|
import 'package:archive/archive.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:path/path.dart' as path;
|
|
|
|
const String kDocRoot = 'dev/docs/doc';
|
|
|
|
/// This script downloads an archive of Javadoc and objc doc for the engine from
|
|
/// the artifact store and extracts them to the location used for Dartdoc.
|
|
Future<void> main(List<String> args) async {
|
|
final String engineVersion = File('bin/internal/engine.version').readAsStringSync().trim();
|
|
String engineRealm = File('bin/internal/engine.realm').readAsStringSync().trim();
|
|
if (engineRealm.isNotEmpty) {
|
|
engineRealm = '$engineRealm/';
|
|
}
|
|
|
|
final String javadocUrl = 'https://storage.googleapis.com/${engineRealm}flutter_infra_release/flutter/$engineVersion/android-javadoc.zip';
|
|
generateDocs(javadocUrl, 'javadoc', 'io/flutter/view/FlutterView.html');
|
|
|
|
final String objcdocUrl = 'https://storage.googleapis.com/${engineRealm}flutter_infra_release/flutter/$engineVersion/ios-objcdoc.zip';
|
|
generateDocs(objcdocUrl, 'objcdoc', 'Classes/FlutterViewController.html');
|
|
}
|
|
|
|
/// Fetches the zip archive at the specified url.
|
|
///
|
|
/// Returns null if the archive fails to download after [maxTries] attempts.
|
|
Future<Archive?> fetchArchive(String url, int maxTries) async {
|
|
List<int>? responseBytes;
|
|
for (int i = 0; i < maxTries; i++) {
|
|
final http.Response response = await http.get(Uri.parse(url));
|
|
if (response.statusCode == 200) {
|
|
responseBytes = response.bodyBytes;
|
|
break;
|
|
}
|
|
stderr.writeln('Failed attempt ${i+1} to fetch $url.');
|
|
|
|
// On failure print a short snipped from the body in case it's helpful.
|
|
final int bodyLength = min(1024, response.body.length);
|
|
stderr.writeln('Response status code ${response.statusCode}. Body: ${response.body.substring(0, bodyLength)}');
|
|
sleep(const Duration(seconds: 1));
|
|
}
|
|
return responseBytes == null ? null : ZipDecoder().decodeBytes(responseBytes);
|
|
}
|
|
|
|
Future<void> generateDocs(String url, String docName, String checkFile) async {
|
|
const int maxTries = 5;
|
|
final Archive? archive = await fetchArchive(url, maxTries);
|
|
if (archive == null) {
|
|
stderr.writeln('Failed to fetch zip archive from: $url after $maxTries attempts. Giving up.');
|
|
exit(1);
|
|
}
|
|
|
|
final Directory output = Directory('$kDocRoot/$docName');
|
|
print('Extracting $docName to ${output.path}');
|
|
output.createSync(recursive: true);
|
|
|
|
for (final ArchiveFile af in archive) {
|
|
if (!af.name.endsWith('/')) {
|
|
final File file = File('${output.path}/${af.name}');
|
|
file.createSync(recursive: true);
|
|
file.writeAsBytesSync(af.content as List<int>);
|
|
}
|
|
}
|
|
|
|
/// If object then copy files to old location if the archive is using the new location.
|
|
final bool exists = Directory('$kDocRoot/$docName/objectc_docs').existsSync();
|
|
if (exists) {
|
|
copyFolder(Directory('$kDocRoot/$docName/objectc_docs'), Directory('$kDocRoot/$docName/'));
|
|
}
|
|
|
|
final File testFile = File('${output.path}/$checkFile');
|
|
if (!testFile.existsSync()) {
|
|
print('Expected file ${testFile.path} not found');
|
|
exit(1);
|
|
}
|
|
print('$docName ready to go!');
|
|
}
|
|
|
|
/// Copies the files in a directory recursively to a new location.
|
|
void copyFolder(Directory source, Directory destination) {
|
|
source.listSync()
|
|
.forEach((FileSystemEntity entity) {
|
|
if (entity is Directory) {
|
|
final Directory newDirectory = Directory(path.join(destination.absolute.path, path.basename(entity.path)));
|
|
newDirectory.createSync();
|
|
copyFolder(entity.absolute, newDirectory);
|
|
} else if (entity is File) {
|
|
entity.copySync(path.join(destination.path, path.basename(entity.path)));
|
|
}
|
|
});
|
|
}
|