spf13 / cobra

A Commander for modern Go CLI interactions
https://cobra.dev
Apache License 2.0
37.8k stars 2.83k forks source link

Recommended Pattern for Argument Pre-Processing? #2171

Open austinarbor opened 2 months ago

austinarbor commented 2 months ago

Is there a recommended pattern for pre-processing the arguments? I have hundreds of commands in different projects which get passed in args, but some of the args may be encrypted values and need to be decrypted before getting passed to the commands. To be more specific, the values are vault paths and network requests need to be made to fetch the actual values, but the concept is the same.

./my-cli --my-arg=/path/to/secret

Since the commands live in different repositories, I'd like to find a way to extract the common pre-processing (decryption) logic into a shareable format.

Both OnInitialize and PersistentPreRun run after arguments are parsed, so i don't think those can be used.

It seems like the only options are:

  1. Have an init function in every repo with logic to replace os.Args with the decrypted values. This would work but would basically be no common logic that could be shared (except for the decryption logic itself). This also feels easy to mess up, in that someone setting up a new repository could easily forget to add this init logic.

  2. Introduce a helper function in a common module to create the root command?

    func NewRootCommand() (*cobra.Command, error) {
    os.Args = .... // replace with decrypted values
    }

    This would solve the "easy-to-forget" issue, but the NewRootCommand function really has no purpose other than making sure the arguments get decrypted. The other problem with this approach is that if someone were to use SetArgs, it would break the logic.

Is there a better approach that I am missing?