blob: 54f0bca13113706f04b3ef3e20056980fdbad6da [file] [log] [blame]
// Copyright 2014 The Flutter 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:file/file.dart';
import 'package:process/process.dart';
import '../base/common.dart';
import '../base/logger.dart';
import '../base/process.dart';
import '../globals.dart' as globals;
import 'fuchsia_sdk.dart';
// Usage: ffx [-c <config>] [-e <env>] [-t <target>] [-T <timeout>] [-v] [<command>] [<args>]
// Fuchsia's developer tool
// Options:
// -c, --config override default configuration
// -e, --env override default environment settings
// -t, --target apply operations across single or multiple targets
// -T, --timeout override default proxy timeout
// -v, --verbose use verbose output
// --help display usage information
// Commands:
// config View and switch default and user configurations
// daemon Interact with/control the ffx daemon
// target Interact with a target device or emulator
// session Control the current session. See
// https://fuchsia.dev/fuchsia-src/concepts/session/introduction
// for details.
/// A simple wrapper for the Fuchsia SDK's 'ffx' tool.
class FuchsiaFfx {
FuchsiaFfx({
FuchsiaArtifacts? fuchsiaArtifacts,
Logger? logger,
ProcessManager? processManager,
}) : _fuchsiaArtifacts = fuchsiaArtifacts ?? globals.fuchsiaArtifacts,
_logger = logger ?? globals.logger,
_processUtils = ProcessUtils(
logger: logger ?? globals.logger,
processManager: processManager ?? globals.processManager);
final FuchsiaArtifacts? _fuchsiaArtifacts;
final Logger _logger;
final ProcessUtils _processUtils;
/// Returns a list of attached devices as a list of strings with entries
/// formatted as follows:
///
/// abcd::abcd:abc:abcd:abcd%qemu scare-cable-skip-joy
Future<List<String>?> list({Duration? timeout}) async {
final File? ffx = _fuchsiaArtifacts?.ffx;
if (ffx == null || !ffx.existsSync()) {
throwToolExit('Fuchsia ffx tool not found.');
}
final List<String> command = <String>[
ffx.path,
if (timeout != null) ...<String>['-T', '${timeout.inSeconds}'],
'target',
'list',
// TODO(akbiggs): Revert -f back to --format once we've verified that
// analytics spam is coming from here.
'-f',
's',
];
final RunResult result = await _processUtils.run(command);
if (result.exitCode != 0) {
_logger.printError('ffx failed: ${result.stderr}');
return null;
}
if (result.stderr.contains('No devices found')) {
return null;
}
return result.stdout.split('\n');
}
/// Returns the address of the named device.
///
/// The string [deviceName] should be the name of the device from the
/// 'list' command, e.g. 'scare-cable-skip-joy'.
Future<String?> resolve(String deviceName) async {
final File? ffx = _fuchsiaArtifacts?.ffx;
if (ffx == null || !ffx.existsSync()) {
throwToolExit('Fuchsia ffx tool not found.');
}
final List<String> command = <String>[
ffx.path,
'target',
'list',
'-f',
'a',
deviceName,
];
final RunResult result = await _processUtils.run(command);
if (result.exitCode != 0) {
_logger.printError('ffx failed: ${result.stderr}');
return null;
}
return result.stdout.trim();
}
/// Show information about the current session
///
/// Returns `null` if the command failed, which can be interpreted as there is
/// no usable session.
Future<String?> sessionShow() async {
final File? ffx = _fuchsiaArtifacts?.ffx;
if (ffx == null || !ffx.existsSync()) {
throwToolExit('Fuchsia ffx tool not found.');
}
final List<String> command = <String>[
ffx.path,
'session',
'show',
];
final RunResult result = await _processUtils.run(command);
if (result.exitCode != 0) {
_logger.printError('ffx failed: ${result.stderr}');
return null;
}
return result.stdout;
}
/// Add an element to the current session
///
/// [url] should be formatted as a Fuchsia-style package URL, e.g.:
/// fuchsia-pkg://fuchsia.com/flutter_gallery#meta/flutter_gallery.cmx
/// Returns true on success and false on failure.
Future<bool> sessionAdd(String url) async {
final File? ffx = _fuchsiaArtifacts?.ffx;
if (ffx == null || !ffx.existsSync()) {
throwToolExit('Fuchsia ffx tool not found.');
}
final List<String> command = <String>[
ffx.path,
'session',
'add',
url,
];
final RunResult result = await _processUtils.run(command);
if (result.exitCode != 0) {
_logger.printError('ffx failed: ${result.stderr}');
return false;
}
return true;
}
}