mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
use status(), error(), and trace() for logging
rename to printTrace(), printStatus(), and printError()
This commit is contained in:
parent
91c0af60f4
commit
d7fbf5302d
@ -6,9 +6,9 @@ import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:stack_trace/stack_trace.dart';
|
||||
|
||||
import 'src/base/context.dart';
|
||||
import 'src/base/process.dart';
|
||||
import 'src/commands/analyze.dart';
|
||||
import 'src/commands/apk.dart';
|
||||
@ -33,28 +33,6 @@ import 'src/runner/flutter_command_runner.dart';
|
||||
///
|
||||
/// This function is intended to be used from the [flutter] command line tool.
|
||||
Future main(List<String> args) async {
|
||||
DateTime startTime = new DateTime.now();
|
||||
|
||||
// This level can be adjusted by users through the `--verbose` option.
|
||||
Logger.root.level = Level.WARNING;
|
||||
Logger.root.onRecord.listen((LogRecord record) {
|
||||
String prefix = '';
|
||||
if (Logger.root.level <= Level.FINE) {
|
||||
Duration elapsed = record.time.difference(startTime);
|
||||
prefix = '[${elapsed.inMilliseconds.toString().padLeft(4)} ms] ';
|
||||
}
|
||||
String level = record.level.name.toLowerCase();
|
||||
if (record.level >= Level.WARNING) {
|
||||
stderr.writeln('$prefix$level: ${record.message}');
|
||||
} else {
|
||||
print('$prefix$level: ${record.message}');
|
||||
}
|
||||
if (record.error != null)
|
||||
stderr.writeln(record.error);
|
||||
if (record.stackTrace != null)
|
||||
stderr.writeln(record.stackTrace);
|
||||
});
|
||||
|
||||
FlutterCommandRunner runner = new FlutterCommandRunner()
|
||||
..addCommand(new AnalyzeCommand())
|
||||
..addCommand(new ApkCommand())
|
||||
@ -92,8 +70,7 @@ Future main(List<String> args) async {
|
||||
// We've caught an exit code.
|
||||
exit(error.exitCode);
|
||||
} else {
|
||||
stderr.writeln(error);
|
||||
Logger.root.log(Level.SEVERE, '\nException:', null, chain.terse.toTrace());
|
||||
printError(error, chain.terse.toTrace());
|
||||
exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import '../base/logging.dart';
|
||||
import '../base/context.dart';
|
||||
import '../base/process.dart';
|
||||
|
||||
// https://android.googlesource.com/platform/system/core/+/android-4.4_r1/adb/OVERVIEW.TXT
|
||||
@ -83,11 +83,11 @@ class Adb {
|
||||
controller = new StreamController(
|
||||
onListen: () async {
|
||||
socket = await Socket.connect(InternetAddress.LOOPBACK_IP_V4, adbServerPort);
|
||||
logging.fine('--> host:track-devices');
|
||||
printTrace('--> host:track-devices');
|
||||
socket.add(_createAdbRequest('host:track-devices'));
|
||||
socket.listen((List<int> data) {
|
||||
String stringResult = new String.fromCharCodes(data);
|
||||
logging.fine('<-- ${stringResult.trim()}');
|
||||
printTrace('<-- ${stringResult.trim()}');
|
||||
_AdbServerResponse response = new _AdbServerResponse(
|
||||
stringResult,
|
||||
noStatus: !isFirstNotification
|
||||
@ -116,14 +116,14 @@ class Adb {
|
||||
Socket socket = await Socket.connect(InternetAddress.LOOPBACK_IP_V4, adbServerPort);
|
||||
|
||||
try {
|
||||
logging.fine('--> $command');
|
||||
printTrace('--> $command');
|
||||
socket.add(_createAdbRequest(command));
|
||||
List<List<int>> result = await socket.toList();
|
||||
List<int> data = result.fold(<int>[], (List<int> previous, List<int> element) {
|
||||
return previous..addAll(element);
|
||||
});
|
||||
String stringResult = new String.fromCharCodes(data);
|
||||
logging.fine('<-- ${stringResult.trim()}');
|
||||
printTrace('<-- ${stringResult.trim()}');
|
||||
return stringResult;
|
||||
} finally {
|
||||
socket.destroy();
|
||||
|
||||
@ -9,7 +9,7 @@ import 'package:crypto/crypto.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import '../application_package.dart';
|
||||
import '../base/logging.dart';
|
||||
import '../base/context.dart';
|
||||
import '../base/process.dart';
|
||||
import '../build_configuration.dart';
|
||||
import '../device.dart';
|
||||
@ -74,7 +74,7 @@ class AndroidDevice extends Device {
|
||||
_hasValidAndroid = _checkForSupportedAndroidVersion();
|
||||
|
||||
if (!_hasAdb || !_hasValidAndroid) {
|
||||
logging.warning('Unable to run on Android.');
|
||||
printError('Unable to run on Android.');
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,11 +88,11 @@ class AndroidDevice extends Device {
|
||||
path.join(androidHomeDir, 'sdk', 'platform-tools'))) {
|
||||
return path.join(androidHomeDir, 'sdk');
|
||||
} else {
|
||||
logging.warning('Android SDK not found at $androidHomeDir');
|
||||
printError('Android SDK not found at $androidHomeDir');
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
logging.warning('Android SDK not found. The ANDROID_HOME variable must be set.');
|
||||
printError('Android SDK not found. The ANDROID_HOME variable must be set.');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -125,7 +125,7 @@ class AndroidDevice extends Device {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
logging.warning(
|
||||
printError(
|
||||
'Unrecognized adb version string $adbVersion. Skipping version check.');
|
||||
return true;
|
||||
}
|
||||
@ -138,16 +138,15 @@ class AndroidDevice extends Device {
|
||||
}
|
||||
|
||||
String locatedAdbPath = runCheckedSync(['which', 'adb']);
|
||||
logging.severe('"$locatedAdbPath" is too old. '
|
||||
printError('"$locatedAdbPath" is too old. '
|
||||
'Please install version 1.0.32 or later.\n'
|
||||
'Try setting ANDROID_HOME to the path to your Android SDK install. '
|
||||
'Android builds are unavailable.');
|
||||
} catch (e, stack) {
|
||||
logging.severe('"adb" not found in \$PATH. '
|
||||
} catch (e) {
|
||||
printError('"adb" not found in \$PATH. '
|
||||
'Please install the Android SDK or set ANDROID_HOME '
|
||||
'to the path of your Android SDK install.');
|
||||
logging.info(e);
|
||||
logging.info(stack);
|
||||
printTrace('$e');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -162,7 +161,7 @@ class AndroidDevice extends Device {
|
||||
|
||||
String ready = runSync(adbCommandForDevice(['shell', 'echo', 'ready']));
|
||||
if (ready.trim() != 'ready') {
|
||||
logging.info('Android device not found.');
|
||||
printTrace('Android device not found.');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -174,18 +173,18 @@ class AndroidDevice extends Device {
|
||||
int sdkVersionParsed =
|
||||
int.parse(sdkVersion, onError: (String source) => null);
|
||||
if (sdkVersionParsed == null) {
|
||||
logging.severe('Unexpected response from getprop: "$sdkVersion"');
|
||||
printError('Unexpected response from getprop: "$sdkVersion"');
|
||||
return false;
|
||||
}
|
||||
if (sdkVersionParsed < minApiLevel) {
|
||||
logging.severe(
|
||||
printError(
|
||||
'The Android version ($sdkVersion) on the target device is too old. Please '
|
||||
'use a $minVersionName (version $minApiLevel / $minVersionText) device or later.');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (e) {
|
||||
logging.severe('Unexpected failure from adb: ', e);
|
||||
printError('Unexpected failure from adb: $e');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -213,12 +212,11 @@ class AndroidDevice extends Device {
|
||||
return false;
|
||||
}
|
||||
if (runCheckedSync(adbCommandForDevice(['shell', 'pm', 'path', app.id])) == '') {
|
||||
logging.info(
|
||||
'TODO(iansf): move this log to the caller. ${app.name} is not on the device. Installing now...');
|
||||
printTrace('TODO(iansf): move this log to the caller. ${app.name} is not on the device. Installing now...');
|
||||
return false;
|
||||
}
|
||||
if (_getDeviceApkSha1(app) != _getSourceSha1(app)) {
|
||||
logging.info(
|
||||
printTrace(
|
||||
'TODO(iansf): move this log to the caller. ${app.name} is out of date. Installing now...');
|
||||
return false;
|
||||
}
|
||||
@ -228,17 +226,17 @@ class AndroidDevice extends Device {
|
||||
@override
|
||||
bool installApp(ApplicationPackage app) {
|
||||
if (!isConnected()) {
|
||||
logging.info('Android device not connected. Not installing.');
|
||||
printTrace('Android device not connected. Not installing.');
|
||||
return false;
|
||||
}
|
||||
if (!FileSystemEntity.isFileSync(app.localPath)) {
|
||||
logging.severe('"${app.localPath}" does not exist.');
|
||||
printError('"${app.localPath}" does not exist.');
|
||||
return false;
|
||||
}
|
||||
|
||||
print('Installing ${app.name} on device.');
|
||||
runCheckedSync(adbCommandForDevice(['install', '-r', app.localPath]));
|
||||
runCheckedSync(adbCommandForDevice(['shell', 'echo', '-n', _getSourceSha1(app), '>', _getDeviceSha1Path(app)]));
|
||||
printStatus('Installing ${app.name} on device.');
|
||||
runCheckedSync(adbCommandForDevice(<String>['install', '-r', app.localPath]));
|
||||
runCheckedSync(adbCommandForDevice(<String>['shell', 'echo', '-n', _getSourceSha1(app), '>', _getDeviceSha1Path(app)]));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -246,9 +244,9 @@ class AndroidDevice extends Device {
|
||||
// Set up port forwarding for observatory.
|
||||
String portString = 'tcp:$_observatoryPort';
|
||||
try {
|
||||
runCheckedSync(adbCommandForDevice(['forward', portString, portString]));
|
||||
runCheckedSync(adbCommandForDevice(<String>['forward', portString, portString]));
|
||||
} catch (e) {
|
||||
logging.warning('Unable to forward observatory port ($_observatoryPort):\n$e');
|
||||
printError('Unable to forward observatory port ($_observatoryPort):\n$e');
|
||||
}
|
||||
}
|
||||
|
||||
@ -259,10 +257,10 @@ class AndroidDevice extends Device {
|
||||
String route,
|
||||
bool clearLogs: false
|
||||
}) {
|
||||
logging.fine('$this startBundle');
|
||||
printTrace('$this startBundle');
|
||||
|
||||
if (!FileSystemEntity.isFileSync(bundlePath)) {
|
||||
logging.severe('Cannot find $bundlePath');
|
||||
printError('Cannot find $bundlePath');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -303,7 +301,7 @@ class AndroidDevice extends Device {
|
||||
toolchain,
|
||||
mainPath: mainPath
|
||||
).then((flx.DirectoryResult buildResult) {
|
||||
logging.fine('Starting bundle for $this.');
|
||||
printTrace('Starting bundle for $this.');
|
||||
|
||||
try {
|
||||
if (startBundle(
|
||||
@ -426,7 +424,7 @@ class AndroidDevice extends Device {
|
||||
));
|
||||
return localPath;
|
||||
}
|
||||
logging.warning('No trace file detected. '
|
||||
printError('No trace file detected. '
|
||||
'Did you remember to start the trace before stopping it?');
|
||||
return null;
|
||||
}
|
||||
@ -447,7 +445,7 @@ List<AndroidDevice> getAdbDevices([AndroidDevice mockAndroid]) {
|
||||
try {
|
||||
runCheckedSync([adbPath, 'version']);
|
||||
} catch (e) {
|
||||
logging.severe('Unable to find adb. Is "adb" in your path?');
|
||||
printError('Unable to find adb. Is "adb" in your path?');
|
||||
return devices;
|
||||
}
|
||||
|
||||
@ -497,16 +495,16 @@ List<AndroidDevice> getAdbDevices([AndroidDevice mockAndroid]) {
|
||||
} else if (unauthorizedRegex.hasMatch(line)) {
|
||||
Match match = unauthorizedRegex.firstMatch(line);
|
||||
String deviceID = match[1];
|
||||
logging.warning(
|
||||
printError(
|
||||
'Device $deviceID is not authorized.\n'
|
||||
'You might need to check your device for an authorization dialog.'
|
||||
);
|
||||
} else if (offlineRegex.hasMatch(line)) {
|
||||
Match match = offlineRegex.firstMatch(line);
|
||||
String deviceID = match[1];
|
||||
logging.warning('Device $deviceID is offline.');
|
||||
printError('Device $deviceID is offline.');
|
||||
} else {
|
||||
logging.warning(
|
||||
printError(
|
||||
'Unexpected failure parsing device information from adb output:\n'
|
||||
'$line\n'
|
||||
'Please report a bug at https://github.com/flutter/flutter/issues/new');
|
||||
@ -525,7 +523,7 @@ String getAdbPath() {
|
||||
} else if (FileSystemEntity.isFileSync(adbPath2)) {
|
||||
return adbPath2;
|
||||
} else {
|
||||
logging.info('"adb" not found at\n "$adbPath1" or\n "$adbPath2"\n' +
|
||||
printTrace('"adb" not found at\n "$adbPath1" or\n "$adbPath2"\n' +
|
||||
'using default path "$_defaultAdbPath"');
|
||||
return _defaultAdbPath;
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ import 'dart:io';
|
||||
import 'package:archive/archive.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import 'base/logging.dart';
|
||||
import 'base/context.dart';
|
||||
import 'base/os.dart';
|
||||
import 'base/process.dart';
|
||||
import 'build_configuration.dart';
|
||||
@ -187,7 +187,7 @@ class ArtifactStore {
|
||||
else
|
||||
message += '\nDid you run this command from the same directory as your pubspec.yaml file?';
|
||||
}
|
||||
stderr.writeln(message);
|
||||
printError(message);
|
||||
throw new ProcessExit(2);
|
||||
}
|
||||
}
|
||||
@ -195,7 +195,7 @@ class ArtifactStore {
|
||||
static void ensureHasSkyEnginePackage() {
|
||||
Directory skyEnginePackage = new Directory(path.join(packageRoot, 'sky_engine'));
|
||||
if (!skyEnginePackage.existsSync()) {
|
||||
stderr.writeln("Cannot locate the sky_engine package; did you include 'flutter' in your pubspec.yaml file?");
|
||||
printError("Cannot locate the sky_engine package; did you include 'flutter' in your pubspec.yaml file?");
|
||||
throw new ProcessExit(2);
|
||||
}
|
||||
}
|
||||
@ -221,12 +221,12 @@ class ArtifactStore {
|
||||
|
||||
/// Download a file from the given URL and return the bytes.
|
||||
static Future<List<int>> _downloadFile(Uri url) async {
|
||||
logging.info('Downloading $url.');
|
||||
printStatus('Downloading $url.');
|
||||
|
||||
HttpClient httpClient = new HttpClient();
|
||||
HttpClientRequest request = await httpClient.getUrl(url);
|
||||
HttpClientResponse response = await request.close();
|
||||
logging.fine('Received response statusCode=${response.statusCode}');
|
||||
printTrace('Received response statusCode=${response.statusCode}');
|
||||
if (response.statusCode != 200)
|
||||
throw new Exception(response.reasonPhrase);
|
||||
|
||||
@ -276,7 +276,7 @@ class ArtifactStore {
|
||||
if (_pendingZipDownloads.containsKey(platform)) {
|
||||
return _pendingZipDownloads[platform];
|
||||
}
|
||||
print('Downloading $platform artifacts from the cloud, one moment please...');
|
||||
printStatus('Downloading $platform artifacts from the cloud, one moment please...');
|
||||
Future future = _doDownloadArtifactsFromZip(platform);
|
||||
_pendingZipDownloads[platform] = future;
|
||||
return future.then((_) => _pendingZipDownloads.remove(platform));
|
||||
@ -286,7 +286,7 @@ class ArtifactStore {
|
||||
|
||||
static Directory _getBaseCacheDir() {
|
||||
if (flutterRoot == null) {
|
||||
logging.severe('FLUTTER_ROOT not specified. Cannot find artifact cache.');
|
||||
printError('FLUTTER_ROOT not specified. Cannot find artifact cache.');
|
||||
throw new ProcessExit(2);
|
||||
}
|
||||
Directory cacheDir = new Directory(path.join(flutterRoot, 'bin', 'cache', 'artifacts'));
|
||||
@ -313,7 +313,7 @@ class ArtifactStore {
|
||||
if (!cachedFile.existsSync()) {
|
||||
await _downloadArtifactsFromZip(artifact.platform);
|
||||
if (!cachedFile.existsSync()) {
|
||||
logging.severe('File not found in the platform artifacts: ${cachedFile.path}');
|
||||
printError('File not found in the platform artifacts: ${cachedFile.path}');
|
||||
throw new ProcessExit(2);
|
||||
}
|
||||
}
|
||||
@ -331,7 +331,7 @@ class ArtifactStore {
|
||||
try {
|
||||
await _downloadFileToCache(url, cachedFile);
|
||||
} catch (e) {
|
||||
logging.severe('Failed to fetch third-party artifact: $url: $e');
|
||||
printError('Failed to fetch third-party artifact: $url: $e');
|
||||
throw new ProcessExit(2);
|
||||
}
|
||||
}
|
||||
@ -340,7 +340,7 @@ class ArtifactStore {
|
||||
|
||||
static void clear() {
|
||||
Directory cacheDir = _getBaseCacheDir();
|
||||
logging.fine('Clearing cache directory ${cacheDir.path}');
|
||||
printTrace('Clearing cache directory ${cacheDir.path}');
|
||||
cacheDir.deleteSync(recursive: true);
|
||||
}
|
||||
|
||||
|
||||
70
packages/flutter_tools/lib/src/base/context.dart
Normal file
70
packages/flutter_tools/lib/src/base/context.dart
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright 2016 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';
|
||||
|
||||
final AppContext _defaultContext = new _DefaultAppContext();
|
||||
|
||||
/// A singleton for application functionality. This singleton can be different
|
||||
/// on a per-Zone basis.
|
||||
AppContext get context {
|
||||
AppContext currentContext = Zone.current['context'];
|
||||
return currentContext == null ? _defaultContext : currentContext;
|
||||
}
|
||||
|
||||
/// Display an error level message to the user. Commands should use this if they
|
||||
/// fail in some way.
|
||||
void printError(String message, [StackTrace stackTrace]) => context.printError(message, stackTrace);
|
||||
|
||||
/// Display normal output of the command. This should be used for things like
|
||||
/// progress messages, success messages, or just normal command output.
|
||||
void printStatus(String message) => context.printStatus(message);
|
||||
|
||||
/// Use this for verbose tracing output. Users can turn this output on in order
|
||||
/// to help diagnose issues with the toolchain or with their setup.
|
||||
void printTrace(String message) => context.printTrace(message);
|
||||
|
||||
abstract class AppContext {
|
||||
bool get verbose;
|
||||
set verbose(bool value);
|
||||
|
||||
void printError(String message, [StackTrace stackTrace]);
|
||||
void printStatus(String message);
|
||||
void printTrace(String message);
|
||||
}
|
||||
|
||||
class _DefaultAppContext implements AppContext {
|
||||
DateTime _startTime = new DateTime.now();
|
||||
|
||||
bool _verbose = false;
|
||||
|
||||
bool get verbose => _verbose;
|
||||
|
||||
set verbose(bool value) {
|
||||
_verbose = value;
|
||||
}
|
||||
|
||||
void printError(String message, [StackTrace stackTrace]) {
|
||||
stderr.writeln(_prefix + message);
|
||||
if (stackTrace != null)
|
||||
stderr.writeln(stackTrace);
|
||||
}
|
||||
|
||||
void printStatus(String message) {
|
||||
print(_prefix + message);
|
||||
}
|
||||
|
||||
void printTrace(String message) {
|
||||
if (_verbose)
|
||||
print('$_prefix- $message');
|
||||
}
|
||||
|
||||
String get _prefix {
|
||||
if (!_verbose)
|
||||
return '';
|
||||
Duration elapsed = new DateTime.now().difference(_startTime);
|
||||
return '[${elapsed.inMilliseconds.toString().padLeft(4)} ms] ';
|
||||
}
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
// 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 'package:logging/logging.dart';
|
||||
|
||||
final Logger logging = new Logger('flutter_tools');
|
||||
@ -6,7 +6,7 @@ import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'logging.dart';
|
||||
import 'context.dart';
|
||||
|
||||
/// This runs the command and streams stdout/stderr from the child process to
|
||||
/// this process' stdout/stderr.
|
||||
@ -15,7 +15,7 @@ Future<int> runCommandAndStreamOutput(List<String> cmd, {
|
||||
RegExp filter,
|
||||
String workingDirectory
|
||||
}) async {
|
||||
logging.info(cmd.join(' '));
|
||||
printTrace(cmd.join(' '));
|
||||
Process process = await Process.start(
|
||||
cmd[0],
|
||||
cmd.sublist(1),
|
||||
@ -28,7 +28,7 @@ Future<int> runCommandAndStreamOutput(List<String> cmd, {
|
||||
dataLines = dataLines.where((String s) => filter.hasMatch(s)).toList();
|
||||
}
|
||||
if (dataLines.length > 0) {
|
||||
stdout.write('$prefix${dataLines.join('\n$prefix')}\n');
|
||||
printStatus('$prefix${dataLines.join('\n$prefix')}');
|
||||
}
|
||||
});
|
||||
process.stderr.transform(UTF8.decoder).listen((String data) {
|
||||
@ -38,7 +38,7 @@ Future<int> runCommandAndStreamOutput(List<String> cmd, {
|
||||
dataLines = dataLines.where((String s) => filter.hasMatch(s));
|
||||
}
|
||||
if (dataLines.length > 0) {
|
||||
stderr.write('$prefix${dataLines.join('\n$prefix')}\n');
|
||||
printError('$prefix${dataLines.join('\n$prefix')}');
|
||||
}
|
||||
});
|
||||
return await process.exitCode;
|
||||
@ -47,13 +47,13 @@ Future<int> runCommandAndStreamOutput(List<String> cmd, {
|
||||
Future runAndKill(List<String> cmd, Duration timeout) {
|
||||
Future<Process> proc = runDetached(cmd);
|
||||
return new Future.delayed(timeout, () async {
|
||||
logging.info('Intentionally killing ${cmd[0]}');
|
||||
printTrace('Intentionally killing ${cmd[0]}');
|
||||
Process.killPid((await proc).pid);
|
||||
});
|
||||
}
|
||||
|
||||
Future<Process> runDetached(List<String> cmd) {
|
||||
logging.info(cmd.join(' '));
|
||||
printTrace(cmd.join(' '));
|
||||
Future<Process> proc = Process.start(
|
||||
cmd[0], cmd.getRange(1, cmd.length).toList(),
|
||||
mode: ProcessStartMode.DETACHED);
|
||||
@ -81,20 +81,20 @@ String _runWithLoggingSync(List<String> cmd, {
|
||||
bool checked: false,
|
||||
String workingDirectory
|
||||
}) {
|
||||
logging.info(cmd.join(' '));
|
||||
printTrace(cmd.join(' '));
|
||||
ProcessResult results =
|
||||
Process.runSync(cmd[0], cmd.getRange(1, cmd.length).toList(), workingDirectory: workingDirectory);
|
||||
if (results.exitCode != 0) {
|
||||
String errorDescription = 'Error code ${results.exitCode} '
|
||||
'returned when attempting to run command: ${cmd.join(' ')}';
|
||||
logging.info(errorDescription);
|
||||
printTrace(errorDescription);
|
||||
if (results.stderr.length > 0)
|
||||
logging.info('Errors logged: ${results.stderr.trim()}');
|
||||
printTrace('Errors logged: ${results.stderr.trim()}');
|
||||
if (checked)
|
||||
throw errorDescription;
|
||||
}
|
||||
if (results.stdout.trim().isNotEmpty)
|
||||
logging.fine(results.stdout.trim());
|
||||
printTrace(results.stdout.trim());
|
||||
return results.stdout;
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import 'base/logging.dart';
|
||||
import 'base/context.dart';
|
||||
|
||||
enum BuildType {
|
||||
prebuilt,
|
||||
@ -32,7 +32,7 @@ HostPlatform getCurrentHostPlatform() {
|
||||
return HostPlatform.mac;
|
||||
if (Platform.isLinux)
|
||||
return HostPlatform.linux;
|
||||
logging.warning('Unsupported host platform, defaulting to Linux');
|
||||
printError('Unsupported host platform, defaulting to Linux');
|
||||
return HostPlatform.linux;
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ TargetPlatform getCurrentHostPlatformAsTarget() {
|
||||
return TargetPlatform.mac;
|
||||
if (Platform.isLinux)
|
||||
return TargetPlatform.linux;
|
||||
logging.warning('Unsupported host platform, defaulting to Linux');
|
||||
printError('Unsupported host platform, defaulting to Linux');
|
||||
return TargetPlatform.linux;
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ import 'package:den_api/den_api.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import '../artifacts.dart';
|
||||
import '../base/logging.dart';
|
||||
import '../base/context.dart';
|
||||
import '../base/process.dart';
|
||||
import '../build_configuration.dart';
|
||||
import '../runner/flutter_command.dart';
|
||||
@ -188,7 +188,7 @@ class AnalyzeCommand extends FlutterCommand {
|
||||
String packageName = pubSpecYaml.name;
|
||||
String packagePath = path.normalize(path.absolute(path.join(directory.path, 'lib')));
|
||||
if (packages.containsKey(packageName) && packages[packageName] != packagePath) {
|
||||
logging.warning('Inconsistent requirements for $packageName; using $packagePath (and not ${packages[packageName]}).');
|
||||
printError('Inconsistent requirements for $packageName; using $packagePath (and not ${packages[packageName]}).');
|
||||
hadInconsistentRequirements = true;
|
||||
}
|
||||
packages[packageName] = packagePath;
|
||||
@ -208,7 +208,7 @@ class AnalyzeCommand extends FlutterCommand {
|
||||
for (String package in dependencies.keys) {
|
||||
if (packages.containsKey(package)) {
|
||||
if (packages[package] != dependencies[package]) {
|
||||
logging.warning('Inconsistent requirements for $package; using ${packages[package]} (and not ${dependencies[package]}).');
|
||||
printError('Inconsistent requirements for $package; using ${packages[package]} (and not ${dependencies[package]}).');
|
||||
hadInconsistentRequirements = true;
|
||||
}
|
||||
} else {
|
||||
@ -219,9 +219,9 @@ class AnalyzeCommand extends FlutterCommand {
|
||||
}
|
||||
if (hadInconsistentRequirements) {
|
||||
if (foundAnyInFlutterRepo)
|
||||
logging.warning('You may need to run "dart ${path.normalize(path.relative(path.join(ArtifactStore.flutterRoot, 'dev/update_packages.dart')))} --upgrade".');
|
||||
printError('You may need to run "dart ${path.normalize(path.relative(path.join(ArtifactStore.flutterRoot, 'dev/update_packages.dart')))} --upgrade".');
|
||||
if (foundAnyInCurrentDirectory)
|
||||
logging.warning('You may need to run "pub upgrade".');
|
||||
printError('You may need to run "pub upgrade".');
|
||||
}
|
||||
|
||||
String buildDir = buildConfigurations.firstWhere((BuildConfiguration config) => config.testable, orElse: () => null)?.buildDir;
|
||||
@ -256,7 +256,7 @@ class AnalyzeCommand extends FlutterCommand {
|
||||
mainFile.path
|
||||
];
|
||||
|
||||
logging.info(cmd.join(' '));
|
||||
printStatus(cmd.join(' '));
|
||||
Process process = await Process.start(
|
||||
cmd[0],
|
||||
cmd.sublist(1),
|
||||
@ -270,7 +270,7 @@ class AnalyzeCommand extends FlutterCommand {
|
||||
process.stderr.transform(UTF8.decoder).listen((String data) {
|
||||
// dartanalyzer doesn't seem to ever output anything on stderr
|
||||
errorCount += 1;
|
||||
print(data);
|
||||
printError(data);
|
||||
});
|
||||
|
||||
int exitCode = await process.exitCode;
|
||||
@ -336,7 +336,7 @@ class AnalyzeCommand extends FlutterCommand {
|
||||
if (shouldIgnore)
|
||||
continue;
|
||||
}
|
||||
print(errorLine);
|
||||
printError(errorLine);
|
||||
errorCount += 1;
|
||||
}
|
||||
}
|
||||
@ -349,7 +349,7 @@ class AnalyzeCommand extends FlutterCommand {
|
||||
if (errorCount > 0)
|
||||
return 1; // Doesn't this mean 'hints' per the above comment?
|
||||
if (argResults['congratulate'])
|
||||
print('No analyzer warnings! (ran in ${elapsed}s)');
|
||||
printStatus('No analyzer warnings! (ran in ${elapsed}s)');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,8 +11,8 @@ import 'package:yaml/yaml.dart';
|
||||
|
||||
import '../android/device_android.dart';
|
||||
import '../artifacts.dart';
|
||||
import '../base/context.dart';
|
||||
import '../base/file_system.dart';
|
||||
import '../base/logging.dart';
|
||||
import '../base/process.dart';
|
||||
import '../build_configuration.dart';
|
||||
import '../flx.dart' as flx;
|
||||
@ -251,25 +251,25 @@ class ApkCommand extends FlutterCommand {
|
||||
|
||||
if (!components.resources.existsSync()) {
|
||||
// TODO(eseidel): This level should be higher when path is manually set.
|
||||
logging.info('Can not locate Resources: ${components.resources}, ignoring.');
|
||||
printStatus('Can not locate Resources: ${components.resources}, ignoring.');
|
||||
components.resources = null;
|
||||
}
|
||||
|
||||
if (!components.androidSdk.existsSync()) {
|
||||
logging.severe('Can not locate Android SDK: $androidSdkPath');
|
||||
printError('Can not locate Android SDK: $androidSdkPath');
|
||||
return null;
|
||||
}
|
||||
if (!(new _ApkBuilder(components.androidSdk.path).checkSdkPath())) {
|
||||
logging.severe('Can not locate expected Android SDK tools at $androidSdkPath');
|
||||
logging.severe('You must install version $_kAndroidPlatformVersion of the SDK platform');
|
||||
logging.severe('and version $_kBuildToolsVersion of the build tools.');
|
||||
printError('Can not locate expected Android SDK tools at $androidSdkPath');
|
||||
printError('You must install version $_kAndroidPlatformVersion of the SDK platform');
|
||||
printError('and version $_kBuildToolsVersion of the build tools.');
|
||||
return null;
|
||||
}
|
||||
for (File f in [components.manifest, components.icuData,
|
||||
components.libSkyShell, components.debugKeystore]
|
||||
..addAll(components.jars)) {
|
||||
if (!f.existsSync()) {
|
||||
logging.severe('Can not locate file: ${f.path}');
|
||||
printError('Can not locate file: ${f.path}');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -327,7 +327,7 @@ class ApkCommand extends FlutterCommand {
|
||||
ensureDirectoryExists(finalApk.path);
|
||||
builder.align(unalignedApk, finalApk);
|
||||
|
||||
print('APK generated: ${finalApk.path}');
|
||||
printStatus('APK generated: ${finalApk.path}');
|
||||
|
||||
return 0;
|
||||
} finally {
|
||||
@ -342,7 +342,7 @@ class ApkCommand extends FlutterCommand {
|
||||
String keyPassword;
|
||||
|
||||
if (argResults['keystore'].isEmpty) {
|
||||
logging.warning('Signing the APK using the debug keystore');
|
||||
printError('Signing the APK using the debug keystore');
|
||||
keystore = components.debugKeystore;
|
||||
keystorePassword = _kDebugKeystorePassword;
|
||||
keyAlias = _kDebugKeystoreKeyAlias;
|
||||
@ -352,7 +352,7 @@ class ApkCommand extends FlutterCommand {
|
||||
keystorePassword = argResults['keystore-password'];
|
||||
keyAlias = argResults['keystore-key-alias'];
|
||||
if (keystorePassword.isEmpty || keyAlias.isEmpty) {
|
||||
logging.severe('Must provide a keystore password and a key alias');
|
||||
printError('Must provide a keystore password and a key alias');
|
||||
return 1;
|
||||
}
|
||||
keyPassword = argResults['keystore-key-password'];
|
||||
@ -373,7 +373,7 @@ class ApkCommand extends FlutterCommand {
|
||||
|
||||
_ApkComponents components = await _findApkComponents(config);
|
||||
if (components == null) {
|
||||
logging.severe('Unable to build APK.');
|
||||
printError('Unable to build APK.');
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -381,8 +381,8 @@ class ApkCommand extends FlutterCommand {
|
||||
|
||||
if (!flxPath.isEmpty) {
|
||||
if (!FileSystemEntity.isFileSync(flxPath)) {
|
||||
logging.severe('FLX does not exist: $flxPath');
|
||||
logging.severe('(Omit the --flx option to build the FLX automatically)');
|
||||
printError('FLX does not exist: $flxPath');
|
||||
printError('(Omit the --flx option to build the FLX automatically)');
|
||||
return 1;
|
||||
}
|
||||
return _buildApk(components, flxPath);
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import '../base/logging.dart';
|
||||
import '../base/context.dart';
|
||||
import '../flx.dart';
|
||||
import '../runner/flutter_command.dart';
|
||||
import '../toolchain.dart';
|
||||
@ -45,9 +45,9 @@ class BuildCommand extends FlutterCommand {
|
||||
precompiledSnapshot: argResults['precompiled']
|
||||
).then((int result) {
|
||||
if (result == 0)
|
||||
print('Built $outputPath.');
|
||||
printStatus('Built $outputPath.');
|
||||
else
|
||||
logging.severe('Error building $outputPath: $result.');
|
||||
printError('Error building $outputPath: $result.');
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ import 'package:path/path.dart' as path;
|
||||
|
||||
import '../android/android.dart' as android;
|
||||
import '../artifacts.dart';
|
||||
import '../base/logging.dart';
|
||||
import '../base/context.dart';
|
||||
import '../base/process.dart';
|
||||
|
||||
class CreateCommand extends Command {
|
||||
@ -28,21 +28,21 @@ class CreateCommand extends Command {
|
||||
@override
|
||||
Future<int> run() async {
|
||||
if (!argResults.wasParsed('out')) {
|
||||
print('No option specified for the output directory.');
|
||||
print(argParser.usage);
|
||||
printStatus('No option specified for the output directory.');
|
||||
printStatus(argParser.usage);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (ArtifactStore.flutterRoot == null) {
|
||||
stderr.writeln('Neither the --flutter-root command line flag nor the FLUTTER_ROOT environment');
|
||||
stderr.writeln('variable was specified. Unable to find package:flutter.');
|
||||
printError('Neither the --flutter-root command line flag nor the FLUTTER_ROOT environment');
|
||||
printError('variable was specified. Unable to find package:flutter.');
|
||||
return 2;
|
||||
}
|
||||
String flutterRoot = path.absolute(ArtifactStore.flutterRoot);
|
||||
|
||||
String flutterPackagePath = path.join(flutterRoot, 'packages', 'flutter');
|
||||
if (!FileSystemEntity.isFileSync(path.join(flutterPackagePath, 'pubspec.yaml'))) {
|
||||
print('Unable to find package:flutter in $flutterPackagePath');
|
||||
printError('Unable to find package:flutter in $flutterPackagePath');
|
||||
return 2;
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ class CreateCommand extends Command {
|
||||
|
||||
new FlutterSimpleTemplate().generateInto(out, flutterPackagePath);
|
||||
|
||||
print('');
|
||||
printStatus('');
|
||||
|
||||
String message = '''All done! To run your application:
|
||||
|
||||
@ -64,7 +64,7 @@ class CreateCommand extends Command {
|
||||
return code;
|
||||
}
|
||||
|
||||
print(message);
|
||||
printStatus(message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -80,13 +80,13 @@ class CreateCommand extends Command {
|
||||
if (!pubSpecYaml.existsSync()) {
|
||||
if (skipIfAbsent)
|
||||
return 0;
|
||||
logging.severe('$directory: no pubspec.yaml found');
|
||||
printError('$directory: no pubspec.yaml found');
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!pubSpecLock.existsSync() || pubSpecYaml.lastModifiedSync().isAfter(pubSpecLock.lastModifiedSync())) {
|
||||
if (verbose)
|
||||
print("Running pub get in $directory...");
|
||||
printStatus("Running pub get in $directory...");
|
||||
int code = await runCommandAndStreamOutput(
|
||||
[sdkBinaryName('pub'), 'get'],
|
||||
workingDirectory: directory
|
||||
@ -99,7 +99,7 @@ class CreateCommand extends Command {
|
||||
(dotPackages.existsSync() && dotPackages.lastModifiedSync().isAfter(pubSpecYaml.lastModifiedSync())))
|
||||
return 0;
|
||||
|
||||
logging.severe('$directory: pubspec.yaml, pubspec.lock, and .packages are in an inconsistent state');
|
||||
printError('$directory: pubspec.yaml, pubspec.lock, and .packages are in an inconsistent state');
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -115,7 +115,7 @@ abstract class Template {
|
||||
void generateInto(Directory dir, String flutterPackagePath) {
|
||||
String dirPath = path.normalize(dir.absolute.path);
|
||||
String projectName = _normalizeProjectName(path.basename(dirPath));
|
||||
print('Creating ${path.basename(projectName)}...');
|
||||
printStatus('Creating ${path.basename(projectName)}...');
|
||||
dir.createSync(recursive: true);
|
||||
|
||||
String relativeFlutterPackagePath = path.relative(flutterPackagePath, from: dirPath);
|
||||
@ -131,7 +131,7 @@ abstract class Template {
|
||||
File file = new File(path.join(dir.path, filePath));
|
||||
file.parent.createSync();
|
||||
file.writeAsStringSync(contents);
|
||||
print(file.path);
|
||||
printStatus(file.path);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -6,11 +6,9 @@ import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:logging/logging.dart';
|
||||
|
||||
import '../android/adb.dart';
|
||||
import '../android/device_android.dart';
|
||||
import '../base/logging.dart';
|
||||
import '../base/context.dart';
|
||||
import '../device.dart';
|
||||
import '../runner/flutter_command.dart';
|
||||
import 'start.dart';
|
||||
@ -30,29 +28,32 @@ class DaemonCommand extends FlutterCommand {
|
||||
|
||||
bool get requiresProjectRoot => false;
|
||||
|
||||
Future<int> runInProject() async {
|
||||
print('Starting device daemon...');
|
||||
Future<int> runInProject() {
|
||||
printStatus('Starting device daemon...');
|
||||
|
||||
Stream<Map> commandStream = stdin
|
||||
.transform(UTF8.decoder)
|
||||
.transform(const LineSplitter())
|
||||
.where((String line) => line.startsWith('[{') && line.endsWith('}]'))
|
||||
.map((String line) {
|
||||
line = line.substring(1, line.length - 1);
|
||||
return JSON.decode(line);
|
||||
});
|
||||
NotifyingAppContext appContext = new NotifyingAppContext();
|
||||
|
||||
Daemon daemon = new Daemon(commandStream, (Map command) {
|
||||
stdout.writeln('[${JSON.encode(command, toEncodable: _jsonEncodeObject)}]');
|
||||
}, daemonCommand: this);
|
||||
return runZoned(() {
|
||||
Stream<Map<String, dynamic>> commandStream = stdin
|
||||
.transform(UTF8.decoder)
|
||||
.transform(const LineSplitter())
|
||||
.where((String line) => line.startsWith('[{') && line.endsWith('}]'))
|
||||
.map((String line) {
|
||||
line = line.substring(1, line.length - 1);
|
||||
return JSON.decode(line);
|
||||
});
|
||||
|
||||
return await daemon.onExit;
|
||||
Daemon daemon = new Daemon(commandStream, (Map command) {
|
||||
stdout.writeln('[${JSON.encode(command, toEncodable: _jsonEncodeObject)}]');
|
||||
}, daemonCommand: this, appContext: appContext);
|
||||
|
||||
return daemon.onExit;
|
||||
}, zoneValues: {'context': appContext});
|
||||
}
|
||||
|
||||
dynamic _jsonEncodeObject(dynamic object) {
|
||||
if (object is Device)
|
||||
return _deviceToMap(object);
|
||||
|
||||
return object;
|
||||
}
|
||||
}
|
||||
@ -62,7 +63,10 @@ typedef void DispatchComand(Map<String, dynamic> command);
|
||||
typedef Future<dynamic> CommandHandler(dynamic args);
|
||||
|
||||
class Daemon {
|
||||
Daemon(Stream<Map> commandStream, this.sendCommand, {this.daemonCommand}) {
|
||||
Daemon(Stream<Map> commandStream, this.sendCommand, {
|
||||
this.daemonCommand,
|
||||
this.appContext
|
||||
}) {
|
||||
// Set up domains.
|
||||
_registerDomain(new DaemonDomain(this));
|
||||
_registerDomain(new AppDomain(this));
|
||||
@ -77,6 +81,7 @@ class Daemon {
|
||||
|
||||
final DispatchComand sendCommand;
|
||||
final DaemonCommand daemonCommand;
|
||||
final NotifyingAppContext appContext;
|
||||
|
||||
final Completer<int> _onExitCompleter = new Completer<int>();
|
||||
final Map<String, Domain> _domainMap = <String, Domain>{};
|
||||
@ -94,7 +99,7 @@ class Daemon {
|
||||
dynamic id = request['id'];
|
||||
|
||||
if (id == null) {
|
||||
logging.severe('no id for request: $request');
|
||||
stderr.writeln('no id for request: $request');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -111,7 +116,8 @@ class Daemon {
|
||||
_domainMap[prefix].handleCommand(name, id, request['params']);
|
||||
} catch (error, trace) {
|
||||
_send({'id': id, 'error': _toJsonable(error)});
|
||||
logging.warning('error handling $request', error, trace);
|
||||
stderr.writeln('error handling $request: $error');
|
||||
stderr.writeln(trace);
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,7 +158,8 @@ abstract class Domain {
|
||||
}
|
||||
}).catchError((error, trace) {
|
||||
_send({'id': id, 'error': _toJsonable(error)});
|
||||
logging.warning("error handling '$name.$command'", error, trace);
|
||||
stderr.writeln("error handling '$name.$command': $error");
|
||||
stderr.writeln(trace);
|
||||
});
|
||||
}
|
||||
|
||||
@ -176,25 +183,23 @@ class DaemonDomain extends Domain {
|
||||
registerHandler('version', version);
|
||||
registerHandler('shutdown', shutdown);
|
||||
|
||||
_subscription = Logger.root.onRecord.listen((LogRecord record) {
|
||||
String message = record.error == null ? record.message : '${record.message}: ${record.error}';
|
||||
|
||||
if (record.stackTrace != null) {
|
||||
_subscription = daemon.appContext.onMessage.listen((LogMessage message) {
|
||||
if (message.stackTrace != null) {
|
||||
sendEvent('daemon.logMessage', {
|
||||
'level': record.level.name.toLowerCase(),
|
||||
'message': message,
|
||||
'stackTrace': record.stackTrace.toString()
|
||||
'level': message.level,
|
||||
'message': message.message,
|
||||
'stackTrace': message.stackTrace.toString()
|
||||
});
|
||||
} else {
|
||||
sendEvent('daemon.logMessage', {
|
||||
'level': record.level.name.toLowerCase(),
|
||||
'message': message
|
||||
'level': message.level,
|
||||
'message': message.message
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
StreamSubscription<LogRecord> _subscription;
|
||||
StreamSubscription<LogMessage> _subscription;
|
||||
|
||||
Future<String> version(dynamic args) {
|
||||
return new Future.value(protocolVersion);
|
||||
@ -403,3 +408,31 @@ dynamic _toJsonable(dynamic obj) {
|
||||
return obj;
|
||||
return '$obj';
|
||||
}
|
||||
|
||||
class NotifyingAppContext implements AppContext {
|
||||
StreamController<LogMessage> _messageController = new StreamController<LogMessage>.broadcast();
|
||||
|
||||
Stream<LogMessage> get onMessage => _messageController.stream;
|
||||
|
||||
bool verbose = false;
|
||||
|
||||
void printError(String message, [StackTrace stackTrace]) {
|
||||
_messageController.add(new LogMessage('error', message, stackTrace));
|
||||
}
|
||||
|
||||
void printStatus(String message) {
|
||||
_messageController.add(new LogMessage('status', message));
|
||||
}
|
||||
|
||||
void printTrace(String message) {
|
||||
_messageController.add(new LogMessage('trace', message));
|
||||
}
|
||||
}
|
||||
|
||||
class LogMessage {
|
||||
final String level;
|
||||
final String message;
|
||||
final StackTrace stackTrace;
|
||||
|
||||
LogMessage(this.level, this.message, [this.stackTrace]);
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ import "dart:io";
|
||||
import "package:path/path.dart" as path;
|
||||
|
||||
import "../artifacts.dart";
|
||||
import "../base/logging.dart";
|
||||
import "../base/context.dart";
|
||||
import "../base/process.dart";
|
||||
import "../runner/flutter_command.dart";
|
||||
import "../runner/flutter_command_runner.dart";
|
||||
@ -29,12 +29,12 @@ class IOSCommand extends FlutterCommand {
|
||||
}
|
||||
|
||||
Future<List<int>> _fetchXcodeArchive() async {
|
||||
print("Fetching the Xcode project archive from the cloud...");
|
||||
printStatus("Fetching the Xcode project archive from the cloud...");
|
||||
|
||||
HttpClient client = new HttpClient();
|
||||
|
||||
Uri xcodeProjectUri = _xcodeProjectUri(ArtifactStore.engineRevision);
|
||||
logging.info("Downloading $xcodeProjectUri...");
|
||||
printStatus("Downloading $xcodeProjectUri...");
|
||||
HttpClientRequest request = await client.getUrl(xcodeProjectUri);
|
||||
HttpClientResponse response = await request.close();
|
||||
|
||||
@ -49,7 +49,7 @@ class IOSCommand extends FlutterCommand {
|
||||
}
|
||||
|
||||
Future<bool> _inflateXcodeArchive(String directory, List<int> archiveBytes) async {
|
||||
print("Unzipping Xcode project to local directory...");
|
||||
printStatus("Unzipping Xcode project to local directory...");
|
||||
|
||||
// We cannot use ArchiveFile because this archive contains files that are exectuable
|
||||
// and there is currently no provision to modify file permissions during
|
||||
@ -117,16 +117,16 @@ class IOSCommand extends FlutterCommand {
|
||||
List<int> archiveBytes = await _fetchXcodeArchive();
|
||||
|
||||
if (archiveBytes.isEmpty) {
|
||||
print("Error: No archive bytes received.");
|
||||
printError("Error: No archive bytes received.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Step 2: Inflate the archive into the user project directory
|
||||
bool result = await _inflateXcodeArchive(xcodeprojPath, archiveBytes);
|
||||
if (!result) {
|
||||
print("Error: Could not init the Xcode project: the 'ios' directory already exists.");
|
||||
print("To proceed, remove the 'ios' directory and try again.");
|
||||
print("Warning: You may have made manual changes to files in the 'ios' directory.");
|
||||
printError("Error: Could not init the Xcode project: the 'ios' directory already exists.");
|
||||
printError("To proceed, remove the 'ios' directory and try again.");
|
||||
printError("Warning: You may have made manual changes to files in the 'ios' directory.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -134,22 +134,22 @@ class IOSCommand extends FlutterCommand {
|
||||
_setupXcodeProjXcconfig(path.join(xcodeprojPath, "Local.xcconfig"));
|
||||
|
||||
// Step 4: Tell the user the location of the generated project.
|
||||
print("An Xcode project has been placed in 'ios/'.");
|
||||
print("You may edit it to modify iOS specific configuration.");
|
||||
printStatus("An Xcode project has been placed in 'ios/'.");
|
||||
printStatus("You may edit it to modify iOS specific configuration.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> runInProject() async {
|
||||
if (!Platform.isMacOS) {
|
||||
print("iOS specific commands may only be run on a Mac.");
|
||||
printStatus("iOS specific commands may only be run on a Mac.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argResults['init'])
|
||||
return await _runInitCommand();
|
||||
|
||||
print("No flags specified.");
|
||||
printError("No flags specified.");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import '../base/context.dart';
|
||||
import '../device.dart';
|
||||
import '../runner/flutter_command.dart';
|
||||
|
||||
@ -19,12 +20,13 @@ class ListCommand extends FlutterCommand {
|
||||
List<Device> devices = await deviceManager.getDevices();
|
||||
|
||||
if (devices.isEmpty) {
|
||||
print('No connected devices.');
|
||||
printStatus('No connected devices.');
|
||||
} else {
|
||||
print('${devices.length} connected ${pluralize('device', devices.length)}:');
|
||||
print('');
|
||||
printStatus('${devices.length} connected ${pluralize('device', devices.length)}:');
|
||||
printStatus('');
|
||||
|
||||
for (Device device in devices) {
|
||||
print('${device.name} (${device.id})');
|
||||
printStatus('${device.name} (${device.id})');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import '../base/logging.dart';
|
||||
import '../base/context.dart';
|
||||
import '../base/process.dart';
|
||||
import 'start.dart';
|
||||
|
||||
@ -36,7 +36,7 @@ class ListenCommand extends StartCommandBase {
|
||||
int result = 0;
|
||||
bool firstTime = true;
|
||||
do {
|
||||
logging.info('Updating running Flutter apps...');
|
||||
printStatus('Updating running Flutter apps...');
|
||||
result = await startApp(
|
||||
devices,
|
||||
applicationPackages,
|
||||
@ -58,7 +58,7 @@ class ListenCommand extends StartCommandBase {
|
||||
try {
|
||||
runCheckedSync(<String>['which', 'fswatch']);
|
||||
} catch (e) {
|
||||
logging.severe('"listen" command is only useful if you have installed '
|
||||
printError('"listen" command is only useful if you have installed '
|
||||
'fswatch on Mac. Run "brew install fswatch" to install it with '
|
||||
'homebrew.');
|
||||
return null;
|
||||
@ -68,7 +68,7 @@ class ListenCommand extends StartCommandBase {
|
||||
try {
|
||||
runCheckedSync(<String>['which', 'inotifywait']);
|
||||
} catch (e) {
|
||||
logging.severe('"listen" command is only useful if you have installed '
|
||||
printError('"listen" command is only useful if you have installed '
|
||||
'inotifywait on Linux. Run "apt-get install inotify-tools" or '
|
||||
'equivalent to install it.');
|
||||
return null;
|
||||
@ -82,18 +82,18 @@ class ListenCommand extends StartCommandBase {
|
||||
'modify,close_write,move,create,delete',
|
||||
]..addAll(directories);
|
||||
} else {
|
||||
logging.severe('"listen" command is only available on Mac and Linux.');
|
||||
printError('"listen" command is only available on Mac and Linux.');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
bool _watchDirectory(List<String> watchCommand) {
|
||||
logging.info('Attempting to listen to these directories: ${watchCommand.join(", ")}');
|
||||
printStatus('Attempting to listen to these directories: ${watchCommand.join(", ")}');
|
||||
assert(watchCommand != null);
|
||||
try {
|
||||
runCheckedSync(watchCommand);
|
||||
} catch (e) {
|
||||
logging.warning('Watching directories failed.', e);
|
||||
printError('Watching directories failed.', e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@ -5,11 +5,10 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import '../artifacts.dart';
|
||||
import '../base/logging.dart';
|
||||
import '../base/context.dart';
|
||||
import '../base/process.dart';
|
||||
import '../build_configuration.dart';
|
||||
import '../flx.dart' as flx;
|
||||
@ -119,12 +118,8 @@ class RunMojoCommand extends FlutterCommand {
|
||||
if (useDevtools) {
|
||||
final String buildFlag = argResults['mojo-debug'] ? '--debug' : '--release';
|
||||
args.add(buildFlag);
|
||||
if (logging.level <= Level.INFO) {
|
||||
if (context.verbose)
|
||||
args.add('--verbose');
|
||||
if (logging.level <= Level.FINE) {
|
||||
args.add('--verbose');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (argResults['checked']) {
|
||||
@ -132,19 +127,19 @@ class RunMojoCommand extends FlutterCommand {
|
||||
}
|
||||
|
||||
args.addAll(argResults.rest);
|
||||
print(args);
|
||||
printStatus('$args');
|
||||
return args;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> runInProject() async {
|
||||
if ((argResults['mojo-path'] == null && argResults['devtools-path'] == null) || (argResults['mojo-path'] != null && argResults['devtools-path'] != null)) {
|
||||
logging.severe('Must specify either --mojo-path or --devtools-path.');
|
||||
printError('Must specify either --mojo-path or --devtools-path.');
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argResults['mojo-debug'] && argResults['mojo-release']) {
|
||||
logging.severe('Cannot specify both --mojo-debug and --mojo-release');
|
||||
printError('Cannot specify both --mojo-debug and --mojo-release');
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ import 'dart:io';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import '../application_package.dart';
|
||||
import '../base/logging.dart';
|
||||
import '../base/context.dart';
|
||||
import '../device.dart';
|
||||
import '../runner/flutter_command.dart';
|
||||
import '../toolchain.dart';
|
||||
@ -64,7 +64,7 @@ class StartCommand extends StartCommandBase {
|
||||
|
||||
@override
|
||||
Future<int> runInProject() async {
|
||||
logging.fine('Downloading toolchain.');
|
||||
printTrace('Downloading toolchain.');
|
||||
|
||||
await Future.wait([
|
||||
downloadToolchain(),
|
||||
@ -89,7 +89,7 @@ class StartCommand extends StartCommandBase {
|
||||
clearLogs: clearLogs
|
||||
);
|
||||
|
||||
logging.fine('Finished start command.');
|
||||
printTrace('Finished start command.');
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@ -113,17 +113,17 @@ Future<int> startApp(
|
||||
String message = 'Tried to run $mainPath, but that file does not exist.';
|
||||
if (target == null)
|
||||
message += '\nConsider using the -t option to specify the Dart file to start.';
|
||||
logging.severe(message);
|
||||
printError(message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (stop) {
|
||||
logging.fine('Running stop command.');
|
||||
printTrace('Running stop command.');
|
||||
stopAll(devices, applicationPackages);
|
||||
}
|
||||
|
||||
if (install) {
|
||||
logging.fine('Running install command.');
|
||||
printTrace('Running install command.');
|
||||
installApp(devices, applicationPackages);
|
||||
}
|
||||
|
||||
@ -134,7 +134,7 @@ Future<int> startApp(
|
||||
if (package == null || !device.isConnected())
|
||||
continue;
|
||||
|
||||
logging.fine('Running build command for $device.');
|
||||
printTrace('Running build command for $device.');
|
||||
|
||||
Map<String, dynamic> platformArgs = <String, dynamic>{};
|
||||
|
||||
@ -155,7 +155,7 @@ Future<int> startApp(
|
||||
);
|
||||
|
||||
if (!result) {
|
||||
logging.severe('Could not start \'${package.name}\' on \'${device.id}\'');
|
||||
printError('Could not start \'${package.name}\' on \'${device.id}\'');
|
||||
} else {
|
||||
startedSomething = true;
|
||||
}
|
||||
@ -163,9 +163,9 @@ Future<int> startApp(
|
||||
|
||||
if (!startedSomething) {
|
||||
if (!devices.all.any((device) => device.isConnected())) {
|
||||
logging.severe('Unable to run application - no connected devices.');
|
||||
printError('Unable to run application - no connected devices.');
|
||||
} else {
|
||||
logging.severe('Unable to run application.');
|
||||
printError('Unable to run application.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ import 'package:path/path.dart' as path;
|
||||
import 'package:test/src/executable.dart' as executable;
|
||||
|
||||
import '../artifacts.dart';
|
||||
import '../base/logging.dart';
|
||||
import '../base/context.dart';
|
||||
import '../build_configuration.dart';
|
||||
import '../runner/flutter_command.dart';
|
||||
import '../test/loader.dart' as loader;
|
||||
@ -105,7 +105,7 @@ class TestCommand extends FlutterCommand {
|
||||
foundOne = true;
|
||||
loader.shellPath = path.absolute(await _getShellPath(config));
|
||||
if (!FileSystemEntity.isFileSync(loader.shellPath)) {
|
||||
logging.severe('Cannot find Flutter shell at ${loader.shellPath}');
|
||||
printError('Cannot find Flutter shell at ${loader.shellPath}');
|
||||
return 1;
|
||||
}
|
||||
await _runTests(testArgs, testDir);
|
||||
@ -113,7 +113,7 @@ class TestCommand extends FlutterCommand {
|
||||
return exitCode;
|
||||
}
|
||||
if (!foundOne) {
|
||||
stderr.writeln('At least one of --debug or --release must be set, to specify the local build products to test.');
|
||||
printError('At least one of --debug or --release must be set, to specify the local build products to test.');
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ import 'dart:async';
|
||||
|
||||
import '../android/device_android.dart';
|
||||
import '../application_package.dart';
|
||||
import '../base/logging.dart';
|
||||
import '../base/context.dart';
|
||||
import '../runner/flutter_command.dart';
|
||||
|
||||
class TraceCommand extends FlutterCommand {
|
||||
@ -30,7 +30,7 @@ class TraceCommand extends FlutterCommand {
|
||||
await downloadApplicationPackagesAndConnectToDevices();
|
||||
|
||||
if (!devices.android.isConnected()) {
|
||||
logging.warning('No device connected, so no trace was completed.');
|
||||
printError('No device connected, so no trace was completed.');
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -56,9 +56,9 @@ class TraceCommand extends FlutterCommand {
|
||||
Future _stopTracing(AndroidDevice android, AndroidApk androidApp) async {
|
||||
String tracePath = await android.stopTracing(androidApp, outPath: argResults['out']);
|
||||
if (tracePath == null) {
|
||||
logging.warning('No trace file saved.');
|
||||
printError('No trace file saved.');
|
||||
} else {
|
||||
print('Trace file saved to $tracePath');
|
||||
printStatus('Trace file saved to $tracePath');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
import 'dart:async';
|
||||
|
||||
import '../artifacts.dart';
|
||||
import '../base/context.dart';
|
||||
import '../base/process.dart';
|
||||
import '../runner/flutter_command.dart';
|
||||
|
||||
@ -19,7 +20,7 @@ class UpgradeCommand extends FlutterCommand {
|
||||
'git', 'rev-parse', '@{u}'
|
||||
], workingDirectory: ArtifactStore.flutterRoot);
|
||||
} catch (e) {
|
||||
print('Unable to upgrade Flutter. No upstream repository configured for Flutter.');
|
||||
printError('Unable to upgrade Flutter. No upstream repository configured for Flutter.');
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ import 'dart:async';
|
||||
|
||||
import 'android/device_android.dart';
|
||||
import 'application_package.dart';
|
||||
import 'base/logging.dart';
|
||||
import 'base/context.dart';
|
||||
import 'build_configuration.dart';
|
||||
import 'ios/device_ios.dart';
|
||||
import 'toolchain.dart';
|
||||
@ -132,7 +132,7 @@ class DeviceStore {
|
||||
(Device dev) => (dev.id == config.deviceId),
|
||||
orElse: () => null);
|
||||
if (device == null) {
|
||||
logging.severe('Warning: Device ID ${config.deviceId} not found');
|
||||
printError('Warning: Device ID ${config.deviceId} not found');
|
||||
}
|
||||
} else if (devices.length == 1) {
|
||||
// Step 2: If no identifier is specified and there is only one connected
|
||||
@ -140,8 +140,8 @@ class DeviceStore {
|
||||
device = devices[0];
|
||||
} else if (devices.length > 1) {
|
||||
// Step 3: D:
|
||||
logging.fine('Multiple devices are connected, but no device ID was specified.');
|
||||
logging.fine('Attempting to launch on all connected devices.');
|
||||
printTrace('Multiple devices are connected, but no device ID was specified.');
|
||||
printTrace('Attempting to launch on all connected devices.');
|
||||
}
|
||||
|
||||
return device;
|
||||
|
||||
@ -12,8 +12,8 @@ import 'package:flx/signing.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:yaml/yaml.dart';
|
||||
|
||||
import 'base/context.dart';
|
||||
import 'base/file_system.dart';
|
||||
import 'base/logging.dart';
|
||||
import 'toolchain.dart';
|
||||
|
||||
const String defaultMainPath = 'lib/main.dart';
|
||||
@ -158,7 +158,7 @@ Future<int> build(
|
||||
String privateKeyPath: defaultPrivateKeyPath,
|
||||
bool precompiledSnapshot: false
|
||||
}) async {
|
||||
logging.fine('Building $outputPath');
|
||||
printTrace('Building $outputPath');
|
||||
|
||||
Map manifestDescriptor = _loadManifest(manifestPath);
|
||||
|
||||
@ -174,7 +174,7 @@ Future<int> build(
|
||||
// content equivalents
|
||||
int result = await toolchain.compiler.compile(mainPath: mainPath, snapshotPath: snapshotPath);
|
||||
if (result != 0) {
|
||||
logging.severe('Failed to run the Flutter compiler. Exit code: $result');
|
||||
printError('Failed to run the Flutter compiler. Exit code: $result');
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -184,7 +184,7 @@ Future<int> build(
|
||||
for (_Asset asset in assets) {
|
||||
ArchiveFile file = _createFile(asset.key, asset.base);
|
||||
if (file == null) {
|
||||
stderr.writeln('Cannot find asset "${asset.key}" in directory "${path.absolute(asset.base)}".');
|
||||
printError('Cannot find asset "${asset.key}" in directory "${path.absolute(asset.base)}".');
|
||||
return 1;
|
||||
}
|
||||
archive.addFile(file);
|
||||
|
||||
@ -8,7 +8,7 @@ import 'dart:io';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import '../application_package.dart';
|
||||
import '../base/logging.dart';
|
||||
import '../base/context.dart';
|
||||
import '../base/process.dart';
|
||||
import '../build_configuration.dart';
|
||||
import '../device.dart';
|
||||
@ -129,9 +129,9 @@ class IOSDevice extends Device {
|
||||
command = runCheckedSync(['which', command]).trim();
|
||||
} catch (e) {
|
||||
if (Platform.isMacOS) {
|
||||
logging.severe('$command not found. $macInstructions');
|
||||
printError('$command not found. $macInstructions');
|
||||
} else {
|
||||
logging.severe('Cannot control iOS devices or simulators. $command is not available on your platform.');
|
||||
printError('Cannot control iOS devices or simulators. $command is not available on your platform.');
|
||||
}
|
||||
}
|
||||
return command;
|
||||
@ -187,13 +187,13 @@ class IOSDevice extends Device {
|
||||
Map<String, dynamic> platformArgs
|
||||
}) async {
|
||||
// TODO: Use checked, mainPath, route
|
||||
logging.fine('Building ${app.name} for $id');
|
||||
printTrace('Building ${app.name} for $id');
|
||||
|
||||
// Step 1: Install the precompiled application if necessary
|
||||
bool buildResult = await _buildIOSXcodeProject(app, true);
|
||||
|
||||
if (!buildResult) {
|
||||
logging.severe('Could not build the precompiled application for the device');
|
||||
printError('Could not build the precompiled application for the device');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -202,7 +202,7 @@ class IOSDevice extends Device {
|
||||
|
||||
bool bundleExists = bundle.existsSync();
|
||||
if (!bundleExists) {
|
||||
logging.severe('Could not find the built application bundle at ${bundle.path}');
|
||||
printError('Could not find the built application bundle at ${bundle.path}');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -217,11 +217,11 @@ class IOSDevice extends Device {
|
||||
]);
|
||||
|
||||
if (installationResult != 0) {
|
||||
logging.severe('Could not install ${bundle.path} on $id');
|
||||
printError('Could not install ${bundle.path} on $id');
|
||||
return false;
|
||||
}
|
||||
|
||||
logging.fine('Installation successful');
|
||||
printTrace('Installation successful');
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -311,13 +311,13 @@ class IOSSimulator extends Device {
|
||||
// More than one simulator is listed as booted, which is not allowed but
|
||||
// sometimes happens erroneously. Kill them all because we don't know
|
||||
// which one is actually running.
|
||||
logging.warning('Multiple running simulators were detected, '
|
||||
printError('Multiple running simulators were detected, '
|
||||
'which is not supposed to happen.');
|
||||
for (Match match in matches) {
|
||||
if (match.groupCount > 0) {
|
||||
// TODO: We're killing simulator devices inside an accessor method;
|
||||
// we probably shouldn't be changing state here.
|
||||
logging.warning('Killing simulator ${match.group(1)}');
|
||||
printError('Killing simulator ${match.group(1)}');
|
||||
runSync([xcrunPath, 'simctl', 'shutdown', match.group(2)]);
|
||||
}
|
||||
}
|
||||
@ -328,7 +328,7 @@ class IOSSimulator extends Device {
|
||||
if (match != null && match.groupCount > 0) {
|
||||
return new _IOSSimulatorInfo(match.group(2), match.group(1));
|
||||
} else {
|
||||
logging.info('No running simulators found');
|
||||
printTrace('No running simulators found');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -368,11 +368,11 @@ class IOSSimulator extends Device {
|
||||
runDetached([iOSSimPath]);
|
||||
Future<bool> checkConnection([int attempts = 20]) async {
|
||||
if (attempts == 0) {
|
||||
logging.info('Timed out waiting for iOS Simulator $id to boot.');
|
||||
printStatus('Timed out waiting for iOS Simulator $id to boot.');
|
||||
return false;
|
||||
}
|
||||
if (!isConnected()) {
|
||||
logging.info('Waiting for iOS Simulator $id to boot...');
|
||||
printStatus('Waiting for iOS Simulator $id to boot...');
|
||||
return await new Future.delayed(new Duration(milliseconds: 500),
|
||||
() => checkConnection(attempts - 1));
|
||||
}
|
||||
@ -383,7 +383,7 @@ class IOSSimulator extends Device {
|
||||
try {
|
||||
runCheckedSync([xcrunPath, 'simctl', 'boot', id]);
|
||||
} catch (e) {
|
||||
logging.warning('Unable to boot iOS Simulator $id: ', e);
|
||||
printError('Unable to boot iOS Simulator $id: ', e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -441,12 +441,12 @@ class IOSSimulator extends Device {
|
||||
Map<String, dynamic> platformArgs
|
||||
}) async {
|
||||
// TODO: Use checked, mainPath, route
|
||||
logging.fine('Building ${app.name} for $id');
|
||||
printTrace('Building ${app.name} for $id');
|
||||
|
||||
// Step 1: Build the Xcode project
|
||||
bool buildResult = await _buildIOSXcodeProject(app, false);
|
||||
if (!buildResult) {
|
||||
logging.severe('Could not build the application for the simulator');
|
||||
printError('Could not build the application for the simulator');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -454,7 +454,7 @@ class IOSSimulator extends Device {
|
||||
Directory bundle = new Directory(path.join(app.localPath, 'build', 'Release-iphonesimulator', 'Runner.app'));
|
||||
bool bundleExists = await bundle.exists();
|
||||
if (!bundleExists) {
|
||||
logging.severe('Could not find the built application bundle at ${bundle.path}');
|
||||
printError('Could not find the built application bundle at ${bundle.path}');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -468,7 +468,7 @@ class IOSSimulator extends Device {
|
||||
]);
|
||||
|
||||
if (installResult != 0) {
|
||||
logging.severe('Could not install the application bundle on the simulator');
|
||||
printError('Could not install the application bundle on the simulator');
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -482,11 +482,11 @@ class IOSSimulator extends Device {
|
||||
]);
|
||||
|
||||
if (launchResult != 0) {
|
||||
logging.severe('Could not launch the freshly installed application on the simulator');
|
||||
printError('Could not launch the freshly installed application on the simulator');
|
||||
return false;
|
||||
}
|
||||
|
||||
logging.fine('Successfully started ${app.name} on $id');
|
||||
printTrace('Successfully started ${app.name} on $id');
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -545,11 +545,11 @@ bool _checkXcodeVersion() {
|
||||
String version = runCheckedSync(['xcodebuild', '-version']);
|
||||
Match match = _xcodeVersionRegExp.firstMatch(version);
|
||||
if (int.parse(match[1]) < 7) {
|
||||
logging.severe('Found "${match[0]}". $_xcodeRequirement');
|
||||
printError('Found "${match[0]}". $_xcodeRequirement');
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
logging.severe('Cannot find "xcodebuid". $_xcodeRequirement');
|
||||
printError('Cannot find "xcodebuid". $_xcodeRequirement');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -557,7 +557,7 @@ bool _checkXcodeVersion() {
|
||||
|
||||
Future<bool> _buildIOSXcodeProject(ApplicationPackage app, bool isDevice) async {
|
||||
if (!FileSystemEntity.isDirectorySync(app.localPath)) {
|
||||
logging.severe('Path "${path.absolute(app.localPath)}" does not exist.\nDid you run `flutter ios --init`?');
|
||||
printError('Path "${path.absolute(app.localPath)}" does not exist.\nDid you run `flutter ios --init`?');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ import 'dart:io';
|
||||
import 'package:args/command_runner.dart';
|
||||
|
||||
import '../application_package.dart';
|
||||
import '../base/context.dart';
|
||||
import '../build_configuration.dart';
|
||||
import '../device.dart';
|
||||
import '../toolchain.dart';
|
||||
@ -55,7 +56,7 @@ abstract class FlutterCommand extends Command {
|
||||
|
||||
bool validateProjectRoot() {
|
||||
if (!FileSystemEntity.isFileSync('pubspec.yaml')) {
|
||||
stderr.writeln(projectRootValidationErrorMessage);
|
||||
printError(projectRootValidationErrorMessage);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@ -7,11 +7,10 @@ import 'dart:io';
|
||||
|
||||
import 'package:args/args.dart';
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import '../artifacts.dart';
|
||||
import '../base/logging.dart';
|
||||
import '../base/context.dart';
|
||||
import '../base/process.dart';
|
||||
import '../build_configuration.dart';
|
||||
import 'version.dart';
|
||||
@ -29,10 +28,6 @@ class FlutterCommandRunner extends CommandRunner {
|
||||
abbr: 'v',
|
||||
negatable: false,
|
||||
help: 'Noisy logging, including all shell commands executed.');
|
||||
argParser.addFlag('very-verbose',
|
||||
negatable: false,
|
||||
help: 'Very noisy logging, including the output of all '
|
||||
'shell commands executed.');
|
||||
argParser.addFlag('version',
|
||||
negatable: false,
|
||||
help: 'Reports the version of this tool.');
|
||||
@ -141,10 +136,7 @@ class FlutterCommandRunner extends CommandRunner {
|
||||
|
||||
Future<int> runCommand(ArgResults globalResults) {
|
||||
if (globalResults['verbose'])
|
||||
Logger.root.level = Level.INFO;
|
||||
|
||||
if (globalResults['very-verbose'])
|
||||
Logger.root.level = Level.FINE;
|
||||
context.verbose = true;
|
||||
|
||||
_globalResults = globalResults;
|
||||
ArtifactStore.flutterRoot = path.normalize(path.absolute(globalResults['flutter-root']));
|
||||
@ -152,7 +144,7 @@ class FlutterCommandRunner extends CommandRunner {
|
||||
ArtifactStore.packageRoot = path.normalize(path.absolute(globalResults['package-root']));
|
||||
|
||||
if (globalResults['version']) {
|
||||
print(getVersion(ArtifactStore.flutterRoot));
|
||||
printStatus(getVersion(ArtifactStore.flutterRoot));
|
||||
return new Future<int>.value(0);
|
||||
}
|
||||
|
||||
@ -186,7 +178,7 @@ class FlutterCommandRunner extends CommandRunner {
|
||||
engineSourcePath = _tryEnginePath(path.join(ArtifactStore.flutterRoot, '../engine/src'));
|
||||
|
||||
if (engineSourcePath == null) {
|
||||
stderr.writeln('Unable to detect local Flutter engine build directory.\n'
|
||||
printError('Unable to detect local Flutter engine build directory.\n'
|
||||
'Either specify a dependency_override for the $kFlutterEnginePackageName package in your pubspec.yaml and\n'
|
||||
'ensure --package-root is set if necessary, or set the \$$kFlutterEngineEnvironmentVariableName environment variable, or\n'
|
||||
'use --engine-src-path to specify the path to the root of your flutter/engine repository.');
|
||||
@ -195,7 +187,7 @@ class FlutterCommandRunner extends CommandRunner {
|
||||
}
|
||||
|
||||
if (engineSourcePath != null && _tryEnginePath(engineSourcePath) == null) {
|
||||
stderr.writeln('Unable to detect a Flutter engine build directory in $engineSourcePath.\n'
|
||||
printError('Unable to detect a Flutter engine build directory in $engineSourcePath.\n'
|
||||
'Please ensure that $engineSourcePath is a Flutter engine \'src\' directory and that\n'
|
||||
'you have compiled the engine in that directory, which should produce an \'out\' directory');
|
||||
throw new ProcessExit(2);
|
||||
@ -240,7 +232,7 @@ class FlutterCommandRunner extends CommandRunner {
|
||||
}
|
||||
} else {
|
||||
if (!FileSystemEntity.isDirectorySync(enginePath))
|
||||
logging.warning('$enginePath is not a valid directory');
|
||||
printError('$enginePath is not a valid directory');
|
||||
|
||||
if (!isDebug && !isRelease)
|
||||
isDebug = true;
|
||||
|
||||
@ -7,8 +7,6 @@ import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:flutter_tools/src/test/json_socket.dart';
|
||||
import 'package:flutter_tools/src/test/remote_test.dart';
|
||||
import 'package:stack_trace/stack_trace.dart';
|
||||
import 'package:test/src/backend/group.dart';
|
||||
import 'package:test/src/backend/metadata.dart';
|
||||
@ -21,6 +19,9 @@ import 'package:test/src/runner/vm/environment.dart';
|
||||
import 'package:test/src/util/io.dart';
|
||||
import 'package:test/src/util/remote_exception.dart';
|
||||
|
||||
import 'json_socket.dart';
|
||||
import 'remote_test.dart';
|
||||
|
||||
void installHook() {
|
||||
hack.loadVMFileHook = _loadVMFile;
|
||||
}
|
||||
|
||||
@ -14,8 +14,8 @@ import 'package:test/src/backend/live_test.dart';
|
||||
import 'package:test/src/backend/metadata.dart';
|
||||
import 'package:test/src/backend/operating_system.dart';
|
||||
import 'package:test/src/backend/suite.dart';
|
||||
import 'package:test/src/backend/test_platform.dart';
|
||||
import 'package:test/src/backend/test.dart';
|
||||
import 'package:test/src/backend/test_platform.dart';
|
||||
import 'package:test/src/util/remote_exception.dart';
|
||||
|
||||
final OperatingSystem currentOS = (() {
|
||||
|
||||
@ -5,18 +5,18 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:stack_trace/stack_trace.dart';
|
||||
import 'package:test/src/backend/group.dart';
|
||||
import 'package:test/src/backend/live_test.dart';
|
||||
import 'package:test/src/backend/live_test_controller.dart';
|
||||
import 'package:test/src/backend/metadata.dart';
|
||||
import 'package:test/src/backend/operating_system.dart';
|
||||
import 'package:test/src/backend/group.dart';
|
||||
import 'package:test/src/backend/state.dart';
|
||||
import 'package:test/src/backend/suite.dart';
|
||||
import 'package:test/src/backend/test.dart';
|
||||
import 'package:test/src/backend/test_platform.dart';
|
||||
import 'package:test/src/util/remote_exception.dart';
|
||||
|
||||
import 'package:flutter_tools/src/test/json_socket.dart';
|
||||
import 'json_socket.dart';
|
||||
|
||||
class RemoteTest extends Test {
|
||||
RemoteTest(this.name, this.metadata, this._socket, this._index);
|
||||
|
||||
66
packages/flutter_tools/test/context_test.dart
Normal file
66
packages/flutter_tools/test/context_test.dart
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright 2016 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 'package:flutter_tools/src/base/context.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
main() => defineTests();
|
||||
|
||||
defineTests() {
|
||||
group('DeviceManager', () {
|
||||
test('error', () async {
|
||||
MockContext mockContext = new MockContext();
|
||||
|
||||
runZoned(() {
|
||||
printError('foo bar');
|
||||
}, zoneValues: {'context': mockContext});
|
||||
|
||||
expect(mockContext.errorText, 'foo bar\n');
|
||||
expect(mockContext.statusText, '');
|
||||
expect(mockContext.traceText, '');
|
||||
});
|
||||
|
||||
test('status', () async {
|
||||
MockContext mockContext = new MockContext();
|
||||
|
||||
runZoned(() {
|
||||
printStatus('foo bar');
|
||||
}, zoneValues: {'context': mockContext});
|
||||
|
||||
expect(mockContext.errorText, '');
|
||||
expect(mockContext.statusText, 'foo bar\n');
|
||||
expect(mockContext.traceText, '');
|
||||
});
|
||||
|
||||
test('trace', () async {
|
||||
MockContext mockContext = new MockContext();
|
||||
|
||||
runZoned(() {
|
||||
printTrace('foo bar');
|
||||
}, zoneValues: {'context': mockContext});
|
||||
|
||||
expect(mockContext.errorText, '');
|
||||
expect(mockContext.statusText, '');
|
||||
expect(mockContext.traceText, 'foo bar\n');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class MockContext implements AppContext {
|
||||
bool verbose = false;
|
||||
|
||||
StringBuffer _error = new StringBuffer();
|
||||
StringBuffer _status = new StringBuffer();
|
||||
StringBuffer _trace = new StringBuffer();
|
||||
|
||||
String get errorText => _error.toString();
|
||||
String get statusText => _status.toString();
|
||||
String get traceText => _trace.toString();
|
||||
|
||||
void printError(String message, [StackTrace stackTrace]) => _error.writeln(message);
|
||||
void printStatus(String message) => _status.writeln(message);
|
||||
void printTrace(String message) => _trace.writeln(message);
|
||||
}
|
||||
@ -5,10 +5,10 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:flutter_tools/src/artifacts.dart';
|
||||
import 'package:flutter_tools/src/commands/create.dart';
|
||||
import 'package:flutter_tools/src/base/process.dart';
|
||||
import 'package:flutter_tools/src/commands/create.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:test/test.dart';
|
||||
|
||||
main() => defineTests();
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_tools/src/base/logging.dart';
|
||||
import 'package:flutter_tools/src/base/context.dart';
|
||||
import 'package:flutter_tools/src/commands/daemon.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:test/test.dart';
|
||||
@ -16,6 +16,11 @@ main() => defineTests();
|
||||
defineTests() {
|
||||
group('daemon', () {
|
||||
Daemon daemon;
|
||||
NotifyingAppContext appContext;
|
||||
|
||||
setUp(() {
|
||||
appContext = new NotifyingAppContext();
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
if (daemon != null)
|
||||
@ -23,11 +28,12 @@ defineTests() {
|
||||
});
|
||||
|
||||
test('daemon.version', () async {
|
||||
StreamController<Map> commands = new StreamController();
|
||||
StreamController<Map> responses = new StreamController();
|
||||
StreamController<Map<String, dynamic>> commands = new StreamController();
|
||||
StreamController<Map<String, dynamic>> responses = new StreamController();
|
||||
daemon = new Daemon(
|
||||
commands.stream,
|
||||
(Map<String, dynamic> result) => responses.add(result)
|
||||
(Map<String, dynamic> result) => responses.add(result),
|
||||
appContext: appContext
|
||||
);
|
||||
commands.add({'id': 0, 'method': 'daemon.version'});
|
||||
Map response = await responses.stream.where(_notEvent).first;
|
||||
@ -36,30 +42,34 @@ defineTests() {
|
||||
expect(response['result'] is String, true);
|
||||
});
|
||||
|
||||
test('daemon.logMessage', () async {
|
||||
StreamController<Map> commands = new StreamController();
|
||||
StreamController<Map> responses = new StreamController();
|
||||
daemon = new Daemon(
|
||||
commands.stream,
|
||||
(Map<String, dynamic> result) => responses.add(result)
|
||||
);
|
||||
logging.warning('daemon.logMessage test');
|
||||
Map response = await responses.stream.where((Map<String, dynamic> map) {
|
||||
return map['event'] == 'daemon.logMessage' && map['params']['level'] == 'warning';
|
||||
}).first;
|
||||
expect(response['id'], isNull);
|
||||
expect(response['event'], 'daemon.logMessage');
|
||||
Map<String, String> logMessage = response['params'];
|
||||
expect(logMessage['level'], 'warning');
|
||||
expect(logMessage['message'], 'daemon.logMessage test');
|
||||
test('daemon.logMessage', () {
|
||||
return runZoned(() async {
|
||||
StreamController<Map<String, dynamic>> commands = new StreamController();
|
||||
StreamController<Map<String, dynamic>> responses = new StreamController();
|
||||
daemon = new Daemon(
|
||||
commands.stream,
|
||||
(Map<String, dynamic> result) => responses.add(result),
|
||||
appContext: appContext
|
||||
);
|
||||
printError('daemon.logMessage test');
|
||||
Map<String, dynamic> response = await responses.stream.where((Map<String, dynamic> map) {
|
||||
return map['event'] == 'daemon.logMessage' && map['params']['level'] == 'error';
|
||||
}).first;
|
||||
expect(response['id'], isNull);
|
||||
expect(response['event'], 'daemon.logMessage');
|
||||
Map<String, String> logMessage = response['params'];
|
||||
expect(logMessage['level'], 'error');
|
||||
expect(logMessage['message'], 'daemon.logMessage test');
|
||||
}, zoneValues: {'context': appContext});
|
||||
});
|
||||
|
||||
test('daemon.shutdown', () async {
|
||||
StreamController<Map> commands = new StreamController();
|
||||
StreamController<Map> responses = new StreamController();
|
||||
StreamController<Map<String, dynamic>> commands = new StreamController();
|
||||
StreamController<Map<String, dynamic>> responses = new StreamController();
|
||||
daemon = new Daemon(
|
||||
commands.stream,
|
||||
(Map<String, dynamic> result) => responses.add(result)
|
||||
(Map<String, dynamic> result) => responses.add(result),
|
||||
appContext: appContext
|
||||
);
|
||||
commands.add({'id': 0, 'method': 'daemon.shutdown'});
|
||||
return daemon.onExit.then((int code) {
|
||||
@ -71,12 +81,13 @@ defineTests() {
|
||||
DaemonCommand command = new DaemonCommand();
|
||||
applyMocksToCommand(command);
|
||||
|
||||
StreamController<Map> commands = new StreamController();
|
||||
StreamController<Map> responses = new StreamController();
|
||||
StreamController<Map<String, dynamic>> commands = new StreamController();
|
||||
StreamController<Map<String, dynamic>> responses = new StreamController();
|
||||
daemon = new Daemon(
|
||||
commands.stream,
|
||||
(Map<String, dynamic> result) => responses.add(result),
|
||||
daemonCommand: command
|
||||
daemonCommand: command,
|
||||
appContext: appContext
|
||||
);
|
||||
|
||||
MockDeviceStore mockDevices = command.devices;
|
||||
@ -97,11 +108,12 @@ defineTests() {
|
||||
});
|
||||
|
||||
test('device.getDevices', () async {
|
||||
StreamController<Map> commands = new StreamController();
|
||||
StreamController<Map> responses = new StreamController();
|
||||
StreamController<Map<String, dynamic>> commands = new StreamController();
|
||||
StreamController<Map<String, dynamic>> responses = new StreamController();
|
||||
daemon = new Daemon(
|
||||
commands.stream,
|
||||
(Map<String, dynamic> result) => responses.add(result)
|
||||
(Map<String, dynamic> result) => responses.add(result),
|
||||
appContext: appContext
|
||||
);
|
||||
commands.add({'id': 0, 'method': 'device.getDevices'});
|
||||
Map response = await responses.stream.where(_notEvent).first;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Copyright 2016 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.
|
||||
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:flutter_tools/src/commands/install.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import 'src/mocks.dart';
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:flutter_tools/src/commands/list.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import 'src/mocks.dart';
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:flutter_tools/src/commands/listen.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import 'src/mocks.dart';
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:flutter_tools/src/commands/logs.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import 'src/mocks.dart';
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter_tools/src/base/os.dart';
|
||||
import 'package:test/test.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:test/test.dart';
|
||||
|
||||
main() => defineTests();
|
||||
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:flutter_tools/src/commands/stop.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import 'src/mocks.dart';
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:args/command_runner.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:flutter_tools/src/commands/trace.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import 'src/mocks.dart';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user