feat(shell): add the small procfile process manager in tmux
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.
This commit is contained in:
parent
1f8b491825
commit
a90542e59d
1 changed files with 80 additions and 0 deletions
80
site-modules/core/files/bin/pf
Executable file
80
site-modules/core/files/bin/pf
Executable file
|
|
@ -0,0 +1,80 @@
|
|||
#!/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."
|
||||
[]
|
||||
(map #(string/split % #":\s+") (string/split (slurp "Procfile.dev") #"\n" )))
|
||||
|
||||
(defn has-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-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-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-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 command-start [_]
|
||||
(when (not (fs/exists? "Procfile.dev"))
|
||||
(println "No Procfile.dev found in the current directory")
|
||||
(System/exit 0))
|
||||
|
||||
(when (not (has-session? (current-project-name)))
|
||||
(shell (format "tmux new-session -d -c %s -s '%s'" (fs/cwd) (current-project-name))))
|
||||
|
||||
(doseq [[name command] (parse-procfile)]
|
||||
(create-window (current-project-name) name command)))
|
||||
|
||||
(defn command-stop [_]
|
||||
(when (has-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}
|
||||
{:cmds ["stop"] :fn command-stop}
|
||||
{:cmds ["restart"] :fn command-restart}
|
||||
{:cmds [] :fn help}])
|
||||
|
||||
(cli/dispatch command-table *command-line-args*)
|
||||
|
||||
Loading…
Reference in a new issue