From 58c1957e9fa5621d38666cf969156ba1f12e1060 Mon Sep 17 00:00:00 2001 From: jutty Date: Thu, 19 Mar 2026 23:37:39 -0300 Subject: [PATCH 01/10] Extend test coverage for test and fixed modules --- .forgejo/workflows/verify.yaml | 16 +-- .justfile | 12 ++- Cargo.lock | 36 ++++--- Cargo.toml | 1 - src/dev/test.rs | 59 ++++++++++- src/router/handlers/fixed.rs | 121 +++++++++++++++++++++-- src/syntax/content/parser/token/verse.rs | 61 ++++++++---- 7 files changed, 249 insertions(+), 57 deletions(-) diff --git a/.forgejo/workflows/verify.yaml b/.forgejo/workflows/verify.yaml index a8ebe71..d4fb5f8 100644 --- a/.forgejo/workflows/verify.yaml +++ b/.forgejo/workflows/verify.yaml @@ -32,19 +32,21 @@ jobs: rustup target add x86_64-unknown-linux-musl - name: Setup additional tooling - run: .forgejo/workflows/setup-tools.sh + run: | + .forgejo/workflows/setup-tools.sh + git config --add safe.directory "$PWD" - name: Build - run: just build + run: just ci build - name: Format - run: just format-assess + run: just ci format-assess - name: Lint - run: just lint-assess + run: just ci lint-assess - name: Cargo check - run: just check + run: just ci check - name: Test - run: just test + run: just ci test - name: Assess test coverage - run: just cover-assess + run: just ci cover-assess diff --git a/.justfile b/.justfile index 0112233..6dc9ac6 100644 --- a/.justfile +++ b/.justfile @@ -82,7 +82,8 @@ test-cover-quick: # Quickly update coverage reports (inaccurate) [group: 'assess'] test-cover-watch-quick: - {{ watch_cmd }} {{ just_cmd }} test-cover-quick + @{{ watch_cmd }} {{ just_cmd_no_ts }} test-cover-quick 2>&1 \ + | grep -v "process didn't exit successfully:" || true alias oq := test-cover-watch-quick @@ -432,6 +433,12 @@ default: choose: @just --choose +[script, private] +ci recipe: + id -u ci >/dev/null 2>&1 || useradd -m ci + chown -R ci:ci . + su ci -c "just {{ recipe }}" + alias ch := choose export CARGO_TERM_COLOR := 'always' @@ -441,9 +448,10 @@ glibc_target := "x86_64-unknown-linux-gnu" default_target := musl_target debug_vars := 'DEBUG=${DEBUG:-} DEBUG_FILTER=${DEBUG_FILTER:-} RUST_BACKTRACE=${RUST_BACKTRACE:-} RUSTFLAGS=${RUSTFLAGS:-}' +just_cmd := 'just --timestamp --explain --command-color green' +just_cmd_no_ts := 'just --explain --command-color green' watch_cmd := "watchexec -qc -r -e rs,toml,html --color always -- " cover_cmd := 'cargo llvm-cov --color always --ignore-filename-regex "main\.rs|log\.rs"' -just_cmd := 'just --timestamp --explain --command-color green' last_tag := `git tag --sort=-creatordate | head -1 | tr -d v` manifest_version := `grep "^version" Cargo.toml | cut -d \" -f 2` diff --git a/Cargo.lock b/Cargo.lock index a4170b3..d5037d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -528,9 +528,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "js-sys" @@ -854,9 +854,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.103.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" dependencies = [ "ring", "rustls-pki-types", @@ -1102,7 +1102,7 @@ dependencies = [ "toml_datetime", "toml_parser", "toml_writer", - "winnow", + "winnow 0.7.15", ] [[package]] @@ -1116,18 +1116,18 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.9+spec-1.1.0" +version = "1.0.10+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702d4415e08923e7e1ef96cd5727c0dfed80b4d2fa25db9647fe5eb6f7c5a4c4" +checksum = "7df25b4befd31c4816df190124375d5a20c6b6921e2cad937316de3fccd63420" dependencies = [ - "winnow", + "winnow 1.0.0", ] [[package]] name = "toml_writer" -version = "1.0.6+spec-1.1.0" +version = "1.0.7+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" +checksum = "f17aaa1c6e3dc22b1da4b6bba97d066e354c7945cac2f7852d4e4e7ca7a6b56d" [[package]] name = "tower" @@ -1475,19 +1475,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" [[package]] -name = "zerocopy" -version = "0.8.42" +name = "winnow" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3" +checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8" + +[[package]] +name = "zerocopy" +version = "0.8.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.42" +version = "0.8.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f" +checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index b8a3e87..d42bdc2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -268,5 +268,4 @@ zero_sized_map_values = "warn" # cargo negative_feature_names = "warn" redundant_feature_names = "warn" -multiple_crate_versions = "warn" wildcard_dependencies = "warn" diff --git a/src/dev/test.rs b/src/dev/test.rs index 4813531..a644e30 100644 --- a/src/dev/test.rs +++ b/src/dev/test.rs @@ -2,9 +2,11 @@ use std::{env, fs, io, path::PathBuf}; use crate::prelude::*; +#[derive(Debug)] pub struct Directories { pub original: PathBuf, pub templates: PathBuf, + pub assets: PathBuf, pub test: PathBuf, } @@ -20,6 +22,7 @@ impl Directories { let original = env::current_dir()?; let test = original.join(format!("target/mocks/{dir_name}")); let templates = test.join("templates"); + let assets = test.join("static").join("public").join("assets"); drop(fs::remove_dir_all(&test)); @@ -37,6 +40,13 @@ impl Directories { )) } + if let Err(error) = fs::create_dir_all(&assets) { + return Err(Error::with_io( + "Failed 'assets' directory creation", + error, + )) + } + if let Err(error) = env::set_current_dir(&test) { return Err(Error::with_io("Failed current directory change", error)) } @@ -44,6 +54,7 @@ impl Directories { Ok(Directories { original, templates, + assets, test, }) } @@ -68,10 +79,10 @@ pub struct Error { } impl Error { - fn with_io(message: &str, inner_io: io::Error) -> Error { + fn with_io(message: &str, inner_error: io::Error) -> Error { Error { message: String::from(message), - inner_io: Some(inner_io), + inner_io: Some(inner_error), inner_tera: None, } } @@ -132,4 +143,48 @@ mod tests { let dirs = Directories::setup("\0"); assert!(dirs.is_err()); } + + #[test] + fn display_contains_str_from_from() { + let payload = "rHneusPkYNGW0Ia0"; + let error = Error::from(payload); + assert!(format!("{error}").contains(payload)); + } + + #[test] + fn display_contains_str_from_io_error() { + let payload = "SsVi0d3Ywc8kVhwp"; + let io_payload = "LoPbZP7cJEHzAjGW"; + let io_error = std::io::Error::other(io_payload); + let error = Error::with_io(payload, io_error); + assert!(format!("{error}").contains(payload)); + assert!(format!("{error}").contains(io_payload)); + } + + #[test] + fn from_io_error() { + let payload = "YgmTKBm3VtHt5h3x9"; + let io_error = std::io::Error::other(payload); + let error = Error::from(io_error); + + assert!(error.message.contains(payload)); + } +} + +#[cfg(test)] +mod serial_tests { + use super::*; + + #[test] + fn failed_working_directory_reset() { + let dirs = Directories::setup("\0"); + + let error = dirs.unwrap_err(); + println!("{error}"); + assert!(error.message.contains("Failed test's directory creation")); + assert!( + format!("{error}") + .contains("file name contained an unexpected NUL byte") + ); + } } diff --git a/src/router/handlers/fixed.rs b/src/router/handlers/fixed.rs index 59c07a5..390e794 100644 --- a/src/router/handlers/fixed.rs +++ b/src/router/handlers/fixed.rs @@ -86,9 +86,9 @@ fn assemble(asset: Asset, graph: &Graph) -> Response { } } -#[expect(clippy::upper_case_acronyms)] #[derive(Debug)] -enum AssetErrorKind { +#[expect(clippy::upper_case_acronyms)] +pub enum AssetErrorKind { NotFound, IO, UTF8, @@ -96,11 +96,11 @@ enum AssetErrorKind { } #[derive(Debug)] -struct AssetError { - path: String, - kind: AssetErrorKind, - io_error: Option, - utf8_error: Option, +pub struct AssetError { + pub path: String, + pub kind: AssetErrorKind, + pub io_error: Option, + pub utf8_error: Option, } impl AssetError { @@ -136,8 +136,7 @@ impl std::fmt::Display for AssetError { let mut message = match self.kind { AssetErrorKind::IO => { format!( - "A default fallback for {} was found, \ - but it could not be loaded", + "File {} was found, but it could not be loaded", self.path ) }, @@ -170,6 +169,7 @@ impl std::fmt::Display for AssetError { } } +#[derive(Debug)] struct Asset { blob: Option>, text: Option, @@ -224,13 +224,14 @@ fn fallback(path: &str, graph: &Graph) -> Result { let mime = mime::Mime::guess(path); match std::fs::read(&target) { - // A matching file exists on disk + // A matching file exists on disk and is accessible Ok(content) => Ok(Asset { blob: Some(content), text: None, mime, }), Err(io_error) => { + // A matching file does not exist on disk if io_error.kind() == ErrorKind::NotFound { if let Some(content) = defaults.get(path) { Ok(Asset::from_str(content, mime)) @@ -252,6 +253,7 @@ fn fallback(path: &str, graph: &Graph) -> Result { None => not_found_error, } } + // A matching file exists on disk and is not accessible } else { Err(AssetError::new( path, @@ -668,4 +670,103 @@ mod tests { let response = file(Path("/k/j/m".to_string()), State(state)).await; assert!(response.status() == StatusCode::NOT_FOUND); } + + #[test] + fn error_from_utf8error() { + let bytes = vec![0, 159]; + let utf8error = String::from_utf8(bytes.clone()).unwrap_err(); + let error = AssetError::from(utf8error); + assert!(error.utf8_error.is_some()); + assert_eq!(error.utf8_error.unwrap().into_bytes(), bytes); + } + + #[test] + fn error_from_string() { + let payload = "r5MDnkEojW9HZDAG"; + let asset_error = AssetError::from(payload.to_string()); + println!("{asset_error}"); + assert!(asset_error.path.contains(payload)); + } + + #[test] + fn new_text_asset() { + let asset = Asset::new(&[1, 0, 1], mime::Mime::Txt).unwrap(); + + assert!(asset.blob.is_none()); + assert!(asset.text.is_some()); + assert_eq!(asset.text.unwrap(), "\u{1}\0\u{1}"); + } + + #[test] + fn new_blob_asset() { + let asset = Asset::new(&[1, 0, 1], mime::Mime::Png).unwrap(); + + assert!(asset.blob.is_some()); + assert!(asset.text.is_none()); + assert_eq!(asset.blob.unwrap(), &[1, 0, 1]); + } + + #[test] + fn asset_from_str() { + let payload = "\u{1}\0\u{6}"; + let asset = Asset::from_str(payload, mime::Mime::Ico); + assert_eq!(asset.blob.unwrap(), &[1, 0, 6]); + } + + #[test] + fn new_asset_utf8_error() { + let bad_bytes = [0xff, 0xc0, 0xf5, 0xc1, 0x80]; + + let error = Asset::new(&bad_bytes, mime::Mime::Txt).unwrap_err(); + + assert!(matches!(&error.kind, AssetErrorKind::UTF8)); + assert!(format!("{error}").contains("UTF8 decoding error")); + } + + #[test] + fn not_found_asset_error() { + let error = fallback("not_found.png", &Graph::default()).unwrap_err(); + + assert!(matches!(&error.kind, AssetErrorKind::NotFound)); + assert!( + format!("{error}") + .contains("The file was not found in the searched path") + ); + } +} + +#[cfg(test)] +#[cfg(unix)] +#[expect(clippy::panic_in_result_fn)] +mod serial_tests { + use std::{fs, os::unix::fs::PermissionsExt as _}; + + use super::*; + use crate::dev::test::{Directories, Error}; + + #[test] + fn io_asset_error() -> Result<(), Error> { + let dirs = Directories::setup("io_asset_error")?; + + let assets = dirs.assets.clone(); + let file = assets.join("unreadable.png"); + + fs::write(&file, [1, 0, 1])?; + let mut permissions = fs::metadata(&file)?.permissions(); + permissions.set_mode(0o200); + fs::set_permissions(&file, permissions)?; + + let new_permissions = fs::metadata(&file)?.permissions(); + assert_eq!(new_permissions.mode() & 0o777, 0o200); + + let error = fallback("unreadable.png", &Graph::default()).unwrap_err(); + + assert!(matches!(&error.kind, AssetErrorKind::IO)); + assert!( + format!("{error}") + .contains("was found, but it could not be loaded") + ); + + Ok(()) + } } diff --git a/src/syntax/content/parser/token/verse.rs b/src/syntax/content/parser/token/verse.rs index 919929a..0c0d696 100644 --- a/src/syntax/content/parser/token/verse.rs +++ b/src/syntax/content/parser/token/verse.rs @@ -3,16 +3,10 @@ use crate::syntax::content::{Parseable, parser::Lexeme}; #[derive(Debug, Clone, Eq, PartialEq)] pub struct Verse { open: Option, - citation: Option, } impl Verse { - pub const fn new(open: bool) -> Verse { - Verse { - open: Some(open), - citation: None, - } - } + pub const fn new(open: bool) -> Verse { Verse { open: Some(open) } } pub fn probe_end(lexeme: &Lexeme) -> bool { lexeme.match_char_triple('\n', '&', '\n') @@ -24,12 +18,7 @@ impl Parseable for Verse { lexeme.match_char_triple('\n', '&', '\n') } - fn lex(_lexeme: &Lexeme) -> Verse { - Verse { - open: None, - citation: None, - } - } + fn lex(_lexeme: &Lexeme) -> Verse { Verse { open: None } } fn render(&self) -> String { if let Some(open) = self.open { @@ -59,12 +48,44 @@ impl std::fmt::Display for Verse { None => "unknown", }; - let citation = if self.citation.is_some() { - " cited" - } else { - "" - }; - - write!(f, "Verse [{display_open_state}{citation}]") + write!(f, "Verse [{display_open_state}]") + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn lexed_verse_is_empty() { + let verse = Verse::lex(&Lexeme::default()); + assert!(verse.open.is_none()); + } + + #[test] + fn flat_verse_is_empty() { + let verse = Verse::new(true); + assert!(verse.flatten().is_empty()); + } + + #[test] + #[should_panic( + expected = "Attempt to render a verse tag while open state is unknown" + )] + fn render_attempt_with_unknown_open_state() { + let verse = Verse::lex(&Lexeme::default()); + verse.render(); + } + + #[test] + fn display() { + let open = Verse::new(true); + assert_eq!(format!("{open}"), "Verse [open]"); + + let closed = Verse::new(false); + assert_eq!(format!("{closed}"), "Verse [closed]"); + + let unknown = Verse::lex(&Lexeme::default()); + assert_eq!(format!("{unknown}"), "Verse [unknown]"); } } From 61ccabeb125540f8c8391b27d671a604fc2b173f Mon Sep 17 00:00:00 2001 From: jutty Date: Sat, 21 Mar 2026 09:11:47 -0300 Subject: [PATCH 02/10] CI: Add debug output for git safe.directory --- .forgejo/workflows/verify.yaml | 10 ++++++---- .justfile | 3 +++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.forgejo/workflows/verify.yaml b/.forgejo/workflows/verify.yaml index d4fb5f8..a30847c 100644 --- a/.forgejo/workflows/verify.yaml +++ b/.forgejo/workflows/verify.yaml @@ -26,15 +26,17 @@ jobs: - name: Setup Rust toolchain run: | - rustup component add llvm-tools-preview - rustup component add --toolchain nightly rustfmt clippy - rustup target add x86_64-unknown-linux-gnu - rustup target add x86_64-unknown-linux-musl + #rustup component add llvm-tools-preview + #rustup component add --toolchain nightly rustfmt clippy + #rustup target add x86_64-unknown-linux-gnu + #rustup target add x86_64-unknown-linux-musl - name: Setup additional tooling run: | .forgejo/workflows/setup-tools.sh git config --add safe.directory "$PWD" + git config --global safe.directory + ls -la - name: Build run: just ci build diff --git a/.justfile b/.justfile index 6dc9ac6..5bb9969 100644 --- a/.justfile +++ b/.justfile @@ -437,7 +437,10 @@ choose: ci recipe: id -u ci >/dev/null 2>&1 || useradd -m ci chown -R ci:ci . + git config --global safe.directory + ls -la su ci -c "just {{ recipe }}" + su ci -c "git config --global safe.directory" alias ch := choose From 3974755531b92b68d5f167b054dff5621c855397 Mon Sep 17 00:00:00 2001 From: jutty Date: Sat, 21 Mar 2026 09:15:09 -0300 Subject: [PATCH 03/10] CI: Add more debug output --- .forgejo/workflows/verify.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.forgejo/workflows/verify.yaml b/.forgejo/workflows/verify.yaml index a30847c..e6b9862 100644 --- a/.forgejo/workflows/verify.yaml +++ b/.forgejo/workflows/verify.yaml @@ -34,8 +34,11 @@ jobs: - name: Setup additional tooling run: | .forgejo/workflows/setup-tools.sh + echo "git config add" git config --add safe.directory "$PWD" + echo "git config get" git config --global safe.directory + echo "ls -la" ls -la - name: Build From 1abbe08c6f3f25ea89b53ed434a3d71a5144e504 Mon Sep 17 00:00:00 2001 From: jutty Date: Sat, 21 Mar 2026 09:16:40 -0300 Subject: [PATCH 04/10] CI: Make git config get infallible --- .forgejo/workflows/verify.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/verify.yaml b/.forgejo/workflows/verify.yaml index e6b9862..2208684 100644 --- a/.forgejo/workflows/verify.yaml +++ b/.forgejo/workflows/verify.yaml @@ -37,7 +37,7 @@ jobs: echo "git config add" git config --add safe.directory "$PWD" echo "git config get" - git config --global safe.directory + git config --global safe.directory || true echo "ls -la" ls -la From bb62f1ae17f60cfdefb58cfa41790db79de013ef Mon Sep 17 00:00:00 2001 From: jutty Date: Sat, 21 Mar 2026 09:18:24 -0300 Subject: [PATCH 05/10] CI: Make git config get infallible in justfile too --- .forgejo/workflows/verify.yaml | 2 +- .justfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/verify.yaml b/.forgejo/workflows/verify.yaml index 2208684..6357fb5 100644 --- a/.forgejo/workflows/verify.yaml +++ b/.forgejo/workflows/verify.yaml @@ -37,7 +37,7 @@ jobs: echo "git config add" git config --add safe.directory "$PWD" echo "git config get" - git config --global safe.directory || true + git config --global safe.directory 2>&1 || true echo "ls -la" ls -la diff --git a/.justfile b/.justfile index 5bb9969..e892fa5 100644 --- a/.justfile +++ b/.justfile @@ -437,7 +437,7 @@ choose: ci recipe: id -u ci >/dev/null 2>&1 || useradd -m ci chown -R ci:ci . - git config --global safe.directory + git config --global safe.directory 2>&1 || true ls -la su ci -c "just {{ recipe }}" su ci -c "git config --global safe.directory" From 39fe2d57cc41f96d037120c7bf1311f2267b0c58 Mon Sep 17 00:00:00 2001 From: jutty Date: Sat, 21 Mar 2026 09:21:36 -0300 Subject: [PATCH 06/10] CI: Cleanup debug output --- .forgejo/workflows/verify.yaml | 5 ----- .justfile | 3 --- 2 files changed, 8 deletions(-) diff --git a/.forgejo/workflows/verify.yaml b/.forgejo/workflows/verify.yaml index 6357fb5..891ef4b 100644 --- a/.forgejo/workflows/verify.yaml +++ b/.forgejo/workflows/verify.yaml @@ -34,12 +34,7 @@ jobs: - name: Setup additional tooling run: | .forgejo/workflows/setup-tools.sh - echo "git config add" git config --add safe.directory "$PWD" - echo "git config get" - git config --global safe.directory 2>&1 || true - echo "ls -la" - ls -la - name: Build run: just ci build diff --git a/.justfile b/.justfile index e892fa5..6dc9ac6 100644 --- a/.justfile +++ b/.justfile @@ -437,10 +437,7 @@ choose: ci recipe: id -u ci >/dev/null 2>&1 || useradd -m ci chown -R ci:ci . - git config --global safe.directory 2>&1 || true - ls -la su ci -c "just {{ recipe }}" - su ci -c "git config --global safe.directory" alias ch := choose From 66470d16a84147792d7ac65d81a31d2e086c6ca5 Mon Sep 17 00:00:00 2001 From: jutty Date: Sat, 21 Mar 2026 09:23:03 -0300 Subject: [PATCH 07/10] CI: Drop extra 'git config set' for safe.directory --- .forgejo/workflows/verify.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.forgejo/workflows/verify.yaml b/.forgejo/workflows/verify.yaml index 891ef4b..2c0c8f8 100644 --- a/.forgejo/workflows/verify.yaml +++ b/.forgejo/workflows/verify.yaml @@ -34,7 +34,6 @@ jobs: - name: Setup additional tooling run: | .forgejo/workflows/setup-tools.sh - git config --add safe.directory "$PWD" - name: Build run: just ci build From f9d9e304e53a9c7fa8d08e7dfe001792faef5b38 Mon Sep 17 00:00:00 2001 From: jutty Date: Sat, 21 Mar 2026 09:24:16 -0300 Subject: [PATCH 08/10] CI: Reenable rustup commands --- .forgejo/workflows/verify.yaml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.forgejo/workflows/verify.yaml b/.forgejo/workflows/verify.yaml index 2c0c8f8..27531a3 100644 --- a/.forgejo/workflows/verify.yaml +++ b/.forgejo/workflows/verify.yaml @@ -26,14 +26,13 @@ jobs: - name: Setup Rust toolchain run: | - #rustup component add llvm-tools-preview - #rustup component add --toolchain nightly rustfmt clippy - #rustup target add x86_64-unknown-linux-gnu - #rustup target add x86_64-unknown-linux-musl + rustup component add llvm-tools-preview + rustup component add --toolchain nightly rustfmt clippy + rustup target add x86_64-unknown-linux-gnu + rustup target add x86_64-unknown-linux-musl - name: Setup additional tooling - run: | - .forgejo/workflows/setup-tools.sh + run: .forgejo/workflows/setup-tools.sh - name: Build run: just ci build From efcbab04c620a776d78b5b1a1cd430112be6c076 Mon Sep 17 00:00:00 2001 From: jutty Date: Thu, 19 Mar 2026 23:37:39 -0300 Subject: [PATCH 09/10] Extend test coverage for test and fixed modules --- .forgejo/workflows/verify.yaml | 16 +++++++++------- .justfile | 6 ++++++ Cargo.lock | 4 ++-- src/router/handlers/fixed.rs | 6 +++++- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/.forgejo/workflows/verify.yaml b/.forgejo/workflows/verify.yaml index a8ebe71..d4fb5f8 100644 --- a/.forgejo/workflows/verify.yaml +++ b/.forgejo/workflows/verify.yaml @@ -32,19 +32,21 @@ jobs: rustup target add x86_64-unknown-linux-musl - name: Setup additional tooling - run: .forgejo/workflows/setup-tools.sh + run: | + .forgejo/workflows/setup-tools.sh + git config --add safe.directory "$PWD" - name: Build - run: just build + run: just ci build - name: Format - run: just format-assess + run: just ci format-assess - name: Lint - run: just lint-assess + run: just ci lint-assess - name: Cargo check - run: just check + run: just ci check - name: Test - run: just test + run: just ci test - name: Assess test coverage - run: just cover-assess + run: just ci cover-assess diff --git a/.justfile b/.justfile index 14705dd..6dc9ac6 100644 --- a/.justfile +++ b/.justfile @@ -433,6 +433,12 @@ default: choose: @just --choose +[script, private] +ci recipe: + id -u ci >/dev/null 2>&1 || useradd -m ci + chown -R ci:ci . + su ci -c "just {{ recipe }}" + alias ch := choose export CARGO_TERM_COLOR := 'always' diff --git a/Cargo.lock b/Cargo.lock index 87d028d..d5037d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -854,9 +854,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.103.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" dependencies = [ "ring", "rustls-pki-types", diff --git a/src/router/handlers/fixed.rs b/src/router/handlers/fixed.rs index 770d139..390e794 100644 --- a/src/router/handlers/fixed.rs +++ b/src/router/handlers/fixed.rs @@ -724,7 +724,7 @@ mod tests { } #[test] - fn not_found_fallback_error() { + fn not_found_asset_error() { let error = fallback("not_found.png", &Graph::default()).unwrap_err(); assert!(matches!(&error.kind, AssetErrorKind::NotFound)); @@ -736,6 +736,7 @@ mod tests { } #[cfg(test)] +#[cfg(unix)] #[expect(clippy::panic_in_result_fn)] mod serial_tests { use std::{fs, os::unix::fs::PermissionsExt as _}; @@ -755,6 +756,9 @@ mod serial_tests { permissions.set_mode(0o200); fs::set_permissions(&file, permissions)?; + let new_permissions = fs::metadata(&file)?.permissions(); + assert_eq!(new_permissions.mode() & 0o777, 0o200); + let error = fallback("unreadable.png", &Graph::default()).unwrap_err(); assert!(matches!(&error.kind, AssetErrorKind::IO)); From f856866a5334cc8d37b08fdcd00f8cea5714f076 Mon Sep 17 00:00:00 2001 From: jutty Date: Sat, 21 Mar 2026 09:11:47 -0300 Subject: [PATCH 10/10] Fix Git safe.directory errors --- .forgejo/workflows/verify.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.forgejo/workflows/verify.yaml b/.forgejo/workflows/verify.yaml index d4fb5f8..27531a3 100644 --- a/.forgejo/workflows/verify.yaml +++ b/.forgejo/workflows/verify.yaml @@ -32,9 +32,7 @@ jobs: rustup target add x86_64-unknown-linux-musl - name: Setup additional tooling - run: | - .forgejo/workflows/setup-tools.sh - git config --add safe.directory "$PWD" + run: .forgejo/workflows/setup-tools.sh - name: Build run: just ci build