Unverified Commit 65599e28 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] use less path manipulation in the Android SDK (#75930)

parent 2d9a01a8
...@@ -45,8 +45,8 @@ class AndroidSdk { ...@@ -45,8 +45,8 @@ class AndroidSdk {
static const String _javaHomeEnvironmentVariable = 'JAVA_HOME'; static const String _javaHomeEnvironmentVariable = 'JAVA_HOME';
static const String _javaExecutable = 'java'; static const String _javaExecutable = 'java';
/// The path to the Android SDK. /// The Android SDK root directory.
final String directory; final Directory directory;
List<AndroidSdkVersion> _sdkVersions; List<AndroidSdkVersion> _sdkVersions;
AndroidSdkVersion _latestVersion; AndroidSdkVersion _latestVersion;
...@@ -57,9 +57,8 @@ class AndroidSdk { ...@@ -57,9 +57,8 @@ class AndroidSdk {
/// the expectation that it will be downloaded later, e.g. by gradle or the /// the expectation that it will be downloaded later, e.g. by gradle or the
/// sdkmanager. The [licensesAvailable] property should be used to determine /// sdkmanager. The [licensesAvailable] property should be used to determine
/// whether the licenses are at least possibly accepted. /// whether the licenses are at least possibly accepted.
bool get platformToolsAvailable => bool get platformToolsAvailable => directory.childDirectory('cmdline-tools').existsSync()
globals.fs.directory(globals.fs.path.join(directory, 'cmdline-tools')).existsSync() || || directory.childDirectory('platform-tools').existsSync();
globals.fs.directory(globals.fs.path.join(directory, 'platform-tools')).existsSync();
/// Whether the `licenses` directory exists in the Android SDK. /// Whether the `licenses` directory exists in the Android SDK.
/// ///
...@@ -68,7 +67,7 @@ class AndroidSdk { ...@@ -68,7 +67,7 @@ class AndroidSdk {
/// from another workstation such as in CI scenarios. If these files are valid /// from another workstation such as in CI scenarios. If these files are valid
/// gradle or the sdkmanager will be able to download and use other parts of /// gradle or the sdkmanager will be able to download and use other parts of
/// the SDK on demand. /// the SDK on demand.
bool get licensesAvailable => globals.fs.directory(globals.fs.path.join(directory, 'licenses')).existsSync(); bool get licensesAvailable => directory.childDirectory('licenses').existsSync();
static AndroidSdk locateAndroidSdk() { static AndroidSdk locateAndroidSdk() {
String findAndroidHomeDir() { String findAndroidHomeDir() {
...@@ -149,7 +148,7 @@ class AndroidSdk { ...@@ -149,7 +148,7 @@ class AndroidSdk {
return null; return null;
} }
return AndroidSdk(androidHomeDir); return AndroidSdk(globals.fs.directory(androidHomeDir));
} }
static bool validSdkDirectory(String dir) { static bool validSdkDirectory(String dir) {
...@@ -200,7 +199,7 @@ class AndroidSdk { ...@@ -200,7 +199,7 @@ class AndroidSdk {
); );
} }
Directory get _platformsDir => globals.fs.directory(globals.fs.path.join(directory, 'platforms')); Directory get _platformsDir => directory.childDirectory('platforms');
Iterable<Directory> get _platforms { Iterable<Directory> get _platforms {
Iterable<Directory> platforms = <Directory>[]; Iterable<Directory> platforms = <Directory>[];
...@@ -236,9 +235,13 @@ class AndroidSdk { ...@@ -236,9 +235,13 @@ class AndroidSdk {
} }
String getPlatformToolsPath(String binaryName) { String getPlatformToolsPath(String binaryName) {
final String path = globals.fs.path.join(directory, 'platform-tools', binaryName); final File cmdlineToolsBinary = directory.childDirectory('cmdline-tools').childFile(binaryName);
if (globals.fs.file(path).existsSync()) { if (cmdlineToolsBinary.existsSync()) {
return path; return cmdlineToolsBinary.path;
}
final File platformToolBinary = directory.childDirectory('platform-tools').childFile(binaryName);
if (platformToolBinary.existsSync()) {
return platformToolBinary.path;
} }
return null; return null;
} }
...@@ -249,9 +252,9 @@ class AndroidSdk { ...@@ -249,9 +252,9 @@ class AndroidSdk {
// try both. // try both.
final List<String> searchFolders = <String>['emulator', 'tools']; final List<String> searchFolders = <String>['emulator', 'tools'];
for (final String folder in searchFolders) { for (final String folder in searchFolders) {
final String path = globals.fs.path.join(directory, folder, binaryName); final File file = directory.childDirectory(folder).childFile(binaryName);
if (globals.fs.file(path).existsSync()) { if (file.existsSync()) {
return path; return file.path;
} }
} }
return null; return null;
...@@ -259,9 +262,9 @@ class AndroidSdk { ...@@ -259,9 +262,9 @@ class AndroidSdk {
String getAvdManagerPath() { String getAvdManagerPath() {
final String binaryName = globals.platform.isWindows ? 'avdmanager.bat' : 'avdmanager'; final String binaryName = globals.platform.isWindows ? 'avdmanager.bat' : 'avdmanager';
final String path = globals.fs.path.join(directory, 'tools', 'bin', binaryName); final File file = directory.childDirectory('tools').childDirectory('bin').childFile(binaryName);
if (globals.fs.file(path).existsSync()) { if (file.existsSync()) {
return path; return file.path;
} }
return null; return null;
} }
...@@ -273,7 +276,7 @@ class AndroidSdk { ...@@ -273,7 +276,7 @@ class AndroidSdk {
void reinitialize() { void reinitialize() {
List<Version> buildTools = <Version>[]; // 19.1.0, 22.0.1, ... List<Version> buildTools = <Version>[]; // 19.1.0, 22.0.1, ...
final Directory buildToolsDir = globals.fs.directory(globals.fs.path.join(directory, 'build-tools')); final Directory buildToolsDir = directory.childDirectory('build-tools');
if (buildToolsDir.existsSync()) { if (buildToolsDir.existsSync()) {
buildTools = buildToolsDir buildTools = buildToolsDir
.listSync() .listSync()
...@@ -339,17 +342,22 @@ class AndroidSdk { ...@@ -339,17 +342,22 @@ class AndroidSdk {
/// The sdkmanager was previously in the tools directory but this component /// The sdkmanager was previously in the tools directory but this component
/// was marked as obsolete in 3.6. /// was marked as obsolete in 3.6.
String get sdkManagerPath { String get sdkManagerPath {
final File cmdlineTool = globals.fs.file( final String executable = globals.platform.isWindows
globals.fs.path.join(directory, 'cmdline-tools', 'latest', 'bin', ? 'sdkmanager.bat'
globals.platform.isWindows : 'sdkmanager';
? 'sdkmanager.bat' final File cmdlineTool = directory
: 'sdkmanager' .childDirectory('cmdline-tools')
), .childDirectory('latest')
); .childDirectory('bin')
.childFile(executable);
if (cmdlineTool.existsSync()) { if (cmdlineTool.existsSync()) {
return cmdlineTool.path; return cmdlineTool.path;
} }
return globals.fs.path.join(directory, 'tools', 'bin', 'sdkmanager'); return directory
.childDirectory('tools')
.childDirectory('bin')
.childFile(executable)
.path;
} }
/// First try Java bundled with Android Studio, then sniff JAVA_HOME, then fallback to PATH. /// First try Java bundled with Android Studio, then sniff JAVA_HOME, then fallback to PATH.
...@@ -477,11 +485,11 @@ class AndroidSdkVersion implements Comparable<AndroidSdkVersion> { ...@@ -477,11 +485,11 @@ class AndroidSdkVersion implements Comparable<AndroidSdkVersion> {
} }
String getPlatformsPath(String itemName) { String getPlatformsPath(String itemName) {
return _fileSystem.path.join(sdk.directory, 'platforms', platformName, itemName); return sdk.directory.childDirectory('platforms').childDirectory(platformName).childFile(itemName).path;
} }
String getBuildToolsPath(String binaryName) { String getBuildToolsPath(String binaryName) {
return _fileSystem.path.join(sdk.directory, 'build-tools', buildToolsVersionName, binaryName); return sdk.directory.childDirectory('build-tools').childDirectory(buildToolsVersionName).childFile(binaryName).path;
} }
@override @override
......
...@@ -189,7 +189,7 @@ class AndroidValidator extends DoctorValidator { ...@@ -189,7 +189,7 @@ class AndroidValidator extends DoctorValidator {
return ValidationResult(ValidationType.partial, messages); return ValidationResult(ValidationType.partial, messages);
} }
messages.add(ValidationMessage(_userMessages.androidSdkLocation(_androidSdk.directory))); messages.add(ValidationMessage(_userMessages.androidSdkLocation(_androidSdk.directory?.path)));
String sdkVersionText; String sdkVersionText;
if (_androidSdk.latestVersion != null) { if (_androidSdk.latestVersion != null) {
......
...@@ -240,7 +240,7 @@ void updateLocalProperties({ ...@@ -240,7 +240,7 @@ void updateLocalProperties({
} }
if (globals.androidSdk != null) { if (globals.androidSdk != null) {
changeIfNecessary('sdk.dir', globals.fsUtils.escapePath(globals.androidSdk.directory)); changeIfNecessary('sdk.dir', globals.fsUtils.escapePath(globals.androidSdk.directory.path));
} }
changeIfNecessary('flutter.sdk', globals.fsUtils.escapePath(Cache.flutterRoot)); changeIfNecessary('flutter.sdk', globals.fsUtils.escapePath(Cache.flutterRoot));
...@@ -271,7 +271,7 @@ void updateLocalProperties({ ...@@ -271,7 +271,7 @@ void updateLocalProperties({
void writeLocalProperties(File properties) { void writeLocalProperties(File properties) {
final SettingsFile settings = SettingsFile(); final SettingsFile settings = SettingsFile();
if (globals.androidSdk != null) { if (globals.androidSdk != null) {
settings.values['sdk.dir'] = globals.fsUtils.escapePath(globals.androidSdk.directory); settings.values['sdk.dir'] = globals.fsUtils.escapePath(globals.androidSdk.directory.path);
} }
settings.writeContents(properties); settings.writeContents(properties);
} }
......
...@@ -180,7 +180,7 @@ class ConfigCommand extends FlutterCommand { ...@@ -180,7 +180,7 @@ class ConfigCommand extends FlutterCommand {
results['android-studio-dir'] = androidStudio.directory; results['android-studio-dir'] = androidStudio.directory;
} }
if (results['android-sdk'] == null && globals.androidSdk != null) { if (results['android-sdk'] == null && globals.androidSdk != null) {
results['android-sdk'] = globals.androidSdk.directory; results['android-sdk'] = globals.androidSdk.directory.path;
} }
globals.printStatus(const JsonEncoder.withIndent(' ').convert(results)); globals.printStatus(const JsonEncoder.withIndent(' ').convert(results));
......
...@@ -10,6 +10,7 @@ import 'package:args/command_runner.dart'; ...@@ -10,6 +10,7 @@ import 'package:args/command_runner.dart';
import 'package:flutter_tools/src/android/android_sdk.dart'; import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/android/android_studio.dart'; import 'package:flutter_tools/src/android/android_studio.dart';
import 'package:flutter_tools/src/base/context.dart'; import 'package:flutter_tools/src/base/context.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/config.dart'; import 'package:flutter_tools/src/commands/config.dart';
...@@ -271,7 +272,7 @@ class MockAndroidStudio extends Mock implements AndroidStudio, Comparable<Androi ...@@ -271,7 +272,7 @@ class MockAndroidStudio extends Mock implements AndroidStudio, Comparable<Androi
class MockAndroidSdk extends Mock implements AndroidSdk { class MockAndroidSdk extends Mock implements AndroidSdk {
@override @override
String get directory => 'path/to/android/sdk'; Directory get directory => globals.fs.directory('path/to/android/sdk');
} }
class MockFlutterVersion extends Mock implements FlutterVersion {} class MockFlutterVersion extends Mock implements FlutterVersion {}
...@@ -227,7 +227,7 @@ void main() { ...@@ -227,7 +227,7 @@ void main() {
when(mockProcessManager.canRun(any)).thenReturn(false); when(mockProcessManager.canRun(any)).thenReturn(false);
mockAndroidSdk = MockAndroidSdk(); mockAndroidSdk = MockAndroidSdk();
when(mockAndroidSdk.directory).thenReturn('irrelevant'); when(mockAndroidSdk.directory).thenReturn(globals.fs.directory('irrelevant'));
}); });
tearDown(() { tearDown(() {
......
...@@ -174,7 +174,7 @@ void main() { ...@@ -174,7 +174,7 @@ void main() {
}); });
mockAndroidSdk = MockAndroidSdk(); mockAndroidSdk = MockAndroidSdk();
when(mockAndroidSdk.directory).thenReturn('irrelevant'); when(mockAndroidSdk.directory).thenReturn(globals.fs.directory('irrelevant'));
}); });
tearDown(() { tearDown(() {
......
...@@ -154,7 +154,7 @@ void main() { ...@@ -154,7 +154,7 @@ void main() {
when(mockAndroidSdk.licensesAvailable).thenReturn(true); when(mockAndroidSdk.licensesAvailable).thenReturn(true);
when(mockAndroidSdk.platformToolsAvailable).thenReturn(true); when(mockAndroidSdk.platformToolsAvailable).thenReturn(true);
when(mockAndroidSdk.validateSdkWellFormed()).thenReturn(const <String>[]); when(mockAndroidSdk.validateSdkWellFormed()).thenReturn(const <String>[]);
when(mockAndroidSdk.directory).thenReturn('irrelevant'); when(mockAndroidSdk.directory).thenReturn(globals.fs.directory('irrelevant'));
}); });
tearDown(() { tearDown(() {
......
...@@ -56,7 +56,7 @@ void main() { ...@@ -56,7 +56,7 @@ void main() {
logger: logger, logger: logger,
); );
when(mockAndroidSdk.directory).thenReturn('irrelevant'); when(mockAndroidSdk.directory).thenReturn(fileSystem.directory('irrelevant'));
final Directory rootDirectory = fileSystem.currentDirectory; final Directory rootDirectory = fileSystem.currentDirectory;
cache = Cache.test( cache = Cache.test(
......
...@@ -73,10 +73,10 @@ void main() { ...@@ -73,10 +73,10 @@ void main() {
final AndroidSdk sdk = AndroidSdk.locateAndroidSdk(); final AndroidSdk sdk = AndroidSdk.locateAndroidSdk();
fileSystem.file( fileSystem.file(
fileSystem.path.join(sdk.directory, 'cmdline-tools', 'latest', 'bin', 'sdkmanager') fileSystem.path.join(sdk.directory.path, 'cmdline-tools', 'latest', 'bin', 'sdkmanager')
).createSync(recursive: true); ).createSync(recursive: true);
expect(sdk.sdkManagerPath, fileSystem.path.join(sdk.directory, 'cmdline-tools', 'latest', 'bin', 'sdkmanager')); expect(sdk.sdkManagerPath, fileSystem.path.join(sdk.directory.path, 'cmdline-tools', 'latest', 'bin', 'sdkmanager'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
...@@ -90,11 +90,11 @@ void main() { ...@@ -90,11 +90,11 @@ void main() {
final AndroidSdk sdk = AndroidSdk.locateAndroidSdk(); final AndroidSdk sdk = AndroidSdk.locateAndroidSdk();
fileSystem.file( fileSystem.file(
fileSystem.path.join(sdk.directory, 'cmdline-tools', 'latest', 'bin', 'sdkmanager.bat') fileSystem.path.join(sdk.directory.path, 'cmdline-tools', 'latest', 'bin', 'sdkmanager.bat')
).createSync(recursive: true); ).createSync(recursive: true);
expect(sdk.sdkManagerPath, expect(sdk.sdkManagerPath,
fileSystem.path.join(sdk.directory, 'cmdline-tools', 'latest', 'bin', 'sdkmanager.bat')); fileSystem.path.join(sdk.directory.path, 'cmdline-tools', 'latest', 'bin', 'sdkmanager.bat'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
...@@ -102,17 +102,32 @@ void main() { ...@@ -102,17 +102,32 @@ void main() {
Config: () => config, Config: () => config,
}); });
testUsingContext('returns sdkmanager path under tools if cmdline doesnt exist', () { testUsingContext("returns sdkmanager path under tools if cmdline doesn't exist", () {
sdkDir = MockAndroidSdk.createSdkDirectory(); sdkDir = MockAndroidSdk.createSdkDirectory();
config.setValue('android-sdk', sdkDir.path); config.setValue('android-sdk', sdkDir.path);
final AndroidSdk sdk = AndroidSdk.locateAndroidSdk(); final AndroidSdk sdk = AndroidSdk.locateAndroidSdk();
expect(sdk.sdkManagerPath, fileSystem.path.join(sdk.directory, 'tools', 'bin', 'sdkmanager')); expect(sdk.sdkManagerPath, fileSystem.path.join(sdk.directory.path, 'tools', 'bin', 'sdkmanager'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FileSystem: () => fileSystem, FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(), ProcessManager: () => FakeProcessManager.any(),
Config: () => config, Config: () => config,
Platform: () => FakePlatform(operatingSystem: 'linux'),
});
testUsingContext("returns sdkmanager path under tools if cmdline doesn't exist on windows", () {
sdkDir = MockAndroidSdk.createSdkDirectory();
config.setValue('android-sdk', sdkDir.path);
final AndroidSdk sdk = AndroidSdk.locateAndroidSdk();
expect(sdk.sdkManagerPath, fileSystem.path.join(sdk.directory.path, 'tools', 'bin', 'sdkmanager.bat'));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
Config: () => config,
Platform: () => FakePlatform(operatingSystem: 'windows'),
}); });
testUsingContext('returns sdkmanager version', () { testUsingContext('returns sdkmanager version', () {
......
...@@ -841,7 +841,7 @@ flutter: ...@@ -841,7 +841,7 @@ flutter:
fs = MemoryFileSystem.test(); fs = MemoryFileSystem.test();
fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]); fakeProcessManager = FakeProcessManager.list(<FakeCommand>[]);
mockAndroidSdk = MockAndroidSdk(); mockAndroidSdk = MockAndroidSdk();
when(mockAndroidSdk.directory).thenReturn('irrelevant'); when(mockAndroidSdk.directory).thenReturn(fs.directory('irrelevant'));
builder = AndroidGradleBuilder(logger: logger); builder = AndroidGradleBuilder(logger: logger);
}); });
......
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