Skip to content

fix(cli): validate --exclude regex pattern before use#251

Merged
rafaeltonholo merged 2 commits intorafaeltonholo:mainfrom
mvanhorn:osc/239-validate-exclude-regex
Mar 28, 2026
Merged

fix(cli): validate --exclude regex pattern before use#251
rafaeltonholo merged 2 commits intorafaeltonholo:mainfrom
mvanhorn:osc/239-validate-exclude-regex

Conversation

@mvanhorn
Copy link
Copy Markdown
Contributor

@mvanhorn mvanhorn commented Mar 27, 2026

Summary

Added Clikt .validate {} to the --exclude option so invalid regex patterns produce a clear error instead of an unhandled exception.

Why this matters

Running ./s2c --exclude "[invalid" ... threw a PatternSyntaxException with a stack trace. Now it shows: Error: Invalid regex pattern: "[invalid". Unclosed character class near index 8.

Changes

  • svg-to-compose/src/nativeMain/kotlin/Main.kt: Added .validate { } block to the exclude option (line 150) that tries constructing a Regex and calls fail() on error. Added validate import.

Testing

The validation runs at option-parsing time before any file processing begins. Invalid patterns now produce Clikt's standard error format.

Fixes #239

This contribution was developed with AI assistance (Claude Code).

Summary by CodeRabbit

  • Bug Fixes
    • Improved validation for the --exclude option so invalid regular expressions are detected during command parsing, producing clearer errors and preventing invalid values from proceeding.

Invalid regex patterns passed to --exclude caused an unhandled
PatternSyntaxException with a stack trace. Added Clikt .validate {}
to catch the error early and display a clear message:

  Error: Invalid regex pattern: "[invalid". Unclosed character class...

Fixes rafaeltonholo#239
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 27, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 43ccbfd1-8bcb-4826-88e3-1657db12c4e7

📥 Commits

Reviewing files that changed from the base of the PR and between dc3e04a and 32f89fb.

📒 Files selected for processing (1)
  • svg-to-compose/src/nativeMain/kotlin/Main.kt

Walkthrough

Added validation for the CLI --exclude option so the provided pattern is compiled as a regex during argument parsing; invalid patterns now cause parsing to fail with a clear error message instead of later throwing an exception.

Changes

Cohort / File(s) Summary
CLI Option Validation
svg-to-compose/src/nativeMain/kotlin/Main.kt
Added a .validate { pattern -> ... } block to the --exclude Clikt option that attempts Regex(pattern) and calls fail(...) with a user-friendly message if compilation throws, ensuring downstream code receives a valid regex or null.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding validation for the --exclude regex pattern before use, which directly addresses the primary objective of the PR.
Linked Issues check ✅ Passed The PR successfully implements the primary requirement from issue #239: validating the --exclude regex pattern at option-parsing time using Clikt's validate block and displaying a clear error message for invalid patterns.
Out of Scope Changes check ✅ Passed All changes are directly related to validating the --exclude regex pattern as specified in issue #239. The PR does not address the additional validation gaps for --indent-size and --recursive-depth mentioned as separate concerns.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
svg-to-compose/src/nativeMain/kotlin/Main.kt (1)

148-157: Consider using .convert {} to avoid compiling the regex twice.

The validation block compiles the regex to check validity, then discards it. Later at line 246, the same pattern is compiled again via exclude?.let(::Regex). Using .convert {} would validate and return the Regex in a single pass.

That said, the current implementation is correct and achieves the PR objective of providing clear error messages for invalid patterns.

♻️ Optional: Single-pass validation and conversion
 private val exclude by option(
     names = arrayOf("--exclude"),
     help = "A regex used to exclude some icons from the parsing.",
-).validate { pattern ->
+).convert { pattern ->
     try {
         Regex(pattern)
     } catch (e: Exception) {
         fail("Invalid regex pattern: \"$pattern\". ${e.message}")
     }
 }

Then at line 246, simplify to:

-                    exclude = exclude?.let(::Regex),
+                    exclude = exclude,

Also applies to: 246-246

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@svg-to-compose/src/nativeMain/kotlin/Main.kt` around lines 148 - 157, The
exclude option currently uses .validate { ... } which compiles the pattern only
to check validity and then later recompiles it with exclude?.let(::Regex);
change the option to use .convert { pattern -> try { Regex(pattern) } catch (e:
Exception) { fail("Invalid regex pattern: \"$pattern\". ${e.message}") } } so
the option returns a Regex (named exclude) directly, and then remove the later
exclude?.let(::Regex) call and use exclude (or exclude?) as a Regex value
wherever referenced (e.g., the code that previously used exclude?.let(::Regex)
at the later usage).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@svg-to-compose/src/nativeMain/kotlin/Main.kt`:
- Around line 148-157: The exclude option currently uses .validate { ... } which
compiles the pattern only to check validity and then later recompiles it with
exclude?.let(::Regex); change the option to use .convert { pattern -> try {
Regex(pattern) } catch (e: Exception) { fail("Invalid regex pattern:
\"$pattern\". ${e.message}") } } so the option returns a Regex (named exclude)
directly, and then remove the later exclude?.let(::Regex) call and use exclude
(or exclude?) as a Regex value wherever referenced (e.g., the code that
previously used exclude?.let(::Regex) at the later usage).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5b7ae189-40f1-43e0-b789-efa25474f36f

📥 Commits

Reviewing files that changed from the base of the PR and between e1a34e0 and dc3e04a.

📒 Files selected for processing (1)
  • svg-to-compose/src/nativeMain/kotlin/Main.kt

Comment on lines +154 to +156
} catch (e: Exception) {
fail("Invalid regex pattern: \"$pattern\". ${e.message}")
}
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @mvanhorn, we should avoid using a too Generic Exception handler because it can cause problems.

Here we should be catching the PatternSyntaxException instead.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Narrowed to IllegalArgumentException in 32f89fb. On Kotlin/Native, Regex() throws IllegalArgumentException for invalid patterns (there's no PatternSyntaxException on native targets - that's JVM-only, where it extends IllegalArgumentException). So this is the tightest catch available here.

Narrow the catch clause for regex validation from generic Exception to
IllegalArgumentException, which is what Kotlin/Native's Regex constructor
throws for invalid patterns. On JVM, PatternSyntaxException extends
IllegalArgumentException, so this is the correct narrowing for native
targets.
Copy link
Copy Markdown
Owner

@rafaeltonholo rafaeltonholo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks for addressing the comment!

@rafaeltonholo rafaeltonholo merged commit 48ea454 into rafaeltonholo:main Mar 28, 2026
4 checks passed
@mvanhorn
Copy link
Copy Markdown
Contributor Author

Thanks for the review and merge! Glad the regex validation approach worked out.

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.

[Bug]: CLI --exclude regex not validated, crashes with unhelpful error on invalid patterns

2 participants