Skip to content

fix(cli): reject unknown flags before -- in exec/check subcommands#202

Merged
fohte merged 4 commits intomainfrom
fohte/reject-unknown-flags
Mar 13, 2026
Merged

fix(cli): reject unknown flags before -- in exec/check subcommands#202
fohte merged 4 commits intomainfrom
fohte/reject-unknown-flags

Conversation

@fohte
Copy link
Owner

@fohte fohte commented Mar 13, 2026

Why

  • Unrecognized flags (e.g. --config) passed to exec/check subcommands were silently absorbed into the command Vec by clap, causing exit 0 with no error
    • The trailing_var_arg = true + allow_hyphen_values = true combination treated unknown flags as positional arguments

What

  • Validate raw process args before clap parsing to detect and reject unknown flags appearing before --
    • Tokens after the first non-flag token (the command name) are treated as command arguments, so patterns like runok check ls -la (without --) continue to work

Open with Devin

`trailing_var_arg = true` + `allow_hyphen_values = true` caused clap to
silently absorb unknown flags (e.g. `--config`) into the `command` Vec
instead of reporting an error. This meant typos like
`runok check --config foo break` would exit 0 with unexpected behavior.

Add a pre-parse validation step that inspects raw process args to detect
unrecognized flags before `--`. Once a non-flag token (the command name)
is encountered, all subsequent tokens are treated as command arguments.
Flags after `--` are always allowed since they belong to the target
command.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a subtle but critical issue in the command-line interface where unknown flags for exec and check subcommands were not being properly rejected. By introducing a pre-parsing validation step, the application now provides immediate feedback for incorrect flag usage, significantly improving the robustness and user experience of the CLI. This change ensures that command-line arguments are interpreted as intended, preventing silent failures and potential misconfigurations.

Highlights

  • Improved CLI Argument Parsing: Implemented a new validation step to explicitly reject unknown flags appearing before the -- separator in exec and check subcommands. This prevents unrecognized flags from being silently absorbed as command arguments, which previously led to unexpected behavior and exit code 0.
  • Enhanced User Feedback: Users will now receive a clear error message when an unknown flag is provided, guiding them to correctly separate runok flags from command arguments using --.
  • New Validation Module: A dedicated validate module was introduced to encapsulate the logic for checking raw command-line arguments, ensuring cleaner separation of concerns and testability.
Changelog
  • docs/src/content/docs/cli/check.md
    • Added documentation clarifying that unrecognized flags before -- are now rejected with an error.
  • docs/src/content/docs/cli/exec.md
    • Updated documentation to highlight that unrecognized flags before -- are now rejected, preventing silent absorption into command arguments.
  • src/cli/mod.rs
    • Introduced a new validate module.
    • Exported the validate_no_unknown_flags function for use within the CLI.
  • src/cli/validate.rs
    • Added a new module validate.rs containing the validate_no_unknown_flags function.
    • Implemented logic to identify and reject unknown flags for exec and check subcommands before the -- separator.
    • Included comprehensive unit tests for both valid and invalid argument scenarios using rstest.
  • src/main.rs
    • Imported the validate_no_unknown_flags function.
    • Integrated the flag validation into the main function, checking raw arguments for exec and check subcommands before clap parsing.
    • Added error handling to print a user-friendly message and exit with a failure code if unknown flags are detected.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@codecov
Copy link

codecov bot commented Mar 13, 2026

Codecov Report

❌ Patch coverage is 89.36170% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.26%. Comparing base (25c6749) to head (df21773).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
src/main.rs 62.50% 3 Missing ⚠️
src/cli/validate.rs 94.87% 2 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main     #202   +/-   ##
=======================================
  Coverage   89.26%   89.26%           
=======================================
  Files          47       48    +1     
  Lines        9046     9093   +47     
=======================================
+ Hits         8075     8117   +42     
- Misses        971      976    +5     
Flag Coverage Δ
Linux 89.15% <89.36%> (+<0.01%) ⬆️
macOS 90.60% <89.36%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

gemini-code-assist[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

Review feedback pointed out three issues:
1. `known_flags` and `flags_with_value` were defined as separate arrays,
   creating a maintenance risk if a new flag with a value is added to one
   but not the other.
2. Manual index management with a `while` loop was less idiomatic than
   using iterators.
3. `check` subcommand validation errors returned exit code 1 instead of
   the documented exit code 2.

Consolidate flag definitions into a single `FlagDef` struct, replace
the index-based loop with an iterator, and use the correct exit code
per subcommand convention.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…alidation

The pre-parse validator rejected `--help`/`-h` and `--version`/`-V`
because they were not listed in the subcommand-specific flag definitions.
These flags are automatically added by clap and must pass through
validation so clap can handle them normally.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…lper

CLAUDE.md requires using the shlex crate for shell splitting. The test
helper was using split_whitespace which would break on quoted arguments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@fohte fohte merged commit 7344abd into main Mar 13, 2026
10 checks passed
@fohte fohte deleted the fohte/reject-unknown-flags branch March 13, 2026 16:46
@fohte-bot fohte-bot bot mentioned this pull request Mar 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant