Repository: reubeno/brush
Pull request #501 (2025-05-18 07:23:25)

fix: fix typos + add spell-checking PR check
* Used [typos](https://github.com/crate-ci/typos) to find typos in code base; corrected typos.
* Added appropriate exclusions to `Cargo.toml` for files that shouldn't be checked (`CHANGELOG.md`) and string patterns to allow-list
* Added PR check to run `typos`

github-actions[bot]: # Performance Benchmark Report
| Benchmark name                         | Baseline (μs) |  Test/PR (μs) |    Delta (μs) | Delta %         |
| -------------------------------------- | ------------- | ------------- | ------------- | --------------- |
| `clone_shell_object                  ` | `   18.35 μs` | `   18.06 μs` | `   -0.28 μs` | `🟢 -1.55%    ` |
| `eval_arithmetic                     ` | `    0.17 μs` | `    0.17 μs` | `    0.00 μs` | `⚪  Unchanged` |
| `expand_one_string                   ` | `    1.82 μs` | `    1.81 μs` | `   -0.01 μs` | `⚪  Unchanged` |
| `for_loop                            ` | `   22.44 μs` | `   23.02 μs` | `    0.58 μs` | `🟠 +2.59%    ` |
| `function_call                       ` | `    2.41 μs` | `    2.39 μs` | `   -0.02 μs` | `⚪  Unchanged` |
| `instantiate_shell                   ` | `   57.33 μs` | `   57.08 μs` | `   -0.25 μs` | `⚪  Unchanged` |
| `instantiate_shell_with_init_scripts ` | `23903.67 μs` | `25083.24 μs` | ` 1179.57 μs` | `🟠 +4.93%    ` |
| `parse_bash_completion               ` | ` 1657.61 μs` | ` 1656.82 μs` | `   -0.79 μs` | `⚪  Unchanged` |
| `parse_sample_script                 ` | `    1.75 μs` | `    1.76 μs` | `    0.01 μs` | `⚪  Unchanged` |
| `run_echo_builtin_command            ` | `   15.53 μs` | `   15.47 μs` | `   -0.05 μs` | `⚪  Unchanged` |
| `run_one_external_command            ` | ` 2340.28 μs` | ` 2360.91 μs` | `   20.63 μs` | `⚪  Unchanged` |
| `tokenize_sample_script              ` | `    2.84 μs` | `    2.94 μs` | `    0.10 μs` | `🟠 +3.56%    ` |

# Code Coverage Report: Only Changed Files listed

| Package | Base Coverage | New Coverage | Difference |
| ------- | ------------- | ------------ | ---------- |
| brush-interactive/src/reedline/reedline_shell.rs | 🟢 78.29% | 🟢 78.53% | 🟢 0.24% |
| **Overall Coverage** | **🟢 76.83%** | **🟢 76.83%** | **⚪ 0%** |

_Minimum allowed coverage is_ `70%`_, this run produced_ `76.83%`

# Test Summary: bash-completion test suite
| Outcome            | Count                   | Percentage |
| ------------------ | ----------------------: | ---------: |
| ✅ Pass            | 1283            | <span style='color:green'>60.83</span> |
| ❗️ Error           | 253           | <span style='color:red'>12.00</span> |
| ❌ Fail            | 194            | <span style='color:red'>9.20</span> |
| ⏩ Skip            | 364            | 17.26 |
| ❎ Expected Fail   | 14   | 0.66 |
| ✔️ Unexpected Pass | 1 | <span style='color:red'>0.05</span> |
| 📊 Total           | 2109           | 100.00 |

<!-- Sticky Pull Request Comment -->
github-actions[bot]: ## Test Results
    3 files     14 suites   3m 37s ⏱️
  746 tests   746 ✅ 0 💤 0 ❌
2 224 runs  2 224 ✅ 0 💤 0 ❌

Results for commit 81094114.

[test-results]:data:application/gzip;base64,H4sIAL+NKWgC/13MSw6DIBSF4a0Yxh3wuC3QzTR4hYRUpeExMt17kWirHX7/Sc5CnB9tIvdOXDqSis8NDKqGEk32Ya7mTNZQt7yuEm67Hqkg/qenf9VEv8EZP56CjTHErcQyr5+cc9i0f57S77P5cNl8fMQwTT5XEMWoBsagl2ANyh6cuTKuqRiQOlRUIxVSaSTvD71I5sgIAQAA


Patch:
diff --git a/.github/workflows/spelling.yaml b/.github/workflows/spelling.yaml
new file mode 100644
index 0000000..d8f8f99
--- /dev/null
+++ b/.github/workflows/spelling.yaml
@@ -0,0 +1,22 @@
+name: Spelling
+on: [pull_request]
+
+env:
+  RUST_BACKTRACE: 1
+  CARGO_TERM_COLOR: always
+  CLICOLOR: 1
+  CLICOLOR_FORCE: 1
+
+permissions:
+  contents: read
+
+jobs:
+  spelling:
+    name: spell-check
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout brush
+        uses: actions/checkout@v4
+
+      - name: Spell check repo
+        uses: crate-ci/typos@master
diff --git a/Cargo.toml b/Cargo.toml
index cd33fb4..005b758 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -58,6 +58,28 @@ result_large_err = "allow"
 similar_names = "allow"
 struct_excessive_bools = "allow"
 
+[workspace.metadata.typos]
+files.extend-exclude = [
+    # Exclude the changelog because it's dynamically generated.
+    "/CHANGELOG.md",
+    # Remove this once impending mapfile updates are merged.
+    "/brush-core/src/builtins/mapfile.rs",
+]
+
+[workspace.metadata.typos.default]
+extend-ignore-re = [
+    # -ot is a valid binary operator
+    "-ot",
+    # Ignore 2-letter string literals, which show up in testing a fair bit.
+    '"[a-zA-Z]{2}"',
+]
+
+[workspace.metadata.typos.default.extend-words]
+# These show up in tests.
+"abd" = "abd"
+"hel" = "hel"
+"ba" = "ba"
+
 [profile.release]
 strip = true
 lto = "fat"
diff --git a/brush-core/src/builtins.rs b/brush-core/src/builtins.rs
index e07c0b6..e31b53a 100644
--- a/brush-core/src/builtins.rs
+++ b/brush-core/src/builtins.rs
@@ -414,7 +414,7 @@ fn brush_help_styles() -> clap::builder::Styles {
 /// # Returns
 ///
 /// * a parsed struct T from [`clap::Parser::parse_from`]
-/// * the remain iterator `args` with `--` and the rest arguments if they present othervise None
+/// * the remain iterator `args` with `--` and the rest arguments if they present otherwise None
 ///
 /// # Examples
 /// ```
diff --git a/brush-core/src/builtins/dot.rs b/brush-core/src/builtins/dot.rs
index 35edff9..75698cb 100644
--- a/brush-core/src/builtins/dot.rs
+++ b/brush-core/src/builtins/dot.rs
@@ -4,7 +4,7 @@ use clap::Parser;
 
 use crate::{builtins, commands};
 
-/// Evalute the provided script in the current shell environment.
+/// Evaluate the provided script in the current shell environment.
 #[derive(Parser)]
 pub(crate) struct DotCommand {
     /// Path to the script to evaluate.
diff --git a/brush-core/src/builtins/eval.rs b/brush-core/src/builtins/eval.rs
index 098f6bb..7016761 100644
--- a/brush-core/src/builtins/eval.rs
+++ b/brush-core/src/builtins/eval.rs
@@ -1,7 +1,7 @@
 use crate::{builtins, commands};
 use clap::Parser;
 
-/// Evalute the given string as script.
+/// Evaluate the given string as script.
 #[derive(Parser)]
 pub(crate) struct EvalCommand {
     /// The script to evaluate.
diff --git a/brush-core/src/builtins/let_.rs b/brush-core/src/builtins/let_.rs
index b950696..2118b04 100644
--- a/brush-core/src/builtins/let_.rs
+++ b/brush-core/src/builtins/let_.rs
@@ -3,7 +3,7 @@ use std::io::Write;
 
 use crate::{arithmetic::Evaluatable, builtins, commands};
 
-/// Evalute arithmetic expressions.
+/// Evaluate arithmetic expressions.
 #[derive(Parser)]
 pub(crate) struct LetCommand {
     /// Arithmetic expressions to evaluate.
diff --git a/brush-core/src/builtins/set.rs b/brush-core/src/builtins/set.rs
index b16b2c9..47a0c8d 100644
--- a/brush-core/src/builtins/set.rs
+++ b/brush-core/src/builtins/set.rs
@@ -12,7 +12,7 @@ builtins::minus_or_plus_flag_arg!(
     "Export variables on modification"
 );
 builtins::minus_or_plus_flag_arg!(
-    NotfyJobTerminationImmediately,
+    NotifyJobTerminationImmediately,
     'b',
     "Notify job termination immediately"
 );
@@ -89,7 +89,7 @@ pub(crate) struct SetCommand {
     #[clap(flatten)]
     export_variables_on_modification: ExportVariablesOnModification,
     #[clap(flatten)]
-    notify_job_termination_immediately: NotfyJobTerminationImmediately,
+    notify_job_termination_immediately: NotifyJobTerminationImmediately,
     #[clap(flatten)]
     exit_on_nonzero_command_exit: ExitOnNonzeroCommandExit,
     #[clap(flatten)]
diff --git a/brush-core/src/commands.rs b/brush-core/src/commands.rs
index a0584b2..5cccb99 100644
--- a/brush-core/src/commands.rs
+++ b/brush-core/src/commands.rs
@@ -19,7 +19,7 @@ use crate::{
 pub(crate) enum CommandSpawnResult {
     /// The child process was spawned.
     SpawnedProcess(processes::ChildProcess),
-    /// The command immediatedly exited with the given numeric exit code.
+    /// The command immediately exited with the given numeric exit code.
     ImmediateExit(u8),
     /// The shell should exit after this command, yielding the given numeric exit code.
     ExitShell(u8),
diff --git a/brush-core/src/processes.rs b/brush-core/src/processes.rs
index 647cc81..8c82462 100644
--- a/brush-core/src/processes.rs
+++ b/brush-core/src/processes.rs
@@ -64,7 +64,7 @@ impl ChildProcess {
     }
 }
 
-/// Reperesents the result of waiting for an executing process.
+/// Represents the result of waiting for an executing process.
 pub(crate) enum ProcessWaitResult {
     /// The process completed.
     Completed(std::process::Output),
diff --git a/brush-parser/src/parser.rs b/brush-parser/src/parser.rs
index 58e3022..b9d5a80 100644
--- a/brush-parser/src/parser.rs
+++ b/brush-parser/src/parser.rs
@@ -7,7 +7,7 @@ use crate::tokenizer::{Token, TokenEndReason, Tokenizer, TokenizerOptions, Token
 pub struct ParserOptions {
     /// Whether or not to enable extended globbing (a.k.a. `extglob`).
     pub enable_extended_globbing: bool,
-    /// Whether or not to enable POSIX complaince mode.
+    /// Whether or not to enable POSIX compliance mode.
     pub posix_mode: bool,
     /// Whether or not to enable maximal compatibility with the `sh` shell.
     pub sh_mode: bool,


Test patch:
diff --git a/brush-shell/tests/cases/command_substitution.yaml b/brush-shell/tests/cases/command_substitution.yaml
index 6347298..d02f9fc 100644
--- a/brush-shell/tests/cases/command_substitution.yaml
+++ b/brush-shell/tests/cases/command_substitution.yaml
@@ -16,7 +16,7 @@ cases:
       )
       echo $var
 
-  - name: "Ignore parantheses in comment in command substitution"
+  - name: "Ignore parentheses in comment in command substitution"
     stdin: |
       var=$(
         # :(
@@ -52,7 +52,7 @@ cases:
       `
       echo $var
 
-  - name: "Ignore parantheses in comment in command substitution (backticks)"
+  - name: "Ignore parentheses in comment in command substitution (backticks)"
     stdin: |
       var=`
         # :(
diff --git a/brush-shell/tests/cases/list.yaml b/brush-shell/tests/cases/list.yaml
index 17dac4d..734f7e3 100644
--- a/brush-shell/tests/cases/list.yaml
+++ b/brush-shell/tests/cases/list.yaml
@@ -14,7 +14,7 @@ cases:
         echo "parsed"
       )
 
-  - name: "Ignore parantheses in comment in list"
+  - name: "Ignore parentheses in comment in list"
     stdin: |
       (
         # :(
@@ -27,4 +27,3 @@ cases:
         #               $
         echo "Mr. Crabs ^"
       )
-
diff --git a/brush-shell/tests/compat_tests.rs b/brush-shell/tests/compat_tests.rs
index bfa51d2..140202d 100644
--- a/brush-shell/tests/compat_tests.rs
+++ b/brush-shell/tests/compat_tests.rs
@@ -1390,7 +1390,7 @@ struct TestOptions {
     #[clap(long = "exact")]
     pub exact_match: bool,
 
-    /// Optionaly specify a non-default path for bash
+    /// Optionally specify a non-default path for bash
     #[clap(long = "bash-path", default_value = "bash", env = "BASH_PATH")]
     pub bash_path: PathBuf,
 
@@ -1474,7 +1474,8 @@ impl TestOptions {
     }
 
     fn test_matches_filters(&self, qualified_test_name: &String, filters: &[String]) -> bool {
-        // In exact match mode, filters must be an exact match; substring matches are not considered.
+        // In exact match mode, filters must be an exact match; substring matches are not
+        // considered.
         if self.exact_match {
             filters.contains(qualified_test_name)
         } else {