Contributing
Thanks for your interest in contributing to ZLint! This document outlines how to set up your development environment and contribution guidelines.
Setup
You'll obviously need to have Zig installed. Right now
we are using version 0.14.0
.
Tl;Dr
If your machine has homebrew or apt-get
, run the setup script to install
necessary tools. Note that this will not install just.
just init
# or run it directly
bash tasks/init.sh
Tools
We use the following tools:
- just for running tasks
- entr for an ad-hoc watch mode
- typos for spell checking
- bun for generating boilerplate for new rules and other tasks
Details
just
and typos
are both cargo crates. If you're familiar with Rust, you can
install them with cargo install
(or even better, with cargo binstall
.
- cargo-binstall
- cargo
- homebrew
cargo install cargo-binstall
cargo binstall just typos-cli
cargo install just typos-cli
brew install just typos-cli
Otherwise, you can follow their respective installation instructions.
You'll also want entr
. We use it for checking code on save. You only need it
to run just watch
, but you'll definitely want to have this. Install it using
your package manager of choice.
- brew
- apt
brew install entr
apt install entr
Building, Testing, etc.
Run just
(with no arguments) to see a full list of available tasks.
When debugging E2E tests or the zlint
binary, using a single-threaded build is
often helpful.
just run -Dsingle-threaded
just e2e -Dsingle-threaded
Contributing New Rules
Check out the Creating Rules guide for how to write new lint rules. A list of rules we want to implement can be found on the Rule Ideas board.
Conventions
Please follow these conventions when contributing to ZLint.
Constructors and Destructors
- Constructors that allocate memory are named
init
. - Constructors that do not allocate memory are named
new
. - Destructors are named
deinit
.
File Naming and Structure
There are two kinds of files: "object" files and "namespace" files. Object files
use the entire file as a single struct
, storing their members in the top
level. Namespace files do not do this, and instead declare or re-export various
data types.
Object File Conventions
Object files use PascalCase
for the file name. Their layout follows this order:
- field properties
- Self-defined constants
- Methods (static and instance)
a. constructors and destructors (
init
,deinit
) come first b. other methods come after - Nested data structures (e.g. structs, enums, unions)
- Imports
- Tests
Namespace File Conventions
Namespace files use snake_case
for the file name. Avoid declaring functions in
the top scope of these files. This is not a hard rule, as it makes sense in some
cases, but try to group them by domain (where the domain is a struct
).
Their layout follows this order:
- Imports
- Public data types
- Public functions
- Private data types & private methods (grouped logically)
- Tests