cursive-ide / cursive

Cursive: The IDE for beautiful Clojure code
581 stars 7 forks source link

Stay on the root module in Polylith workspaces #2828

Open tengstrand opened 1 year ago

tengstrand commented 1 year ago

Since issue #2554 we have much better support for working with Polylith codebases in Cursive, by checking "Resolve over whole project": image

We need one more change to get the integration to work well, and that is to be able to set the "root" module, which will be used when running tests from the IDE. In Polylith, tests are always executed from the root module, e.g. "polylith" for the polylith codebase itself, as an example.

As it is now, if we execute a test from e.g. the shell brick, it will use "shell" as module, and the test will fail. Right now I need to manually change the module to "polylith" and run the test again, which doesn't give a nice user experience.

jasonjckn commented 11 months ago

+1

imrekoszo commented 11 months ago

running tests from the IDE

@tengstrand there are a few different ways of running tests in Cursive, which one is causing you this problem?

tengstrand commented 11 months ago

When I click on the green arrow for a test, e.g. the check test function in select-candidates-test from the shell component, and run the test: image

I get this error: image

If I go and look in the configuration that Cursive created for me, then it has set "Module" to shell and "Working dir" to /Users/joakimtengstrand/source/polylith/components/shell: image

If I change "Module" to polylith it will also set "Working dir" to /Users/joakimtengstrand/source/polylith for me. If I now run the test again, by clicking the "run test" icon, at the top of the page, it will run the test again: image

And they will be green.

All these steps can be hard to figure out for someone new to Polylith, but it's also a really bad default behaviour, regardless of how experienced user you are. For example, if I choose to run another test, I have to repeat the steps, and if I want to reuse a test configuration, I have to look it up in the growing list of test configurations.

imrekoszo commented 11 months ago

@tengstrand interesting! Do you prefer this way of running tests to running them in the repl and if yes, why?

I always use a repl + the actions to run the test under caret or tests in the namespace in the repl and never this one you showed. What I dislike about this one is that it starts a separate java process and so feedback is slower compared to just executing in the already running repl process.

tengstrand commented 11 months ago

I guess it's just an old habit, that originates from the time when I used IntelliJ/IDEA to program in Java! I should probably switch to your style of working. But regardless of that, I think it's important that the integration works.

cursive-ide commented 11 months ago

Here's how you can do this. You need to edit the template for test configurations, which is used to create new configurations including the temporary ones created by clicking on the gutter icons:

Screenshot 2023-10-26 at 11 27 48

Then set the module in the template for the clojure.test type:

Screenshot 2023-10-26 at 11 28 14

The one caveat with this is that it's a per-project setting, so you'll have to do this once for each new Polylith project. I don't think there's a good way around this unfortunately.

tengstrand commented 11 months ago

After I have clicked "Add new configuration", I can't see "Run IDE" in the list:

image

I'm using this at the moment: "IntelliJ IDEA 2023.2.1 (Community Edition) Build #IC-232.9559.62, built on August 23, 2023 Runtime version: 17.0.8+7-b1000.8 aarch64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. macOS 14.0 GC: G1 Young Generation, G1 Old Generation Memory: 2048M Cores: 10 Metal Rendering is ON Non-Bundled Plugins: com.paperetto.dash (3.3) org.asciidoctor.intellij.asciidoc (0.38.20) com.cursiveclojure.cursive (1.13.1-eap3-2023.2)

cursive-ide commented 11 months ago

Sorry, Run IDE is just what happened to be open when I opened the dialog. The first screenshot is to indicate the "Edit configuration templates..." link, which should be there whatever type you have selected. Then, in the next screen where you're actually editing the templates, you need to select the clojure.test type.

tengstrand commented 11 months ago

Okay cool, I misunderstood.

If I open a file, e.g. components/common/test/polylith/clj/core/common/brick_names_to_test.clj: image

And then click on the green arrow for the first all-bricks function, and run the test: image

It will create this configuration for me, and use it to run the test: image

The test will now fail, because it uses common as module: image

If I now change the module for that test to polylith: image

I can run the test: image

image

But if I run another test in-between and click on the green triangle again, then it will create a new configuration for me, and forget that it should run the test from the polylith module, and the test will fail. If I run many test this way, the list of configured tests will grow, and it takes a lot of time to find the correct configuration each time.

I didn't manage to create a configuration for the common component, that it will use every time I execute the all-bricks function, but maybe you know how to do it? For Polylith codebases, it would be much better if Cursive could create a clojure.test configuration where module was set to polylith, regardless which test that was executed, but as you said, this seems not to be doable. It's just that it would be great if the user experience could be improved compared to how it works today!

cursive-ide commented 11 months ago

Ok, here is what I am doing:

  1. I import a freshly-cloned copy of polylith.
  2. I open components/common/test/polylith/clj/core/common/brick_names_to_test.clj.
  3. I run the all-bricks test, and indeed it fails, and checking I can see that the config is created in the common module.
  4. I delete the temporary configuration created by running the test, since it might interfere with the next steps.
  5. I "Edit Configurations..." and then "Edit configuration templates...." as shown in my comment above.
  6. In the clojure.test template configuration, I change the Module setting from "No default module" to "polylith".
  7. Apply, OK, etc...
  8. Now, when I run the all-bricks test, it works correctly.

What step 6 does is reconfigure the template that is cloned when any new run config of that type is created in this project. That's why in step 4 I delete the previous temporary config, to ensure that it is not re-used since we want IntelliJ to create a new one based on the modified template. From this point forward, any clojure.test run config which is created in this project will be created with "polylith" as its module. However, pre-existing ones will not be corrected.

If there's a reliable way to detect that a project uses polylith, then I might be able to detect it, prompt the user to ensure that it's what they want, and then update the template automatically - I'm not sure if it's possible to programmatically update the template configurations, I'd have to investigate. I could also at that point detect any test configs that have a different module set, and prompt the user which they would like to update to use the main module.

tengstrand commented 11 months ago

Now it works, thanks! Sorry that I wasn't able to follow your pretty clear instructions!

The brick-names-to-test lives here:

.
├── bases
├── components
│   ├── common
│   │   ├── deps.edn
│   │   ├── src
│   │   └── test
│   │       └── polylith
│   │           └── clj
│   │               └── core
│   │                   └── common
│   │                       ├── brick_names_to_test.clj
├── deps.edn
├── development
├── projects
│   ├── poly
│   │   ├── deps.edn
└── workspace.edn

What identifies this as a Polylith workspace, is that there is a workspace.edn config file a few levels up from brick-names-to-test, which is considered the root for the workspace. We could also check that workspace.edn contains a :top-namespace key.

A workspace can either live at the root, or in a directory or sub directory, see the high-level description of workspaces.

In addition to components, tests can also live under the bases and projects directories and possible (but rarely) under development.

If you want, you can read more about how the poly tool handles workspaces here or just ask me if you have questions.