I try to accommodate everyone's workflow. Here's ways to contribute and how, in my order of preference:
If you want to connect with me directly: my email address is at the bottom of the man pages or in the commit logs. Vulnerability disclosures should be PGP-encrypted using the PGP key 1E892DB2A5F84479. Alternatively, send an encrypted message on Matrix to
doc/SECURITY.md for information on security requirements.
Preferred and canonical ticket tracker: https://todo.sr.ht/~seirdy/MOAC. Send an email to ~email@example.com to automatically file a bug, no account needed. The tracker might also have some tickets labeled "good first issue" ideal for contributors with less experience.
I also check issues in the GitHub, GitLab, and Codeberg mirrors linked at the top of the README, if you prefer. No matter which option you choose, your bug gets emailed to me.
Preferred location: https://lists.sr.ht/~seirdy/moac. Send emails and patches to ~firstname.lastname@example.org. I also check the GitHub, GitLab, and Codeberg mirrors for issues and PRs. In fact, I'll even accept a contribution as a link to a completely different Git remote; Sourcehut's CI is remote-neutral.
Contributions don't need to follow these standards to be useful. If a useful patch doesn't pass the below checks, I might clean it up myself.
This project uses
shfmt -ln posix -bn -p -s -d, and
mdfmt -stxHeaders for formatting; it uses
shfmt (again), and
checkmake for linting. You can install all except ShellCheck to your
GOBIN by running
make fmt to format code,
make lint to run the linters (except
make test to run unit tests.
make pre-commit runs all three. I recommend using committer to auto-run pre-commit checks; just add
committer to your hooks.
The linters are very opinionated. If you find this annoying, you can send your patch anyway; I'll clean it up if it looks useful.
See the "Testing" section near the bottom for info about the tests.
doc/SECURITY.md lays out some additional requirements.
Excluding tests, MOAC has <1k SLOC; it shouldn't be hard to grok. Here's a one-minute overview:
givens.gohandles given physical values (what you'd call "the givens" if you were solving a physics problem) and computes missing values/bottlenecks.
charsets/handles parsing, building, and de-duplicating charsets to use when calculating password entropy or building passwords.
entropy/, well, calculates entropy. It figures out what charsets are contained in a password (saving these in a data structure defined by
charsets) and figures out how many combinations can fit in the resulting space.
GenPWfunction builds passwords that match the given requirements: length bounds, target entropy, and charsets to use.
.go-arch-lint.yml in the repo root lists who-imports-whom.
For the library: everything possible should be covered by tests. If a branch that handles an error should be impossible to reach and is therefore uncovered, replace it with a panic to indicate the presence of a bug. Any uncovered line that isn't a panic or a deprecated function is in need of a test.
That being said, don't write tests just for the sake of ticking off a box. Statement coverage isn't sufficient to show that most/all statements are useful and correct. Other ways to measure test comprehensiveness include branch coverage (see gobco) and mutation scores (see go-mutesting). Should you choose to give these tools a spin (you don't have to), be aware of false positives. I try to keep the mutation score above 0.7 for now.
For the CLI: this uses testscript for scenario tests.
If you want live test feedback while hacking and find the tests to be too slow (they typically take under 3s by default on my low-end notebook), set the environment variable
LOOPS to something below
make test-quick will set it to
10. Test-cases for password generation run multiple times because of the non-determinism inherent to random password generation. Tests are a bit slow since
GenPW()'s tests have thousands of test-cases generated from combinations of possible parameters.
If you notice that a change causes a big slowdown in
make test, run
make test-prof to generate a
cpu.prof file. Inspect that file with
go tool pprof cpu.prof.
make test-san will run two very slow tests: one with race-condition detection, the second with the memory sanitizer. This requires Clang to be installed with a complete
compiler-rt package; Alpine distro packages won't work.
-msan is only supported on Linux amd64/arm64; see
go help build for more info.