executable.dart 5.16 KB
Newer Older
1 2 3 4
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6 7 8
import 'dart:async';
import 'dart:io';

import 'package:args/command_runner.dart';
Devon Carew's avatar
Devon Carew committed
9
import 'package:path/path.dart' as path;
10
import 'package:stack_trace/stack_trace.dart';
11

12 13
import 'src/base/context.dart';
import 'src/base/logger.dart';
14
import 'src/base/process.dart';
Devon Carew's avatar
Devon Carew committed
15
import 'src/base/utils.dart';
Hixie's avatar
Hixie committed
16
import 'src/commands/analyze.dart';
17
import 'src/commands/build.dart';
18
import 'src/commands/create.dart';
Devon Carew's avatar
Devon Carew committed
19
import 'src/commands/daemon.dart';
20
import 'src/commands/devices.dart';
21
import 'src/commands/doctor.dart';
yjbanov's avatar
yjbanov committed
22
import 'src/commands/drive.dart';
23 24 25
import 'src/commands/install.dart';
import 'src/commands/listen.dart';
import 'src/commands/logs.dart';
26
import 'src/commands/precache.dart';
27
import 'src/commands/refresh.dart';
28
import 'src/commands/run.dart';
29
import 'src/commands/run_mojo.dart';
Devon Carew's avatar
Devon Carew committed
30
import 'src/commands/screenshot.dart';
31
import 'src/commands/skia.dart';
32
import 'src/commands/stop.dart';
33
import 'src/commands/test.dart';
34
import 'src/commands/trace.dart';
35
import 'src/commands/update_packages.dart';
36
import 'src/commands/upgrade.dart';
37
import 'src/device.dart';
38
import 'src/doctor.dart';
Devon Carew's avatar
Devon Carew committed
39
import 'src/globals.dart';
40
import 'src/runner/flutter_command_runner.dart';
41 42 43 44

/// Main entry point for commands.
///
/// This function is intended to be used from the [flutter] command line tool.
45
Future<Null> main(List<String> args) async {
Devon Carew's avatar
Devon Carew committed
46 47
  bool help = args.contains('-h') || args.contains('--help');
  bool verbose = args.contains('-v') || args.contains('--verbose');
48
  bool verboseHelp = help && verbose;
Devon Carew's avatar
Devon Carew committed
49

Devon Carew's avatar
Devon Carew committed
50 51 52 53 54 55
  if (verboseHelp) {
    // Remove the verbose option; for help, users don't need to see verbose logs.
    args = new List<String>.from(args);
    args.removeWhere((String option) => option == '-v' || option == '--verbose');
  }

56
  FlutterCommandRunner runner = new FlutterCommandRunner(verboseHelp: verboseHelp)
Hixie's avatar
Hixie committed
57
    ..addCommand(new AnalyzeCommand())
58
    ..addCommand(new BuildCommand())
59
    ..addCommand(new CreateCommand())
60
    ..addCommand(new DaemonCommand(hidden: !verboseHelp))
61
    ..addCommand(new DevicesCommand())
62
    ..addCommand(new DoctorCommand())
yjbanov's avatar
yjbanov committed
63
    ..addCommand(new DriveCommand())
64 65 66
    ..addCommand(new InstallCommand())
    ..addCommand(new ListenCommand())
    ..addCommand(new LogsCommand())
67
    ..addCommand(new PrecacheCommand())
68
    ..addCommand(new RefreshCommand())
69
    ..addCommand(new RunCommand())
70
    ..addCommand(new RunMojoCommand(hidden: !verboseHelp))
Devon Carew's avatar
Devon Carew committed
71
    ..addCommand(new ScreenshotCommand())
72
    ..addCommand(new SkiaCommand())
73
    ..addCommand(new StopCommand())
74
    ..addCommand(new TestCommand())
75
    ..addCommand(new TraceCommand())
76
    ..addCommand(new UpdatePackagesCommand(hidden: !verboseHelp))
77
    ..addCommand(new UpgradeCommand());
78

79
  return Chain.capture(() async {
80 81 82
    // Initialize globals.
    context[Logger] = new StdoutLogger();
    context[DeviceManager] = new DeviceManager();
83
    Doctor.initGlobal();
84

85
    dynamic result = await runner.run(args);
86

87 88
    if (result is int)
      exit(result);
89
  }, onError: (dynamic error, Chain chain) {
90
    if (error is UsageException) {
Devon Carew's avatar
Devon Carew committed
91 92 93 94
      stderr.writeln(error.message);
      stderr.writeln();
      stderr.writeln("Run 'flutter -h' (or 'flutter <command> -h') for available "
        "flutter commands and options.");
95 96 97
      // Argument error exit code.
      exit(64);
    } else if (error is ProcessExit) {
98
      // We've caught an exit code.
99 100
      exit(error.exitCode);
    } else {
Devon Carew's avatar
Devon Carew committed
101 102
      // We've crashed; emit a log report.
      stderr.writeln();
103 104

      if (Platform.environment.containsKey('FLUTTER_DEV')) {
105 106
        // If we're working on the tools themselves, just print the stack trace.
        stderr.writeln('$error');
107 108
        stderr.writeln(chain.terse.toString());
      } else {
109 110 111 112 113
        if (error is String)
          stderr.writeln('Oops; flutter has exited unexpectedly: "$error".');
        else
          stderr.writeln('Oops; flutter has exited unexpectedly.');

114 115
        File file = _createCrashReport(args, error, chain);

116 117 118
        stderr.writeln(
          'Crash report written to ${path.relative(file.path)}; '
          'please let us know at https://github.com/flutter/flutter/issues.');
119 120
      }

121
      exit(1);
122
    }
123
  });
124
}
Devon Carew's avatar
Devon Carew committed
125 126

File _createCrashReport(List<String> args, dynamic error, Chain chain) {
Devon Carew's avatar
Devon Carew committed
127
  File crashFile = getUniqueFile(Directory.current, 'flutter', 'log');
Devon Carew's avatar
Devon Carew committed
128 129 130 131 132 133 134 135 136 137

  StringBuffer buf = new StringBuffer();

  buf.writeln('Flutter crash report; please file at https://github.com/flutter/flutter/issues.\n');

  buf.writeln('## command\n');
  buf.writeln('flutter ${args.join(' ')}\n');

  buf.writeln('## exception\n');
  buf.writeln('$error\n');
138
  buf.writeln('```\n${chain.terse}```\n');
Devon Carew's avatar
Devon Carew committed
139 140

  buf.writeln('## flutter doctor\n');
141
  buf.writeln('```\n${_doctorText()}```');
Devon Carew's avatar
Devon Carew committed
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157

  crashFile.writeAsStringSync(buf.toString());

  return crashFile;
}

String _doctorText() {
  try {
    BufferLogger logger = new BufferLogger();
    AppContext appContext = new AppContext();

    appContext[Logger] = logger;

    appContext.runInZone(() => doctor.diagnose());

    return logger.statusText;
158
  } catch (error, trace) {
159
    return 'encountered exception: $error\n\n${trace.toString().trim()}\n';
Devon Carew's avatar
Devon Carew committed
160 161
  }
}