<commit_before>// 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.

import 'dart:async';
import 'dart:io';

import '../application_package.dart';
import '../base/common.dart';
import '../base/utils.dart';
import '../build_info.dart';
import '../cache.dart';
import '../device.dart';
import '../globals.dart';
import '../hot.dart';
import '../ios/mac.dart';
import '../vmservice.dart';
import '../resident_runner.dart';
import '../run.dart';
import '../runner/flutter_command.dart';
import 'build_apk.dart';
import 'install.dart';
import 'trace.dart';

abstract class RunCommandBase extends FlutterCommand {
  RunCommandBase() {
    addBuildModeFlags(defaultToRelease: false);
    argParser.addFlag('trace-startup',
        negatable: true,
        defaultsTo: false,
        help: 'Start tracing during startup.');
    argParser.addOption('route',
        help: 'Which route to load when running the app.');
    usesTargetOption();
  }

  bool get traceStartup => argResults['trace-startup'];
  String get route => argResults['route'];
}

class RunCommand extends RunCommandBase {
  @override
  final String name = 'run';

  @override
  final String description = 'Run your Flutter app on an attached device.';

  RunCommand() {
    argParser.addFlag('full-restart',
        defaultsTo: true,
        help: 'Stop any currently running application process before running the app.');
    argParser.addFlag('start-paused',
        defaultsTo: false,
        negatable: false,
        help: 'Start in a paused mode and wait for a debugger to connect.');
    argParser.addOption('debug-port',
        help: 'Listen to the given port for a debug connection (defaults to $kDefaultObservatoryPort).');
    argParser.addFlag('build',
        defaultsTo: true,
        help: 'If necessary, build the app before running.');
    argParser.addOption('use-application-binary',
        hide: true,
        help: 'Specify a pre-built application binary to use when running.');
    usesPubOption();

    // Option to enable hot reloading.
    argParser.addFlag('hot',
                      negatable: false,
                      defaultsTo: false,
                      help: 'Run with support for hot reloading.');

    // Option to write the pid to a file.
    argParser.addOption('pid-file',
                        help: 'Specify a file to write the process id to.'
                              'You can send SIGUSR1 to trigger a hot reload '
                              'and SIGUSR2 to trigger a full restart.');


    // Hidden option to enable a benchmarking mode. This will run the given
    // application, measure the startup time and the app restart time, write the
    // results out to 'refresh_benchmark.json', and exit. This flag is intended
    // for use in generating automated flutter benchmarks.
    argParser.addFlag('benchmark', negatable: false, hide: true);
  }

  @override
  bool get requiresDevice => true;

  @override
  String get usagePath {
    Device device = deviceForCommand;

    String command = argResults['hot'] ? 'hotrun' : name;

    if (device == null)
      return command;

    // Return 'run/ios'.
    return '$command/${getNameForTargetPlatform(device.platform)}';
  }

  @override
  void printNoConnectedDevices() {
    super.printNoConnectedDevices();
    if (getCurrentHostPlatform() == HostPlatform.darwin_x64 &&
        XCode.instance.isInstalledAndMeetsVersionCheck) {
      printStatus('');
      printStatus('To run on a simulator, launch it first:');
      printStatus('open -a Simulator.app');
      printStatus('');
    }
  }

  @override
  Future<int> runInProject() async {
    int debugPort;

    if (argResults['debug-port'] != null) {
      try {
        debugPort = int.parse(argResults['debug-port']);
      } catch (error) {
        printError('Invalid port for `--debug-port`: $error');
        return 1;
      }
    }

    if (deviceForCommand.isLocalEmulator && !isEmulatorBuildMode(getBuildMode())) {
      printError('${toTitleCase(getModeName(getBuildMode()))} mode is not supported for emulators.');
      return 1;
    }

    DebuggingOptions options;

    if (getBuildMode() == BuildMode.release) {
      options = new DebuggingOptions.disabled(getBuildMode());
    } else {
      options = new DebuggingOptions.enabled(
        getBuildMode(),
        startPaused: argResults['start-paused'],
        observatoryPort: debugPort
      );
    }

    Cache.releaseLockEarly();

    // Do some early error checks for hot mode.
    bool hotMode = argResults['hot'];

    if (hotMode) {
      if (getBuildMode() != BuildMode.debug) {
        printError('Hot mode only works with debug builds.');
        return 1;
      }
      if (!deviceForCommand.supportsHotMode) {
        printError('Hot mode is not supported by this device.');
        return 1;
      }
    }

    String pidFile = argResults['pid-file'];
    if (pidFile != null) {
      // Write our pid to the file.
      new File(pidFile).writeAsStringSync(pid.toString());
    }
    ResidentRunner runner;

    if (argResults['hot']) {
      runner = new HotRunner(
        deviceForCommand,
        target: targetFile,
        debuggingOptions: options,
        benchmarkMode: argResults['benchmark'],
      );
    } else {
      runner = new RunAndStayResident(
        deviceForCommand,
        target: targetFile,
        debuggingOptions: options,
        traceStartup: traceStartup,
        benchmark: argResults['benchmark'],
        applicationBinary: argResults['use-application-binary']
      );
    }

    return runner.run(route: route, shouldBuild: argResults['build']);
  }
}

Future<int> startApp(
  Device device, {
  String target,
  bool stop: true,
  bool install: true,
  DebuggingOptions debuggingOptions,
  bool traceStartup: false,
  bool benchmark: false,
  String route,
  BuildMode buildMode: BuildMode.debug<commit_msg>Enable hot mode by default. --no-hot disables it (#5794)<commit_after>// 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.

import 'dart:async';
import 'dart:io';

import '../application_package.dart';
import '../base/common.dart';
import '../base/utils.dart';
import '../build_info.dart';
import '../cache.dart';
import '../device.dart';
import '../globals.dart';
import '../hot.dart';
import '../ios/mac.dart';
import '../vmservice.dart';
import '../resident_runner.dart';
import '../run.dart';
import '../runner/flutter_command.dart';
import 'build_apk.dart';
import 'install.dart';
import 'trace.dart';

abstract class RunCommandBase extends FlutterCommand {
  RunCommandBase() {
    addBuildModeFlags(defaultToRelease: false);
    argParser.addFlag('trace-startup',
        negatable: true,
        defaultsTo: false,
        help: 'Start tracing during startup.');
    argParser.addOption('route',
        help: 'Which route to load when running the app.');
    usesTargetOption();
  }

  bool get traceStartup => argResults['trace-startup'];
  String get route => argResults['route'];
}

class RunCommand extends RunCommandBase {
  @override
  final String name = 'run';

  @override
  final String description = 'Run your Flutter app on an attached device.';

  RunCommand() {
    argParser.addFlag('full-restart',
        defaultsTo: true,
        help: 'Stop any currently running application process before running the app.');
    argParser.addFlag('start-paused',
        defaultsTo: false,
        negatable: false,
        help: 'Start in a paused mode and wait for a debugger to connect.');
    argParser.addOption('debug-port',
        help: 'Listen to the given port for a debug connection (defaults to $kDefaultObservatoryPort).');
    argParser.addFlag('build',
        defaultsTo: true,
        help: 'If necessary, build the app before running.');
    argParser.addOption('use-application-binary',
        hide: true,
        help: 'Specify a pre-built application binary to use when running.');
    usesPubOption();

    // Option to enable hot reloading.
    argParser.addFlag('hot',
                      negatable: true,
                      defaultsTo: true,
                      help: 'Run with support for hot reloading.');

    // Option to write the pid to a file.
    argParser.addOption('pid-file',
                        help: 'Specify a file to write the process id to.'
                              'You can send SIGUSR1 to trigger a hot reload '
                              'and SIGUSR2 to trigger a full restart.');


    // Hidden option to enable a benchmarking mode. This will run the given
    // application, measure the startup time and the app restart time, write the
    // results out to 'refresh_benchmark.json', and exit. This flag is intended
    // for use in generating automated flutter benchmarks.
    argParser.addFlag('benchmark', negatable: false, hide: true);
  }

  @override
  bool get requiresDevice => true;

  @override
  String get usagePath {
    Device device = deviceForCommand;

    String command = shouldUseHotMode() ? 'hotrun' : name;

    if (device == null)
      return command;

    // Return 'run/ios'.
    return '$command/${getNameForTargetPlatform(device.platform)}';
  }

  @override
  void printNoConnectedDevices() {
    super.printNoConnectedDevices();
    if (getCurrentHostPlatform() == HostPlatform.darwin_x64 &&
        XCode.instance.isInstalledAndMeetsVersionCheck) {
      printStatus('');
      printStatus('To run on a simulator, launch it first:');
      printStatus('open -a Simulator.app');
      printStatus('');
    }
  }

  bool shouldUseHotMode() {
    return argResults['hot'] && (getBuildMode() == BuildMode.debug);
  }

  @override
  Future<int> runInProject() async {
    int debugPort;

    if (argResults['debug-port'] != null) {
      try {
        debugPort = int.parse(argResults['debug-port']);
      } catch (error) {
        printError('Invalid port for `--debug-port`: $error');
        return 1;
      }
    }

    if (deviceForCommand.isLocalEmulator && !isEmulatorBuildMode(getBuildMode())) {
      printError('${toTitleCase(getModeName(getBuildMode()))} mode is not supported for emulators.');
      return 1;
    }

    DebuggingOptions options;

    if (getBuildMode() == BuildMode.release) {
      options = new DebuggingOptions.disabled(getBuildMode());
    } else {
      options = new DebuggingOptions.enabled(
        getBuildMode(),
        startPaused: argResults['start-paused'],
        observatoryPort: debugPort
      );
    }

    Cache.releaseLockEarly();

    // Enable hot mode by default if ``--no-hot` was not passed and we are in
    // debug mode.
    final bool hotMode = shouldUseHotMode();

    if (hotMode) {
      if (!deviceForCommand.supportsHotMode) {
        printError('Hot mode is not supported by this device. '
                   'Run with --no-hot.');
        return 1;
      }
    }

    String pidFile = argResults['pid-file'];
    if (pidFile != null) {
      // Write our pid to the file.
      new File(pidFile).writeAsStringSync(pid.toString());
    }
    ResidentRunner runner;

    if (hotMode) {
      runner = new HotRunner(
        deviceForCommand,
        target: targetFile,
        debuggingOptions: options,
        benchmarkMode: argResults['benchmark'],
      );
    } else {
      runner = new RunAndStayResident(
        deviceForCommand,
        target: targetFile,
        debuggingOptions: options,
        traceStartup: traceStartup,
        benchmark: argResults['benchmark'],
        applicationBinary: argResults['use-application-binary']
      );
    }

    return runner.run(route: route, shouldBuild: argResults['build']);
  }
}

Future<int> startApp(
  Device device, {
  String target,
  bool stop: true,
  bool install: true,
  DebuggingOptions debuggingOptions,
  bool traceStartup: false,
  bool benchmark: false,
  String route,
  BuildMode buildMode: BuildMode.debug
{'fraction_non_alphanumeric': 0.11597210692346006, 'fraction_numerical': 0.0022414079362443966, 'mean_word_length': 2.745957711442786, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4662434', 'n_tokens_mistral': 3435, 'n_tokens_neox': 3348, 'n_words': 1013}