From c490e26fb90e0bac2b0b33517d83fc03a14b461e Mon Sep 17 00:00:00 2001 From: Connor Olding Date: Fri, 23 Sep 2022 12:14:00 -0700 Subject: [PATCH] add incomplete notes on code style --- README.md | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/README.md b/README.md index c38319b..33ea7f1 100644 --- a/README.md +++ b/README.md @@ -44,3 +44,79 @@ this project must be built on a host running Linux. if you are not running Linux, use a VM of some sort. i personally use VirtualBox running Alpine Linux. i have not tried building with WSL2. + +### Code Style + +this project encourages a heretical and horrifying style of code +for its shell scripts. the intent is to chain `&&`s while facilitating +trivial re-ordering of lines. for instance, a `RUN` command in a Dockerfile +(which just executes a line of shell) might look like this: + +```sh +RUN : \ + && echo hello \ + && note() \ + { : \ + && printf '\033[1m%s\033[m: %s\n' >&2 \ + noted "$*" \ + ;} \ + && note '\\( o _ o )//' \ +; +``` + +*gratuitous explanation:* + + * 4-space indentation is a must, since at least three characters + are needed to contain the operators on the left of each line. + + * `:` is akin to the `true` command; it's used as a no-op + that only sets the most recent exit code (`$?`) to `0`. + + * `\` continues the code to the next line; + the proceeding newline is removed and ignored. + this is purely superficial. + + * `&&` is a short-circuiting operator that only evaluates + its right-hand side when `$?` is `0`. `&&` is preferred + over a simple semicolon because most programs use a + non-zero exit code to indicate that an error occurred, + whereas `;` will continue executing code, + even in the presence of an error. + + * `||` is like `&&` but only executes when `$?` is *not* `0`. + **important:** `||` has a lower precedence than `&&`! + make sure to wrap your `||`s in braces unless you want to + capture *everything* before it. for instance: + ` && { test -e myfile || touch myfile ;} \` + + * leftmost `&&`s and `||`s are always centered within their 4-space indent. + + * avoid using pipes (`|`) when possible, because only the + exit code of the final command in any pipe is respected. + + * functions are declared (`()`) on their own line + without any braces or other commands. + + * `{ :` is used to begin a multi-line block, + similar to how `RUN :` begins a shell command. + sadly, the space between the brace and the colon is not optional. + + * ';}` is used to finish a multi-line block. + this is aligned with the preceeding `&&` and `||` operators. + thankfully, the space between `;` and `}` is optional. + + * a final `;` is used to finish off the line-continutation. + this means that every line before it can end with a `\`, + which simplifies editing. when podman gives you strange errors, + double-check that you aren't forgetting the final semicolon. + + * redirections are usually specified *before* a final list of arguments. + this makes skimming code easier when arguments extend across many lines. + + * **TODO:** explain `if cmd ␤ ;then : ␤ ;fi`. + + * **TODO:** explain `for cmd ␤ ;do : ␤ ;done`. + + * **TODO:** explain `while cmd ␤ ;do : ␤ ;done`. + + * **TODO:** explain `test`s.