run_mojo.dart 5.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
// 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 'package:logging/logging.dart';
import 'package:path/path.dart' as path;

11
import '../artifacts.dart';
12 13
import '../base/logging.dart';
import '../base/process.dart';
14
import '../build_configuration.dart';
15
import '../runner/flutter_command.dart';
16 17 18 19
import 'build.dart';
import 'start.dart';

const String _kDefaultBundlePath = 'build/app.flx';
20

21
class RunMojoCommand extends FlutterCommand {
22 23 24
  final String name = 'run_mojo';
  final String description = 'Run a Flutter app in mojo.';

25 26
  RunMojoCommand() {
    argParser.addFlag('android', negatable: false, help: 'Run on an Android device');
27
    argParser.addFlag('checked', negatable: false, help: 'Run Flutter in checked mode');
28 29 30
    argParser.addFlag('mojo-debug', negatable: false, help: 'Use Debug build of mojo');
    argParser.addFlag('mojo-release', negatable: false, help: 'Use Release build of mojo (default)');

31 32 33 34 35
    argParser.addOption('target',
        defaultsTo: '',
        abbr: 't',
        help: 'Target app path or filename to start.');
    argParser.addOption('app', help: 'Run this Flutter app instead of building the target.');
36 37
    argParser.addOption('mojo-path', help: 'Path to directory containing mojo_shell and services.');
    argParser.addOption('devtools-path', help: 'Path to mojo devtools\' mojo_run command.');
38 39
  }

Kris Giesing's avatar
Kris Giesing committed
40 41
  bool get requiresProjectRoot => false;

42
  // TODO(abarth): Why not use path.absolute?
43
  String _makePathAbsolute(String relativePath) {
44
    File file = new File(relativePath);
45
    if (!file.existsSync()) {
Hixie's avatar
Hixie committed
46
      throw new Exception('Path "$relativePath" does not exist');
47 48 49 50
    }
    return file.absolute.path;
  }

51 52 53 54 55 56 57 58 59 60
  bool _useDevtools() {
    if (argResults['android'] || argResults['devtools-path'] != null) {
      return true;
    }
    return false;
  }

  String _getDevtoolsPath() {
    if (argResults['devtools-path'] != null) {
      return _makePathAbsolute(argResults['devtools-path']);
61
    }
62 63 64 65 66 67
    return _makePathAbsolute(path.join(argResults['mojo-path'], 'mojo', 'devtools', 'common', 'mojo_run'));
  }

  String _getMojoShellPath() {
    final mojoBuildType = argResults['mojo-debug']  ? 'Debug' : 'Release';
    return _makePathAbsolute(path.join(argResults['mojo-path'], 'out', mojoBuildType, 'mojo_shell'));
68 69
  }

Kris Giesing's avatar
Kris Giesing committed
70
  BuildConfiguration _getCurrentHostConfig() {
71
    BuildConfiguration result;
72 73
    TargetPlatform target = argResults['android'] ?
      TargetPlatform.android : getCurrentHostPlatformAsTarget();
74 75 76 77 78 79 80 81 82
    for (BuildConfiguration config in buildConfigurations) {
      if (config.targetPlatform == target) {
        result = config;
        break;
      }
    }
    return result;
  }

83
  Future<List<String>> _getShellConfig(String bundlePath) async {
84
    List<String> args = <String>[];
85

86 87
    final bool useDevtools = _useDevtools();
    final String command = useDevtools ? _getDevtoolsPath() : _getMojoShellPath();
88 89
    args.add(command);

90
    BuildConfiguration config = _getCurrentHostConfig();
91 92 93 94 95 96 97 98 99 100 101
    final String appPath = _makePathAbsolute(bundlePath);

    String flutterPath;
    if (config == null || config.type == BuildType.prebuilt) {
      TargetPlatform targetPlatform = argResults['android'] ? TargetPlatform.android : TargetPlatform.linux;
      Artifact artifact = ArtifactStore.getArtifact(type: ArtifactType.mojo, targetPlatform: targetPlatform);
      flutterPath = _makePathAbsolute(await ArtifactStore.getPath(artifact));
    } else {
      String localPath = path.join(config.buildDir, 'flutter.mojo');
      flutterPath = _makePathAbsolute(localPath);
    }
102

103 104
    if (argResults['android']) {
      args.add('--android');
105 106
      final String appName = path.basename(appPath);
      final String appDir = path.dirname(appPath);
107 108
      args.add('http://app/$appName');
      args.add('--map-origin=http://app/=$appDir');
109 110 111 112 113

      final String flutterName = path.basename(flutterPath);
      final String flutterDir = path.dirname(flutterPath);
      args.add('--map-origin=http://flutter/=$flutterDir');
      args.add('--url-mappings=mojo:flutter=http://flutter/$flutterName');
114
    } else {
Hixie's avatar
Hixie committed
115
      args.add('file://$appPath');
116
      args.add('--url-mappings=mojo:flutter=file://$flutterPath');
117 118 119
    }

    if (useDevtools) {
120
      final String buildFlag = argResults['mojo-debug'] ? '--debug' : '--release';
121
      args.add(buildFlag);
122
      if (logging.level <= Level.INFO) {
123
        args.add('--verbose');
124
        if (logging.level <= Level.FINE) {
125 126 127 128 129 130
          args.add('--verbose');
        }
      }
    }

    if (argResults['checked']) {
131
      args.add('--args-for=mojo:flutter --enable-checked-mode');
132 133 134 135 136
    }

    args.addAll(argResults.rest);
    print(args);
    return args;
137 138
  }

139
  @override
Kris Giesing's avatar
Kris Giesing committed
140
  Future<int> runInProject() async {
141
    if ((argResults['mojo-path'] == null && argResults['devtools-path'] == null) || (argResults['mojo-path'] != null && argResults['devtools-path'] != null)) {
142
      logging.severe('Must specify either --mojo-path or --devtools-path.');
143 144 145
      return 1;
    }

146
    if (argResults['mojo-debug'] && argResults['mojo-release']) {
147
      logging.severe('Cannot specify both --mojo-debug and --mojo-release');
148 149
      return 1;
    }
150

151 152 153 154 155 156 157
    await downloadToolchain();

    String bundlePath = argResults['app'];
    if (bundlePath == null) {
      bundlePath = _kDefaultBundlePath;

      String mainPath = StartCommand.findMainDartFile(argResults['target']);
Kris Giesing's avatar
Kris Giesing committed
158

159 160 161 162 163 164 165 166 167
      BuildCommand builder = new BuildCommand();
      builder.inheritFromParent(this);
      int result = await builder.build(mainPath: mainPath, outputPath: bundlePath);
      if (result != 0)
        return result;
    }

    return await runCommandAndStreamOutput(await _getShellConfig(bundlePath));
  }
168
}