From 7f986e51d342f7940cba8c55c38ee97aea1f96ea Mon Sep 17 00:00:00 2001 From: Hyperling Date: Wed, 4 Nov 2026 08:48:26 -0700 Subject: [PATCH] AGENTS.md, add coding conventions and layout logistics including code snippets and example programs. --- .../workstation/linux/software/ai/sandbox.yml | 184 ++++++++++++++++++ 1 file changed, 184 insertions(+) diff --git a/tasks/workstation/linux/software/ai/sandbox.yml b/tasks/workstation/linux/software/ai/sandbox.yml index 7971940..d0ddcd3 100644 --- a/tasks/workstation/linux/software/ai/sandbox.yml +++ b/tasks/workstation/linux/software/ai/sandbox.yml @@ -306,6 +306,190 @@ # Run all tests ./gradlew allTests ``` + + # Coding Conventions + + Preferences related to how code should be written. + + ## All languages + + If a value is going to be used more than once, even a small path or file + name, it should exist in a variable. + + Relative shebangs such as `#!/usr/bin/env bash` and `#!/usr/bin/env node` + are always preferred over static shebangs such as `#!/bin/bash`, since + scripts are run across a multitude of different systems. + + ### Layout + + Programs should be laid out in 5 sections. + + - Variables + - Instantiate global variables and defaults used for parameters which + do not get passed an explicit value by the user. + - Functions + - Functions to be used throughout the program, including the Usage. + - Parameters / Validation + - Parse the parameters, validate the input, and assign any defaults. + - Main + - The primary logic of the program, completes the task at hand. + - Finish / Cleanup + - Typically just `exit 0`, but sometimes a summary of what was done. + + All sections may not always apply, such as with Hugo websites. With + projects like Android apps this would apply to each individual function, + method, and class. If a section does not need anything, it can be blank. + + ``` + public static void doThing(String thingName) { + // Variables // + String thingPrefix = "/place/for/thing/" + + // Functions // + + // Parameters // + if (thingName.isEmpty) { + Exception e = new Exception("No name passed!"); + throw e; + } + + // Main // + runStuff(thingPrefix + thingName); + + // Finish // + } + ``` + + The comments do not need to be included, this example is just as valid, + what maytters most is that the 5 section are done in order rather than + instantiating variable mid-scope. + + ``` + public static void doThing(String thingName) { + String thingPrefix = "/place/for/thing/" + + if (thingName.isEmpty) { + Exception e = new Exception("No name passed!"); + throw e; + } + + runStuff(thingPrefix + thingName); + } + ``` + + `if` statements and loops start new scope, so they also need the layout + applied to them. Loops may sometimes require a variable assignment before + it begins which is completely okay and does not break the layout rule. + This example has a Variables, Validation, Main, and Finish section without + the use of labels or comments since the code itself is simple and small. + + ``` + count=0 + array="cats dogs giraffes rhinos horses" + last_animal="" + for animal in $array; do + if (( count >= 3 )); then + echo "That's enough! We finished at the ${last_animal}." + break; + fi + + echo "We're looking at ${animal}." + + last_animal=$animal + (( count++ )) + done + ``` + + Providing the user's input in error messages is really helpful and can aid + their troubleshooting if things are not going according to expectations. + + Example using Bash: + + ``` + #!/usr/bin/env bash + + ### Variables ### + + declare A B + typeset -i a b + + ### Functions ### + + function usage() { + status="$1" + cat << EOF + Usage: add.sh -a NUM -b NUM [-h] + + Adds two numbers and prints out the full equation. + + Example: + + $ add.sh -a 5 -b 25 + 5 + 25 = 30 + EOF + exit $status + } + function add() { + num1="$1" + num2="$2" + sum="" + + if [[ -z $num1 || -z $num2 ]]; then + echo "ERROR: Two numnbers must be passed." + fi + + sum=$(( num1 + num2 )) + echo "${num1} + ${num2} = ${sum}" + } + + ### Parameters ### + + while getopts ':a:b:h' opt; do + case $opt in + a) A="$OPTARG" ;; + b) B="$OPTARG" ;; + h) usage 0 ;; + *) echo "ERROR: Option $OPTARG not recognized." >&2 && usage 1 ;; + esac + done + + if [[ -z "$A" || -z "$B" ]]; then + echo "ERROR: Both numbers need to be passed. A=${A} B=${B}" >&2 + usage 2 + fi + a="$A" b="$B" + if [[ "$a" != "$A" || "$b" != "$B" ]]; then + echo "ERROR: Values contain non-numeric data, please try again." >&2 + echo "A=${A} B=${B}" >&2 + usage 3 + fi + + ### Main ### + + add "$a" "$b" + + ### Finish ### + + unset A B usage add + exit 0 + ``` + + ## Bash + + `[[ ]]` are preferred over `[ ]`, `test`, etc. `(( ))` are always fine. + + When defining a function please use both the keyword `function` as well as + the `()`, such as `function myfunc() {}`. + + When instantiating global variables, please use `typeset` or `declare` + rather than just `VAR1=""; VAR2=""`, such as: + + ``` + declare VAR1="" VAR2="" BOOL="true" BOOL2="false" + typeset -i INT1=0 INT2=99 + ``` + + When doing colored output, `tput` is always preferred over literal values. backup: false owner: "{{ user }}" group: "{{ user }}"