Compare commits

...

8 Commits

Author SHA1 Message Date
John Swanson
97952d5a2a latest 2026-07-22 07:38:07 -07:00
John Swanson
709e060e1b more improvements 2026-06-04 09:22:38 -07:00
John Swanson
b8b20b78a4 config file 2026-06-04 09:22:38 -07:00
John Swanson
b4d965968b allow non-interactive 2026-06-04 09:22:38 -07:00
John Swanson
dafe2d58f8 improved h2 handling, env vars for psql, mysql, mariadb 2026-06-04 09:22:38 -07:00
John Swanson
4232ee5623 dev-env: filter list to active envs, add open command, improve status display
- `list` now shows only active environments by default (--all for everything)
- Add `open` subcommand to open backend in browser
- Show human-readable uptime in status (e.g. "Up About 2 hours")
- Remove pid/log columns from status table, simplify to service/port/status
- Track started-at timestamp for backend/frontend processes
- Add ports summary column to list view
- Merge state file on stand-up to preserve existing entries
- Improve logs help text

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-04 09:22:38 -07:00
John Swanson
440077a671 add logs command 2026-06-04 09:22:38 -07:00
John Swanson
72de30fde9 Improved dev environment
- docker-compose style subcommands (up, stop, down, status)
- better status
- works in separate worktrees
- help available for each subcommand
2026-06-04 09:22:37 -07:00
4 changed files with 1468 additions and 314 deletions

52
bb.edn
View File

@@ -602,24 +602,50 @@
:task (task! (dev-env/dev-env! parsed))}
-johnswanson-dev-env
{:doc "Stand up (or tear down) an isolated dev environment for this worktree. Interactive prompts when flags omitted."
:examples [["./bin/mage -johnswanson-dev-env" "Interactive TUI to configure infra (saves config)"]
["./bin/mage -johnswanson-dev-env --run" "Configure + launch backend/frontend"]
["./bin/mage -johnswanson-dev-env --run --no-frontend" "Configure + backend only"]
["./bin/mage -johnswanson-dev-env --down" "Stop everything for this worktree"]
["./bin/mage -johnswanson-dev-env --status" "Show running containers and processes"]]
{:doc "Manage an isolated dev environment for this worktree (docker-compose style)."
:examples [["./bin/mage -johnswanson-dev-env" "Show status and available commands"]
["./bin/mage -johnswanson-dev-env up" "Configure + start everything (idempotent)"]
["./bin/mage -johnswanson-dev-env up --fresh" "Force-recreate containers and restart processes"]
["./bin/mage -johnswanson-dev-env up --no-frontend" "Start without frontend dev server"]
["./bin/mage -johnswanson-dev-env up --no-backend" "Start containers only, no backend process"]
["./bin/mage -johnswanson-dev-env up --edition ee --token all-features --app-db h2 --with none" "Fully non-interactive: all flags specified"]
["./bin/mage -johnswanson-dev-env up --config-file ./local/configs/seed.yml" "Preseed users/dbs/settings from a config file"]
["./bin/mage -johnswanson-dev-env up --encryption-key my-secret-key" "Set MB_ENCRYPTION_SECRET_KEY"]
["./bin/mage -johnswanson-dev-env up --non-interactive" "Reuse saved config without prompting"]
["./bin/mage -johnswanson-dev-env add mongo" "Add MongoDB warehouse to running env"]
["./bin/mage -johnswanson-dev-env logs" "Show last 100 lines from all log sources"]
["./bin/mage -johnswanson-dev-env logs backend" "Show last 100 lines of backend logs"]
["./bin/mage -johnswanson-dev-env logs -f" "Stream all logs (new lines only, interleaved)"]
["./bin/mage -johnswanson-dev-env logs backend -f" "Stream backend logs"]
["./bin/mage -johnswanson-dev-env open" "Open backend in default browser"]
["./bin/mage -johnswanson-dev-env stop" "Stop processes and containers (preserves data)"]
["./bin/mage -johnswanson-dev-env down" "Tear down everything (removes containers and config)"]]
:requires [[mage.johnswanson.dev-env :as jds-dev-env]]
:options [["-e" "--edition EDITION" "ee or oss (default: prompt)"]
:custom-help? true
:arg-schema [:or
[:tuple]
[:tuple [:enum "open" "status" "list"]]
[:cat [:enum "up" "stop" "down"] [:* :string]]
[:cat [:= "add"] [:* :string]]
[:cat [:= "logs"] [:* :string]]]
:options [["-h" "--help" "Show help for a command"]
["-e" "--edition EDITION" "ee or oss (default: prompt)"]
["-t" "--token TOKEN" "Token type: all-features, starter-cloud, pro-cloud, pro-self-hosted, none"]
[nil "--app-db DB" "App database: h2, postgres, mysql, mariadb (default: prompt)"]
[nil "--with SERVICE" "Warehouse service (repeatable): postgres, mysql, mariadb, mongo, clickhouse, ldap, maildev"
[nil "--with SERVICE" "Warehouse service (repeatable): postgres, mysql, mariadb, mongo, clickhouse, ldap, maildev, or 'none' to skip"
:multi true :default [] :update-fn conj]
[nil "--run" "Also launch backend + frontend in background"]
[nil "--no-frontend" "Skip frontend dev server (only with --run)"]
[nil "--down" "Stop everything for this worktree"]
[nil "--status" "Show current env status"]
[nil "--config-file PATH" "Metabase config.yml to load on backend start (MB_CONFIG_FILE_PATH)"]
[nil "--encryption-key KEY" "Set MB_ENCRYPTION_SECRET_KEY"]
[nil "--non-interactive" "Never prompt. Fail if required flags are missing; treat missing --with as 'none'."]
[nil "--no-frontend" "Skip frontend dev server"]
[nil "--no-backend" "Skip backend process (containers + config only)"]
[nil "--slot SLOT" "Override port slot (0-99)" :parse-fn Integer/parseInt]
[nil "--fresh" "Recreate containers from scratch"]]
[nil "--fresh" "Force-recreate containers from scratch"]
["-f" "--follow" "Stream new log lines in real time (logs subcommand)"]
[nil "--tail N" "Lines to show in dump mode, default 100 (logs subcommand)" :default 100 :parse-fn Integer/parseInt]
[nil "--stop" "With list: select envs to stop"]
[nil "--down" "With list: select envs to tear down"]
["-a" "--all" "With list: show all worktrees, not just active ones"]]
:task (task! (jds-dev-env/dev-env! parsed))}
-bot-dev-env

View File

@@ -231,7 +231,7 @@ main() {
dbg_info "Running mage_core with args: '$*'"
# log_info $MAGE_CORE_PATH
# log_info "${BB_EXEC} ${MAGE_CORE_PATH}"
(cd "${MB}" && exec "${BB_EXEC}" "${MAGE_CORE_PATH}" "$@")
(export MAGE_ORIGINAL_CWD="${MAGE_ORIGINAL_CWD:-$(pwd)}" && cd "${MB}" && exec "${BB_EXEC}" "${MAGE_CORE_PATH}" "$@")
}
# Run the main function with all arguments

View File

@@ -42,40 +42,41 @@
:sequential (when-let [desc (-> arg-schema mc/children first :desc)]
{(name-arguments arg-schema) desc})))
(defn- check-print-help [{:keys [options usage-fn arg-schema] :as current-task}]
(let [command-line-args *command-line-args*
summary (:summary (tools.cli/parse-opts *command-line-args* options))
usage-name (str " " (:name current-task) (when-not (str/blank? summary) " [OPTIONS]"))]
(when (or (get (set command-line-args) "-h")
(get (set command-line-args) "--help"))
(println "Task Name:" (:name current-task))
(println (str " " (c/green (:doc current-task))))
(println "\nUsages:")
(if-not arg-schema
(println usage-name)
(let [arg-usages (name-arguments (mc/schema arg-schema))
argument-descriptions (desc-arguments arg-schema)]
(if (seq? arg-usages)
(doseq [arg-usage arg-usages]
(println (str usage-name " " arg-usage)))
(println (str usage-name " " arg-usages)))
(when (seq argument-descriptions)
(println "\nArguments:")
(doseq [[name desc] argument-descriptions]
(println (str " " name ": " desc))))))
(when-not (str/blank? summary)
(println "\nOptions:")
(println summary))
(when-let [examples (:examples current-task)]
(println "\nExamples:")
(doseq [[cmd effect] examples]
(println "\n" cmd "\n -" (c/magenta effect))))
(when usage-fn
(println "\n"
#_:clj-kondo/ignore
((eval usage-fn) current-task)))
#_{:clj-kondo/ignore [:discouraged-java-method]}
(System/exit 0))))
(defn- check-print-help [{:keys [options usage-fn arg-schema custom-help?] :as current-task}]
(when-not custom-help?
(let [command-line-args *command-line-args*
summary (:summary (tools.cli/parse-opts *command-line-args* options))
usage-name (str " " (:name current-task) (when-not (str/blank? summary) " [OPTIONS]"))]
(when (or (get (set command-line-args) "-h")
(get (set command-line-args) "--help"))
(println "Task Name:" (:name current-task))
(println (str " " (c/green (:doc current-task))))
(println "\nUsages:")
(if-not arg-schema
(println usage-name)
(let [arg-usages (name-arguments (mc/schema arg-schema))
argument-descriptions (desc-arguments arg-schema)]
(if (seq? arg-usages)
(doseq [arg-usage arg-usages]
(println (str usage-name " " arg-usage)))
(println (str usage-name " " arg-usages)))
(when (seq argument-descriptions)
(println "\nArguments:")
(doseq [[name desc] argument-descriptions]
(println (str " " name ": " desc))))))
(when-not (str/blank? summary)
(println "\nOptions:")
(println summary))
(when-let [examples (:examples current-task)]
(println "\nExamples:")
(doseq [[cmd effect] examples]
(println "\n" cmd "\n -" (c/magenta effect))))
(when usage-fn
(println "\n"
#_:clj-kondo/ignore
((eval usage-fn) current-task)))
#_{:clj-kondo/ignore [:discouraged-java-method]}
(System/exit 0)))))
(defn- coerce-arguments [arg-schema current-task arguments]
(if-not arg-schema

File diff suppressed because it is too large Load Diff