mirror of
https://github.com/flutter/flutter
synced 2024-10-13 19:52:53 +00:00
Support for fuchsia device discovery, workflow, and sdk wrapper (#23282)
This commit is contained in:
parent
43c99404c5
commit
b7c9c96c6b
|
@ -26,6 +26,8 @@ import 'devfs.dart';
|
|||
import 'device.dart';
|
||||
import 'doctor.dart';
|
||||
import 'emulator.dart';
|
||||
import 'fuchsia/fuchsia_sdk.dart';
|
||||
import 'fuchsia/fuchsia_workflow.dart';
|
||||
import 'ios/cocoapods.dart';
|
||||
import 'ios/ios_workflow.dart';
|
||||
import 'ios/mac.dart';
|
||||
|
@ -62,6 +64,8 @@ Future<T> runInContext<T>(
|
|||
Doctor: () => const Doctor(),
|
||||
DoctorValidatorsProvider: () => DoctorValidatorsProvider.defaultInstance,
|
||||
EmulatorManager: () => EmulatorManager(),
|
||||
FuchsiaSdk: () => FuchsiaSdk(),
|
||||
FuchsiaWorkflow: () => FuchsiaWorkflow(),
|
||||
Flags: () => const EmptyFlags(),
|
||||
FlutterVersion: () => FlutterVersion(const Clock()),
|
||||
GenSnapshot: () => const GenSnapshot(),
|
||||
|
|
|
@ -11,6 +11,8 @@ import 'base/context.dart';
|
|||
import 'base/file_system.dart';
|
||||
import 'base/utils.dart';
|
||||
import 'build_info.dart';
|
||||
import 'fuchsia/fuchsia_device.dart';
|
||||
|
||||
import 'globals.dart';
|
||||
import 'ios/devices.dart';
|
||||
import 'ios/simulators.dart';
|
||||
|
@ -27,6 +29,7 @@ class DeviceManager {
|
|||
_deviceDiscoverers.add(AndroidDevices());
|
||||
_deviceDiscoverers.add(IOSDevices());
|
||||
_deviceDiscoverers.add(IOSSimulators());
|
||||
_deviceDiscoverers.add(FuchsiaDevices());
|
||||
_deviceDiscoverers.add(FlutterTesterDevices());
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import 'base/utils.dart';
|
|||
import 'base/version.dart';
|
||||
import 'cache.dart';
|
||||
import 'device.dart';
|
||||
import 'fuchsia/fuchsia_workflow.dart';
|
||||
import 'globals.dart';
|
||||
import 'intellij/intellij.dart';
|
||||
import 'ios/ios_workflow.dart';
|
||||
|
@ -80,6 +81,9 @@ class _DefaultDoctorValidatorsProvider implements DoctorValidatorsProvider {
|
|||
|
||||
if (androidWorkflow.appliesToHostPlatform)
|
||||
_workflows.add(androidWorkflow);
|
||||
|
||||
if (fuchsiaWorkflow.appliesToHostPlatform)
|
||||
_workflows.add(fuchsiaWorkflow);
|
||||
}
|
||||
return _workflows;
|
||||
}
|
||||
|
|
|
@ -4,10 +4,16 @@
|
|||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import '../application_package.dart';
|
||||
import '../base/platform.dart';
|
||||
import '../build_info.dart';
|
||||
import '../device.dart';
|
||||
|
||||
import 'fuchsia_sdk.dart';
|
||||
import 'fuchsia_workflow.dart';
|
||||
|
||||
/// Read the log for a particular device.
|
||||
class _FuchsiaLogReader extends DeviceLogReader {
|
||||
_FuchsiaLogReader(this._device);
|
||||
|
@ -27,6 +33,49 @@ class _FuchsiaLogReader extends DeviceLogReader {
|
|||
String toString() => name;
|
||||
}
|
||||
|
||||
class FuchsiaDevices extends PollingDeviceDiscovery {
|
||||
FuchsiaDevices() : super('Fuchsia devices');
|
||||
|
||||
@override
|
||||
bool get supportsPlatform => platform.isLinux || platform.isMacOS;
|
||||
|
||||
@override
|
||||
bool get canListAnything => fuchsiaWorkflow.canListDevices;
|
||||
|
||||
@override
|
||||
Future<List<Device>> pollingGetDevices() async {
|
||||
if (!fuchsiaWorkflow.canListDevices) {
|
||||
return <Device>[];
|
||||
}
|
||||
final String text = await fuchsiaSdk.netls();
|
||||
return parseFuchsiaDeviceOutput(text);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<String>> getDiagnostics() async => const <String>[];
|
||||
}
|
||||
|
||||
/// Parses output from the netls tool into fuchsia devices.
|
||||
///
|
||||
/// Example output:
|
||||
/// $ ./netls
|
||||
/// > device liliac-shore-only-last (fe80::82e4:da4d:fe81:227d/3)
|
||||
@visibleForTesting
|
||||
List<FuchsiaDevice> parseFuchsiaDeviceOutput(String text) {
|
||||
final List<FuchsiaDevice> devices = <FuchsiaDevice>[];
|
||||
for (String rawLine in text.trim().split('\n')) {
|
||||
final String line = rawLine.trim();
|
||||
if (!line.startsWith('device'))
|
||||
continue;
|
||||
// ['device', 'device name', '(id)']
|
||||
final List<String> words = line.split(' ');
|
||||
final String name = words[1];
|
||||
final String id = words[2].substring(1, words[2].length - 1);
|
||||
devices.add(FuchsiaDevice(id, name: name));
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
|
||||
class FuchsiaDevice extends Device {
|
||||
FuchsiaDevice(String id, { this.name }) : super(id);
|
||||
|
||||
|
|
54
packages/flutter_tools/lib/src/fuchsia/fuchsia_sdk.dart
Normal file
54
packages/flutter_tools/lib/src/fuchsia/fuchsia_sdk.dart
Normal file
|
@ -0,0 +1,54 @@
|
|||
// Copyright 2018 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 '../base/common.dart';
|
||||
import '../base/context.dart';
|
||||
import '../base/process.dart';
|
||||
|
||||
/// The [FuchsiaSdk] instance.
|
||||
FuchsiaSdk get fuchsiaSdk => context[FuchsiaSdk];
|
||||
|
||||
/// The Fuchsia SDK shell commands.
|
||||
///
|
||||
/// This workflow assumes development within the fuchsia source tree,
|
||||
/// including a working fx command-line tool in the user's PATH.
|
||||
class FuchsiaSdk {
|
||||
|
||||
/// Invokes the `netaddr` command.
|
||||
///
|
||||
/// This returns the network address of an attached fuchsia device. Does
|
||||
/// not currently support multiple attached devices.
|
||||
///
|
||||
/// Example output:
|
||||
/// $ fx netaddr --fuchsia
|
||||
/// > fe80::9aaa:fcff:fe60:d3af%eth1
|
||||
Future<String> netaddr() async {
|
||||
try {
|
||||
final RunResult process = await runAsync(<String>['fx', 'netaddr', '--fuchsia', '--nowait']);
|
||||
return process.stdout;
|
||||
} on ArgumentError catch (exception) {
|
||||
throwToolExit('$exception');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Invokes the `netls` command.
|
||||
///
|
||||
/// This lists attached fuchsia devices with their name and address. Does
|
||||
/// not currently support multiple attached devices.
|
||||
///
|
||||
/// Example output:
|
||||
/// $ fx netls
|
||||
/// > device liliac-shore-only-last (fe80::82e4:da4d:fe81:227d/3)
|
||||
Future<String> netls() async {
|
||||
try {
|
||||
final RunResult process = await runAsync(
|
||||
<String>['fx', 'netls', '--nowait']);
|
||||
return process.stdout;
|
||||
} on ArgumentError catch (exception) {
|
||||
throwToolExit('$exception');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
34
packages/flutter_tools/lib/src/fuchsia/fuchsia_workflow.dart
Normal file
34
packages/flutter_tools/lib/src/fuchsia/fuchsia_workflow.dart
Normal file
|
@ -0,0 +1,34 @@
|
|||
// Copyright 2018 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 '../base/context.dart';
|
||||
import '../base/os.dart';
|
||||
import '../base/platform.dart';
|
||||
import '../doctor.dart';
|
||||
|
||||
/// The [FuchsiaWorkflow] instance.
|
||||
FuchsiaWorkflow get fuchsiaWorkflow => context[FuchsiaWorkflow];
|
||||
|
||||
/// The Fuchsia-specific implementation of a [Workflow].
|
||||
///
|
||||
/// This workflow assumes development within the fuchsia source tree,
|
||||
/// including a working fx command-line tool in the user's PATH.
|
||||
class FuchsiaWorkflow implements Workflow {
|
||||
|
||||
@override
|
||||
bool get appliesToHostPlatform => platform.isLinux || platform.isMacOS;
|
||||
|
||||
@override
|
||||
bool get canListDevices {
|
||||
return os.which('fx') != null;
|
||||
}
|
||||
|
||||
@override
|
||||
bool get canLaunchDevices {
|
||||
return os.which('fx') != null;
|
||||
}
|
||||
|
||||
@override
|
||||
bool get canListEmulators => false;
|
||||
}
|
29
packages/flutter_tools/test/fuchsia/fuchsa_device_test.dart
Normal file
29
packages/flutter_tools/test/fuchsia/fuchsa_device_test.dart
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2018 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:flutter_tools/src/fuchsia/fuchsia_device.dart';
|
||||
|
||||
import '../src/common.dart';
|
||||
import '../src/context.dart';
|
||||
|
||||
void main() {
|
||||
group('fuchsia device', () {
|
||||
testUsingContext('stores the requested id and name', () {
|
||||
const String deviceId = 'e80::0000:a00a:f00f:2002/3';
|
||||
const String name = 'halfbaked';
|
||||
final FuchsiaDevice device = FuchsiaDevice(deviceId, name: name);
|
||||
expect(device.id, deviceId);
|
||||
expect(device.name, name);
|
||||
});
|
||||
|
||||
test('parse netls log output', () {
|
||||
const String example = 'device lilia-shore-only-last (fe80::0000:a00a:f00f:2002/3)';
|
||||
final List<FuchsiaDevice> devices = parseFuchsiaDeviceOutput(example);
|
||||
|
||||
expect(devices.length, 1);
|
||||
expect(devices.first.id, 'fe80::0000:a00a:f00f:2002/3');
|
||||
expect(devices.first.name, 'lilia-shore-only-last');
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright 2018 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:flutter_tools/src/base/file_system.dart';
|
||||
import 'package:flutter_tools/src/base/os.dart';
|
||||
import 'package:flutter_tools/src/fuchsia/fuchsia_workflow.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import '../src/common.dart';
|
||||
import '../src/context.dart';
|
||||
|
||||
class MockOperatingSystemUtils extends Mock implements OperatingSystemUtils {}
|
||||
class MockFile extends Mock implements File {}
|
||||
|
||||
void main() {
|
||||
bool fxPresent = false;
|
||||
final MockOperatingSystemUtils utils = MockOperatingSystemUtils();
|
||||
final MockFile file = MockFile();
|
||||
when(utils.which('fx')).thenAnswer((Invocation _) => fxPresent ? file : null);
|
||||
|
||||
group('android workflow', () {
|
||||
testUsingContext('can not list and launch devices if there is no `fx` command', () {
|
||||
fxPresent = false;
|
||||
expect(fuchsiaWorkflow.canLaunchDevices, false);
|
||||
expect(fuchsiaWorkflow.canListDevices, false);
|
||||
expect(fuchsiaWorkflow.canListEmulators, false);
|
||||
}, overrides: <Type, Generator>{
|
||||
OperatingSystemUtils: () => utils,
|
||||
});
|
||||
|
||||
testUsingContext('can list and launch devices supported if there is a `fx` command', () {
|
||||
fxPresent = true;
|
||||
expect(fuchsiaWorkflow.canLaunchDevices, true);
|
||||
expect(fuchsiaWorkflow.canListDevices, true);
|
||||
expect(fuchsiaWorkflow.canListEmulators, false);
|
||||
}, overrides: <Type, Generator>{
|
||||
OperatingSystemUtils: () => utils,
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in a new issue