Created
October 23, 2020 12:12
-
-
Save evansd/96edf2f45815624cac8084a51724e89d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -euo pipefail | |
help_text=" | |
Usage: bin/development-services [-h|--help] [-n|--no-attach] | |
Executes the commands listed in the 'Procfile.development' file, each in its | |
own pane of a new tmux session, and then attaches to that session. | |
If an appropriate tmux session already exists then we attach to it without | |
starting anything. | |
--no-attach: Don't attach to the session, just ensure it is started and | |
then wait for it to terminate | |
" | |
show_help=false | |
no_attach=false | |
unknown_arg='' | |
while [[ $# -gt 0 ]]; do | |
case "$1" in | |
-h|--help) | |
show_help=true;; | |
-n|--no-attach) | |
no_attach=true;; | |
*) | |
unknown_arg="$unknown_arg $1";; | |
esac | |
shift | |
done | |
if $show_help; then | |
echo "$help_text" | |
exit 0 | |
fi | |
if [[ -n "$unknown_arg" ]]; then | |
echo "UNRECOGNISED ARGUMENT:$unknown_arg" | |
echo "$help_text" | |
exit 1 | |
fi | |
# Change in the project root directory | |
unset CDPATH | |
cd "$( dirname "${BASH_SOURCE[0]}" )/.." | |
process_file="$PWD/Procfile.development" | |
# Default project data directory if not already set | |
: ${PROJECT_DATA_DIR:="$PWD/local-data"} | |
export PROJECT_DATA_DIR | |
socket_path="$PROJECT_DATA_DIR/tmux.socket" | |
# Check tmux is installed | |
if ! which tmux >/dev/null; then | |
echo "You must install tmux to use this script" | |
echo "Note: you can always run the commands listed in the '$process_file' file manually." | |
exit 1 | |
fi | |
# tmux wrapper function which uses the correct socket file | |
_tmux() { | |
tmux -2 -S "$socket_path" "$@" | |
} | |
process_list="$(sed --regexp-extended --quiet 's/^([A-Za-z0-9_]+):\s*(.+)$/\1:\2/p' "$process_file")" | |
adjective='existing' | |
if ! _tmux has-session 2>/dev/null; then | |
adjective='new' | |
mkdir -p "$(dirname "$socket_path")" | |
_tmux new-session -d | |
# Show pane titles in their borders | |
_tmux set pane-border-status | |
# Enable mouse mode so clicking in a pane will select it | |
_tmux set mouse on | |
IFS=$'\n' | |
first=true | |
for process_definition in $process_list; do | |
# Extract substring up to first colon | |
process_name="${process_definition%%:*}" | |
# Extract substring after first colon | |
process_command="${process_definition#*:}" | |
if $first; then | |
first=false | |
else | |
# Split pane, giving 95% of remaining space to new pane so we have plenty | |
# of space to keep opening more panes (panes will be resized evenly at | |
# the end of the loop) | |
_tmux split-window -p 95 | |
fi | |
echo "Starting service '$process_name': $process_command" | |
# Sets the current pane title to the process name using the required escape | |
# sequence. We use a tiny delay to avoid writing characters before the | |
# shell is ready (everything will still work if this happens, we may just | |
# get some extraneous characters appearing in the pane). We use a leading | |
# space to avoid polluting bash history. | |
sleep 0.01 | |
_tmux send-keys " printf '\\033]2;%s\\033\\\\' '$process_name'; clear" enter | |
sleep 0.01 | |
# Run the process command | |
_tmux send-keys "$process_command" enter | |
done | |
_tmux select-layout even-vertical | |
fi | |
if ! $no_attach; then | |
echo "Attaching to $adjective tmux session on $socket_path" | |
exec tmux -2 -S "$socket_path" attach-session | |
else | |
echo "Waiting for $adjective tmux session to close on $socket_path" | |
while _tmux has-session 2>/dev/null; do | |
sleep 1 | |
done | |
echo 'Session closed' | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment