This is a little project simply to make trivial tools in Go effortless for my personal usage. These tools are almost surely of low utility to most people, but may be instructive nonetheless.
I have CI/CD to build this into a single
binary and an
explode tool that builds
symlinks for each
tool in the busybox style.
I have automation in my
dotfiles
to pull the latest binary at install time and run the explode tool.
Here's a copy pasteable script to install the leatherman on OSX or Linux:
OS=$([ $(uname -s) = "Darwin" ] && echo "-osx")
LMURL="$(curl -s https://api.github.com/repos/frioux/leatherman/releases/latest |
grep browser_download_url |
cut -d '"' -f 4 |
grep -F leatherman${OS}.xz )"
mkdir -p ~/bin
curl -sL "$LMURL" > ~/bin/leatherman.xz
xz -d -f ~/bin/leatherman.xz
chmod +x ~/bin/leatherman
~/bin/leatherman explodeThis asssumes that ~/bin is in your path. The explode command will create a
symlink for each of the tools listed below.
Each tool takes different args, but to run a tool you can either use a symlink
(presumably created by explode):
$ echo "---\nfoo: 1" | yaml2json
{"foo":1}or use it as a subcommand:
echo "---\nfoo: 1" | leatherman yaml2json
{"foo":1}alluni: Prints all unicode character names (internal/tool/allpurpose/uni/alluni.md)clocks: Shows my personal, digital, wall of clocks (internal/tool/allpurpose/clocks/clocks.md)csv2json: Reads CSV on stdin and writes JSON on stdout (internal/tool/allpurpose/csv/csv2json.md)csv2md: Reads CSV on stdin and writes Markdown on stdout (internal/tool/allpurpose/csv/csv2md.md)debounce: Run debounces input from stdin to stdout (internal/tool/allpurpose/debounce/debounce.md)dump-mozlz4: Dumps the contents of amozlz4(akajsonlz4) file. (internal/tool/allpurpose/dumpmozlz4/dump-mozlz4.md)expand-url: Converts links in text to markdown links. (internal/tool/allpurpose/expandurl/expand-url.md)fn: Creates persistent functions by generating scripts. (internal/tool/allpurpose/fn/fn.md)group-by-date: Creates time series data by counting lines and grouping them by a given date format. (internal/tool/allpurpose/groupbydate/group-by-date.md)minotaur: Watches directories and runs a command when files change. (internal/tool/allpurpose/minotaur/minotaur.md)name2rune: Prints characters based on name. (internal/tool/allpurpose/uni/name2rune.md)netrc-password: Prints password for a hostname, login pair. (internal/tool/allpurpose/netrcpassword/netrc-password.md)pomotimer: Conveniently counts down a duration. (internal/tool/allpurpose/pomotimer/pomotimer.md)replace-unzip: Does whatunzipdoes more safely. (internal/tool/allpurpose/replaceunzip/replace-unzip.md)srv: Serves a directory over http, automatically refreshing when files change. (internal/tool/allpurpose/srv/srv.md)toml2json: Reads TOML on stdin and writes JSON on stdout. (internal/tool/allpurpose/toml/toml2json.md)uni: Describes unicode characters. (internal/tool/allpurpose/uni/uni.md)yaml2json: Reads YAML on stdin and writes JSON on stdout. (internal/tool/allpurpose/yaml/yaml2json.md)
auto-emote: Reacts to discord messages with vaguely related emoji. (internal/tool/chat/automoji/auto-emote.md)slack-deaddrop: Sends messages to a slack channel. (internal/tool/chat/slack/slack-deaddrop.md)slack-open: Opens a channel, group message, or direct message by name. (internal/tool/chat/slack/slack-open.md)slack-status: Sets slack status. (internal/tool/chat/slack/slack-status.md)
update: Installs new version of leatherman if one exists. (internal/tool/leatherman/update/update.md)
backlight: Modifies screen brightness. (internal/tool/misc/backlight/backlight.md)draw: Draws images with lua. (internal/tool/misc/img/draw.md)export-bamboohr: Exports company directory as JSON. (internal/tool/misc/bamboo/export-bamboohr.md)media-remote:media-remotecontrol media players on Linux. (internal/tool/misc/desktop/media-remote.md)prepend-hist: Combines a history file and stdin. (internal/tool/misc/prependhist/prepend-hist.md)status: Serves information about host machine. (internal/tool/misc/status/status.md)steamsrv: Steamsrv renders steam screenshots and the steam log (what games you played and when) over http. (internal/tool/misc/steamsrv/steamsrv.md)twilio: Makes callbacks like twilio. (internal/tool/misc/twilio/twilio.md)wuphf: Sends notifications on lots (2) of platforms. (internal/tool/misc/wuphf/wuphf.md)
amygdala: Automated assistant. (internal/tool/notes/amygdala/amygdala.md)brainstem: Interacts with amygdala without using any server components. (internal/tool/notes/brainstem/brainstem.md)notes: Serves my notes from disk or Dropbox. (internal/tool/notes/now/notes.md)proj: Integrates my various project management tools. (internal/tool/notes/proj/proj.md)zine: Read only view of my notes via the filesystem. (internal/tool/notes/zine/zine.md)
In an effort to make debugging simpler, I've created three ways to see what
leatherman is doing:
LMTRACE=$somefile will write an execution trace to $somefile; look at that with go tool trace $somefile
Since so many of the tools are short lived my assumption is that the execution trace will be the most useful.
LMPROF=$somefile will write a cpu profile to $somefile; look at that with go tool pprof -http localhost:10123 $somefile
If you have a long running tool, the pprof http endpoint is exposed on
localhost:6060/debug/pprof but picks a random port if that port is in use; the
port can be overridden by setting LMHTTPPROF=$someport.
Some tools are annoying to have in the main leatherman tool. Maybe they pull
in deps that are huge or need cgo, but in any case I try to keep them separate.
For now, these tools are under leatherman/cmd and must be built and run
separately. At some point I may come up with a policy around building or naming these,
but for now they are simply extra tools.