Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android Studio Integration #576

Merged
merged 4 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ const kFvmLegacyConfigFileName = 'fvm_config.json';
/// Vscode name
const kVsCode = 'VSCode';

/// IntelliJ name
const kIntelliJ = 'IntelliJ (Android Studio, ...)';

/// Environment variables
final _env = Platform.environment;

Expand Down
38 changes: 36 additions & 2 deletions lib/src/commands/doctor_command.dart
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class DoctorCommand extends BaseCommand {
table.insertRow([kVsCode, 'No .vscode directory found']);
}

table.insertRow(['Android Studio']);
table.insertRow([kIntelliJ]);

// Get localproperties file within flutter project
final localPropertiesFile =
Expand All @@ -140,11 +140,45 @@ class DoctorCommand extends BaseCommand {
table.insertRow(['Matches pinned version:', sdkPath == resolvedLink]);
} else {
table.insertRow([
'Android Studio',
kIntelliJ,
'No local.properties file found in android directory'
]);
}

final dartSdkFile = File(join(project.path, '.idea', 'libraries', 'Dart_SDK.xml'));

if (dartSdkFile.existsSync()) {
final dartSdk = dartSdkFile.readAsStringSync();
final containsUserHome = dartSdk.contains(r'$USER_HOME$');
final containsProjectDir = dartSdk.contains(r'$PROJECT_DIR$');
final containsSymLinkName = dartSdk.contains('.fvm/flutter_sdk');

if (!containsUserHome && containsProjectDir) {
if (containsSymLinkName) {
table.insertRow([
'SDK Path',
'SDK Path points to project directory. $kIntelliJ will dynamically switch SDK when using "fvm use"'
]);
}
else {
table.insertRow([
'SDK Path',
'SDK Path points to project directory, but does not use the flutter_sdk symlink. Using "fvm use" will break the project. Please consult documentation.'
]);
}
} else {
table.insertRow([
'SDK Path',
'SDK Path does not point to the project directory. "fvm use" will not make $kIntelliJ switch Flutter version. Please consult documentation.'
]);
}
} else {
table.insertRow([
kIntelliJ,
'No .idea folder found'
]);
}

logger.write(table.toString());
}

Expand Down
40 changes: 27 additions & 13 deletions lib/src/workflows/use_version.workflow.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ Future<void> useVersionWorkflow({
updatedProject,
version,
);
_updateCurrentSdkReference(
updatedProject,
version
);

_manageVscodeSettings(updatedProject);

Expand Down Expand Up @@ -253,17 +257,6 @@ void _checkProjectVersionConstraints(
///
/// Throws an [AppException] if the project doesn't have a pinned Flutter SDK version.
void _updateLocalSdkReference(Project project, CacheFlutterVersion version) {
// Legacy link for fvm < 3.0.0
final legacyLink = join(
project.localFvmPath,
'flutter_sdk',
);

// Clean up pre 3.0 links
if (legacyLink.link.existsSync()) {
legacyLink.link.deleteSync();
}

if (project.localFvmPath.file.existsSync()) {
project.localFvmPath.file.createSync(recursive: true);
}
Expand All @@ -285,12 +278,33 @@ void _updateLocalSdkReference(Project project, CacheFlutterVersion version) {
);
}

/// Updates the `flutter_sdk` link to ensure it always points to the pinned SDK version.
///
/// This is required for Android Studio to work with different Flutter SDK versions.
///
/// Throws an [AppException] if the project doesn't have a pinned Flutter SDK version.
void _updateCurrentSdkReference(Project project, CacheFlutterVersion version) {
final currentSdkLink = join(
project.localFvmPath,
'flutter_sdk',
);

if (currentSdkLink.link.existsSync()) {
currentSdkLink.link.deleteSync();
}

if (!ctx.priviledgedAccess) return;

currentSdkLink.link.createLink(
version.directory,
);
}

/// Updates VS Code configuration for the project
///
/// This method updates the VS Code configuration for the provided [project].
/// It sets the correct exclude settings in the VS Code settings file to exclude
/// the .fvm/versions directory from search and file watchers.
///
/// the .fvm/versions directory from search and file watchers.///
/// The method also updates the "dart.flutterSdkPath" setting to use the relative
/// path of the .fvm symlink.
void _manageVscodeSettings(Project project) {
Expand Down
73 changes: 73 additions & 0 deletions website/docs/guides/intellij.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
id: intellij
title: IntelliJ (Android Studio, ...) Integration
sidebar_position: 3
---

Read this guide to learn how to use fvm with any IntelliJ-based IDE, like Android Studio.
This guide will from now on write IntelliJ only.

Please note, that you need to do this per project.

:::info
Before proceeding, make sure, you've run `fvm use` with a specific version or channel in your project.
Otherwise you cannot setup the IntelliJ integration.
:::

## Update IntelliJ Settings

1. In IntelliJ go to `Languages & Frameworks > Flutter` or search for Flutter and change Flutter SDK path.
2. Copy the **_absolute_** path of fvm symbolic link in your root project directory. Example: `/absolute-project-path/.fvm/flutter_sdk`
3. Apply the changes.

### Symlink path

Due to `.fvm/flutter_sdk` being a symlink, IntelliJ may visually change the value of the path to the absolute path whereever the symlink does point to.
As long as you leave the path untouched, it should work as expected.

Please run `fvm doctor` in your project and find `IntelliJ > SDK Path`.
It will show an information, if something has not been setup correctly.

:::important SDK change
If you're changing the SDK via `fvm use` it may take IntelliJ some seconds to notice the change.

If it does not recognize it after some seconds or after a restart, please run `fvm doctor` in your project's directory.
Find `IntelliJ > SDK Path`.
It will show an information, if something has not been setup correctly.
:::

## Ignore Flutter SDK root

If you want to ignore the Flutter SDK root directory within IntelliJ you can add the following to `.idea/workspace.xml`.

```xml
<component name="VcsManagerConfiguration">
<ignored-roots>
<path value="$PROJECT_DIR$/.fvm/flutter_sdk" />
</ignored-roots>
</component>
...
```

If that doesn't work, go to IntelliJ -> Preferences -> Editor -> File Types -> Ignored Files and Folders and add `flutter_sdk`:
![IntelliJ Configuration](../../../assets/android-studio-config.png)

## Troubleshooting

### IntelliJ is not changing the SDK then using `fvm use`

If you setup IntelliJ like described above and it does not change the SDK when using `fvm use`,
open the file `.idea/libraries/Dart_SDK.xml` in your project's root directory.

Within this file, you should check, if all paths contain `$PROJECT_DIR$/.fvm/flutter_sdk`.
If so, then the setup should be correct and you may should restart IntelliJ.

If it is not the case, the setup was not correct.
Now, select any other Flutter version you have available.
Using one from `fvm` is ok, as long as you point to it directly, not via the `.fvm/flutter_sdk` symlink.
After selecting any other version, `Apply` the changes in IntelliJ.
After that, select `.fvm/flutter_sdk` again and `Apply` the changes.

Now, everything should work as expected.

If nothing has helped, please see [this issue](https://github.com/leoafarias/fvm/issues/310#issuecomment-1822660953) for more insights.
31 changes: 0 additions & 31 deletions website/docs/references/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -103,34 +103,3 @@ Alternatively, you can specify only selected versions. The following snippet wil
```

To change current Flutter version open a project and select `Flutter: Change SDK` in the command palette. You should see all the versions as depicted in the following screenshot.

### Android Studio

1. Go to `Languages & Frameworks > Flutter` or search for Flutter and change Flutter SDK path.
2. Copy the **_absolute_** path of fvm symbolic link in your root project directory. Example: `/absolute-project-path/.fvm/flutter_sdk`
3. Apply the changes.
4. Restart Android Studio to see the new settings applied.

:::important
For Android Studio to detect the dynamic change of SDKs, the installed SDK must have finished setup.

Using `fvm install <VERSION>` will ensure that setup during install.

If you have installed through another command and setup was not completed. You can finish by just running `fvm flutter --version`

Android Studio might take a few seconds to detect the dynamic SDK change.
:::

If you want to ignore the Flutter SDK root directory within Android Studio you can add the following to `.idea/workspace.xml`.

```xml
<component name="VcsManagerConfiguration">
<ignored-roots>
<path value="$PROJECT_DIR$/.fvm/flutter_sdk" />
</ignored-roots>
</component>
...
```

If that doesn't work, go to Android Studio -> Preferences -> Editor -> File Types -> Ignored Files and Folders and add `flutter_sdk`:
![Android Studio Configuration](../../../assets/android-studio-config.png)
Loading