6464 OptFlag = enum
6565 optHidden
6666 optDebug
67+ optObsolete
6768
6869 OptInfo = ref object
6970 name, abbr, desc, typename: string
7475 flags: set [OptFlag ]
7576 hasDefault: bool
7677 defaultInHelpText: string
78+ obsoleteMsg: string
7779 case kind: OptKind
7880 of Discriminator :
7981 isCommand: bool
@@ -270,8 +272,7 @@ func hasAbbrs(cmds: openArray[CmdInfo], excl: set[OptFlag]): bool =
270272 return true
271273 false
272274
273- func hasDebugOpts (cmds: openArray [CmdInfo ]): bool =
274- let excl = {optHidden}
275+ func hasDebugOpts (cmds: openArray [CmdInfo ], excl: set [OptFlag ]): bool =
275276 for opt in helpOptsIt (cmds, excl):
276277 if optDebug in opt.flags:
277278 return true
@@ -492,13 +493,13 @@ proc showHelp(help: var string,
492493
493494 let cmd = activeCmds[^ 1 ]
494495
495- var excl = {optHidden}
496+ var excl = {optHidden, optObsolete }
496497 if hlpDebug notin appInfo.flags:
497498 excl.incl optDebug
498499
499500 appInfo.maxNameLen = maxNameLen (activeCmds, excl)
500501 appInfo.hasAbbrs = hasAbbrs (activeCmds, excl)
501- appInfo.hasDebugOpts = hasDebugOpts (activeCmds)
502+ appInfo.hasDebugOpts = hasDebugOpts (activeCmds, excl - {optDebug} )
502503 let termWidth =
503504 try :
504505 terminalWidth ()
@@ -782,6 +783,24 @@ func requiresInput*(T: type): bool =
782783func acceptsMultipleValues * (T: type ): bool =
783784 T is seq
784785
786+ when defined (nimscript):
787+ template warnOutput (args: varargs [string ]) =
788+ writeLine (stderr, " Warning: " & join (@ args))
789+ else :
790+ template warnOutput (args: varargs [untyped ]) =
791+ errorOutput (styleBright, fgYellow, " Warning: " , resetStyle, args)
792+ errorOutput (" \p " )
793+
794+ proc obsoleteCmdOpt (T: type , opt, msg: string ) =
795+ if msg.len > 0 :
796+ warnOutput (msg, " ; " , opt, " is deprecated" )
797+ else :
798+ warnOutput (opt, " is deprecated" )
799+
800+ proc obsoleteCmdOptAux (T: type , opt, msg: string ) =
801+ mixin obsoleteCmdOpt
802+ obsoleteCmdOpt (T, opt, msg)
803+
785804template debugMacroResult (macroName: string ) {.dirty .} =
786805 when defined (debugMacros) or defined (debugConfutils):
787806 echo " \n -------- " , macroName, " ----------------------"
@@ -890,6 +909,8 @@ func readPragmaFlags(field: FieldDescription): set[OptFlag] =
890909 result .incl optHidden
891910 if field.readPragma (" debug" ) != nil :
892911 result .incl optDebug
912+ if field.readPragma " obsolete" != nil :
913+ result .incl optObsolete
893914
894915proc cmdInfoFromType (T: NimNode ): CmdInfo =
895916 result = CmdInfo ()
@@ -907,6 +928,7 @@ proc cmdInfoFromType(T: NimNode): CmdInfo =
907928 defaultInHelp = if defaultValueDesc != nil : defaultValueDesc
908929 else : defaultValue
909930 defaultInHelpText = toText (defaultInHelp)
931+ obsoleteMsg = field.readPragma " obsolete"
910932 separator = field.readPragma " separator"
911933 longDesc = field.readPragma " longDesc"
912934 envVarValueSep = field.readPragma " envVarValueSep"
@@ -932,6 +954,7 @@ proc cmdInfoFromType(T: NimNode): CmdInfo =
932954 if separator != nil : opt.separator = separator.strVal
933955 if longDesc != nil : opt.longDesc = longDesc.strVal
934956 if envVarValueSep != nil : opt.envVarValueSep = envVarValueSep.strVal
957+ if obsoleteMsg != nil : opt.obsoleteMsg = obsoleteMsg.strVal
935958
936959 inc fieldIdx
937960
@@ -1090,7 +1113,10 @@ proc loadImpl[C, SecondarySources](
10901113 config: Configuration , sources: ref SecondarySources
10911114 ) {.gcsafe , raises : [ConfigurationError ].} = nil ,
10921115 envVarsPrefix = appInvocation (),
1093- termWidth = 0
1116+ termWidth = 0 ,
1117+ loggerSetup: proc (
1118+ config: Configuration
1119+ ) {.gcsafe , raises : [ConfigurationError ].} = nil ,
10941120): Configuration {.raises : [ConfigurationError ].} =
10951121 # # Loads a program configuration by parsing command-line arguments
10961122 # # and a standard set of config files that can specify:
@@ -1369,6 +1395,17 @@ proc loadImpl[C, SecondarySources](
13691395 for cmd in activeCmds:
13701396 result .processMissingOpts (cmd)
13711397
1398+ if not isNil (loggerSetup):
1399+ try :
1400+ loggerSetup (result )
1401+ except ConfigurationError as err:
1402+ fail " Failed to setup the logger: '" & err.msg & " '"
1403+
1404+ for cmd in activeCmds:
1405+ for opt in cmd.opts:
1406+ if optObsolete in opt.flags and fieldCounters[opt.idx] != 0 :
1407+ obsoleteCmdOptAux (typeof (Configuration ), opt.humaneName (), opt.obsoleteMsg)
1408+
13721409template load * (
13731410 Configuration: type ,
13741411 cmdLine = commandLineParams (),
@@ -1379,12 +1416,14 @@ template load*(
13791416 ignoreUnknown = false ,
13801417 secondarySources: untyped = nil ,
13811418 envVarsPrefix = appInvocation (),
1382- termWidth = 0 ): untyped =
1419+ termWidth = 0 ,
1420+ loggerSetup: untyped = nil
1421+ ): untyped =
13831422 block :
13841423 let secondarySourcesRef = generateSecondarySources (Configuration )
13851424 loadImpl (Configuration , cmdLine, version,
13861425 copyrightBanner, printUsage, quitOnFailure, ignoreUnknown,
1387- secondarySourcesRef, secondarySources, envVarsPrefix, termWidth)
1426+ secondarySourcesRef, secondarySources, envVarsPrefix, termWidth, loggerSetup )
13881427
13891428func defaults * (Configuration: type ): Configuration =
13901429 load (Configuration , cmdLine = @ [], printUsage = false , quitOnFailure = false )
0 commit comments