blob: 0d2c39f788b01f9d18ad23353708248524d3502f [file] [log] [blame]
Sarah Zakariasd97b13b2017-06-26 12:15:24 +02001// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'dart:async';
6import 'dart:io';
Chris Bracken7022f982019-01-10 15:23:59 -08007import 'dart:math';
Sarah Zakariasd97b13b2017-06-26 12:15:24 +02008
9import 'package:archive/archive.dart';
10import 'package:http/http.dart' as http;
11
12const String kDocRoot = 'dev/docs/doc';
13
14/// This script downloads an archive of Javadoc and objc doc for the engine from
15/// the artifact store and extracts them to the location used for Dartdoc.
Alexandre Ardhuind340e2f2018-10-04 18:44:23 +020016Future<void> main(List<String> args) async {
Alexandre Ardhuind927c932018-09-12 08:29:29 +020017 final String engineVersion = File('bin/internal/engine.version').readAsStringSync().trim();
Sarah Zakariasd97b13b2017-06-26 12:15:24 +020018
Ian Hickson66550742017-07-28 15:44:38 -070019 final String javadocUrl = 'https://storage.googleapis.com/flutter_infra/flutter/$engineVersion/android-javadoc.zip';
Sarah Zakariasd97b13b2017-06-26 12:15:24 +020020 generateDocs(javadocUrl, 'javadoc', 'io/flutter/view/FlutterView.html');
21
Ian Hickson66550742017-07-28 15:44:38 -070022 final String objcdocUrl = 'https://storage.googleapis.com/flutter_infra/flutter/$engineVersion/ios-objcdoc.zip';
23 generateDocs(objcdocUrl, 'objcdoc', 'Classes/FlutterViewController.html');
Sarah Zakariasd97b13b2017-06-26 12:15:24 +020024}
25
Chris Bracken7022f982019-01-10 15:23:59 -080026/// Fetches the zip archive at the specified url.
27///
28/// Returns null if the archive fails to download after [maxTries] attempts.
29Future<Archive> fetchArchive(String url, int maxTries) async {
30 List<int> responseBytes;
31 for (int i = 0; i < maxTries; i++) {
32 final http.Response response = await http.get(url);
33 if (response.statusCode == 200) {
34 responseBytes = response.bodyBytes;
35 break;
36 }
37 stderr.writeln('Failed attempt ${i+1} to fetch $url.');
Sarah Zakariasd97b13b2017-06-26 12:15:24 +020038
Chris Bracken7022f982019-01-10 15:23:59 -080039 // On failure print a short snipped from the body in case it's helpful.
Chris Bracken17d741e2019-01-10 16:05:39 -080040 final int bodyLength = min(1024, response.body.length);
Chris Bracken7022f982019-01-10 15:23:59 -080041 stderr.writeln('Response status code ${response.statusCode}. Body: ' + response.body.substring(0, bodyLength));
42 sleep(const Duration(seconds: 1));
43 }
44 return responseBytes == null ? null : ZipDecoder().decodeBytes(responseBytes);
45}
46
47Future<void> generateDocs(String url, String docName, String checkFile) async {
48 const int maxTries = 5;
49 final Archive archive = await fetchArchive(url, maxTries);
50 if (archive == null) {
51 stderr.writeln('Failed to fetch zip archive from: $url after $maxTries attempts. Giving up.');
52 exit(1);
53 }
Sarah Zakariasd97b13b2017-06-26 12:15:24 +020054
Alexandre Ardhuind927c932018-09-12 08:29:29 +020055 final Directory output = Directory('$kDocRoot/$docName');
Ian Hickson6e872922018-01-30 09:00:45 -080056 print('Extracting $docName to ${output.path}');
Sarah Zakariasd97b13b2017-06-26 12:15:24 +020057 output.createSync(recursive: true);
58
59 for (ArchiveFile af in archive) {
Dan Field496c5732019-01-24 16:02:45 -080060 // TODO(dnfield): Archive changed their API so that isFile now returns true
61 // for directories.
62 if (!af.name.endsWith('/')) {
Alexandre Ardhuind927c932018-09-12 08:29:29 +020063 final File file = File('${output.path}/${af.name}');
Sarah Zakariasd97b13b2017-06-26 12:15:24 +020064 file.createSync(recursive: true);
65 file.writeAsBytesSync(af.content);
66 }
67 }
68
Alexandre Ardhuind927c932018-09-12 08:29:29 +020069 final File testFile = File('${output.path}/$checkFile');
Sarah Zakariasd97b13b2017-06-26 12:15:24 +020070 if (!testFile.existsSync()) {
71 print('Expected file ${testFile.path} not found');
72 exit(1);
73 }
74 print('$docName ready to go!');
75}