Commit f44ba8b9 authored by Jason Simmons's avatar Jason Simmons Committed by GitHub

Add a flutter doctor --android-licenses command that locates and runs the...

Add a flutter doctor --android-licenses command that locates and runs the Android SDK license manager (#9892)

See https://github.com/flutter/flutter/issues/8438
parent 5cec1080
......@@ -32,7 +32,7 @@ class AndroidWorkflow extends DoctorValidator implements Workflow {
static const String _kJdkDownload = 'https://www.oracle.com/technetwork/java/javase/downloads/';
/// First try Java bundled with Android Studio, then sniff JAVA_HOME, then fallback to PATH.
String _findJavaBinary() {
static String _findJavaBinary() {
if (android_studio.javaPath != null)
return fs.path.join(android_studio.javaPath, 'bin', 'java');
......@@ -163,4 +163,32 @@ class AndroidWorkflow extends DoctorValidator implements Workflow {
// Success.
return new ValidationResult(ValidationType.installed, messages, statusInfo: sdkVersionText);
}
/// Run the Android SDK manager tool in order to accept SDK licenses.
static Future<bool> runLicenseManager() async {
if (androidSdk == null) {
printStatus('Unable to locate Android SDK.');
return false;
}
// If we can locate Java, then add it to the path used to run the Android SDK manager.
final Map<String, String> sdkManagerEnv = <String, String>{};
final String javaBinary = _findJavaBinary();
if (javaBinary != null) {
sdkManagerEnv['PATH'] =
platform.environment['PATH'] + os.pathVarSeparator + fs.path.dirname(javaBinary);
}
final Process process = await Process.start(
fs.path.join(androidSdk.directory, 'tools', 'bin', 'sdkmanager'),
<String>['--licenses'],
environment: sdkManagerEnv,
);
stdout.addStream(process.stdout);
stderr.addStream(process.stderr);
process.stdin.addStream(stdin);
final int exitCode = await process.exitCode;
return exitCode == 0;
}
}
......@@ -61,6 +61,9 @@ abstract class OperatingSystemUtils {
}
List<File> _which(String execName, {bool all: false});
/// Returns the separator between items in the PATH environment variable.
String get pathVarSeparator;
}
class _PosixUtils extends OperatingSystemUtils {
......@@ -120,6 +123,9 @@ class _PosixUtils extends OperatingSystemUtils {
}
return _name;
}
@override
String get pathVarSeparator => ':';
}
class _WindowsUtils extends OperatingSystemUtils {
......@@ -193,6 +199,9 @@ class _WindowsUtils extends OperatingSystemUtils {
}
return _name;
}
@override
String get pathVarSeparator => ';';
}
/// Find and return the project root directory relative to the specified
......
......@@ -8,6 +8,13 @@ import '../doctor.dart';
import '../runner/flutter_command.dart';
class DoctorCommand extends FlutterCommand {
DoctorCommand() {
argParser.addFlag('android-licenses',
defaultsTo: false,
help: 'Run the Android SDK manager tool to accept the SDK\'s licenses.',
);
}
@override
final String name = 'doctor';
......@@ -16,7 +23,7 @@ class DoctorCommand extends FlutterCommand {
@override
Future<FlutterCommandResult> runCommand() async {
final bool success = await doctor.diagnose();
final bool success = await doctor.diagnose(androidLicenses: argResults['android-licenses']);
return new FlutterCommandResult(success ? ExitStatus.success : ExitStatus.warning);
}
}
......@@ -106,7 +106,10 @@ class Doctor {
}
/// Print verbose information about the state of installed tooling.
Future<bool> diagnose() async {
Future<bool> diagnose({ bool androidLicenses: false }) async {
if (androidLicenses)
return AndroidWorkflow.runLicenseManager();
bool doctorResult = true;
for (DoctorValidator validator in validators) {
......
......@@ -93,7 +93,7 @@ void main() {
testUsingContext('flutter commands send timing events', () async {
mockTimes = <int>[1000, 2000];
when(mockDoctor.diagnose()).thenReturn(true);
when(mockDoctor.diagnose(androidLicenses: false)).thenReturn(true);
final DoctorCommand command = new DoctorCommand();
final CommandRunner<Null> runner = createTestCommandRunner(command);
await runner.run(<String>['doctor']);
......@@ -112,7 +112,7 @@ void main() {
testUsingContext('doctor fail sends warning', () async {
mockTimes = <int>[1000, 2000];
when(mockDoctor.diagnose()).thenReturn(false);
when(mockDoctor.diagnose(androidLicenses: false)).thenReturn(false);
final DoctorCommand command = new DoctorCommand();
final CommandRunner<Null> runner = createTestCommandRunner(command);
await runner.run(<String>['doctor']);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment