pushdown.scala
pushdown is a script I wrote during lockdown to keep track of pushups that I was doing. When learning a new language I like to convert existing things because it is easier, I have already thought about the problem I just need to write the solution figuring out the syntax of the new language
Getting started
I already have coursier installed (see my setup setup on how I do that)
Thought about using giter8 template as suggested by devinsideyou, but decided go with what comes default with coursier so I can gain an appreciation of what the templates give me.
I followed this one
Move everything in current pushdown directory into pushdown.py
sbt new scala/scala3.g8
takes a little longer than I expected the first time I ran it.
pushdown/pushdown.scala on master [?] is 📦 v0.1.0 via ☕ v11.0.20 via 🆂
❯ ls --tree
drwxr-xr-x - mandla 6 Jun 06:00 .
drwxr-xr-x - mandla 6 Jun 06:00 ├── project
.rw-r--r-- 19 mandla 6 Jun 06:00 │ └── build.properties
drwxr-xr-x - mandla 6 Jun 06:00 ├── src
drwxr-xr-x - mandla 6 Jun 06:00 │ ├── main
drwxr-xr-x - mandla 6 Jun 06:00 │ │ └── scala
.rw-r--r-- 110 mandla 6 Jun 06:00 │ │ └── Main.scala
drwxr-xr-x - mandla 6 Jun 06:00 │ └── test
drwxr-xr-x - mandla 6 Jun 06:00 │ └── scala
.rw-r--r-- 268 mandla 6 Jun 06:00 │ └── MySuite.scala
.rw-r--r-- 258 mandla 6 Jun 06:00 ├── build.sbt
.rw-r--r-- 338 mandla 6 Jun 06:00 └── README.md
Then run
sbt
and the first thing I miss from the devinsideyou template is the r
for run.
I must say, I really like sbt so far. A little more than cargo cause of the
interactive shell.
It does it’s thing, I then get this output
[info] running hello
Hello world!
I was compiled by Scala 3. :)
[success] Total time: 19 s, completed 06 Jun 2024, 06:09:36
sbt:pushdown.scala>
So far, so good.
Next, I know this is a CLI application, so I want something like click (for python) or clap (for rust). I am happy to let other people handle the CLI stuff for me.
The first thing I do then is to find out what the crate.io kasite for scala is.
Searching for scala package search
lands me on: scaladex
which looks like a portmanteau
of scala and index.
A search for cli gives finds me zio/zio-cli
I take it because:
- I don’t want to compare the “best” cli tool, I just need one that can autogenerate help for me, I can always change it later if it doesn’t suit my needs.
- It has ZIO, I am curious about ZIO, I watched 3 videos by devinsideyou about ZIO and… ZIO holds weight that is it good for okay.
Now, let’s add the package and see if the hello world works.
Add the dependency
val scala3Version = "3.4.2"
lazy val root = project
.in(file("."))
.settings(
:= "pushdown.scala",
name := "0.1.0-SNAPSHOT",
version := scala3Version,
scalaVersion += "dev.zio" %% "zio-cli" % "0.6.0",
libraryDependencies += "org.scalameta" %% "munit" % "1.0.0" % Test
libraryDependencies )
Try to run it and :-(
sbt:pushdown.scala> run
[info] Updating pushdown-scala_3
[info] Resolved pushdown-scala_3 dependencies
[warn]
[warn] Note: Unresolved dependencies path:
[error] stack trace is suppressed; run last update for the full output
[error] (update) sbt.librarymanagement.ResolveException: Error downloading dev.zio:zio-cli_3:0.6.0
[error] Not found
[error] Not found
[error] not found: /home/leny/.ivy2/localdev.zio/zio-cli_3/0.6.0/ivys/ivy.xml
[error] not found: https://repo1.maven.org/maven2/dev/zio/zio-cli_3/0.6.0/zio-cli_3-0.6.0.pom
[error] Total time: 2 s, completed 06 Jun 2024, 06:34:12
Which looks like it is search locally for zio-cli then trying maven central. So maybe I should just find a way to specify scaladex as a place to search. Turns out there isn’t a 0.6.0 version. I literally browsed the maven repo and can onl y find 0.5.0. Looking at the scaladex page also only shows upto 0.5.0 so, that must be right.
Restart sbt and try build again and…
[info] started sbt server
sbt:pushdown.scala> run
[info] compiling 1 Scala source to /home/leny/Izinto/Proyectos/code/scripts/pushdown/pushdown.scala/target/scala-3.4.2/classes ...
[info] running Sample
_____ __ _______ __
/ ___/____ _____ ___ ____ / /__ / ____(_) /_
\__ \/ __ `/ __ `__ \/ __ \/ / _ \ / / __/ / __/
___/ / /_/ / / / / / / /_/ / / __/ / /_/ / / /_
/____/\__,_/_/ /_/ /_/ .___/_/\___/ \____/_/\__/
/_/
Sample Git v1.1.0 -- Sample implementation of git clone
USAGE
$ clone clone [(-l, --local)] <repository>
COMMANDS
clone [(-l, --local)] <repository> Creates a copy of an existing repository
[success] Total time: 30 s, completed 06 Jun 2024, 06:55:37
sbt:pushdown.scala>
It worked and the hello world works. Time to plan
Problems for next time.
It is now next time (June 8, 2024)
Pushdown design
One of the things I like about FP is that I should be to create something similar to kwalk. There is an input, a black box and an output. I haven’t not managed to do this yet, so let’s try again.
features:
- I want a reminder to do push-ups
- I want to do push-ups based on my goals
- Goal are like:
- 20 push-ups every 60min
- x push-ups where x increases normally till y then decrease till x repeat all this 5 times
- basically a Goal is a template of the push-ups I want to do
- Log how many push-ups I managed to do
- Allow me to add a comment on how it was if I want
stateDiagram-v2 direction LR [*] --> Plan note left of Plan Planning stage either reads the plans for a file or gets them from interactive prompts end note Plan --> Run state Run { [*] --> countdown countdown --> notify notify --> savelogs savelogs --> if_state <>: "continue?" if_state --> countdown: Yes if_state --> [*]: No } Run --> Summarize Summarize --> [*]
This was just to play with mermaid.js
The CLI
Let’s understand zio-cli
- docs and examples: https://zio.dev/zio-cli/
- The docs have a couple of short videos.
commit: 921d162
Don’t know how to run the app though. What is a native image I wonder.
How will this thing be run?
ZIO cli has a plugin which is meant to use nativeImage for creating a standalone executable. I can’t get the right version of this plugin though. I tried using nativeImage directly and it has an issue which I’m lazy to figure out. I ended up finding sbt assembly which creates a jar which I have to run with java. Not ideal but meh. Good enough for now.
Let’s add a timer next