Add code styleguide split into general, Go, JS, and Python files
This commit is contained in:
101
prompts/CODE_STYLEGUIDE.md
Normal file
101
prompts/CODE_STYLEGUIDE.md
Normal 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).
|
||||
Reference in New Issue
Block a user