Skip to content

Commit c502199

Browse files
authored
Merge pull request #1149 from Gedochao/intellij-cookbooks
Add cookbooks for working with Scala CLI in IDEA IntelliJ
2 parents f7c159a + b76d5e0 commit c502199

20 files changed

+481
-6
lines changed
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
---
2+
title: Setup multiple Scala CLI projects in IDEA IntelliJ as separate modules
3+
sidebar_position: 7
4+
---
5+
6+
import {ChainedSnippets} from "../../src/components/MarkdownComponents.js";
7+
8+
If you've read through [the basic IDEA IntelliJ cookbook](intellij.md), then you already know how to import a Scala CLI
9+
project using `BSP`. However, in some cases importing a single project just does not fit the bill.
10+
11+
Here's a walk-through for a slightly more advanced scenario.
12+
13+
Let's say we keep the sources for 2 separate Scala apps in one repository. Each has its own subdirectory, to keep things
14+
clean. Additionally, you have another one for scripts alongside them.
15+
16+
It looks somewhat similar to this:
17+
18+
<ChainedSnippets>
19+
20+
```bash
21+
tree -a
22+
```
23+
24+
```text
25+
.
26+
├── app1
27+
│   ├── src
28+
│   │   └── HelloWorld1.scala
29+
│   └── test
30+
│   └── MyTests1.test.scala
31+
├── app2
32+
│   ├── src
33+
│   │   └── HelloWorld2.scala
34+
│   └── test
35+
│   └── MyTests2.test.scala
36+
└── scripts
37+
├── AnotherScript.sc
38+
└── SomeScript.sc
39+
40+
7 directories, 6 files
41+
```
42+
43+
</ChainedSnippets>
44+
45+
When running these apps, you'd like to run them separately. `app1` and `app2` may have conflicting dependencies, or it
46+
may just not feel hygienic to share their classpath long term.
47+
48+
However, you keep those in one repository because of business relevance (or whatever other reasons why they are tied
49+
together), and so, you'd like to see them all at once in your IDE, with all the syntax coloring, completions and
50+
debugging
51+
your code straight from the IDE, the whole shebang.
52+
53+
It's tempting to just run:
54+
55+
```bash
56+
scala-cli setup-ide .
57+
```
58+
59+
Unfortunately, in this case that won't really do the trick. Even if you run and package the apps & scripts from the
60+
terminal separately, when importing everything together to your IDE like this, the single `BSP` project will make them
61+
share their classpath. This in turn means that things will break.
62+
63+
The only way to solve this is for each to have its own `BSP` configuration, really.
64+
And so:
65+
66+
```bash ignore
67+
scala-cli setup-ide app1
68+
scala-cli setup-ide app2
69+
scala-cli setup-ide scripts
70+
```
71+
72+
As a result, a separate `.bsp` directory was created in `app1`, `app2` and `scripts`, respectively.
73+
74+
<ChainedSnippets>
75+
76+
```bash
77+
tree -a
78+
```
79+
80+
```text
81+
.
82+
├── app1
83+
│   ├── .bsp
84+
│   │   └── scala-cli.json
85+
│   ├── .scala-build
86+
│   │   ├── ide-inputs.json
87+
│   │   └── ide-options-v2.json
88+
│   ├── src
89+
│   │   └── HelloWorld1.scala
90+
│   └── test
91+
│   └── MyTests1.test.scala
92+
├── app2
93+
│   ├── .bsp
94+
│   │   └── scala-cli.json
95+
│   ├── .scala-build
96+
│   │   ├── ide-inputs.json
97+
│   │   └── ide-options-v2.json
98+
│   ├── src
99+
│   │   └── HelloWorld2.scala
100+
│   └── test
101+
│   └── MyTests2.test.scala
102+
└── scripts
103+
├── .bsp
104+
│   └── scala-cli.json
105+
├── .scala-build
106+
│   ├── ide-inputs.json
107+
│   └── ide-options-v2.json
108+
├── AnotherScript.sc
109+
└── SomeScript.sc
110+
111+
13 directories, 15 files
112+
113+
114+
115+
```
116+
117+
</ChainedSnippets>
118+
119+
120+
After opening the root directory in `IntelliJ` (`File` -> `Open...`), the 3 `BSP` setups should be successfully
121+
detected.
122+
123+
![IntelliJ noticed the 3 BSP configs](/img/intellij_bsp_build_scripts_found.png)
124+
125+
However, since there are 3 different setups, `IntelliJ` doesn't know what to import. And so, we have to set it up
126+
ourselves.
127+
128+
Right-click on your project root directory in `Intellij` and go into `Module Settings`.
129+
130+
![Go into Module Settings](/img/intellij_module_settings.png)
131+
132+
Then, under `Project Structure` -> `Modules` press the `+` button and then `Import Module`.
133+
134+
![Import a module](/img/intellij_module_settings_import_module.png)
135+
136+
Navigate to each of the subdirectories from there and add them as a `BSP` module (`BSP` should be an available choice,
137+
if the `setup-ide` was run correctly).
138+
139+
![Import from BSP as external model](/img/intellij_import_bsp_module.png)
140+
141+
You have to import each of the subdirectories separately (`app1`, `app2` and `scripts`, in the example).
142+
143+
The end result should look like this:
144+
145+
![End result multi-BSP setup](/img/intellij_multi_bsp_setup.png)
146+
147+
Now each of the subdirectories uses its own `BSP` connection, which in turn means a separate classpath. And all of that
148+
in a single `IntelliJ` project!
149+
150+
Upon closer inspection, you may notice that `IntelliJ` stores this as separate sub-project configurations. Each
151+
subdirectory gets its own `.idea` folder with the relevant settings.
152+
153+
<ChainedSnippets>
154+
155+
```bash
156+
tree -a
157+
```
158+
159+
```text
160+
.
161+
├── .idea
162+
│   ├── .gitignore
163+
│   ├── bsp.xml
164+
│   ├── codeStyles
165+
│   │   ├── Project.xml
166+
│   │   └── codeStyleConfig.xml
167+
│   ├── intellij-multi-bsp.iml
168+
│   ├── misc.xml
169+
│   ├── modules.xml
170+
│   ├── sbt.xml
171+
│   ├── vcs.xml
172+
│   └── workspace.xml
173+
├── app1
174+
│   ├── .bsp
175+
│   │   └── scala-cli.json
176+
│   ├── .idea
177+
│   │   └── modules
178+
│   │   └── app1-root.iml
179+
│   ├── .scala-build
180+
│   │   ├── ide-inputs.json
181+
│   │   └── ide-options-v2.json
182+
│   ├── src
183+
│   │   └── HelloWorld1.scala
184+
│   └── test
185+
│   └── MyTests1.test.scala
186+
├── app2
187+
│   ├── .bsp
188+
│   │   └── scala-cli.json
189+
│   ├── .idea
190+
│   │   └── modules
191+
│   │   └── app2-root.iml
192+
│   ├── .scala-build
193+
│   │   ├── ide-inputs.json
194+
│   │   └── ide-options-v2.json
195+
│   ├── src
196+
│   │   └── HelloWorld2.scala
197+
│   └── test
198+
│   └── MyTests2.test.scala
199+
└── scripts
200+
├── .bsp
201+
│   └── scala-cli.json
202+
├── .idea
203+
│   └── modules
204+
│   └── scripts-root.iml
205+
├── .scala-build
206+
│   ├── ide-inputs.json
207+
│   └── ide-options-v2.json
208+
├── AnotherScript.sc
209+
└── SomeScript.sc
210+
211+
21 directories, 28 files
212+
```
213+
214+
</ChainedSnippets>
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
---
2+
title: Setup a Scala CLI project in IntelliJ alongside your existing SBT project
3+
sidebar_position: 7
4+
---
5+
6+
import {ChainedSnippets} from "../../src/components/MarkdownComponents.js";
7+
8+
If you've read through [the basic IDEA IntelliJ cookbook](intellij.md), then you already know how to import a Scala CLI
9+
project using `BSP`. However, did you know that it's possible to import one alongside an `SBT` project? (Or any other
10+
build tool's project, for that matter.)
11+
12+
Here's a walk-through for a simple example.
13+
14+
Let's say you have an existing `SBT` project that you're working with for a while now. You have imported it in IntelliJ
15+
and the integration works nicely.
16+
The project's structure looks roughly like this:
17+
18+
<ChainedSnippets>
19+
20+
```bash
21+
tree -a
22+
```
23+
24+
```text
25+
.
26+
├── .bsp
27+
│   └── sbt.json
28+
├── .idea
29+
│   ├── .gitignore
30+
│   ├── codeStyles
31+
│   │   ├── Project.xml
32+
│   │   └── codeStyleConfig.xml
33+
│   ├── libraries
34+
│   │   ├── sbt__junit_junit_4_13_2_jar.xml
35+
│   │   ├── sbt__org_hamcrest_hamcrest_core_1_3_jar.xml
36+
│   │   ├── sbt__org_scala_lang_scala3_library_3_3_1_3_jar.xml
37+
│   │   ├── sbt__org_scala_lang_scala_library_2_13_8_jar.xml
38+
│   │   ├── sbt__org_scala_sbt_test_interface_1_0_jar.xml
39+
│   │   ├── sbt__org_scalameta_junit_interface_1_0_0_M6_jar.xml
40+
│   │   └── sbt__org_scalameta_munit_3_1_0_0_M6_jar.xml
41+
│   ├── misc.xml
42+
│   ├── modules
43+
│   │   ├── intellij-sbt-with-scala-cli-bsp-build.iml
44+
│   │   └── intellij-sbt-with-scala-cli-bsp.iml
45+
│   ├── modules.xml
46+
│   ├── sbt.xml
47+
│   ├── scala_compiler.xml
48+
│   ├── vcs.xml
49+
│   └── workspace.xml
50+
├── build.sbt
51+
├── project
52+
│   └── build.properties
53+
├── scripts
54+
│   ├── AnotherScript.sc
55+
│   └── SomeScript.sc
56+
├── src
57+
│   ├── main
58+
│   │   └── scala
59+
│   │   └── main.scala
60+
│   └── test
61+
│   └── scala
62+
│   └── MyTests.test.scala
63+
└── target
64+
└── scala-3.1.3
65+
├── classes
66+
│   ├── main$package$.class
67+
│   ├── main$package.class
68+
│   ├── main$package.tasty
69+
│   ├── main.class
70+
│   └── main.tasty
71+
└── test-classes
72+
├── MyTests.class
73+
└── MyTests.tasty
74+
75+
16 directories, 32 files
76+
```
77+
78+
</ChainedSnippets>
79+
80+
Now, let's say that at some point you decide you need to occasionally run some scripts relevant to this project. You run
81+
those scripts with Scala CLI and decide it'd be convenient to keep them in the same repository.
82+
83+
<ChainedSnippets>
84+
```bash ignore
85+
tree scripts
86+
```
87+
88+
```text
89+
scripts
90+
├── AnotherScript.sc
91+
└── SomeScript.sc
92+
93+
0 directories, 2 files
94+
```
95+
</ChainedSnippets>
96+
97+
However, you already import this repo as an `SBT` project, so what can you do?
98+
Well, you can import the Scala CLI scripts as a `BSP` module **alongside** your `SBT` project.
99+
100+
Make sure you setup the `BSP` configuration for the `scripts` directory first:
101+
102+
```bash ignore
103+
scala-cli setup-ide scripts
104+
```
105+
106+
As a result, a `scripts/.bsp` directory should be created.
107+
Now, right-click on your project root directory in `IntelliJ` and go into `Module Settings`
108+
109+
![Go into Module Settings](/img/intellij_sbt_module_settings.png)
110+
111+
Then, under `Project Structure` -> `Modules` press the `+` button and then `Import Module`.
112+
113+
![Import a module](/img/intellij_module_settings_import_module.png)
114+
115+
Navigate to the `scripts` directory from there and add it as a `BSP` module (`BSP` should be an available choice,
116+
if the `setup-ide` command was run correctly).
117+
118+
![Import from BSP as external model](/img/intellij_import_bsp_module.png)
119+
120+
Now the `scripts` `BSP` module should be imported and you should be able to run the scripts from your IDE.
121+
The end result should look like this:
122+
123+
![Import from BSP as external model](/img/intellij_sbt_alongside_bsp.png)

0 commit comments

Comments
 (0)