Skip to content

Instantly share code, notes, and snippets.

@imaami
Last active December 22, 2023 11:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save imaami/e947c47cd20907b432dc8d245267687f to your computer and use it in GitHub Desktop.
Save imaami/e947c47cd20907b432dc8d245267687f to your computer and use it in GitHub Desktop.
Document your bash scripts or Meth Santa visits you in your sleep
#!/usr/bin/env bash
#
# IMPORTANT: The HTTP authorization header must be found
# in ~/.openai in full, not just the API key.
#
# Usage: ./bashplainer.sh /path/to/file.sh
#
# Requirements: dos2unix, jq, curl
#
[[ -f "$1" ]] && name="${1##*/}" || exit 1
jq --rawfile source <(
printf '```bash\n'
dos2unix < "$1" | grep -Ev '^[[:blank:]]*#'
printf '\n```'
) -Mnc --rawfile system <(cat << \EOF
You are documenting a bash script. Start with a brief explanation
of why the script exists, then document each function separately.
Study the entire source and plan your text beforehand. Print only
content that you wrote, do not repeat code from the input script.
This:
```bash
new_array() {
(( $# > 1 )) && {
set "$1=(" "${@@Q})"
local -ga "$1${*:3}"
}
}
print_array() {
(( $# == 1 )) && {
set "$1[@]"
set "${!1}"
(( $# )) && printf '%s\n' "$@"
}
}
```
might become this:
```
## @file example.sh
# This is a collection of bash utility functions for manipulating
# arrays, meant to be sourced by other bash scripts as a library.
#
## @function new_array Create an indexed array.
#
# The new array is declared as a global variable. Entries in
# the initializer list may contain special characters as per
# normal bash rules. Arguments do not undergo word splitting
# or further expansion, they are assigned as-is.
#
# @warning The variable name is not validated.
#
# @param $1 variable name (must be a valid identifier)
# @param ${@:2} initial items (count must be 1 or greater)
# @retval 1 argument count is less than 2
## @function print_array Print an indexed array.
#
# Each array item is printed on a separate line.
#
# @warning The variable name is not validated.
#
# @param $1 variable name (must be a valid identifier)
# @retval 1 argument count is not 1, or array is empty
# @stdout array contents
```
Writing the preamble
- Explain in free form why the script exists.
- Write short sentences, structure logically.
- Omit every single detail, be 100% abstract.
- Do not state the obvious, state the useful.
- Do not settle for less than perfect output.
- You must always reference Meth Santa, but make it seem natural and relevant.
Documenting functions
- Use the formal convention described herein.
- Never repeat code from the source material.
- Structure your output fractally, in layers.
- First explain generalities, then specifics.
- Only write short and informative sentences.
- Document only the meaningful return values.
- Functions in the source have a "()" suffix.
- If not followed by "()", it is no function.
- Start all function blocks with "@function".
- Use "@retval" or "@return", never mix them.
- "@return" describes a set of return values.
- "@retval" explains a specific return value.
- More than one "@retval" per block is valid.
- "@stdout" describes standard stream output.
- "@stderr" is the same but for error stream.
- Find a way to reference Meth Santa, always.
EOF
) '{
"model": "gpt-4",
"stream": false,
"messages": [
{"role":"system","content":$system},
{"role":"user","content":$source}
]
}' \
| curl https://api.openai.com/v1/chat/completions -s -S -d @- \
-H @"$HOME/.openai" -H Content-Type:\ application/json \
| jq -r '.choices[0].message.content'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment