diff --git a/bin/eezo b/bin/eezo index 875f926..45608af 100755 --- a/bin/eezo +++ b/bin/eezo @@ -11,6 +11,7 @@ # https://eezo.io/install writes with the released version. set -euo pipefail +unset CDPATH SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" ROOT="$(dirname "$SCRIPT_DIR")" @@ -20,6 +21,7 @@ usage() { eezo — the framework launcher eezo new scaffold a new application in ./ + eezo new . scaffold a new application in the current directory, named after it eezo dev serve, restarting on every save eezo build stage the app for deployment (jars, migrations, Dockerfile) eezo deploy ship it: build, deploy to Fly.io, migrate, wait for health @@ -516,25 +518,64 @@ read_version_file() { } } +# The scaffold's gitignore entries, either written to a new .gitignore file or appended if .gitignore +# already exists, in which case it names the entries it appended +write_gitignore() { # + local file="$1" existed=0 line added=() + [ ! -f "$file" ] || existed=1 + for line in target/ .bsp/ .metals/ .bloop/; do + [ "$existed" -eq 1 ] && grep -qxF "$line" "$file" && continue + added+=("$line") + done + [ "${#added[@]}" -gt 0 ] || return 0 + if [ -s "$file" ] && [ -n "$(tail -c1 "$file")" ]; then echo >> "$file"; fi + printf '%s\n' "${added[@]}" >> "$file" + [ "$existed" -eq 0 ] || echo "added ${added[*]} to the existing .gitignore" +} + scaffold() { - name="${1:-}" - [ -n "$name" ] || { echo "eezo: new needs a name: eezo new myapp" >&2; exit 1; } - [ ! -e "$name" ] || { echo "eezo: ./$name already exists" >&2; exit 1; } + dir="${1:-}" + [ -n "$dir" ] || { echo "eezo: new needs a name: eezo new myapp, or eezo new . for the current directory ($(basename "$PWD"))" >&2; exit 1; } + # Any reference to the current directory such as: ./, "$PWD", or a symlink to it + if [ "$dir" -ef . ]; then dir="."; fi + if [ "$dir" = "." ]; then + # In place: the app is named after the directory + name="$(basename "$PWD")" + local existing=() file + for file in build.sbt build.sc build.mill project src; do + [ ! -e "$file" ] && [ ! -L "$file" ] || existing+=("$file") + done + [ "${#existing[@]}" -eq 0 ] || { + echo "eezo: this directory already has ${existing[*]}; new scaffolds a project only where there is none" >&2 + exit 1 + } + [ ! -L .gitignore ] || { + echo "eezo: .gitignore here is a symlink; new appends its entries only to a plain .gitignore" >&2 + exit 1 + } + [ ! -e .gitignore ] || { [ -f .gitignore ] && [ -r .gitignore ] && [ -w .gitignore ]; } || { + echo "eezo: .gitignore here is not a file new can append to; make it a writable file or remove it" >&2 + exit 1 + } + else + name="$dir" + [ ! -e "$dir" ] || { echo "eezo: ./$dir already exists" >&2; exit 1; } + fi read_version_file - mkdir -p "$name/project" "$name/src/main/scala/app" "$name/src/main/scala/models" + mkdir -p "$dir/project" "$dir/src/main/scala/app" "$dir/src/main/scala/models" - cat > "$name/project/build.properties" < "$dir/project/build.properties" < "$name/project/plugins.sbt" < "$dir/project/plugins.sbt" < "$name/build.sbt" < "$dir/build.sbt" < "$name/src/main/scala/Main.scala" <<'EOF' + cat > "$dir/src/main/scala/Main.scala" <<'EOF' import io.eezo.EezoApp import io.eezo.db.Schema import io.eezo.generated.Routes @@ -574,7 +615,7 @@ object Main extends EezoApp { } EOF - cat > "$name/src/main/scala/app/Index.scala" <<'EOF' + cat > "$dir/src/main/scala/app/Index.scala" <<'EOF' package app import io.eezo.core.html.* @@ -600,17 +641,11 @@ object Index { } EOF - cat > "$name/.gitignore" <<'EOF' -target/ -.bsp/ -.metals/ -.bloop/ -EOF - - echo "created ./$name (eezo $EEZO_VERSION, Scala $SCALA_VERSION, sbt $SBT_VERSION)" + echo "created $name at $(cd -- "$dir" 2> /dev/null && pwd) (eezo $EEZO_VERSION, Scala $SCALA_VERSION, sbt $SBT_VERSION)" + write_gitignore "$dir/.gitignore" echo echo "next:" - echo " cd $name" + [ "$dir" = "." ] || echo " cd $name" echo " eezo dev # serve on :8080, restart on save" echo " eezo routes # what is mounted" } diff --git a/docs/reference/cli.md b/docs/reference/cli.md index 5139ca0..b66c51b 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -21,7 +21,7 @@ layer can shadow it. No arguments runs the application. | command | layer | needs | what it does | |---|---|---|---| -| `new ` | launcher | `~/.eezo/eezo-version` | scaffolds `./` | +| `new `, `new .` | launcher | `~/.eezo/eezo-version` | scaffolds `./`, or the current directory, named after it | | `dev` | sbt task | | serves with restart on save, the route listing and the reload client; Ctrl-C stops it | | `routes [--json]` | http layer | | the mounted table and boot's warnings | | `db` | database layer | | the eight schema commands, listed; `db help` is the same | @@ -149,6 +149,11 @@ the command's answer and not a build failure: .gitignore ``` +`eezo new .` writes the same files into the current directory. +It refuses if the directory already has a build definition (`build.sbt`, `build.sc`, `build.mill`), a `project/` or a `src/` directory. +An existing `.gitignore` keeps its lines; the entries it lacks are appended to it, and `new` names them. +It refuses a `.gitignore` that is a symlink or that it cannot append to. + ## Related [Configuration](configuration.md) is what the commands read from the environment. diff --git a/docs/tutorials/getting-started.md b/docs/tutorials/getting-started.md index 9e81f33..8df2a24 100644 --- a/docs/tutorials/getting-started.md +++ b/docs/tutorials/getting-started.md @@ -25,7 +25,7 @@ eezo new bookshelf ``` ``` -created ./bookshelf (eezo 0.2.0, Scala 3.8.4, sbt 1.12.14) +created bookshelf at /home//projects/bookshelf (eezo 0.2.0, Scala 3.8.4, sbt 1.12.14) next: cd bookshelf