Development
Prerequisites
- Rust and Cargo for frontend and backend (recommended: via Rustup)
- A PostgreSQL database for kittehlist to connect to
- wasm-pack for building the Rust frontend
- esbuild for bundling CSS and static files
- (optional) diesel (ORM) which must be configured for a PostgreSQL database
- (optional) minify for minifying frontend release artifacts
- (optional) pre-commit for pre-commit checks that cover the most basic CI checks; install hooks with
pre-commit install - (optional) just script runner
Basic workflow
kittehlist’s backend is a single Rust application (cargo build --bin server).
kittehlist’s frontend is a Rust WebAssembly module in addition to some static files which the server reads from the file system. The static files are bundled and minified with esbuild, while the Wasm module is built with wasm-pack. See just build-frontend for details.
The justfile provides many more utility functions, many of which are not documented elsewhere. Use just --list to view all of them and their descriptions.
For NixOS, a shell.nix development environment is provided.
You can put custom Cargo configuration options in .cargo/local.toml. This file is automatically included if it exists. Some useful unstable options are commented out in .cargo/config.toml and should be copied to local.toml before use.
kittehlist compiles for and has been tested/deployed on AArch64 and RISC-V (specifically, aarch64-unknown-linux-gnu and riscv64gc-unknown-linux-gnu). The configuration in .cargo/cross-compile.toml is set up for cross-compilation from an x86 Linux machine (tested on Ubuntu, Debian, and Arch Linux). If you want to compile for either of these architectures natively, comment out the relevant options.
Testing
By convention, dev_config.kdl is the kittehlist server configuration used for development. This file is gitignored so you can’t commit it accidentally, and it’s also what the just recipes use.
kittehlist contains plenty of tests. Use cargo test or cargo nextest run to run them. Note that on first run, due to database migrations, the multi-process cargo nextest may fail. Either use cargo nextest --jobs 1 or try re-running it.
The integration tests in the top-level tests folder will run the server in a special test mode and execute regular API calls against it. Note that these calls will of course interact with the database, and the database will be permanently changed by these tests. You should of course never use a production database for development and testing. The config used by integration tests is tests/test_config.kdl. (The tests will not compile if you don’t create this file.)
Commits and checks
We use lefthook as a pre-commit system. Use lefthook install to install the hooks.
Use reasonable descriptive commit messages. We don’t like Conventional commits (see here and here), since they are the opposite of descriptive, so do not use them.
We run the usual suite of tests, lints and other checks on CI. This includes cross-compilation to AArch64 and RISC-V 64GC. As we have experienced CI runner issues with the latter two jobs in the past, we don’t necessarily require these checks to pass for each commit.
Releasing and Packaging
This section concerns itself with how to build kittehlist release artifacts, and how to configure it for release. Note that at present, kittehlist is not in a state where it can reasonably be packaged in a sensible way.
Currently, we are not accepting contributions to add package definitions into the main kittehlist repo. We are however open to contributions which allow kittehlist to be packaged (better) on some system, including ones that don’t currently work, and to link any kittehlist package from the repo.
The Nix shell can be used as a starting point for packaging on NixOS.
Note that in addition to MIT OR Apache, the license for the Inter font used and vendored by kittehlist must be observed, which is the SIL Open Font License 1.1. All three licenses are OSI-compatible.
When building kittehlist repeatedly, build information may be cached even when some build inputs change. This is to speed up development builds where this does not matter, but it may result in kittehlist_server --version containing incorrect version or feature information (among others). To ensure that all build information is correct, delete the build directory before performing a release build.
Release Profile
Due to a long-standing limitation in wasm-opt (see also frontend below), it is not possible to use the built-in release profile for anything other than the frontend build. Therefore, the ideal release build settings have been applied to the releash profile:
$ cargo build --profile releash
Dynamic Dependencies
By default, kittehlist comes with no dynamic dependencies to simplify development and CI. This can be changed by disabling the feature no_dynamic_deps, which is on by default:
$ cargo build --no-default-features
When no_dynamic_deps is present, the PostgreSQL backend has no TLS support, since that always requires a dynamically linked OpenSSL. When this feature is missing, kittehlist requires the following dynamic libraries (and their dependencies):
libpq, PostgreSQL client library. Details on how libpq is discovered.- OpenSSL (for PostgreSQL). Details on how OpenSSL is discovered.
Frontend
The kittehlist frontend is put together from:
- static files copied by
esbuild - CSS bundled by
esbuild - WebAssembly modules and their JavaScript interface shims created by
wasm-packandwasm-bindgen
The build-release-frontend recipe additionally minifies all plaintext files using minify. This is optional but reduces the file transfer size.
It is crucial to use build-release-frontend (or directly wasm-pack with --release) for the WebAssembly module. For development purposes, we add DWARF information and don’t run wasm-opt for the debug build, which massively increases the binary size. The release build decreases the WebAssembly size from multiple megabytes down to ~300KB.
Additionally, release builds should disable the default debug_log feature and enable the disable_log feature. (The reason for two separate features is unfortunate, but rooted in how Cargo features and defaults work.) This removes both regular and panic logging, which saves 20KB+ of space. You may also consider specifying RUSTFLAGS="-C panic=abort", though in our experience it does not help much.
Paths
kittehlist does not have a built-in default for the config file. On Unix systems that run one kittehlist installation, /etc/kittehlist.kdl should be used.
On Unix systems, it is recommended to install the frontend to /usr/share/kittehlist/frontend. The default-provided configuration should reference this directory.
At the moment, kittehlist does not require write access to any paths, as all data is stored with the database.