executable.dart 9.77 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5
import 'runner.dart' as runner;
6
import 'src/artifacts.dart';
7
import 'src/base/context.dart';
8
import 'src/base/io.dart';
9
import 'src/base/logger.dart';
10
import 'src/base/platform.dart';
11
import 'src/base/template.dart';
12
import 'src/base/terminal.dart';
13 14
import 'src/base/user_messages.dart';
import 'src/cache.dart';
Hixie's avatar
Hixie committed
15
import 'src/commands/analyze.dart';
16
import 'src/commands/assemble.dart';
17
import 'src/commands/attach.dart';
18
import 'src/commands/build.dart';
19
import 'src/commands/channel.dart';
20
import 'src/commands/clean.dart';
21
import 'src/commands/config.dart';
22
import 'src/commands/create.dart';
23
import 'src/commands/custom_devices.dart';
Devon Carew's avatar
Devon Carew committed
24
import 'src/commands/daemon.dart';
25
import 'src/commands/debug_adapter.dart';
26
import 'src/commands/devices.dart';
27
import 'src/commands/doctor.dart';
28
import 'src/commands/downgrade.dart';
yjbanov's avatar
yjbanov committed
29
import 'src/commands/drive.dart';
30
import 'src/commands/emulators.dart';
31
import 'src/commands/format.dart';
32
import 'src/commands/generate.dart';
33
import 'src/commands/generate_localizations.dart';
34
import 'src/commands/ide_config.dart';
35 36
import 'src/commands/install.dart';
import 'src/commands/logs.dart';
37
import 'src/commands/make_host_app_editable.dart';
38
import 'src/commands/packages.dart';
39
import 'src/commands/precache.dart';
40
import 'src/commands/run.dart';
Devon Carew's avatar
Devon Carew committed
41
import 'src/commands/screenshot.dart';
42
import 'src/commands/shell_completion.dart';
43
import 'src/commands/symbolize.dart';
44
import 'src/commands/test.dart';
45
import 'src/commands/update_packages.dart';
46
import 'src/commands/upgrade.dart';
47
import 'src/devtools_launcher.dart';
48
import 'src/features.dart';
49
import 'src/globals.dart' as globals;
50 51 52
// Files in `isolated` are intentionally excluded from google3 tooling.
import 'src/isolated/mustache_template.dart';
import 'src/isolated/resident_web_runner.dart';
53
import 'src/pre_run_validator.dart';
54
import 'src/project_validator.dart';
55
import 'src/resident_runner.dart';
56
import 'src/runner/flutter_command.dart';
57
import 'src/web/web_runner.dart';
58

59 60
/// Main entry point for commands.
///
61
/// This function is intended to be used from the `flutter` command line tool.
62
Future<void> main(List<String> args) async {
63 64
  final bool veryVerbose = args.contains('-vv');
  final bool verbose = args.contains('-v') || args.contains('--verbose') || veryVerbose;
65
  final bool prefixedErrors = args.contains('--prefixed-errors');
66 67 68 69 70
  // Support the -? Powershell help idiom.
  final int powershellHelpIndex = args.indexOf('-?');
  if (powershellHelpIndex != -1) {
    args[powershellHelpIndex] = '-h';
  }
71 72 73

  final bool doctor = (args.isNotEmpty && args.first == 'doctor') ||
      (args.length == 2 && verbose && args.last == 'doctor');
74
  final bool help = args.contains('-h') || args.contains('--help') ||
75
      (args.isNotEmpty && args.first == 'help') || (args.length == 1 && verbose);
76
  final bool muteCommandLogging = (help || doctor) && !veryVerbose;
77
  final bool verboseHelp = help && verbose;
78
  final bool daemon = args.contains('daemon');
79 80
  final bool runMachine = (args.contains('--machine') && args.contains('run')) ||
                          (args.contains('--machine') && args.contains('attach'));
Devon Carew's avatar
Devon Carew committed
81

82 83 84 85 86
  // Cache.flutterRoot must be set early because other features use it (e.g.
  // enginePath's initializer uses it). This can only work with the real
  // instances of the platform or filesystem, so just use those.
  Cache.flutterRoot = Cache.defaultFlutterRoot(
    platform: const LocalPlatform(),
87
    fileSystem: globals.localFileSystem,
88 89 90
    userMessages: UserMessages(),
  );

91 92 93
  await runner.run(
    args,
    () => generateCommands(
94
      verboseHelp: verboseHelp,
95
      verbose: verbose,
96
    ),
97 98 99 100 101 102 103 104 105 106 107 108 109
    verbose: verbose,
    muteCommandLogging: muteCommandLogging,
    verboseHelp: verboseHelp,
    overrides: <Type, Generator>{
      // The web runner is not supported in google3 because it depends
      // on dwds.
      WebRunnerFactory: () => DwdsWebRunnerFactory(),
      // The mustache dependency is different in google3
      TemplateRenderer: () => const MustacheTemplateRenderer(),
      // The devtools launcher is not supported in google3 because it depends on
      // devtools source code.
      DevtoolsLauncher: () => DevtoolsServerLauncher(
        processManager: globals.processManager,
110
        dartExecutable: globals.artifacts!.getArtifactPath(Artifact.engineDartBinary),
111
        logger: globals.logger,
112
        botDetector: globals.botDetector,
113 114
      ),
      Logger: () {
115 116 117 118 119 120 121
        final LoggerFactory loggerFactory = LoggerFactory(
          outputPreferences: globals.outputPreferences,
          terminal: globals.terminal,
          stdio: globals.stdio,
        );
        return loggerFactory.createLogger(
          daemon: daemon,
122
          machine: runMachine,
123 124 125 126
          verbose: verbose && !muteCommandLogging,
          prefixedErrors: prefixedErrors,
          windows: globals.platform.isWindows,
        );
127
      },
128
      PreRunValidator: () => PreRunValidator(fileSystem: globals.fs),
129
    },
130
    shutdownHooks: globals.shutdownHooks,
131
  );
132
}
133

134
List<FlutterCommand> generateCommands({
135 136
  required bool verboseHelp,
  required bool verbose,
137 138 139 140 141 142 143 144
}) => <FlutterCommand>[
  AnalyzeCommand(
    verboseHelp: verboseHelp,
    fileSystem: globals.fs,
    platform: globals.platform,
    processManager: globals.processManager,
    logger: globals.logger,
    terminal: globals.terminal,
145
    artifacts: globals.artifacts!,
146
    // new ProjectValidators should be added here for the --suggestions to run
147 148 149 150 151 152 153 154
    allProjectValidators: <ProjectValidator>[
      GeneralInfoProjectValidator(),
      VariableDumpMachineProjectValidator(
        logger: globals.logger,
        fileSystem: globals.fs,
        platform: globals.platform,
      ),
    ],
155
    suppressAnalytics: globals.flutterUsage.suppressAnalytics,
156
  ),
157
  AssembleCommand(verboseHelp: verboseHelp, buildSystem: globals.buildSystem),
158 159 160 161 162 163 164 165 166 167 168
  AttachCommand(
    verboseHelp: verboseHelp,
    artifacts: globals.artifacts,
    stdio: globals.stdio,
    logger: globals.logger,
    terminal: globals.terminal,
    signals: globals.signals,
    platform: globals.platform,
    processInfo: globals.processInfo,
    fileSystem: globals.fs,
  ),
169 170 171 172 173 174
  BuildCommand(
    fileSystem: globals.fs,
    buildSystem: globals.buildSystem,
    osUtils: globals.os,
    verboseHelp: verboseHelp,
    androidSdk: globals.androidSdk,
175
    logger: globals.logger,
176
  ),
177 178 179
  ChannelCommand(verboseHelp: verboseHelp),
  CleanCommand(verbose: verbose),
  ConfigCommand(verboseHelp: verboseHelp),
180 181 182 183 184 185 186 187 188 189
  CustomDevicesCommand(
    customDevicesConfig: globals.customDevicesConfig,
    operatingSystemUtils: globals.os,
    terminal: globals.terminal,
    platform: globals.platform,
    featureFlags: featureFlags,
    processManager: globals.processManager,
    fileSystem: globals.fs,
    logger: globals.logger
  ),
190 191
  CreateCommand(verboseHelp: verboseHelp),
  DaemonCommand(hidden: !verboseHelp),
192
  DebugAdapterCommand(verboseHelp: verboseHelp),
193 194
  DevicesCommand(verboseHelp: verboseHelp),
  DoctorCommand(verbose: verbose),
195
  DowngradeCommand(verboseHelp: verboseHelp, logger: globals.logger),
196 197 198
  DriveCommand(verboseHelp: verboseHelp,
    fileSystem: globals.fs,
    logger: globals.logger,
199
    platform: globals.platform,
200
    signals: globals.signals,
201 202
  ),
  EmulatorsCommand(),
203
  FormatCommand(),
204 205 206 207
  GenerateCommand(),
  GenerateLocalizationsCommand(
    fileSystem: globals.fs,
    logger: globals.logger,
208 209
    artifacts: globals.artifacts!,
    processManager: globals.processManager,
210
  ),
211 212 213
  InstallCommand(
    verboseHelp: verboseHelp,
  ),
214 215 216 217 218 219 220 221 222 223 224
  LogsCommand(),
  MakeHostAppEditableCommand(),
  PackagesCommand(),
  PrecacheCommand(
    verboseHelp: verboseHelp,
    cache: globals.cache,
    logger: globals.logger,
    platform: globals.platform,
    featureFlags: featureFlags,
  ),
  RunCommand(verboseHelp: verboseHelp),
225
  ScreenshotCommand(fs: globals.fs),
226
  ShellCompletionCommand(),
227
  TestCommand(verboseHelp: verboseHelp, verbose: verbose),
228 229 230 231 232 233 234 235 236 237
  UpgradeCommand(verboseHelp: verboseHelp),
  SymbolizeCommand(
    stdio: globals.stdio,
    fileSystem: globals.fs,
  ),
  // Development-only commands. These are always hidden,
  IdeConfigCommand(),
  UpdatePackagesCommand(),
];

238 239 240 241 242
/// An abstraction for instantiation of the correct logger type.
///
/// Our logger class hierarchy and runtime requirements are overly complicated.
class LoggerFactory {
  LoggerFactory({
243 244 245
    required Terminal terminal,
    required Stdio stdio,
    required OutputPreferences outputPreferences,
246 247 248 249 250 251 252 253 254 255 256 257 258
    StopwatchFactory stopwatchFactory = const StopwatchFactory(),
  }) : _terminal = terminal,
       _stdio = stdio,
       _stopwatchFactory = stopwatchFactory,
       _outputPreferences = outputPreferences;

  final Terminal _terminal;
  final Stdio _stdio;
  final StopwatchFactory _stopwatchFactory;
  final OutputPreferences _outputPreferences;

  /// Create the appropriate logger for the current platform and configuration.
  Logger createLogger({
259 260 261 262 263
    required bool verbose,
    required bool prefixedErrors,
    required bool machine,
    required bool daemon,
    required bool windows,
264 265 266 267 268 269 270 271 272 273 274 275 276 277
  }) {
    Logger logger;
    if (windows) {
      logger = WindowsStdoutLogger(
        terminal: _terminal,
        stdio: _stdio,
        outputPreferences: _outputPreferences,
        stopwatchFactory: _stopwatchFactory,
      );
    } else {
      logger = StdoutLogger(
        terminal: _terminal,
        stdio: _stdio,
        outputPreferences: _outputPreferences,
278
        stopwatchFactory: _stopwatchFactory
279 280 281 282 283
      );
    }
    if (verbose) {
      logger = VerboseLogger(logger, stopwatchFactory: _stopwatchFactory);
    }
284 285 286
    if (prefixedErrors) {
      logger = PrefixedErrorLogger(logger);
    }
287 288 289
    if (daemon) {
      return NotifyingLogger(verbose: verbose, parent: logger);
    }
290
    if (machine) {
291 292 293 294 295
      return AppRunLogger(parent: logger);
    }
    return logger;
  }
}