Skip to content

Commit

Permalink
Add CLI-interface for lein support (#90)
Browse files Browse the repository at this point in the history
  • Loading branch information
abogoyavlensky authored Apr 12, 2024
1 parent 34ee27e commit a2e79c5
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 13 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ All notable changes to this project will be documented in this file.
- Read database URL from env variable by default.
- Add ability to set a name for the env variable of database URL.
- Add ability to run commands from a jar.
- Add CLI-interface for Leiningen support

### Changed

Expand All @@ -27,7 +28,7 @@ All notable changes to this project will be documented in this file.
:models-file "resources/db/models.edn"}
```
then you can just remove that from config and everything will work as expected because
those values now are defaults.
those values are defaults now.

- If you have custom values for paths:
```clojure
Expand Down
51 changes: 44 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,65 @@ Breaking changes are possible.

[![Clojars Project](https://img.shields.io/clojars/v/net.clojars.abogoyavlensky/automigrate.svg)](https://clojars.org/net.clojars.abogoyavlensky/automigrate)

#### Setup database connection

Before running migrations we need to set database URL with `DATABASE_URL` env var, for example:

```shell
export DATABASE_URL="jdbc:postgresql://localhost:5432/mydb?user=myuser&password=secret"
```

***Note:** There is an ability to change the name of the environment variable using command argument: `:jdbc-url-env-var`.
Alternatively, instead of env var we can use `:jdbc-url` argument to setup the database URL directly for commands.*

#### tools.deps -X option

*deps.edn*
```clojure
{...
{:deps {org.clojure/clojure {:mvn/version "1.11.2"}
org.postgresql/postgresql {:mvn/version "42.3.1"}}
:paths [... "resources"]
:aliases
{...
:migrations {:extra-deps {net.clojars.abogoyavlensky/automigrate {:mvn/version "<VERSION>"}
org.postgresql/postgresql {:mvn/version "42.3.1"}}
:migrations {:extra-deps {net.clojars.abogoyavlensky/automigrate {:mvn/version "<VERSION>"}}
:ns-default automigrate.core}}}
```

Then you need to set database URL either using `DATABASE_URL` env var or `:jdbc-url` in `:exec-args`.
*Optionally, you can change the env var name using `:jdbc-url-env-var` in `:exec-args`.*
Now we can create `resources/db/models.edn` file with a map and run commands:

```shell
export DATABASE_URL="jdbc:postgresql://localhost:5432/mydb?user=myuser&password=secret"
$ clojure -X:migrations list
$ clojure -X:migrations make
$ clojure -X:migrations migrate
$ clojure -X:migrations explain :number 1
$ clojure -X:migrations help
```

#### Leiningen

:construction: *Leiningen support is planned.*
*project.clj*
```clojure
(defproject myprj "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.11.2"]
[org.postgresql/postgresql "42.7.3"]]
:resource-paths ["resources"]
:profiles {...
:migrations
{:dependencies [[net.clojars.abogoyavlensky/automigrate "<VERSION>"]]
:main automigrate.core}}
:aliases {"migrations" ["with-profile" "+migrations" "run"]})
```

Usage example:
```clojure
$ lein migrations list
$ lein migrations make
$ lein migrations migrate
$ lein migrations explain --number 1
$ lein migrations help
```
***Note:** For lein there is the same CLI-interface with the same commands and options, but
instead of keywords (e.g.`:number`) for option names you should use `--...` (e.g. `--number`).*

### Getting started

Expand Down Expand Up @@ -689,6 +725,7 @@ $ java -jar target/standalone.jar
- [x] Partial indexes.
- [x] Auto-generated backward migration.
- [x] Field level CHECK constraints.
- [x] Leiningen support.
- [ ] Data-migration using Clojure.
- [ ] Support for SQLite.
- [ ] Model level constraints.
Expand Down
7 changes: 4 additions & 3 deletions deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
differ/differ {:mvn/version "0.3.3"}
slingshot/slingshot {:mvn/version "0.12.2"}
com.github.vertical-blank/sql-formatter {:mvn/version "2.0.5"}
resauce/resauce {:mvn/version "0.2.0"}}
resauce/resauce {:mvn/version "0.2.0"}
org.clojure/tools.cli {:mvn/version "1.1.230"}}

:tools/usage {:ns-default automigrate.core}

Expand All @@ -25,9 +26,9 @@
:exec-args {:multithread? false
:test-warn-time 500}}

:outdated {:extra-deps {com.github.liquidz/antq {:mvn/version "2.8.1185"}
:outdated {:extra-deps {com.github.liquidz/antq {:mvn/version "2.8.1194"}
; suppress logger output
org.slf4j/slf4j-nop {:mvn/version "2.0.12"}}
org.slf4j/slf4j-nop {:mvn/version "2.0.13"}}
:main-opts ["-m" "antq.core" "--no-diff"
"--exclude=io.github.seancorfield/build-clj"
"--exclude=net.clojars.abogoyavlensky/automigrate"]}
Expand Down
66 changes: 64 additions & 2 deletions src/automigrate/core.clj
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
(ns automigrate.core
"Public interface for lib's users."
(:gen-class)
(:require [clojure.spec.alpha :as s]
[clojure.string :as str]
[clojure.tools.cli :as cli]
[slingshot.slingshot :refer [try+]]
[automigrate.migrations :as migrations]
[automigrate.util.spec :as spec-util]
Expand All @@ -21,7 +23,10 @@
(s/def ::number int?)


(s/def ::cmd (set automigrate-help/HELP-CMDS-ORDER))
(s/def ::cmd
(s/and
(s/conformer symbol)
(set automigrate-help/HELP-CMDS-ORDER)))


(s/def ::format
Expand Down Expand Up @@ -95,7 +100,7 @@
(defn- run-fn
[f args args-spec]
(try+
(let [args* (spec-util/conform args-spec args)]
(let [args* (spec-util/conform args-spec (or args {}))]
(f args*))
(catch [:type ::s/invalid] e
(file-util/prn-err e))
Expand Down Expand Up @@ -174,3 +179,60 @@ Available options:
:cmd - Command name to display help information for a specific command. (optional)"
[args]
(run-fn automigrate-help/show-help! args ::help-args))


; Classic CLI-interface support

(def cli-options-common
[[nil "--jdbc-url URL"]
[nil "--jdbc-url-env-var ENV_VAR"]
[nil "--migrations-dir DIR_PATH"]
[nil "--models-file FILE_PATH"]
[nil "--migrations-table TABLE"]
[nil "--resources-dir DIR"]])


(def cli-options-explain
(concat
cli-options-common
[["-n" "--number NUMBER"
:parse-fn #(Integer/parseInt %)]
["-d" "--direction DIRECTION"]
["-f" "--format FORMAT"]]))


(def cli-options-make
(concat
cli-options-common
[[nil "--name NAME"]]
[[nil "--type TYPE"]]))


(def cli-options-migrate
(concat
cli-options-common
[["-n" "--number NUMBER"
:parse-fn #(Integer/parseInt %)]]))


(def cli-options-help
[[nil "--cmd COMMAND"]])


(defn- parse-opts-or-throw-err
[args options-spec]
(let [args-parsed (cli/parse-opts args options-spec)]
(if (seq (:errors args-parsed))
(throw (ex-info (format "Command error: %s" (:errors args-parsed)) {}))
(:options args-parsed))))


(defn -main
[command & args]
(case command
"list" (list (parse-opts-or-throw-err args cli-options-common))
"migrate" (migrate (parse-opts-or-throw-err args cli-options-migrate))
"make" (make (parse-opts-or-throw-err args cli-options-make))
"explain" (explain (parse-opts-or-throw-err args cli-options-explain))
"help" (help (parse-opts-or-throw-err args cli-options-help))
(println "ERROR: command does not exist.")))

0 comments on commit a2e79c5

Please sign in to comment.