• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2013 The Flutter 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:io";
6
7import "package:args/args.dart";
8
9Future<void> main(List<String> args) async {
10  final parser = new ArgParser();
11  parser.addOption("far-tool", help: "Path to `far` tool");
12  parser.addOption("archive", help: "Path to the far archive to extract from");
13  parser.addOption("out-dir", help: "Path to output directory");
14  final usage = """
15Usage: extract_far.dart [options] {paths}
16
17Options:
18${parser.usage};
19""";
20
21  ArgResults options;
22  try {
23    options = parser.parse(args);
24    if (options["far-tool"] == null) {
25      throw "Must specify --far-tool";
26    }
27    if (options["archive"] == null) {
28      throw "Must specify --archive";
29    }
30    if (options["out-dir"] == null) {
31      throw "Must specify --out-dir";
32    }
33  } catch (e) {
34    print("ERROR: $e\n");
35    print(usage);
36    exitCode = 1;
37    return;
38  }
39
40  await run(options);
41}
42
43Future<void> run(ArgResults options) async {
44  final far = options["far-tool"];
45
46  Future<void> extract(String archive, String file, String output) async {
47    await new File(output).parent.create(recursive: true);
48    final args = ["extract-file", "--archive=$archive", "--file=$file", "--output=$output"];
49    final result = await Process.run(far, args);
50    if (result.exitCode != 0) {
51      print(result.stdout);
52      print(result.stderr);
53      throw "Command failed: $far $args";
54    }
55  }
56
57  final outerArchive = options["archive"];
58  final outDir = options["out-dir"];
59
60  final innerArchive = "$outDir/meta.far";
61  await extract(outerArchive, "meta.far", innerArchive);
62
63  final manifest = "$outDir/meta/contents";
64  await extract(innerArchive, "meta/contents", manifest);
65
66  final blobNames = <String, String>{};
67  for (final line in await new File(manifest).readAsLines()) {
68    final pivot = line.lastIndexOf("=");
69    blobNames[line.substring(0, pivot)] = line.substring(pivot + 1, line.length);
70  }
71
72  for (final path in options.rest) {
73    final blobName = blobNames[path];
74    if (blobName == null) {
75      print("Archive contents: ");
76      for (final key in blobNames.keys) {
77        print(key);
78      }
79      throw "$outerArchive does not contain $path";
80    }
81    await extract(outerArchive, blobName, "$outDir/$path");
82  }
83}
84