-
Notifications
You must be signed in to change notification settings - Fork 33
Description
Description
Problem
Applications using Fang may need to display additional custom sections in their help output beyond the standard sections (usage, commands, flags, examples). Currently, there's no way to extend Fang's help rendering to include custom content.
Use Case
CLI applications often need to display additional information in their help output, such as:
- Environment Variables - Documentation for environment variables that affect the CLI
- Learn More - Additional resources or tips
- Feedback/Support - How to report bugs or request features
- Configuration - Where config files are located
- License/Legal - License or attribution information
Many applications use Cobra's Annotations map to store this custom content:
rootCmd := &cobra.Command{
// ...
Annotations: map[string]string{
"help:environment": heredoc.Doc(`
MYAPP_HOST: Specify the URL of the server
MYAPP_TOKEN: Authentication token for API requests
// ... more env vars
`),
"help:feedback": `
Encountered a bug? Open an issue at github.com/org/repo
`,
},
}With a custom help function, these annotations can be rendered as additional sections. However, Fang's Execute() function sets its own help function internally, making it impossible to extend the help output without copying and modifying Fang's internal rendering logic.
Current Limitations
fang.Execute()setsroot.SetHelpFunc()internally and then callsExecuteContext(), which blocks- The
helpFnfunction inhelp.gois not exported, so it can't be wrapped or extended - No hooks or callbacks are provided to inject custom content before/after standard help rendering
- Copying Fang's entire help rendering logic (~481 lines) creates maintenance burden
Proposed Solutions
Option 1: Help Section Hook (Preferred)
Add an option to provide a callback that runs after Fang's standard help rendering:
fang.Execute(ctx, root,
fang.WithHelpAppender(func(w io.Writer, cmd *cobra.Command, styles Styles) {
// Custom rendering logic here
if envHelp, ok := cmd.Annotations["help:environment"]; ok {
fmt.Fprintln(w, styles.Title.Render("ENVIRONMENT VARIABLES"))
fmt.Fprintln(w, envHelp)
}
}),
)Option 2: Annotation Support
Built-in support for rendering custom annotation sections:
fang.Execute(ctx, root,
fang.WithCustomSections(map[string]string{
"help:environment": "ENVIRONMENT VARIABLES",
"help:feedback": "FEEDBACK",
}),
)Option 3: Export helpFn and makeStyles
Export the help rendering function so downstream users can wrap it:
// In fang package
func RenderHelp(c *cobra.Command, w io.Writer, styles Styles) {
// existing helpFn logic
}
// In user code
root.SetHelpFunc(func(c *cobra.Command, args []string) {
w := colorprofile.NewWriter(c.OutOrStdout(), os.Environ())
fang.RenderHelp(c, w, styles)
appendCustomSections(w, c, styles)
})
// Then call root.ExecuteContext() directly instead of fang.Execute()Benefits
- Allows applications to maintain existing help customizations when migrating to Fang
- Provides flexibility for application-specific help content
- Avoids need to fork or copy Fang's rendering logic
- Maintains Fang's excellent styling while adding custom sections