From c1489fbca6adc4e31a7156f16f1f6615afa829d0 Mon Sep 17 00:00:00 2001 From: hippietrail Date: Sun, 25 Jan 2026 17:13:13 +0700 Subject: [PATCH 1/5] fix: allow `check-rust` to complete without `cargo hack` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit instead of failing at this point it will issue the warning ``` ⚠️ cargo-hack not found. Install with 'cargo install cargo-hack' for complete feature testing. ``` --- justfile | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/justfile b/justfile index 0b08b7b78..0e26e4116 100644 --- a/justfile +++ b/justfile @@ -276,7 +276,11 @@ check-rust: auditdictionary cargo fmt -- --check cargo clippy -- -Dwarnings -D clippy::dbg_macro -D clippy::needless_raw_string_hashes - cargo hack check --each-feature + if command -v cargo-hack >/dev/null 2>&1; then + cargo hack check --each-feature + else + echo "\n⚠️ cargo-hack not found. Install with 'cargo install cargo-hack' for complete feature testing.\n" + fi # Perform format and type checking. check: check-rust check-js build-web From 6c8ab9b5dc6c0908a316e577a8cda664cf679bba Mon Sep 17 00:00:00 2001 From: hippietrail Date: Sun, 25 Jan 2026 17:26:11 +0700 Subject: [PATCH 2/5] fix: change the check for `cargo hack` --- justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/justfile b/justfile index 0e26e4116..dc3d7aeb3 100644 --- a/justfile +++ b/justfile @@ -276,7 +276,7 @@ check-rust: auditdictionary cargo fmt -- --check cargo clippy -- -Dwarnings -D clippy::dbg_macro -D clippy::needless_raw_string_hashes - if command -v cargo-hack >/dev/null 2>&1; then + if cargo --list | grep -q '^ *hack$'; then cargo hack check --each-feature else echo "\n⚠️ cargo-hack not found. Install with 'cargo install cargo-hack' for complete feature testing.\n" From 07827db9ec64dc284c94f4eb00b29e971e7f579d Mon Sep 17 00:00:00 2001 From: hippietrail Date: Tue, 27 Jan 2026 16:15:58 +0700 Subject: [PATCH 3/5] refactor: `DISABLE_CARGO_HACK` approach as per PR feedback --- justfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/justfile b/justfile index dc3d7aeb3..b43657a47 100644 --- a/justfile +++ b/justfile @@ -278,8 +278,10 @@ check-rust: auditdictionary if cargo --list | grep -q '^ *hack$'; then cargo hack check --each-feature + elif [[ "${DISABLE_CARGO_HACK:-0}" -eq 1 ]]; then + echo "ℹ️ cargo-hack disabled via DISABLE_CARGO_HACK=1" else - echo "\n⚠️ cargo-hack not found. Install with 'cargo install cargo-hack' for complete feature testing.\n" + echo "\n⚠️ cargo-hack not found. Install with 'cargo install cargo-hack' or set DISABLE_CARGO_HACK=1 to skip.\n" fi # Perform format and type checking. From 021ceafe42d17039c548f77bfb8d0fb549c60888 Mon Sep 17 00:00:00 2001 From: hippietrail Date: Wed, 28 Jan 2026 14:30:10 +0700 Subject: [PATCH 4/5] fix: fail if `cargo-hack` is missing and `DISABLE_CARGO_HACK` not specified Make `check-rust` fail if `cargo-hack` is missing unless `DISABLE_CARGO_HACK=1` is set, following the same pattern as `DISABLE_WASM_OPT`. --- justfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/justfile b/justfile index 35a6bd58b..7e5216ef5 100644 --- a/justfile +++ b/justfile @@ -295,7 +295,8 @@ check-rust: auditdictionary elif [[ "${DISABLE_CARGO_HACK:-0}" -eq 1 ]]; then echo "ℹ️ cargo-hack disabled via DISABLE_CARGO_HACK=1" else - echo "\n⚠️ cargo-hack not found. Install with 'cargo install cargo-hack' or set DISABLE_CARGO_HACK=1 to skip.\n" + echo "\n❌ cargo-hack not found. Install with 'cargo install cargo-hack' or set DISABLE_CARGO_HACK=1 to skip.\n" >&2 + exit 1 fi # Perform format and type checking. From 5e3ffd9bcaae53289dcc8bb44a66fb23d44310d2 Mon Sep 17 00:00:00 2001 From: hippietrail Date: Wed, 28 Jan 2026 23:40:05 +0700 Subject: [PATCH 5/5] =?UTF-8?q?feat:=20flash=20in=20the=20pans=E2=86=92fla?= =?UTF-8?q?shes=20in=20the=20pan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../linting/plural_wrong_word_of_phrase.rs | 39 +++++++++++++++++-- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/harper-core/src/linting/plural_wrong_word_of_phrase.rs b/harper-core/src/linting/plural_wrong_word_of_phrase.rs index d666cfe04..fd6db65ea 100644 --- a/harper-core/src/linting/plural_wrong_word_of_phrase.rs +++ b/harper-core/src/linting/plural_wrong_word_of_phrase.rs @@ -11,6 +11,8 @@ pub struct PluralWrongWordOfPhrase { // If a noun needs other than an -s suffix to be pluralized, include it as the 2nd array element. const PATTERNS: &[(&[&str], &str, &[&str])] = &[ (&["body", "bodies"], "in", &["white"]), + (&["flash", "flashes"], "in the", &["pan"]), + (&["flash", "flashes"], "in-the", &["pan"]), (&["line"], "of", &["code"]), (&["part"], "of", &["speech", "speeches"]), (&["point"], "of", &["view"]), @@ -33,7 +35,7 @@ impl Default for PluralWrongWordOfPhrase { let mut mistakes = vec![]; - for &(main_noun, prep, last_noun) in PATTERNS { + for &(main_noun, mid, last_noun) in PATTERNS { let main_pl = if main_noun.len() == 2 { main_noun[1].to_string() } else { @@ -51,7 +53,7 @@ impl Default for PluralWrongWordOfPhrase { Box::new(word_string(main_pl)), ]) .t_ws_h() - .t_aco(prep) + .then_fixed_phrase(mid) .t_ws_h() .then(word_string(last_pl)), ) as Box); @@ -82,7 +84,7 @@ impl ExprLinter for PluralWrongWordOfPhrase { last_noun_span.get_content(src), ); - let (main_noun, prep, last_noun) = PATTERNS.iter().find(|(main, _, last)| { + let (main_noun, mid, last_noun) = PATTERNS.iter().find(|(main, _, last)| { main_noun_chars.starts_with_ignore_ascii_case_str(main[0]) && last_noun_chars.starts_with_ignore_ascii_case_str(last[0]) })?; @@ -97,7 +99,7 @@ impl ExprLinter for PluralWrongWordOfPhrase { lint_kind: LintKind::Usage, span: toks.span()?, suggestions: vec![Suggestion::replace_with_match_case( - format!("{} {} {}", main_noun_pl, prep, last_noun[0]) + format!("{} {} {}", main_noun_pl, mid, last_noun[0]) .chars() .collect::>(), toks.span()?.get_content(src), @@ -232,4 +234,33 @@ mod tests { "I'm not sure, but just having seen a lot of bodies in white, I know normally they try to spot weld it.", ); } + + // FlashesInThePan + + #[test] + fn correct_flash_in_the_pans() { + assert_suggestion_result( + "I wish they do more flash in the pans, like the suggestions they do on ERB2 could be such a good way to see if these suggestions are worthy.", + PluralWrongWordOfPhrase::default(), + "I wish they do more flashes in the pan, like the suggestions they do on ERB2 could be such a good way to see if these suggestions are worthy.", + ); + } + + #[test] + fn correct_flash_in_the_pans_hyphenated() { + assert_suggestion_result( + "what makes 'Super Hexagon' rise above other nostalgic flash-in-the-pans is that there is a game to be learned here", + PluralWrongWordOfPhrase::default(), + "what makes 'Super Hexagon' rise above other nostalgic flashes in the pan is that there is a game to be learned here", + ); + } + + #[test] + fn correct_flashes_in_the_pans() { + assert_suggestion_result( + "Who are some of the biggest flashes in the pans in wrestling history?", + PluralWrongWordOfPhrase::default(), + "Who are some of the biggest flashes in the pan in wrestling history?", + ); + } }