diff --git a/lib/constants.dart b/lib/constants.dart index 443a4c12..7fdf963f 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -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; diff --git a/lib/src/commands/doctor_command.dart b/lib/src/commands/doctor_command.dart index 1c21345a..555f2d88 100644 --- a/lib/src/commands/doctor_command.dart +++ b/lib/src/commands/doctor_command.dart @@ -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 = @@ -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()); } diff --git a/lib/src/workflows/use_version.workflow.dart b/lib/src/workflows/use_version.workflow.dart index 2af115a4..f247ebf6 100644 --- a/lib/src/workflows/use_version.workflow.dart +++ b/lib/src/workflows/use_version.workflow.dart @@ -76,6 +76,10 @@ Future useVersionWorkflow({ updatedProject, version, ); + _updateCurrentSdkReference( + updatedProject, + version + ); _manageVscodeSettings(updatedProject); @@ -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); } @@ -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) { diff --git a/website/docs/guides/intellij.md b/website/docs/guides/intellij.md new file mode 100644 index 00000000..de78667c --- /dev/null +++ b/website/docs/guides/intellij.md @@ -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 + + + + + +... +``` + +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. \ No newline at end of file diff --git a/website/docs/references/configuration.mdx b/website/docs/references/configuration.mdx index f4e05f95..1b3dd4d7 100644 --- a/website/docs/references/configuration.mdx +++ b/website/docs/references/configuration.mdx @@ -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 ` 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 - - - - - -... -``` - -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) \ No newline at end of file