Skip to content

Latest commit

 

History

History
103 lines (63 loc) · 4.37 KB

File metadata and controls

103 lines (63 loc) · 4.37 KB

Development Guide

Installing Dependencies

To get started it's recommended to install the Rust toolchain using rustup. If you've already installed rustup before, you can update with

rustup update

To aid in the editing and navigating of Rust code, install rust-analyzer in your development environment of choice. I highly recommend turning on your editor's format-on-save feature to keep the code properly formatted.

Next, you'll want to install the build and runtime dependencies. On Debian-based systems, this looks something like

sudo apt update && sudo apt install -y build-essential perl

Note: Although development could technically be done without this setup by using docker compose build, I don't recommend this as the main development loop as the Docker build is much slower than building locally.

Rust Basics

Compiling

To compile the server, enter the server/ directory and run

cargo build

If you would just like to check if the server compiles, you can run

cargo check

This is much faster than building, as it skips the expensive code generation step of compilation. Finally, to run, run

cargo run

Note that by default, these commands operate on the debug profile, which adds extra checks and symbols useful for debugging. However, debug is usually 10-100x slower than release builds. If you would like to compile the release profile, you can add the --release flag can be added to any of these commands.

Testing

The server-side code has a number of unit tests, most of which require a connection to the database. Make sure the PostgreSQL server is up and ready to make connections before running tests.

To run all server unit tests, run

cargo test

Some tests take a few minutes to run in debug, so you may wish to add --release to speed things up. By default, the test runner hides any console output during tests. You can opt out of this behavior with the following flag:

cargo test -- --nocapture

You can also run a subset of tests using

cargo test test_filter

where only tests with test_filter in their name or namespace will be run. You can learn about additional test options here.

If there are any test failures, make sure to start your investigation at the first test failure. Some test failures can cause other failures due to database consistency issues.

Linting

After a series of changes to the code, it's good practice to run Rust's static analysis tool, clippy, to help catch subtle bugs and style issues. You can do this by running

cargo clippy --all-targets

If a warning is particularly oppressive or unhelpful, it can be disabled locally with #[allow(clippy::warning_name)] above the offending line or globally with #![allow(clippy::warning_name)].

Adding a Migration

Sometimes it is necessary to make modifications to the database schema. To accomplish this, you must add a migration to the oxibooru/server/migrations/ directory. These migrations consist of a up.sql that makes the modification and a down.sql that reverts the modification.

Diesel uses the schema.rs file to keep track of the current state of the database in order to make compile-time checks on constructed queries. However, this is not automatically updated when a migration is added. DO NOT update schema.rs manually. Instead, use the Diesel CLI to run the new migration and generate a new schema.rs.

Using the Diesel CLI

If you haven't already, install the Diesel CLI. Once you've down this, navigate to the server directory and run

diesel migration run --database-url='postgres://POSTGRES_USER:POSTGRES_PASSWORD@localhost:POSTGRES_PORT/POSTGRES_DB'

where POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_PORT, and POSTGRES_DB are the values of the environment variables defined in .env.

Each migration is run inside a transaction and will be reverted automatically if an error is encountered. After a migration is applied successfully, it's good practice to make sure that it is reversible. To do this, run

diesel migration redo --database-url='postgres://POSTGRES_USER:POSTGRES_PASSWORD@localhost:POSTGRES_PORT/POSTGRES_DB'

which applies the down.sql and then up.sql again.