使用Cobra更改为新标志名称时,如何支持旧标志名称?

问题描述

我有一个带标志名的CLI,我想对其进行重命名,但是我也想这样做,因此此更改是向后兼容的,并且仍然可以使用旧的标志名,例如:

# New flag name
root subcommand --no-color

# Old flag name still works
root subcommand --nocolour

我最初的想法是按照here的描述将标志名别名为新名称。这种方法的确将标志名称更改为新名称,但是并没有这样做,因此您也可以使用标志的旧名称

我通过定义另一个具有相同属性名称不同的标志并将速记方式移动到新标志来解决此问题,例如:

// Old flag name
cmd.PersistentFlags().BoolP(
    "nocolour","",false,"disable colouring (default: false)")

// New flag name
cmd.PersistentFlags().BoolP(
    "no-color","C","disable coloring (default: false)")

然后我将旧名称标记为隐藏:

cmd.PersistentFlags().MarkHidden("nocolour")

我想知道是否有一种方法可以完成上面的操作而不必定义和支持两个标志?

解决方法

我使用 cobra 提供的 SetNormalizeFunc 函数将旧标志值重命名为新标志值。

func addFlags() {
    // Define a new flag `ignore-var-run` and use the same variable opts.IgnoreVarRun to capture the flag value.
    RootCmd.PersistentFlags().BoolVarP(&opts.IgnoreVarRun,"ignore-var-run","",true,"Ignore /var/run directory when taking image snapshot. Set it to false to preserve /var/run/ in destination image. (Default true).")
    
    // Keep the old flag `whitelist-var-run` as is.
    RootCmd.PersistentFlags().BoolVarP(&opts.IgnoreVarRun,"whitelist-var-run","Ignore /var/run directory when taking image snapshot. Set it to false to preserve /var/run/ in destination image. (Default true).")
    
    // Mark the old flag as deprecated. 
    RootCmd.PersistentFlags().MarkDeprecated("whitelist-var-run","please use ignore-var-run instead.")

    // SetNormalize function to translate the use of `whitelist-var-run` to `ignore-var-run`
    RootCmd.PersistentFlags().SetNormalizeFunc(normalizeWhitelistVarRun)
}

func normalizeWhitelistVarRun(f *pflag.FlagSet,name string) pflag.NormalizedName {
    switch name {
    case "whitelist-var-run":
        name = "ignore-var-run"
        break
    }
    return pflag.NormalizedName(name)
}

这是此 https://github.com/GoogleContainerTools/kaniko/pull/1668/ 的 PR