Add code styleguide split into general, Go, JS, and Python files

This commit is contained in:
2026-02-22 16:26:52 +01:00
parent 2ab09985e0
commit d523ff37ae
4 changed files with 712 additions and 0 deletions

101
prompts/CODE_STYLEGUIDE.md Normal file
View File

@@ -0,0 +1,101 @@
# sneak/styleguide
The following is the first released version of my personal code styleguide.
There are many like it, but this one is mine.
Only the Go portion is "complete". The others are mostly just placeholders.
Feedback and suggestions are not only welcome but explicitly encouraged.
[sneak@sneak.berlin](mailto:sneak@sneak.berlin)
# My 2024 Code Styleguide
## All
1. Every project/repo should have a `Makefile` in the root. At a minimum,
`make clean`, `make run`, `make fmt`, and `make test` should work. Choose a
sane default target (`test` for libraries, `run` or `publish` for binaries).
`fmt` should invoke the appropriate formatters for the files in the repo,
such as `go fmt`, `prettier`, `black`, etc. Other standard `Makefile` targets
include `deploy`, `lint`. Consider the `Makefile` the official documentation
about how to operate the repository.
1. If it's possible to write a `Dockerfile`, include at least a simple one. It
should be possible to build and run the project with `docker build .`.
1. For F/OSS-licensed software, try to include the full source code of the
current version (and any dependencies, such as vendored dependencies) in the
docker image. They're small and should be included with the binary.
1. Under no circumstances should any credentials or secrets ever be committed to
any repository, even private ones. Store secrets in environment variables,
and if they are absolutely required, check on startup to make sure they are
set/non-default and complain loudly if not. Exception, sometimes: public
keys. (Public keys can still sometimes be secrets for operational security
reasons.)
1. Avoid nesting `if` statements. If you have more than one level of nesting,
consider inverting the condition and using `return` to exit early.
1. Almost all services/servers should accept their configuration via environment
variables. Only go full config file if absolutely necessary.
1. For services/servers, log JSON to stdout. This makes it easier to parse and
aggregate logs when run under `docker`. Use structured logging whenever
possible. You may detect if the output is a terminal and pretty-print the
logs in that case.
1. Debug mode is enabled by setting the environment variable `DEBUG` to a
non-empty string. This should enable verbose logging and such. It will never
be enabled in prod.
1. For services/servers, make a healthcheck available at
`/.well-known/healthcheck`. This is out of spec but it is my personal
standard. This should return a 200 OK if the service is healthy, along with a
JSON object containing the service's name, uptime, and any other relevant
information, and a key of "status" with a value of "ok" if the service is
healthy. Make sure that in the event of a failure, the service returns a 5xx
status code for that route.
1. If possible, for services/servers, include a /metrics endpoint that returns
Prometheus-formatted metrics. This is not required for all services, but is a
nice-to-have.
## Bash / Shell
1. Use `[[` instead of `[` for conditionals. It's a shell builtin and doesn't
have to execute a separate process.
1. Use `$( )` instead of backticks. It's easier to read and nest.
1. Use `#!/usr/bin/env bash` as the shebang line. This allows the script to be
run on systems where `bash` is not in `/bin`.
1. Use `set -euo pipefail` at the top of every script. This will cause the
script to exit if any command fails, and will cause the script to exit if any
variable is used before it is set.
1. Use `pv` for progress bars when piping data through a command. This makes it
easier to see how much data has been processed.
1. Put all code in functions, even a main function. Define all functions then
call main at the bottom of the file.
## Docker Containers (for services)
1. Use `runit` with `runsvinit` as the entrypoint for all containers. This
allows for easy service management and logging. In startup scripts
(`/etc/service/*/run`) in the container, put a `sleep 1` at the top of the
script to avoid spiking the cpu in the case of a fast-exiting process (such
as in an error condition). This also limits the maximum number of error
messages in logs to 86400/day.
# Author
[@sneak](https://sneak.berlin)
<[sneak@sneak.berlin](mailto:sneak@sneak.berlin)>
# License
MIT. See [LICENSE](../LICENSE).