Enforce shared Rust lint policy and document review rules
This commit is contained in:
1 parent
f2e728b503
commit
34f2f07301
24 files changed
+148
-1
No files matched your search
+13
@@ -27,6 +27,19 @@ edition = "2024"
|
||||
license = "MIT"
|
||||
rust-version = "1.95"
|
||||
|
||||
[workspace.lints.rust]
|
||||
unsafe_op_in_unsafe_fn = "deny"
|
||||
unused_must_use = "deny"
|
||||
|
||||
[workspace.lints.clippy]
|
||||
borrowed_box = "deny"
|
||||
must_use_candidate = "warn"
|
||||
needless_for_each = "warn"
|
||||
ptr_arg = "deny"
|
||||
ref_option = "deny"
|
||||
undocumented_unsafe_blocks = "deny"
|
||||
wildcard_imports = "deny"
|
||||
|
||||
[workspace.dependencies]
|
||||
ferese-shape = { git = "https://github.com/ferese-wm/ferese-shape", tag = "v0.1.0" }
|
||||
bitflags = "2.9.4"
|
||||
|
||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
ferese-activities = { path = "../crates/ferese-activities" }
|
||||
ferese-panel = { path = "../crates/ferese-panel" }
|
||||
|
||||
@@ -5,5 +5,8 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
serde.workspace = true
|
||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
ferese-layout = { path = "../ferese-layout" }
|
||||
serde.workspace = true
|
||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
ferese-activities = { path = "../ferese-activities" }
|
||||
regex = "1.12"
|
||||
|
||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
ferese-layout = { path = "../ferese-layout" }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
ferese-activities = { path = "../ferese-activities" }
|
||||
serde.workspace = true
|
||||
|
||||
@@ -5,4 +5,7 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
ferese-animation = { path = "../ferese-animation" }
|
||||
ferese-layout = { path = "../ferese-layout" }
|
||||
|
||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[features]
|
||||
default = ["client", "server"]
|
||||
client = ["dep:wayland-client", "wayland-protocols-wlr/client"]
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// The scanner's generated modules resolve protocol objects through these namespaces.
|
||||
#![allow(
|
||||
clippy::wildcard_imports,
|
||||
reason = "Wayland scanner bindings require protocol imports"
|
||||
)]
|
||||
#![forbid(unsafe_code)]
|
||||
|
||||
/// Semantic surface effects protocol.
|
||||
|
||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
ferese-config = { path = "../ferese-config" }
|
||||
ferese-ipc = { path = "../ferese-ipc" }
|
||||
|
||||
@@ -5,5 +5,8 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
serde.workspace = true
|
||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
ferese-layout = { path = "../ferese-layout" }
|
||||
ferese-panel = { path = "../ferese-panel" }
|
||||
|
||||
@@ -43,6 +43,7 @@ and [guides at that tag](https://github.com/ferese-wm/ferese/tree/v0.1.0-beta/do
|
||||
- [Packages and releases](packaging.md): build Fedora and Arch packages and publish a tagged release.
|
||||
- [Development](development.md): build Ferese, run tests and check portal contracts.
|
||||
- [Publishing activities](development/activities.md): IPC schema, ownership, limits and templates.
|
||||
- [Rust style](development/rust-style.md): module boundaries, ownership, API contracts and enforced checks.
|
||||
- [Animation model](animation-model.md): geometry, spring motion, gestures and prediction.
|
||||
- [Rendering diagnostics](rendering-performance.md): outcome counters, capture cost and repeatable hardware baselines.
|
||||
- [Output management tests](output-management-testing.md): profiles, hotplug and DRM failures.
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# Development
|
||||
|
||||
Follow the [Rust style rules](development/rust-style.md) when changing workspace code.
|
||||
They cover module boundaries, API contracts, ownership and the checks enforced by CI.
|
||||
|
||||
Install the [build dependencies](installation.md#requirements), then run:
|
||||
|
||||
```sh
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
# Rust style
|
||||
|
||||
Ferese follows the [Rust Style Guide](https://google.github.io/styleguide/rustguide.html)
|
||||
with the stable toolchain pinned in `rust-toolchain.toml`. Rules marked for Chromium
|
||||
or Fuchsia belong to those projects, so they do not change Ferese's Cargo layout,
|
||||
async runtimes, threading or test framework.
|
||||
|
||||
Keep each change focused enough to review and test on its own. Formatting, module
|
||||
moves and behavioral fixes should have separate commits, and a refactor should
|
||||
retain the assertions that established the existing behavior.
|
||||
|
||||
## Modules and imports
|
||||
|
||||
Keep library roots focused on module declarations and re-exports, and put substantial
|
||||
implementations in modules named for the types they own. Application entry points
|
||||
can contain the wiring needed to start their services; splitting that wiring should
|
||||
make ownership clearer rather than add forwarding layers.
|
||||
|
||||
Import types by name and qualify functions through their module unless their names
|
||||
already identify their purpose unambiguously. Each import should draw from one
|
||||
module. Avoid glob imports, with the guide's exceptions for inline tests, local enum
|
||||
matches and re-exports. The Wayland scanner's generated namespaces also need glob
|
||||
imports, and GStreamer's prelude supplies its extension traits.
|
||||
|
||||
## APIs and ownership
|
||||
|
||||
Borrow the data a function needs: use `&str` and slices instead of references to
|
||||
owned containers, and `Option<&T>` instead of `&Option<T>`. Clone when the caller
|
||||
needs independent ownership, including messages that outlive the current callback.
|
||||
Shared worker state and UI resources can use `Arc` when their lifetimes require it.
|
||||
|
||||
Name fallible constructors `try_new`, use standard traits when their contracts fit,
|
||||
and mark pure return values with `#[must_use]`. Prefer named fields when tuple
|
||||
positions would conceal meaning. Document constraints, failure conditions and
|
||||
ownership that callers cannot infer from the signature, without repeating obvious
|
||||
method names in comments.
|
||||
|
||||
Ferese's workspace crates evolve together. Their shared enums can remain exhaustive
|
||||
so adding a state makes every affected consumer visible to the compiler. Apply
|
||||
`#[non_exhaustive]` when an API crosses an independently maintained boundary and its
|
||||
consumers cannot be updated together.
|
||||
|
||||
## Safety and errors
|
||||
|
||||
Use `Result` when callers need to distinguish recoverable failures and `Option` when
|
||||
absence explains the outcome. Match a checked value rather than checking and then
|
||||
unwrapping it. If an invariant requires a panic, use `expect` to explain it.
|
||||
|
||||
Keep unsafe operations at their system or library boundary. Every unsafe block needs
|
||||
a `SAFETY:` comment explaining its actual pointer bounds, ownership, lifetime or ABI
|
||||
requirements, and unsafe functions must document what their callers guarantee.
|
||||
Never recover the contents of a poisoned mutex. A disposable cache may be skipped;
|
||||
state needed for correctness must fail or stop being used.
|
||||
|
||||
## Checks
|
||||
|
||||
Stable rustfmt uses a 100-column target. Keep imports grouped by module during
|
||||
review, since stable rustfmt does not yet enforce that setting. All workspace
|
||||
members inherit the shared Rust and Clippy lints from the root manifest.
|
||||
|
||||
```sh
|
||||
cargo fmt --all --check
|
||||
cargo clippy --locked --workspace --all-targets -- -D warnings
|
||||
cargo clippy --locked --workspace --all-targets --all-features -- -D warnings
|
||||
cargo test --locked --workspace --no-fail-fast
|
||||
python3 -m unittest discover -s scripts/tests -v
|
||||
```
|
||||
|
||||
Use the [native test guides](../development.md#test-guides) for changes to rendering,
|
||||
input, surface lifetimes or process supervision. Headless checks complement native
|
||||
and hardware testing; they do not establish frame pacing or direct-session stability.
|
||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
ferese-activities = { path = "../crates/ferese-activities" }
|
||||
clap = { version = "4.5", features = ["derive"] }
|
||||
|
||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[[bin]]
|
||||
name = "xdg-desktop-portal-ferese"
|
||||
path = "src/main.rs"
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
[toolchain]
|
||||
channel = "1.95.0"
|
||||
profile = "minimal"
|
||||
components = ["rustfmt"]
|
||||
components = ["rustfmt", "clippy"]
|
||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
ferese-theme-client = { path = "../../crates/ferese-theme-client" }
|
||||
ferese-ipc = { path = "../../crates/ferese-ipc" }
|
||||
|
||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
ferese-theme-client = { path = "../../crates/ferese-theme-client" }
|
||||
ferese-ipc = { path = "../../crates/ferese-ipc" }
|
||||
|
||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
ferese-panel = { path = "../../crates/ferese-panel" }
|
||||
ferese-theme-client = { path = "../../crates/ferese-theme-client" }
|
||||
|
||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
||||
license.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
fff-search = "=0.11.0"
|
||||
mime_guess = "2.0.5"
|
||||
|
||||
Reference in new issue
Block a user