When the move from tmux I can no longer use pf to start processes from a Procfile in a new session. This will do basically the same if we are not in a tmux session and start all the processes in wezterm tabs in the same workspace. This currently does not support closing the tabs, if this needs to be done you can kill the hole terminal and start it again. This also updates the script so you can pass in a file and it will use that file. Previously it was hardcoded to `Procfile.dev`, now this is the default however, can be overridden
120 lines
4.3 KiB
Clojure
Executable file
120 lines
4.3 KiB
Clojure
Executable file
#!/usr/bin/env bb
|
|
;; vi: ft=clojure
|
|
;;
|
|
;; A Procfile runner for tmux. Each procfile will have its own tmux session and
|
|
;; each process will have its own window. This way you can use tmux to attach
|
|
;; view logs and also restart individual processes.
|
|
;;
|
|
(require '[babashka.process :refer [shell]]
|
|
'[babashka.cli :as cli]
|
|
'[babashka.fs :as fs]
|
|
'[clojure.string :as string])
|
|
|
|
(defn current-project-name
|
|
"Returns the current project name based on the current working directory.
|
|
This assumes you have our porjects organised in a GOPATH style. This will
|
|
return the last two components of the current working directory, that should
|
|
be {org}/{project}"
|
|
[]
|
|
(string/join "/" (map #(.toString %) (take 2 (reverse(fs/components (fs/cwd)))))))
|
|
|
|
(defn parse-procfile
|
|
"Parses a procfile file and returns a list of [name command] pairs."
|
|
[file]
|
|
(map #(string/split % #":\s+") (string/split (slurp file) #"\n" )))
|
|
|
|
(defn has-tmux-session?
|
|
"Tests to see if a session already exists with a given name."
|
|
[session-name]
|
|
(string/includes? (:out (shell {:out :string} "tmux list-sessions")) session-name))
|
|
|
|
(defn has-tmux-window?
|
|
"Tests to see if a window already exists within a tmux session."
|
|
[session-name window-name]
|
|
(string/includes? (:out (shell {:out :string} (format "tmux list-windows -t '%s'" session-name))) window-name))
|
|
|
|
(defn create-tmux-window
|
|
"Creates a new tmux window in a session if it dose not already exists. Then
|
|
it will run any commands that are passed inside the new window."
|
|
[project name & commands]
|
|
(when-not (has-tmux-window? project name)
|
|
(shell (format "tmux new-window -t '%s' -n '%s'" project name))
|
|
(doseq [command commands]
|
|
(shell (format "tmux send-keys -t %s:'%s' '%s' C-m" project name command)))))
|
|
|
|
(defn tmux-start [file]
|
|
(when (not (has-tmux-session? (current-project-name)))
|
|
(shell (format "tmux new-session -d -c %s -s '%s'" (fs/cwd) (current-project-name))))
|
|
|
|
(doseq [[name command] (parse-procfile file)]
|
|
(create-tmux-window (current-project-name) name command)))
|
|
|
|
(defn is-in-tmux?
|
|
"Tests to see if we are in a tmux session or not."
|
|
[]
|
|
(not (nil? (System/getenv "TMUX"))))
|
|
|
|
(defn has-wezterm-pane?
|
|
"Tests to see if a wezterm pane already exists."
|
|
[name]
|
|
(string/includes? (:out (shell {:out :string} "wezterm cli list")) (format "pf: %s" name)))
|
|
|
|
(defn create-wezterm-pane
|
|
"Create a new wezterm pane and spawn a command in it."
|
|
[name command]
|
|
(let [pane-id (:out (shell {:out :string} (format "wezterm cli spawn --cwd %s" (fs/cwd))))]
|
|
(shell (format "wezterm cli set-tab-title --pane-id %s 'pf: %s'" pane-id name))
|
|
(shell {:in command} (format "wezterm cli send-text --pane-id %s" pane-id))
|
|
(shell {:in "\n"} (format "wezterm cli send-text --pane-id %s" pane-id))))
|
|
|
|
(defn wezterm-start [file]
|
|
(let [pane-id (System/getenv "WEZTERM_PANE")]
|
|
(doseq [[name command] (parse-procfile file)]
|
|
(when (not (has-wezterm-pane? name))
|
|
(create-wezterm-pane name command)))
|
|
|
|
(shell (format "wezterm cli activate-pane --pane-id %s" pane-id))))
|
|
|
|
(defn is-in-wezterm?
|
|
"Tests to see if we are in a wezterm session or not."
|
|
[]
|
|
(not (nil? (System/getenv "WEZTERM_PANE"))))
|
|
|
|
(defn command-start [m]
|
|
(let [file (get-in m [:opts :file] "Procfile.dev")]
|
|
(when (not (fs/exists? file))
|
|
(println "No Procfile.dev found in the current directory")
|
|
(System/exit 0))
|
|
|
|
(cond
|
|
(is-in-tmux?) (tmux-start file)
|
|
(is-in-wezterm?) (wezterm-start file)
|
|
:else (println "Unable to spawn processes in the current environment"))
|
|
|
|
(System/exit 0)))
|
|
|
|
(defn command-stop [_]
|
|
(when (has-tmux-session? (current-project-name))
|
|
(shell (format "tmux kill-session -t '%s'" (current-project-name)))))
|
|
|
|
(defn command-restart [args]
|
|
(command-stop args)
|
|
(command-start args))
|
|
|
|
(defn help [_m]
|
|
(println "A Procfile runner for tmux")
|
|
(println "")
|
|
(println "\033[1mCommands:\033[0m")
|
|
(println " start Start all of the processes in your Procfile.dev")
|
|
(println " stop Stop all the currently running processes")
|
|
(println " restart Restart all of the processes")
|
|
(println ""))
|
|
|
|
(def command-table
|
|
[{:cmds ["start"] :fn command-start :opts {:file "Procfile.dev"}}
|
|
{:cmds ["stop"] :fn command-stop}
|
|
{:cmds ["restart"] :fn command-restart}
|
|
{:cmds [] :fn help}])
|
|
|
|
(cli/dispatch command-table *command-line-args*)
|
|
|