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"
|
license = "MIT"
|
||||||
rust-version = "1.95"
|
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]
|
[workspace.dependencies]
|
||||||
ferese-shape = { git = "https://github.com/ferese-wm/ferese-shape", tag = "v0.1.0" }
|
ferese-shape = { git = "https://github.com/ferese-wm/ferese-shape", tag = "v0.1.0" }
|
||||||
bitflags = "2.9.4"
|
bitflags = "2.9.4"
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ferese-activities = { path = "../crates/ferese-activities" }
|
ferese-activities = { path = "../crates/ferese-activities" }
|
||||||
ferese-panel = { path = "../crates/ferese-panel" }
|
ferese-panel = { path = "../crates/ferese-panel" }
|
||||||
|
|||||||
@@ -5,5 +5,8 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ferese-layout = { path = "../ferese-layout" }
|
ferese-layout = { path = "../ferese-layout" }
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ferese-activities = { path = "../ferese-activities" }
|
ferese-activities = { path = "../ferese-activities" }
|
||||||
regex = "1.12"
|
regex = "1.12"
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ferese-layout = { path = "../ferese-layout" }
|
ferese-layout = { path = "../ferese-layout" }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ferese-activities = { path = "../ferese-activities" }
|
ferese-activities = { path = "../ferese-activities" }
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
|
|||||||
@@ -5,4 +5,7 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ferese-animation = { path = "../ferese-animation" }
|
ferese-animation = { path = "../ferese-animation" }
|
||||||
ferese-layout = { path = "../ferese-layout" }
|
ferese-layout = { path = "../ferese-layout" }
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["client", "server"]
|
default = ["client", "server"]
|
||||||
client = ["dep:wayland-client", "wayland-protocols-wlr/client"]
|
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)]
|
#![forbid(unsafe_code)]
|
||||||
|
|
||||||
/// Semantic surface effects protocol.
|
/// Semantic surface effects protocol.
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ferese-config = { path = "../ferese-config" }
|
ferese-config = { path = "../ferese-config" }
|
||||||
ferese-ipc = { path = "../ferese-ipc" }
|
ferese-ipc = { path = "../ferese-ipc" }
|
||||||
|
|||||||
@@ -5,5 +5,8 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ferese-layout = { path = "../ferese-layout" }
|
ferese-layout = { path = "../ferese-layout" }
|
||||||
ferese-panel = { path = "../ferese-panel" }
|
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.
|
- [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.
|
- [Development](development.md): build Ferese, run tests and check portal contracts.
|
||||||
- [Publishing activities](development/activities.md): IPC schema, ownership, limits and templates.
|
- [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.
|
- [Animation model](animation-model.md): geometry, spring motion, gestures and prediction.
|
||||||
- [Rendering diagnostics](rendering-performance.md): outcome counters, capture cost and repeatable hardware baselines.
|
- [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.
|
- [Output management tests](output-management-testing.md): profiles, hotplug and DRM failures.
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
# Development
|
# 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:
|
Install the [build dependencies](installation.md#requirements), then run:
|
||||||
|
|
||||||
```sh
|
```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
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ferese-activities = { path = "../crates/ferese-activities" }
|
ferese-activities = { path = "../crates/ferese-activities" }
|
||||||
clap = { version = "4.5", features = ["derive"] }
|
clap = { version = "4.5", features = ["derive"] }
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "xdg-desktop-portal-ferese"
|
name = "xdg-desktop-portal-ferese"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "1.95.0"
|
channel = "1.95.0"
|
||||||
profile = "minimal"
|
profile = "minimal"
|
||||||
components = ["rustfmt"]
|
components = ["rustfmt", "clippy"]
|
||||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ferese-theme-client = { path = "../../crates/ferese-theme-client" }
|
ferese-theme-client = { path = "../../crates/ferese-theme-client" }
|
||||||
ferese-ipc = { path = "../../crates/ferese-ipc" }
|
ferese-ipc = { path = "../../crates/ferese-ipc" }
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ferese-theme-client = { path = "../../crates/ferese-theme-client" }
|
ferese-theme-client = { path = "../../crates/ferese-theme-client" }
|
||||||
ferese-ipc = { path = "../../crates/ferese-ipc" }
|
ferese-ipc = { path = "../../crates/ferese-ipc" }
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ferese-panel = { path = "../../crates/ferese-panel" }
|
ferese-panel = { path = "../../crates/ferese-panel" }
|
||||||
ferese-theme-client = { path = "../../crates/ferese-theme-client" }
|
ferese-theme-client = { path = "../../crates/ferese-theme-client" }
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ edition.workspace = true
|
|||||||
license.workspace = true
|
license.workspace = true
|
||||||
rust-version.workspace = true
|
rust-version.workspace = true
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
fff-search = "=0.11.0"
|
fff-search = "=0.11.0"
|
||||||
mime_guess = "2.0.5"
|
mime_guess = "2.0.5"
|
||||||
|
|||||||
Reference in new issue
Block a user