Unverified Commit 390ed1cd authored by Zachary Anderson's avatar Zachary Anderson Committed by GitHub

[flutter_tools] Move homeDirPath to FileSystemUtils (#49909)

parent 3bee1903
......@@ -307,16 +307,31 @@ class AndroidSdk {
} else if (globals.platform.environment.containsKey(kAndroidSdkRoot)) {
androidHomeDir = globals.platform.environment[kAndroidSdkRoot];
} else if (globals.platform.isLinux) {
if (homeDirPath != null) {
androidHomeDir = globals.fs.path.join(homeDirPath, 'Android', 'Sdk');
if (globals.fsUtils.homeDirPath != null) {
androidHomeDir = globals.fs.path.join(
globals.fsUtils.homeDirPath,
'Android',
'Sdk',
);
}
} else if (globals.platform.isMacOS) {
if (homeDirPath != null) {
androidHomeDir = globals.fs.path.join(homeDirPath, 'Library', 'Android', 'sdk');
if (globals.fsUtils.homeDirPath != null) {
androidHomeDir = globals.fs.path.join(
globals.fsUtils.homeDirPath,
'Library',
'Android',
'sdk',
);
}
} else if (globals.platform.isWindows) {
if (homeDirPath != null) {
androidHomeDir = globals.fs.path.join(homeDirPath, 'AppData', 'Local', 'Android', 'sdk');
if (globals.fsUtils.homeDirPath != null) {
androidHomeDir = globals.fs.path.join(
globals.fsUtils.homeDirPath,
'AppData',
'Local',
'Android',
'sdk',
);
}
}
......
......@@ -2,7 +2,6 @@
// 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/file_system.dart';
import '../base/process.dart';
......@@ -67,8 +66,13 @@ class AndroidStudio implements Comparable<AndroidStudio> {
}
}
final String presetPluginsPath = pathsSelectorValue == null
? null
: globals.fs.path.join(homeDirPath, 'Library', 'Application Support', pathsSelectorValue);
? null
: globals.fs.path.join(
globals.fsUtils.homeDirPath,
'Library',
'Application Support',
pathsSelectorValue,
);
return AndroidStudio(studioPath, version: version, presetPluginsPath: presetPluginsPath);
}
......@@ -123,15 +127,18 @@ class AndroidStudio implements Comparable<AndroidStudio> {
final int minor = version?.minor;
if (globals.platform.isMacOS) {
return globals.fs.path.join(
homeDirPath,
'Library',
'Application Support',
'AndroidStudio$major.$minor');
globals.fsUtils.homeDirPath,
'Library',
'Application Support',
'AndroidStudio$major.$minor',
);
} else {
return globals.fs.path.join(homeDirPath,
'.$studioAppName$major.$minor',
'config',
'plugins');
return globals.fs.path.join(
globals.fsUtils.homeDirPath,
'.$studioAppName$major.$minor',
'config',
'plugins',
);
}
}
......@@ -198,7 +205,10 @@ class AndroidStudio implements Comparable<AndroidStudio> {
}
_checkForStudio('/Applications');
_checkForStudio(globals.fs.path.join(homeDirPath, 'Applications'));
_checkForStudio(globals.fs.path.join(
globals.fsUtils.homeDirPath,
'Applications',
));
final String configuredStudioDir = globals.config.getValue('android-studio-dir') as String;
if (configuredStudioDir != null) {
......@@ -235,14 +245,17 @@ class AndroidStudio implements Comparable<AndroidStudio> {
// Read all $HOME/.AndroidStudio*/system/.home files. There may be several
// pointing to the same installation, so we grab only the latest one.
if (homeDirPath != null && globals.fs.directory(homeDirPath).existsSync()) {
for (final FileSystemEntity entity in globals.fs.directory(homeDirPath).listSync(followLinks: false)) {
if (entity is Directory && entity.basename.startsWith('.AndroidStudio')) {
final AndroidStudio studio = AndroidStudio.fromHomeDot(entity);
if (studio != null && !_hasStudioAt(studio.directory, newerThan: studio.version)) {
studios.removeWhere((AndroidStudio other) => other.directory == studio.directory);
studios.add(studio);
}
if (globals.fsUtils.homeDirPath != null &&
globals.fs.directory(globals.fsUtils.homeDirPath).existsSync()) {
final Directory homeDir = globals.fs.directory(globals.fsUtils.homeDirPath);
for (final Directory entity in homeDir.listSync(followLinks: false).whereType<Directory>()) {
if (!entity.basename.startsWith('.AndroidStudio')) {
continue;
}
final AndroidStudio studio = AndroidStudio.fromHomeDot(entity);
if (studio != null && !_hasStudioAt(studio.directory, newerThan: studio.version)) {
studios.removeWhere((AndroidStudio other) => other.directory == studio.directory);
studios.add(studio);
}
}
}
......@@ -262,7 +275,7 @@ class AndroidStudio implements Comparable<AndroidStudio> {
// Add /opt/android-studio and $HOME/android-studio, if they exist.
_checkWellKnownPath('/opt/android-studio');
_checkWellKnownPath('$homeDirPath/android-studio');
_checkWellKnownPath('${globals.fsUtils.homeDirPath}/android-studio');
}
return studios;
}
......
......@@ -2,23 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '../globals.dart' as globals;
/// Whether the tool started from the daemon, as opposed to the command line.
// TODO(jonahwilliams): remove once IDE updates have rolled.
bool isRunningFromDaemon = false;
/// Return the absolute path of the user's home directory
String get homeDirPath {
String path = globals.platform.isWindows
? globals.platform.environment['USERPROFILE']
: globals.platform.environment['HOME'];
if (path != null) {
path = globals.fs.path.absolute(path);
}
return path;
}
/// Throw a specialized exception for expected situations
/// where the tool should exit with a clear message to the user
/// and no stack trace unless the --verbose option is specified.
......
......@@ -140,4 +140,15 @@ class FileSystemUtils {
final String envKey = _platform.operatingSystem == 'windows' ? 'APPDATA' : 'HOME';
return _platform.environment[envKey] ?? '.';
}
/// Return the absolute path of the user's home directory
String get homeDirPath {
String path = _platform.isWindows
? _platform.environment['USERPROFILE']
: _platform.environment['HOME'];
if (path != null) {
path = _fileSystem.path.absolute(path);
}
return path;
}
}
......@@ -8,7 +8,6 @@ import 'android/android_studio_validator.dart';
import 'android/android_workflow.dart';
import 'artifacts.dart';
import 'base/async_guard.dart';
import 'base/common.dart';
import 'base/context.dart';
import 'base/file_system.dart';
import 'base/logger.dart';
......@@ -748,7 +747,7 @@ class IntelliJValidatorOnLinuxAndWindows extends IntelliJValidator {
static Iterable<DoctorValidator> get installed {
final List<DoctorValidator> validators = <DoctorValidator>[];
if (homeDirPath == null) {
if (globals.fsUtils.homeDirPath == null) {
return validators;
}
......@@ -767,25 +766,24 @@ class IntelliJValidatorOnLinuxAndWindows extends IntelliJValidator {
validators.add(validator);
}
for (final FileSystemEntity dir in globals.fs.directory(homeDirPath).listSync()) {
if (dir is Directory) {
final String name = globals.fs.path.basename(dir.path);
IntelliJValidator._idToTitle.forEach((String id, String title) {
if (name.startsWith('.$id')) {
final String version = name.substring(id.length + 1);
String installPath;
try {
installPath = globals.fs.file(globals.fs.path.join(dir.path, 'system', '.home')).readAsStringSync();
} catch (e) {
// ignored
}
if (installPath != null && globals.fs.isDirectorySync(installPath)) {
final String pluginsPath = globals.fs.path.join(dir.path, 'config', 'plugins');
addValidator(title, version, installPath, pluginsPath);
}
final Directory homeDir = globals.fs.directory(globals.fsUtils.homeDirPath);
for (final Directory dir in homeDir.listSync().whereType<Directory>()) {
final String name = globals.fs.path.basename(dir.path);
IntelliJValidator._idToTitle.forEach((String id, String title) {
if (name.startsWith('.$id')) {
final String version = name.substring(id.length + 1);
String installPath;
try {
installPath = globals.fs.file(globals.fs.path.join(dir.path, 'system', '.home')).readAsStringSync();
} catch (e) {
// ignored
}
});
}
if (installPath != null && globals.fs.isDirectorySync(installPath)) {
final String pluginsPath = globals.fs.path.join(dir.path, 'config', 'plugins');
addValidator(title, version, installPath, pluginsPath);
}
}
});
}
return validators;
}
......@@ -804,7 +802,10 @@ class IntelliJValidatorOnMac extends IntelliJValidator {
static Iterable<DoctorValidator> get installed {
final List<DoctorValidator> validators = <DoctorValidator>[];
final List<String> installPaths = <String>['/Applications', globals.fs.path.join(homeDirPath, 'Applications')];
final List<String> installPaths = <String>[
'/Applications',
globals.fs.path.join(globals.fsUtils.homeDirPath, 'Applications'),
];
void checkForIntelliJ(Directory dir) {
final String name = globals.fs.path.basename(dir.path);
......@@ -861,7 +862,12 @@ class IntelliJValidatorOnMac extends IntelliJValidator {
final List<String> split = version.split('.');
final String major = split[0];
final String minor = split[1];
return globals.fs.path.join(homeDirPath, 'Library', 'Application Support', '$id$major.$minor');
return globals.fs.path.join(
globals.fsUtils.homeDirPath,
'Library',
'Application Support',
'$id$major.$minor',
);
}
}
......
......@@ -471,8 +471,15 @@ class IOSSimulator extends Device {
String get logFilePath {
return globals.platform.environment.containsKey('IOS_SIMULATOR_LOG_FILE_PATH')
? globals.platform.environment['IOS_SIMULATOR_LOG_FILE_PATH'].replaceAll('%{id}', id)
: globals.fs.path.join(homeDirPath, 'Library', 'Logs', 'CoreSimulator', id, 'system.log');
? globals.platform.environment['IOS_SIMULATOR_LOG_FILE_PATH'].replaceAll('%{id}', id)
: globals.fs.path.join(
globals.fsUtils.homeDirPath,
'Library',
'Logs',
'CoreSimulator',
id,
'system.log',
);
}
@override
......
......@@ -129,7 +129,7 @@ class CocoaPods {
return true;
}
final String cocoapodsReposDir = globals.platform.environment['CP_REPOS_DIR']
?? globals.fs.path.join(homeDirPath, '.cocoapods', 'repos');
?? globals.fs.path.join(globals.fsUtils.homeDirPath, '.cocoapods', 'repos');
return globals.fs.isDirectory(globals.fs.path.join(cocoapodsReposDir, 'master'));
}
......
......@@ -2,7 +2,6 @@
// 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/file_system.dart';
import '../base/utils.dart';
import '../base/version.dart';
......@@ -116,7 +115,12 @@ class VsCode {
'.vscode',
),
_VsCodeInstallLocation(
globals.fs.path.join(homeDirPath, 'Applications', 'Visual Studio Code.app', 'Contents'),
globals.fs.path.join(
globals.fsUtils.homeDirPath,
'Applications',
'Visual Studio Code.app',
'Contents',
),
'.vscode',
),
_VsCodeInstallLocation(
......@@ -125,7 +129,12 @@ class VsCode {
isInsiders: true,
),
_VsCodeInstallLocation(
globals.fs.path.join(homeDirPath, 'Applications', 'Visual Studio Code - Insiders.app', 'Contents'),
globals.fs.path.join(
globals.fsUtils.homeDirPath,
'Applications',
'Visual Studio Code - Insiders.app',
'Contents',
),
'.vscode-insiders',
isInsiders: true,
),
......@@ -154,31 +163,39 @@ class VsCode {
if (localAppData != null) {
searchLocations.add(_VsCodeInstallLocation(
globals.fs.path.join(localAppData, 'Programs\\Microsoft VS Code'),
'.vscode'));
globals.fs.path.join(localAppData, 'Programs\\Microsoft VS Code'),
'.vscode',
));
}
searchLocations.add(_VsCodeInstallLocation(
globals.fs.path.join(progFiles86, 'Microsoft VS Code'), '.vscode',
edition: '32-bit edition'));
globals.fs.path.join(progFiles86, 'Microsoft VS Code'),
'.vscode',
edition: '32-bit edition',
));
searchLocations.add(_VsCodeInstallLocation(
globals.fs.path.join(progFiles, 'Microsoft VS Code'), '.vscode',
edition: '64-bit edition'));
globals.fs.path.join(progFiles, 'Microsoft VS Code'),
'.vscode',
edition: '64-bit edition',
));
if (localAppData != null) {
searchLocations.add(_VsCodeInstallLocation(
globals.fs.path.join(localAppData, 'Programs\\Microsoft VS Code Insiders'),
'.vscode-insiders',
isInsiders: true));
globals.fs.path.join(localAppData, 'Programs\\Microsoft VS Code Insiders'),
'.vscode-insiders',
isInsiders: true,
));
}
searchLocations.add(_VsCodeInstallLocation(
globals.fs.path.join(progFiles86, 'Microsoft VS Code Insiders'),
'.vscode-insiders',
edition: '32-bit edition',
isInsiders: true));
globals.fs.path.join(progFiles86, 'Microsoft VS Code Insiders'),
'.vscode-insiders',
edition: '32-bit edition',
isInsiders: true,
));
searchLocations.add(_VsCodeInstallLocation(
globals.fs.path.join(progFiles, 'Microsoft VS Code Insiders'),
'.vscode-insiders',
edition: '64-bit edition',
isInsiders: true));
globals.fs.path.join(progFiles, 'Microsoft VS Code Insiders'),
'.vscode-insiders',
edition: '64-bit edition',
isInsiders: true,
));
return _findInstalled(searchLocations);
}
......@@ -192,7 +209,11 @@ class VsCode {
static List<VsCode> _installedLinux() {
return _findInstalled(<_VsCodeInstallLocation>[
const _VsCodeInstallLocation('/usr/share/code', '.vscode'),
const _VsCodeInstallLocation('/usr/share/code-insiders', '.vscode-insiders', isInsiders: true),
const _VsCodeInstallLocation(
'/usr/share/code-insiders',
'.vscode-insiders',
isInsiders: true,
),
]);
}
......@@ -206,9 +227,16 @@ class VsCode {
for (final _VsCodeInstallLocation searchLocation in searchLocations) {
if (globals.fs.isDirectorySync(searchLocation.installPath)) {
final String extensionDirectory =
globals.fs.path.join(homeDirPath, searchLocation.extensionsFolder, 'extensions');
results.add(VsCode.fromDirectory(searchLocation.installPath, extensionDirectory, edition: searchLocation.edition));
final String extensionDirectory = globals.fs.path.join(
globals.fsUtils.homeDirPath,
searchLocation.extensionsFolder,
'extensions',
);
results.add(VsCode.fromDirectory(
searchLocation.installPath,
extensionDirectory,
edition: searchLocation.edition,
));
}
}
......@@ -235,8 +263,13 @@ class VsCode {
}
class _VsCodeInstallLocation {
const _VsCodeInstallLocation(this.installPath, this.extensionsFolder, { this.edition, bool isInsiders })
: isInsiders = isInsiders ?? false;
const _VsCodeInstallLocation(
this.installPath,
this.extensionsFolder, {
this.edition,
bool isInsiders
}) : isInsiders = isInsiders ?? false;
final String installPath;
final String extensionsFolder;
final String edition;
......
......@@ -76,27 +76,56 @@ void main() {
});
group('pluginsPath on Mac', () {
FileSystemUtils fsUtils;
Platform platform;
setUp(() {
platform = macPlatform();
fsUtils = FileSystemUtils(
fileSystem: fs,
platform: platform,
);
});
testUsingContext('extracts custom paths for directly downloaded Android Studio on Mac', () {
final String studioInApplicationPlistFolder = globals.fs.path.join('/', 'Application', 'Android Studio.app', 'Contents');
final String studioInApplicationPlistFolder = globals.fs.path.join(
'/',
'Application',
'Android Studio.app',
'Contents',
);
globals.fs.directory(studioInApplicationPlistFolder).createSync(recursive: true);
final String plistFilePath = globals.fs.path.join(studioInApplicationPlistFolder, 'Info.plist');
when(plistUtils.parseFile(plistFilePath)).thenReturn(macStudioInfoPlist);
final AndroidStudio studio = AndroidStudio.fromMacOSBundle(globals.fs.directory(studioInApplicationPlistFolder)?.parent?.path);
final AndroidStudio studio = AndroidStudio.fromMacOSBundle(
globals.fs.directory(studioInApplicationPlistFolder)?.parent?.path,
);
expect(studio, isNotNull);
expect(studio.pluginsPath,
equals(globals.fs.path.join(homeMac, 'Library', 'Application Support', 'AndroidStudio3.3')));
expect(studio.pluginsPath, equals(globals.fs.path.join(
homeMac,
'Library',
'Application Support',
'AndroidStudio3.3',
)));
}, overrides: <Type, Generator>{
FileSystem: () => fs,
FileSystemUtils: () => fsUtils,
ProcessManager: () => FakeProcessManager.any(),
// Custom home paths are not supported on macOS nor Windows yet,
// so we force the platform to fake Linux here.
Platform: () => macPlatform(),
Platform: () => platform,
PlistParser: () => plistUtils,
});
testUsingContext('extracts custom paths for Android Studio downloaded by JetBrainsToolbox on Mac', () {
final String jetbrainsStudioInApplicationPlistFolder = globals.fs.path.join(homeMac, 'Application', 'JetBrains Toolbox', 'Android Studio.app', 'Contents');
final String jetbrainsStudioInApplicationPlistFolder = globals.fs.path.join(
homeMac,
'Application',
'JetBrains Toolbox',
'Android Studio.app',
'Contents',
);
globals.fs.directory(jetbrainsStudioInApplicationPlistFolder).createSync(recursive: true);
const Map<String, dynamic> jetbrainsInfoPlist = <String, dynamic>{
'CFBundleLongVersionString': '3.3',
......@@ -104,24 +133,46 @@ void main() {
'CFBundleVersion': '3.3',
'JetBrainsToolboxApp': '$homeMac/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/183.5256920/Android Studio 3.3.app',
};
final String jetbrainsPlistFilePath = globals.fs.path.join(jetbrainsStudioInApplicationPlistFolder, 'Info.plist');
final String jetbrainsPlistFilePath = globals.fs.path.join(
jetbrainsStudioInApplicationPlistFolder,
'Info.plist',
);
when(plistUtils.parseFile(jetbrainsPlistFilePath)).thenReturn(jetbrainsInfoPlist);
final String studioInApplicationPlistFolder = globals.fs.path.join(globals.fs.path.join(homeMac, 'Library', 'Application Support'), 'JetBrains', 'Toolbox', 'apps', 'AndroidStudio', 'ch-0', '183.5256920', globals.fs.path.join('Android Studio 3.3.app', 'Contents'));
final String studioInApplicationPlistFolder = globals.fs.path.join(
globals.fs.path.join(homeMac,'Library','Application Support'),
'JetBrains',
'Toolbox',
'apps',
'AndroidStudio',
'ch-0',
'183.5256920',
globals.fs.path.join('Android Studio 3.3.app', 'Contents'),
);
globals.fs.directory(studioInApplicationPlistFolder).createSync(recursive: true);
final String studioPlistFilePath = globals.fs.path.join(studioInApplicationPlistFolder, 'Info.plist');
final String studioPlistFilePath = globals.fs.path.join(
studioInApplicationPlistFolder,
'Info.plist',
);
when(plistUtils.parseFile(studioPlistFilePath)).thenReturn(macStudioInfoPlist);
final AndroidStudio studio = AndroidStudio.fromMacOSBundle(globals.fs.directory(jetbrainsStudioInApplicationPlistFolder)?.parent?.path);
final AndroidStudio studio = AndroidStudio.fromMacOSBundle(
globals.fs.directory(jetbrainsStudioInApplicationPlistFolder)?.parent?.path,
);
expect(studio, isNotNull);
expect(studio.pluginsPath,
equals(globals.fs.path.join(homeMac, 'Library', 'Application Support', 'AndroidStudio3.3')));
expect(studio.pluginsPath, equals(globals.fs.path.join(
homeMac,
'Library',
'Application Support',
'AndroidStudio3.3',
)));
}, overrides: <Type, Generator>{
FileSystem: () => fs,
FileSystemUtils: () => fsUtils,
ProcessManager: () => FakeProcessManager.any(),
// Custom home paths are not supported on macOS nor Windows yet,
// so we force the platform to fake Linux here.
Platform: () => macPlatform(),
Platform: () => platform,
PlistParser: () => plistUtils,
});
......
......@@ -13,6 +13,7 @@ import 'package:process/process.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/macos/cocoapods.dart';
import 'package:flutter_tools/src/plugins.dart';
......@@ -40,11 +41,21 @@ void main() {
}
void podsIsInHomeDir() {
fs.directory(fs.path.join(homeDirPath, '.cocoapods', 'repos', 'master')).createSync(recursive: true);
fs.directory(fs.path.join(
globals.fsUtils.homeDirPath,
'.cocoapods',
'repos',
'master',
)).createSync(recursive: true);
}
String podsIsInCustomDir({String cocoapodsReposDir}) {
cocoapodsReposDir ??= fs.path.join(homeDirPath, 'cache', 'cocoapods', 'repos');
cocoapodsReposDir ??= fs.path.join(
globals.fsUtils.homeDirPath,
'cache',
'cocoapods',
'repos',
);
fs.directory(fs.path.join(cocoapodsReposDir, 'master')).createSync(recursive: true);
return cocoapodsReposDir;
}
......
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