Unverified Commit ff829fd8 authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Add doxygen doc generation. (#131356)

parent 7ef4290a
...@@ -134,6 +134,11 @@ function main() { ...@@ -134,6 +134,11 @@ function main() {
if ! [[ "$DESTINATION" =~ ^/ ]]; then if ! [[ "$DESTINATION" =~ ^/ ]]; then
DESTINATION="$PWD/$DESTINATION" DESTINATION="$PWD/$DESTINATION"
fi fi
# Make sure the destination has .zip as an extension, because zip will add it
# anyhow, and we want to print the correct output location.
DESTINATION=${DESTINATION%.zip}.zip
# Zip up doc directory and write the output to the destination. # Zip up doc directory and write the output to the destination.
(cd "$STAGING_DIR"; zip -r -9 -q "$DESTINATION" ./doc) (cd "$STAGING_DIR"; zip -r -9 -q "$DESTINATION" ./doc)
if [[ $KEEP_STAGING -eq 1 ]]; then if [[ $KEEP_STAGING -eq 1 ]]; then
......
...@@ -14,6 +14,14 @@ This site hosts Flutter's API documentation. Other documentation can be found at ...@@ -14,6 +14,14 @@ This site hosts Flutter's API documentation. Other documentation can be found at
the following locations: the following locations:
* [flutter.dev](https://flutter.dev) (main site) * [flutter.dev](https://flutter.dev) (main site)
* [api.flutter.dev](https://api.flutter.dev) (API docs reference site)
* Engine Embedder API documentation:
* [Android Embedder](https://api.flutter.dev/javadoc/index.html)
* [iOS Embedder](https://api.flutter.dev/ios-embedder/index.html)
* [macOS Embedder](https://api.flutter.dev/macos-embedder/index.html)
* [Linux Embedder](https://api.flutter.dev/linux-embedder/index.html)
* [Windows Embedder](https://api.flutter.dev/windows-embedder/index.html)
* [Web Embedder](https://api.flutter.dev/flutter/dart-ui_web/dart-ui_web-library.html)
* [Installation](https://flutter.dev/docs/get-started/install) * [Installation](https://flutter.dev/docs/get-started/install)
* [Codelabs](https://flutter.dev/docs/codelabs) * [Codelabs](https://flutter.dev/docs/codelabs)
* [Contributing to Flutter](https://github.com/flutter/flutter/blob/master/CONTRIBUTING.md) * [Contributing to Flutter](https://github.com/flutter/flutter/blob/master/CONTRIBUTING.md)
......
...@@ -2,5 +2,5 @@ ...@@ -2,5 +2,5 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
/// [Flutter platform integration APIs for iOS.](https://api.flutter.dev/objcdoc/) /// [Flutter platform integration APIs for iOS.](https://api.flutter.dev/ios-embedder/)
library iOS; library iOS;
// 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.
/// [Flutter platform integration APIs for Linux.](https://api.flutter.dev/linux-embedder/)
library Linux;
// 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.
/// [Flutter platform integration APIs for macOS.](https://api.flutter.dev/macos-embedder/)
library macOS;
// 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.
/// [Flutter platform integration APIs for Windows.](https://api.flutter.dev/windows-embedder/)
library Windows;
// 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.
/// [Flutter APIs for the Impeller renderer.](https://api.flutter.dev/impeller/)
library Impeller;
name: renderers
environment:
sdk: '>=2.19.0-0 <4.0.0'
...@@ -23,6 +23,58 @@ import 'dartdoc_checker.dart'; ...@@ -23,6 +23,58 @@ import 'dartdoc_checker.dart';
const String kDummyPackageName = 'Flutter'; const String kDummyPackageName = 'Flutter';
const String kPlatformIntegrationPackageName = 'platform_integration'; const String kPlatformIntegrationPackageName = 'platform_integration';
class PlatformDocsSection {
const PlatformDocsSection({
required this.zipName,
required this.sectionName,
required this.checkFile,
required this.subdir,
});
final String zipName;
final String sectionName;
final String checkFile;
final String subdir;
}
const Map<String, PlatformDocsSection> kPlatformDocs = <String, PlatformDocsSection>{
'android': PlatformDocsSection(
zipName: 'android-javadoc.zip',
sectionName: 'Android',
checkFile: 'io/flutter/view/FlutterView.html',
subdir: 'javadoc',
),
'ios': PlatformDocsSection(
zipName: 'ios-docs.zip',
sectionName: 'iOS',
checkFile: 'interface_flutter_view.html',
subdir: 'ios-embedder',
),
'macos': PlatformDocsSection(
zipName: 'macos-docs.zip',
sectionName: 'macOS',
checkFile: 'interface_flutter_view.html',
subdir: 'macos-embedder',
),
'linux': PlatformDocsSection(
zipName: 'linux-docs.zip',
sectionName: 'Linux',
checkFile: 'struct___fl_view.html',
subdir: 'linux-embedder',
),
'windows': PlatformDocsSection(
zipName: 'windows-docs.zip',
sectionName: 'Windows',
checkFile: 'classflutter_1_1_flutter_view.html',
subdir: 'windows-embedder',
),
'impeller': PlatformDocsSection(
zipName: 'impeller-docs.zip',
sectionName: 'Impeller',
checkFile: 'classimpeller_1_1_canvas.html',
subdir: 'impeller',
),
};
/// This script will generate documentation for the packages in `packages/` and /// This script will generate documentation for the packages in `packages/` and
/// write the documentation to the output directory specified on the command /// write the documentation to the output directory specified on the command
/// line. /// line.
...@@ -43,9 +95,8 @@ Future<void> main(List<String> arguments) async { ...@@ -43,9 +95,8 @@ Future<void> main(List<String> arguments) async {
// The place to find customization files and configuration files for docs // The place to find customization files and configuration files for docs
// generation. // generation.
final Directory docsRoot = filesystem final Directory docsRoot =
.directory(FlutterInformation.instance.getFlutterRoot().childDirectory('dev').childDirectory('docs')) FlutterInformation.instance.getFlutterRoot().childDirectory('dev').childDirectory('docs').absolute;
.absolute;
final ArgParser argParser = _createArgsParser( final ArgParser argParser = _createArgsParser(
publishDefault: docsRoot.childDirectory('doc').path, publishDefault: docsRoot.childDirectory('doc').path,
); );
...@@ -187,6 +238,9 @@ class Configurator { ...@@ -187,6 +238,9 @@ class Configurator {
// Add a fake package for platform integration APIs. // Add a fake package for platform integration APIs.
yield '$kPlatformIntegrationPackageName/android.dart'; yield '$kPlatformIntegrationPackageName/android.dart';
yield '$kPlatformIntegrationPackageName/ios.dart'; yield '$kPlatformIntegrationPackageName/ios.dart';
yield '$kPlatformIntegrationPackageName/macos.dart';
yield '$kPlatformIntegrationPackageName/linux.dart';
yield '$kPlatformIntegrationPackageName/windows.dart';
} }
void _createDummyPubspec() { void _createDummyPubspec() {
...@@ -732,14 +786,15 @@ class DartdocGenerator { ...@@ -732,14 +786,15 @@ class DartdocGenerator {
'</title>\n', '</title>\n',
'</title>\n <base href="./flutter/">\n', '</title>\n <base href="./flutter/">\n',
); );
indexContents = indexContents.replaceAll(
'href="Android/Android-library.html"', for (final String platform in kPlatformDocs.keys) {
'href="/javadoc/"', final String sectionName = kPlatformDocs[platform]!.sectionName;
); final String subdir = kPlatformDocs[platform]!.subdir;
indexContents = indexContents.replaceAll( indexContents = indexContents.replaceAll(
'href="iOS/iOS-library.html"', 'href="$sectionName/$sectionName-library.html"',
'href="/objcdoc/"', 'href="../$subdir/index.html"',
); );
}
indexFile.writeAsStringSync(indexContents); indexFile.writeAsStringSync(indexContents);
} }
...@@ -782,13 +837,12 @@ class PlatformDocGenerator { ...@@ -782,13 +837,12 @@ class PlatformDocGenerator {
Future<void> generatePlatformDocs() async { Future<void> generatePlatformDocs() async {
final String realm = engineRealm.isNotEmpty ? '$engineRealm/' : ''; final String realm = engineRealm.isNotEmpty ? '$engineRealm/' : '';
final String javadocUrl = for (final String platform in kPlatformDocs.keys) {
'https://storage.googleapis.com/${realm}flutter_infra_release/flutter/$engineRevision/android-javadoc.zip'; final String zipFile = kPlatformDocs[platform]!.zipName;
await _extractDocs(javadocUrl, 'javadoc', 'io/flutter/view/FlutterView.html', outputDir); final String url =
'https://storage.googleapis.com/${realm}flutter_infra_release/flutter/$engineRevision/$zipFile';
final String objcdocUrl = await _extractDocs(url, platform, kPlatformDocs[platform]!, outputDir);
'https://storage.googleapis.com/${realm}flutter_infra_release/flutter/$engineRevision/ios-objcdoc.zip'; }
await _extractDocs(objcdocUrl, 'objcdoc', 'Classes/FlutterViewController.html', outputDir);
} }
/// Fetches the zip archive at the specified url. /// Fetches the zip archive at the specified url.
...@@ -812,7 +866,7 @@ class PlatformDocGenerator { ...@@ -812,7 +866,7 @@ class PlatformDocGenerator {
return responseBytes == null ? null : ZipDecoder().decodeBytes(responseBytes); return responseBytes == null ? null : ZipDecoder().decodeBytes(responseBytes);
} }
Future<void> _extractDocs(String url, String docName, String checkFile, Directory outputDir) async { Future<void> _extractDocs(String url, String name, PlatformDocsSection platform, Directory outputDir) async {
const int maxTries = 5; const int maxTries = 5;
final Archive? archive = await _fetchArchive(url, maxTries); final Archive? archive = await _fetchArchive(url, maxTries);
if (archive == null) { if (archive == null) {
...@@ -820,8 +874,8 @@ class PlatformDocGenerator { ...@@ -820,8 +874,8 @@ class PlatformDocGenerator {
exit(1); exit(1);
} }
final Directory output = outputDir.childDirectory(docName); final Directory output = outputDir.childDirectory(platform.subdir);
print('Extracting $docName to ${output.path}'); print('Extracting ${platform.zipName} to ${output.path}');
output.createSync(recursive: true); output.createSync(recursive: true);
for (final ArchiveFile af in archive) { for (final ArchiveFile af in archive) {
...@@ -832,18 +886,12 @@ class PlatformDocGenerator { ...@@ -832,18 +886,12 @@ class PlatformDocGenerator {
} }
} }
/// If object then copy files to old location if the archive is using the new location. final File testFile = output.childFile(platform.checkFile);
final Directory objcDocsDir = output.childDirectory('objectc_docs');
if (objcDocsDir.existsSync()) {
copyDirectorySync(objcDocsDir, output, filesystem: filesystem);
}
final File testFile = output.childFile(checkFile);
if (!testFile.existsSync()) { if (!testFile.existsSync()) {
print('Expected file ${testFile.path} not found'); print('Expected file ${testFile.path} not found');
exit(1); exit(1);
} }
print('$docName ready to go!'); print('${platform.sectionName} ready to go!');
} }
} }
...@@ -955,12 +1003,13 @@ List<Directory> findPackages(FileSystem filesystem) { ...@@ -955,12 +1003,13 @@ List<Directory> findPackages(FileSystem filesystem) {
if (entity is! Directory) { if (entity is! Directory) {
return false; return false;
} }
final File pubspec = filesystem.file('${entity.path}/pubspec.yaml'); final File pubspec = entity.childFile('pubspec.yaml');
if (!pubspec.existsSync()) { if (!pubspec.existsSync()) {
print("Unexpected package '${entity.path}' found in packages directory"); print("Unexpected package '${entity.path}' found in packages directory");
return false; return false;
} }
// TODO(ianh): Use a real YAML parser here // Would be nice to use a real YAML parser here, but we don't want to
// depend on a whole package for it, and this is sufficient.
return !pubspec.readAsStringSync().contains('nodoc: true'); return !pubspec.readAsStringSync().contains('nodoc: true');
}) })
.cast<Directory>() .cast<Directory>()
...@@ -1058,6 +1107,9 @@ class FlutterInformation { ...@@ -1058,6 +1107,9 @@ class FlutterInformation {
if (platform.environment['FLUTTER_VERSION'] != null) { if (platform.environment['FLUTTER_VERSION'] != null) {
flutterVersionJson = platform.environment['FLUTTER_VERSION']!; flutterVersionJson = platform.environment['FLUTTER_VERSION']!;
} else { } else {
// Determine which flutter command to run, which will determine which
// flutter root is eventually used. If the FLUTTER_ROOT is set, then use
// that flutter command, otherwise use the first one in the PATH.
String flutterCommand; String flutterCommand;
if (platform.environment['FLUTTER_ROOT'] != null) { if (platform.environment['FLUTTER_ROOT'] != null) {
flutterCommand = filesystem flutterCommand = filesystem
...@@ -1071,15 +1123,21 @@ class FlutterInformation { ...@@ -1071,15 +1123,21 @@ class FlutterInformation {
} }
ProcessResult result; ProcessResult result;
try { try {
result = processManager.runSync(<String>[flutterCommand, '--version', '--machine'], stdoutEncoding: utf8); result = processManager.runSync(
<String>[flutterCommand, '--version', '--machine'],
stdoutEncoding: utf8,
);
} on ProcessException catch (e) { } on ProcessException catch (e) {
throw FlutterInformationException( throw FlutterInformationException(
'Unable to determine Flutter information. Either set FLUTTER_ROOT, or place flutter command in your path.\n$e'); 'Unable to determine Flutter information. Either set FLUTTER_ROOT, or place the '
'flutter command in your PATH.\n$e');
} }
if (result.exitCode != 0) { if (result.exitCode != 0) {
throw FlutterInformationException( throw FlutterInformationException(
'Unable to determine Flutter information, because of abnormal exit to flutter command.'); 'Unable to determine Flutter information, because of abnormal exit of flutter command.');
} }
// Strip out any non-JSON that might be printed along with the command
// output.
flutterVersionJson = (result.stdout as String) flutterVersionJson = (result.stdout as String)
.replaceAll('Waiting for another flutter command to release the startup lock...', ''); .replaceAll('Waiting for another flutter command to release the startup lock...', '');
} }
...@@ -1139,7 +1197,7 @@ class FlutterInformation { ...@@ -1139,7 +1197,7 @@ class FlutterInformation {
String _getFlutterGitRevision() { String _getFlutterGitRevision() {
const int kGitRevisionLength = 10; const int kGitRevisionLength = 10;
final ProcessResult gitResult = Process.runSync('git', <String>['rev-parse', 'HEAD']); final ProcessResult gitResult = processManager.runSync(<String>['git', 'rev-parse', 'HEAD']);
if (gitResult.exitCode != 0) { if (gitResult.exitCode != 0) {
throw 'git rev-parse exit with non-zero exit code: ${gitResult.exitCode}'; throw 'git rev-parse exit with non-zero exit code: ${gitResult.exitCode}';
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment