Skip to content

Instantly share code, notes, and snippets.

@ifnull
Last active January 16, 2025 19:12
Show Gist options
  • Save ifnull/25c49f3f0428be85fcb1b4ed39d34bee to your computer and use it in GitHub Desktop.
Save ifnull/25c49f3f0428be85fcb1b4ed39d34bee to your computer and use it in GitHub Desktop.
Watcher for PlantUML on MacOS

Install

brew install plantuml fswatch
# Download plantuml-watch.sh
chmod +x ./plantuml-watch.sh
mkdir -p /usr/local/bin
mv ./plantuml-watch.sh /usr/local/bin/plantuml-watch
# Confirm /usr/local/bin is in PATH or mv script to directory in PATH
echo $PATH

Usage

Use plantuml-watch exactly as you would plantuml. Assuming the file foobar.puml is in the current directory, you should see the output below and the default app for the output filetype should open automatically and refresh after every saved change to the the source file.

$ plantuml-watch "*.puml"
Watching for changes in:
foo.puml
bar.puml
#!/bin/bash
# Check if at least one argument is provided
if [ $# -lt 1 ]; then
echo "Usage: $0 \"<file.puml or wildcard>\" [additional arguments for plantuml]"
exit 1
fi
# Expand wildcard pattern into a list of files
WATCH_FILES=$(ls $1 2>/dev/null)
if [ -z "$WATCH_FILES" ]; then
echo "No files matching pattern: $1"
exit 1
fi
shift
PLANTUML_ARGS="$@"
# Function to process a single file
process_file() {
local file="$1"
local base_name=$(basename "$file" .puml)
local dir_name=$(dirname "$file")
# Determine the output format and file extension
local output_format="png" # Default output format
local extension="png" # Default extension
for arg in $PLANTUML_ARGS; do
if [[ "$arg" == "-t"* ]]; then
output_format="${arg#-t}"
extension="${output_format}"
break
fi
done
if [[ "$extension" == "xmi" || "$extension" == "dot" || "$extension" == "txt" || "$extension" == "pdf" ]]; then
extension="${output_format}"
elif [[ "$extension" == "svg" ]]; then
extension="svg"
elif [[ "$extension" == "eps" ]]; then
extension="eps"
else
extension="png"
fi
local output_file="${dir_name}/${base_name}.${extension}"
echo "Generating diagram for $file..."
plantuml "$file" $PLANTUML_ARGS
if [ -f "$output_file" ]; then
open "$output_file"
else
echo "Output file not found: $output_file"
fi
}
# Initial run for all matched files
for file in $WATCH_FILES; do
process_file "$file"
done
# Watch for changes using fswatch
echo "Watching for changes in:"
for file in $WATCH_FILES; do
echo "$file"
done
# Use fswatch and ensure the output is properly handled
fswatch $WATCH_FILES | while read -r changed_file; do
# Check if the detected file is valid
if [ -f "$changed_file" ]; then
echo "File $changed_file changed, re-running plantuml..."
process_file "$changed_file"
else
echo "Change detected, but no valid file found: $changed_file"
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment