Sarah Zakarias | d97b13b | 2017-06-26 12:15:24 +0200 | [diff] [blame] | 1 | // 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 | |
| 5 | import 'dart:async'; |
| 6 | import 'dart:io'; |
Chris Bracken | 7022f98 | 2019-01-10 15:23:59 -0800 | [diff] [blame] | 7 | import 'dart:math'; |
Sarah Zakarias | d97b13b | 2017-06-26 12:15:24 +0200 | [diff] [blame] | 8 | |
| 9 | import 'package:archive/archive.dart'; |
| 10 | import 'package:http/http.dart' as http; |
| 11 | |
| 12 | const 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 Ardhuin | d340e2f | 2018-10-04 18:44:23 +0200 | [diff] [blame] | 16 | Future<void> main(List<String> args) async { |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 17 | final String engineVersion = File('bin/internal/engine.version').readAsStringSync().trim(); |
Sarah Zakarias | d97b13b | 2017-06-26 12:15:24 +0200 | [diff] [blame] | 18 | |
Ian Hickson | 6655074 | 2017-07-28 15:44:38 -0700 | [diff] [blame] | 19 | final String javadocUrl = 'https://storage.googleapis.com/flutter_infra/flutter/$engineVersion/android-javadoc.zip'; |
Sarah Zakarias | d97b13b | 2017-06-26 12:15:24 +0200 | [diff] [blame] | 20 | generateDocs(javadocUrl, 'javadoc', 'io/flutter/view/FlutterView.html'); |
| 21 | |
Ian Hickson | 6655074 | 2017-07-28 15:44:38 -0700 | [diff] [blame] | 22 | final String objcdocUrl = 'https://storage.googleapis.com/flutter_infra/flutter/$engineVersion/ios-objcdoc.zip'; |
| 23 | generateDocs(objcdocUrl, 'objcdoc', 'Classes/FlutterViewController.html'); |
Sarah Zakarias | d97b13b | 2017-06-26 12:15:24 +0200 | [diff] [blame] | 24 | } |
| 25 | |
Chris Bracken | 7022f98 | 2019-01-10 15:23:59 -0800 | [diff] [blame] | 26 | /// Fetches the zip archive at the specified url. |
| 27 | /// |
| 28 | /// Returns null if the archive fails to download after [maxTries] attempts. |
| 29 | Future<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 Zakarias | d97b13b | 2017-06-26 12:15:24 +0200 | [diff] [blame] | 38 | |
Chris Bracken | 7022f98 | 2019-01-10 15:23:59 -0800 | [diff] [blame] | 39 | // On failure print a short snipped from the body in case it's helpful. |
Chris Bracken | 17d741e | 2019-01-10 16:05:39 -0800 | [diff] [blame] | 40 | final int bodyLength = min(1024, response.body.length); |
Chris Bracken | 7022f98 | 2019-01-10 15:23:59 -0800 | [diff] [blame] | 41 | 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 | |
| 47 | Future<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 Zakarias | d97b13b | 2017-06-26 12:15:24 +0200 | [diff] [blame] | 54 | |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 55 | final Directory output = Directory('$kDocRoot/$docName'); |
Ian Hickson | 6e87292 | 2018-01-30 09:00:45 -0800 | [diff] [blame] | 56 | print('Extracting $docName to ${output.path}'); |
Sarah Zakarias | d97b13b | 2017-06-26 12:15:24 +0200 | [diff] [blame] | 57 | output.createSync(recursive: true); |
| 58 | |
| 59 | for (ArchiveFile af in archive) { |
Dan Field | 496c573 | 2019-01-24 16:02:45 -0800 | [diff] [blame] | 60 | // TODO(dnfield): Archive changed their API so that isFile now returns true |
| 61 | // for directories. |
| 62 | if (!af.name.endsWith('/')) { |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 63 | final File file = File('${output.path}/${af.name}'); |
Sarah Zakarias | d97b13b | 2017-06-26 12:15:24 +0200 | [diff] [blame] | 64 | file.createSync(recursive: true); |
| 65 | file.writeAsBytesSync(af.content); |
| 66 | } |
| 67 | } |
| 68 | |
Alexandre Ardhuin | d927c93 | 2018-09-12 08:29:29 +0200 | [diff] [blame] | 69 | final File testFile = File('${output.path}/$checkFile'); |
Sarah Zakarias | d97b13b | 2017-06-26 12:15:24 +0200 | [diff] [blame] | 70 | if (!testFile.existsSync()) { |
| 71 | print('Expected file ${testFile.path} not found'); |
| 72 | exit(1); |
| 73 | } |
| 74 | print('$docName ready to go!'); |
| 75 | } |