Skip to content

Commit f3cd3fa

Browse files
committed
Add post "2023-05-08-replacing-sbt-with-scala-cli-in-a-simple-project.md"
1 parent f39aa18 commit f3cd3fa

6 files changed

Lines changed: 98 additions & 0 deletions

File tree

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
---
2+
layout: post
3+
title: "Replacing sbt with scala-cli in a simple project"
4+
date: 2023-05-08 08:30:32 -0700
5+
categories: scala
6+
post_photo: assets/posts/scala-cli-replacing-sbt/post_photo.png
7+
permalink: /blog/:slug
8+
---
9+
10+
11+
This is a somewhat controversial post because we got to use [scala-cli](https://scala-cli.virtuslab.org) outside its purpose, as a build-tool for a multi-module project.
12+
13+
![scala-cli-is-not-a-build-tool](/assets/posts/scala-cli-replacing-sbt/scala-cli-is-not-a-build-tool.png)
14+
15+
> scala-cli: We do not call Scala CLI a build tool
16+
17+
So far, we are very happy with the outcome and we are keen to continue trying this approach in other simple projects.
18+
19+
## Summary
20+
21+
I have been jealous from Rust ecosystem in the sense that `cargo` already handles many common tasks without the need to install any plugin, for example, besides compiling and running the app, it also executes the tests, formats the code, packages the application into a binary, etc.
22+
23+
Turns out that `scala-cli` let us do that and more, all of this with a fast startup time (no need to load 13k settings at startup, looking at you sbt).
24+
25+
Not only that, our Continuous Integration (CI) workflow runtime is consistently below 1 minute (check code format, run tests, package modules), the most expensive step being downloading dependencies (which is cached):
26+
27+
![github-actions-runtime](/assets/posts/scala-cli-replacing-sbt/ci-runtime.png)
28+
29+
> 38s github-actions workflow execution
30+
31+
## Context
32+
33+
The project benefiting from this setup is [codepreview.io](https://codepreview.io), a tool to create preview environments from Pull Requests which is mainly built with Scala and shines with Scala projects.
34+
35+
The way that [codepreview.io](https://codepreview.io) works is by defining a small Scala script that holds the custom environment requirements for each project, such a script gets packaged by scala-cli, and, it eventually get executed by a CI workflow that creates the preview environment.
36+
37+
## Show me the code
38+
39+
I have prepared a [demo](https://github.com/wiringbits/scala-cli-multi-module-demo) repository for this.
40+
41+
This is the file structure:
42+
43+
```shell
44+
├── common
45+
│   ├── SharedCode.scala
46+
│   └── SharedCode.test.scala
47+
├── LICENSE
48+
├── module-1
49+
│   ├── App.scala
50+
│   └── package.sh
51+
├── module-2
52+
│   ├── App.scala
53+
│   └── package.sh
54+
└── README.md
55+
56+
3 directories, 8 files
57+
```
58+
59+
- [common/SharedCode.scala](https://github.com/wiringbits/scala-cli-multi-module-demo/blob/main/common/SharedCode.scala) holds the code that's shared by `module-1` and `module-2`.
60+
- [common/SharedCode.test.scala](https://github.com/wiringbits/scala-cli-multi-module-demo/blob/main/common/SharedCode.test.scala) has the tests for `SharedCode.scala`
61+
- [module-1/App.scala](https://github.com/wiringbits/scala-cli-multi-module-demo/blob/main/module-1/App.scala) is the module-1 application source.
62+
- [module-2/App.scala](https://github.com/wiringbits/scala-cli-multi-module-demo/blob/main/module-2/App.scala) is the module-2 application source.
63+
64+
Let's expand `module-1/App.scala`:
65+
66+
```scala
67+
//> using file "../common/SharedCode.scala"
68+
69+
object App {
70+
def main(args: Array[String]): Unit = {
71+
println(
72+
renderText("module-2")
73+
)
74+
}
75+
}
76+
```
77+
78+
## Show me the CI
79+
80+
The CI is compiling the code, checking its format, as well as packaging the module apps.
81+
82+
The [first execution](https://github.com/wiringbits/scala-cli-multi-module-demo/actions/runs/4916752733/jobs/8780920466) took 1m33s, most of the time is spent downloading and caching dependencies:
83+
84+
![ci-demo-execution-1](/assets/posts/scala-cli-replacing-sbt/ci-demo-execution-1.png)
85+
86+
87+
The [first execution](https://github.com/wiringbits/scala-cli-multi-module-demo/actions/runs/4916771498/jobs/8780964617) took only 25s! This is an outstanding runtime for scala projects:
88+
89+
![ci-demo-execution-2](/assets/posts/scala-cli-replacing-sbt/ci-demo-execution-2.png)
90+
91+
92+
## Conclusion
93+
94+
While scala-cli does not advertise itself as a build-tool, we saw that it can be a viable option for small projects.
95+
96+
I'm keep to try it on bigger projects and see how far we can go, could it possible be as nice for a simple fullstack Scala application?
97+
98+
Thanks.
74.7 KB
Loading
74.4 KB
Loading
85.9 KB
Loading
28.9 KB
Loading
139 KB
Loading

0 commit comments

Comments
 (0)