akinsho / flutter-tools.nvim

Tools to help create flutter apps in neovim using the native lsp
MIT License
932 stars 75 forks source link

feat: support monorepo #330

Open IgorKhramtsov opened 4 months ago

IgorKhramtsov commented 4 months ago

In my project, we are using monorepo, so the project structure looks like this:

flutter-monorepo
  melos.yaml
  packages
    -- core
    -- module 1
    -- module 2
    -- example

With such a structure, in order to be able to run example app from any other package, you need to add melos.yaml to root_patterns. After that, if you try to run the flutter app by specifying target packages/example/lib/main.dart, you will get an error "this project is not configured for x (macos/chrome/etc.)" . This happens because flutter command is run from the lsp.get_lsp_root_dir(), which is flutter-monorepo.

I checked how vscode behaves in such situation, and when you specify packages/example/lib/main.dart as a target in launch.json without explicitly specifying the cwd - looks like it will internally check that the flutter package root (packages/example) is different from the whole project root (flutter-monorepo) and changes the target to be relative to that package.

sidlatau commented 3 months ago

@IgorKhramtsov are you using a debugger? Looks like I can make it work if I disable the debugger in settings:

      debugger = {
        enabled = false,
        run_via_dap = false
      },

But if the debugger is enabled it does not work. I guess some changes need to be done there: https://github.com/akinsho/flutter-tools.nvim/blob/4f18033c3b78aa5450e538d81dfbbb3e67aeadec/lua/flutter-tools/runners/debugger_runner.lua#L96

IgorKhramtsov commented 2 months ago

Hey, @sidlatau! Yes, I use the debugger and now when I tried to launch a flutter app without it, I found out this fix doesn't work, so I need to think on it more.

Regarding the issue - it doesn't work for me without the debugger. Here are the steps:

  1. Open nvim in the root of monorepo;
  2. Open any dart file from the packages/core package;
  3. Execute :FlutterRun --target packages/example/lib/main.dart. This results in the "target not found" flutter error, because this command will be executed from the packages/core directory (I can see that dartls root directory points to that package by executing :LspInfo, so get_lsp_root_dir will return that path).
  4. Alternatively, you can run :FlutterRun --target ../example/lib/main.dart. This results in "no supported device connected" error because packages/core package is not configured to be run on any device.

Previously, when I used vscode, I had the following launch.json config:

{
    "name": "Launch example",
    "request": "launch",
    "type": "dart",
    "program": "packages/example/lib/main.dart"
},

And when I execute it I can see that vscode internally resolves this path and use packages/example as cwd for the flutter command becauase there is a message in the console saying Launching lib/main.dart on macOS in debug mode... where target is relative to example package.

You say it works for you; do you make something different, am I missing something?

For the case with the debugger, it turned out I'm able to run it without changes from this PR. I have the following dap configuration applied for my project:

dap.configurations.dart = {
    {
        type = "flutter",
        request = "launch",
        name = "Launch flutter",
        dartSdkPath = paths.dart_sdk,
        flutterSdkPath = paths.flutter_sdk,
        program = "lib/main.dart",
        cwd = "${workspaceFolder}/packages/example",
    }
}

I'm not sure how dap determines ${workspaceFolder}; maybe it uses the directory where nvim was opened.