Skip to content

Conversation

silverweed
Copy link
Contributor

We now have enough C++ executables (with more to be ported) to justify sharing some code between them, in particular option parsing.

This PR introduces a simple option parser class that covers most of our cases. Not all cases (e.g. hadd keeps its custom parsing because it's a bit weird), but it's already enough to cover rootls and rootbrowse, and will in the future also cover rootcp, rootmv etc.

The parser is documented with code examples and properly tested and it's about 300 lines of codes (about an order of magnitude less than e.g. cxxopts which in my opinion is overkill for our use case).

Checklist:

  • tested changes locally
  • updated the docs (if necessary)

Copy link

github-actions bot commented Oct 9, 2025

Test Results

    19 files      19 suites   3d 3h 52m 28s ⏱️
 3 667 tests  3 666 ✅ 0 💤 1 ❌
68 916 runs  68 912 ✅ 0 💤 4 ❌

For more details on these failures, see this check.

Results for commit c566635.

♻️ This comment has been updated with latest results.

Copy link
Member

@pcanal pcanal left a comment

Choose a reason for hiding this comment

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

LGTM (Beside the comments and portability issue)

@ferdymercury
Copy link
Collaborator

ferdymercury commented Oct 9, 2025

Thanks a lot for the initiative!

Even if it's 300 lines of code, isn't it better to rely on something external that gets auto-maintained, even if it's bigger in number of lines of code?
Such as the header-only https://github.com/CLIUtils/CLI11 by @henryiii

Or to understand better the motivation, what do we gain by having a small parser for which we have to add our own tests?

  • Is it because then compile time is smaller?
  • Or is initialization time more performant?
  • Or is the overkill of CLI11 or cxxopt increasing the size of the produced binaries or sth like that?
  • Or to not rely on external sources?

@silverweed
Copy link
Contributor Author

Thanks a lot for the initiative!

Even if it's 300 lines of code, isn't it better to rely on something external that gets auto-maintained, even if it's bigger in number of lines of code? Such as the header-only https://github.com/CLIUtils/CLI11

Or to understand better the motivation, what do we gain by having a small parser for which we have to add our own tests?

* Is it because then compile time is smaller?

* Or is initialization time more performant?

* Or is the overkill of CLI11 or cxxopt increasing the size of the produced binaries or sth like that?

* Or to not rely on external sources?

It's mostly the last point (though the first is also somewhat important).
Simply put, if the functionality is not particularly complex (as is this case) it's always better to have your own code that you know what it does and can easily control than an external dependency that you need to maintain and complicates your build system.
Furthermore, if such dependency is 10x the code size (without providing at least 10x the benefits) then you would just be carrying around much more weight than you really need.
External dependencies are not free and should only be used where there is a really good argument for them, which in this case I don't see.

@henryiii
Copy link
Contributor

On the flipside, a library that is heavily used is more likely to come across all of the weird edge cases that are going to end up making the custom implementation significantly longer eventually.

When I designed CLI11, I did have ROOT in mind, and with that you could actually make it easy to have a user extend an application. That would definitely be more than 10x functionality.

@silverweed
Copy link
Contributor Author

weird edge cases that are going to end up making the custom implementation significantly longer eventually.

This is an unprovable assumption as of now - if we start finding such edge cases regularly then this might tilt the decision towards an external library. It's very easy to change our mind later after all, this is all "leaf code", which brings me to the second point:

you could actually make it easy to have a user extend an application

I don't see the point here: the user cannot "extend" a binary like rootls or rootcp as in "use it as a library", and if they want to write some sort of wrapper around them they are free to bring their own option parsing library. optparse.hxx is not meant to be used as a library, which is why it's in src and not in inc/ROOT.

That would definitely be more than 10x functionality.

Again, this is conjecture which can only be proven with actually trying both things. My position is: let's start with the simpler option, then if we realize it was a mistake we can easily swap the implementation later.

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.

4 participants