venom

package module
v0.0.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 20, 2023 License: Apache-2.0 Imports: 18 Imported by: 0

README

venom

All you need to know about cobra commands. Generate documentation in a variety of formats, similar to what's available in Cobra but with some simplifications and fixes.

GitHub release (latest SemVer) Go Version Apache 2.0 License
build Go Report Card

Features

  • Documentation output for Markdown, YAML, JSON, reStructuredText
  • Customizable YAML and JSON marshaling
  • User-defined templating for Markdown and reStructuredText

TODO

  • Manpage support

Install

go get -u github.com/jimschubert/venom

Usage

Venom can be used either to add a documentation command as a child to another command, or to perform ad hoc writes of documentation directly.

The options, constructed via venom.NewOptions(), are the same for both use cases. These options follow the builder pattern to make available options easily discoverable.

All defined formats will be generated into the output directory, which defaults to docs and is configurable.

As a child command

First, initialize venom.NewOptions(). Next, initialize venom by passing your root command the above options. For example:

func init() {
	opts := venom.NewOptions().
		WithFormats(venom.Yaml | venom.Json | venom.Markdown).
		WithShowHiddenCommands()
	cobra.CheckErr(venom.Initialize(rootCmd, opts))
}

Here is a full example of generating only markdown:

package main

import (
	"github.com/jimschubert/venom"
	"github.com/spf13/cobra"
)

var rootCmd = &cobra.Command{
	Use:   "example",
	Short: "root command",
	RunE: func(cmd *cobra.Command, args []string) error {
		return cmd.Help()
	},
}

func init() {
	rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
	opts := venom.NewOptions().WithFormats(venom.Markdown)
	cobra.CheckErr(venom.Initialize(rootCmd, opts))
}

func main() {
	rootCmd.Execute()
}

If you compile and run this application, you won't see a docs command because it's hidden. Invoke the hidden command (e.g. example docs) to output the documentation.

The docs subcommand which venom creates will allow the user to specify a subset of the allowed formats, to define a new output directory, and to show all hidden commands.

Usage:
  example docs [flags]

Flags:
      --formats strings   A comma-separated list of formats to output. Allowed: [yaml,markdown] (default [yaml,markdown])
  -h, --help              help for docs
      --out-dir string    The target output directory (default "docs")
      --show-hidden       Also show hidden commands

Via Write

Suppose you want to wire this functionality up into an existing documentation command, or maybe you want to generate on build via a go generator utility command. You can do this by invoking the Write command directly.

For example:

docs := venom.NewDocumentation(rootCmd, venom.NewOptions().WithFormats(venom.Markdown))
if err := venom.Write(docs)); err != nil {
	// do something with err
}

Custom Templates

You can provide your own templates if the built-in templates don't suit your needs. The built-in templates are intended to match as closely as possible with those output by Cobra's built-in command. But, there are cases where these aren't desirable. For instance:

  • markdown-driven doc sites like Docusaurus generate first-level headers if missing in markdown
  • you want front-matter for an extended markdown system like Jekyll
  • you want to do something unexpected like output Asciidoc by tweaking the Markdown templates
  • you simply don't like the formatting

To provide custom templates, you just need to make sure your files are named exactly the same as they are under ./templates in this repository. Then, pass an implementation of fs.FS to our options. You can use go embed to read an entire directory called your_directory like this:

//go:embed your_directory/*.tmpl
var templates embed.FS

func init() {
	opts := venom.NewOptions().WithCustomTemplates(templates)
	cobra.CheckErr(venom.Initialize(rootCmd, opts))
}

And as long as you have both markdown_command.tmpl and markdown_index.tmpl defined under your_directory, you're all set!

The types definitions which are bound to these templates can be found in ./types.go.

Command templates will be bound to a data structure matching:

struct {
    Command
    Doc Documentation
}

The embedded Command allows you to interact with the command's fields directly at the top level of the template. The Doc field is the full documentation, providing you access to the root command and all child commands.

Index templates will be bound to the Documentation structure directly.

NOTE Not all output formats are template driven. Be sure to review ./templates.

Build/Test

go test -v -race -cover ./...

License

This project is licensed under Apache 2.0.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Initialize

func Initialize(cmd *cobra.Command, options *Options) error

Initialize a new documentation command with cmd as the parent, providing options for customization The provided command will always provide documentation from the *root*, which allows the caller to list this automated command under other administrative/tooling/hidden commands as needed.

func Write

func Write(documentation Documentation) error

Write to outDir the documentation for all given formats

Types

type Command

type Command struct {
	Name            string            `yaml:"name,omitempty" json:"name,omitempty"`
	Usage           string            `yaml:"usage,omitempty" json:"usage,omitempty"`
	Aliases         []string          `yaml:"aliases,omitempty" json:"aliases,omitempty"`
	SuggestFor      []string          `yaml:"suggestFor,omitempty" json:"suggestFor,omitempty"`
	Short           string            `yaml:"short,omitempty" json:"short,omitempty"`
	Long            string            `yaml:"long,omitempty" json:"long,omitempty"`
	GroupID         string            `yaml:"groupID,omitempty" json:"groupID,omitempty"`
	ValidArgs       []string          `yaml:"validArgs,omitempty" json:"validArgs,omitempty"`
	ArgAliases      []string          `yaml:"argAliases,omitempty" json:"argAliases,omitempty"`
	Deprecated      string            `yaml:"deprecated,omitempty" json:"deprecated,omitempty"`
	Annotations     map[string]string `yaml:"annotations,omitempty" json:"annotations,omitempty"`
	Version         string            `yaml:"version,omitempty" json:"version,omitempty"`
	Hidden          bool              `yaml:"hidden" json:"hidden"`
	Runnable        bool              `yaml:"runnable" json:"runnable"`
	RawFlagUsages   string            `yaml:"rawFlagUsages,omitempty" json:"rawFlagUsages,omitempty"`
	Parent          *ParentCommand    `yaml:"parent,omitempty" json:"parent,omitempty"`
	Subcommands     []Command         `yaml:"subcommands,omitempty" json:"subcommands,omitempty"`
	LocalFlags      []Flag            `yaml:"localFlags,omitempty" json:"localFlags,omitempty"`
	InheritedFlags  []Flag            `yaml:"inheritedFlags,omitempty" json:"inheritedFlags,omitempty"`
	PersistentFlags []Flag            `yaml:"persistentFlags,omitempty" json:"persistentFlags,omitempty"`
	Examples        []string          `yaml:"examples,omitempty" json:"examples,omitempty"`
	FullPath        string            `yaml:"fullPath,omitempty" json:"fullPath,omitempty"`
}

Command is a different representation of cobra.Command

func NewCommandFromCobra

func NewCommandFromCobra(cmd *cobra.Command, options *Options) Command

NewCommandFromCobra creates a venom.Command from a cobra.Command

type Documentation

type Documentation struct {
	GenerationDate    string  `yaml:"generationDate,omitempty" json:"generationDate,omitempty"`
	AutoGenerationTag string  `yaml:"autoGenerationTag,omitempty" json:"autoGenerationTag,omitempty"`
	RootCommand       Command `yaml:"rootCommand,omitempty" json:"rootCommand,omitempty"`
	// contains filtered or unexported fields
}

Documentation represents the "top-level" of documentation to be passed to a template

func NewDocumentation added in v0.0.3

func NewDocumentation(cmd *cobra.Command, options *Options) Documentation

func (*Documentation) Write added in v0.0.3

func (d *Documentation) Write() error

Write these docs

type Flag

type Flag struct {
	Name                string `json:"name,omitempty" yaml:"name,omitempty"`
	Shorthand           string `json:"shorthand,omitempty" yaml:"shorthand,omitempty"`
	Usage               string `json:"usage,omitempty" yaml:"usage,omitempty"`
	DefValue            string `json:"defValue,omitempty" yaml:"defValue,omitempty"`
	NoOptDefVal         string `json:"noOptDefVal,omitempty" yaml:"noOptDefVal,omitempty"`
	Deprecated          string `json:"deprecated,omitempty" yaml:"deprecated,omitempty"`
	Hidden              bool   `json:"hidden,omitempty" yaml:"hidden,omitempty"`
	ShorthandDeprecated string `json:"shorthandDeprecated,omitempty" yaml:"shorthandDeprecated,omitempty"`
	Inherited           bool   `json:"inherited,omitempty" yaml:"inherited,omitempty"`
	Persistent          bool   `json:"persistent,omitempty" yaml:"persistent,omitempty"`
	Local               bool   `json:"local,omitempty" yaml:"local,omitempty"`
	RawUsage            string `json:"rawUsage,omitempty" yaml:"rawUsage,omitempty"`
}

Flag is a representation of pflag.Flag

type Formats

type Formats byte

Formats defines the flag of supported documentation formats

const (
	// Markdown will result in Markdown/CommonMark style output
	Markdown Formats = 1 << iota
	// Man will result in manpage format
	Man
	// Yaml will result in the YAML 1.1+ format
	Yaml
	// ReST will result in Restructured Text format
	ReST
	// Json will result in JavaScript Object Notation (JSON) format
	Json
)

func (*Formats) IsSet

func (f *Formats) IsSet(format Formats) bool

IsSet determines if the desired flag(s) are set

func (*Formats) IsValid

func (f *Formats) IsValid() bool

IsValid determines if this set of Formats flags are valid; anything set but not defined in the Formats flag set will return false.

func (*Formats) Set

func (f *Formats) Set(format Formats) *Formats

Set will define the desired flag(s)

func (Formats) String added in v0.0.2

func (i Formats) String() string

func (*Formats) Unset

func (f *Formats) Unset(format Formats) *Formats

Unset will remove the desired flag(s)

type Logger

type Logger interface {
	// Printf is a common signature used by log.Logger, logrus.Logger, and others
	Printf(format string, v ...any)
}

Logger allows the user to provide any logger fulfilling this interface

type MarshalFn

type MarshalFn func(in interface{}) (out []byte, err error)

MarshalFn is a common interface allowing the caller to provide yaml/json marshaller functions

type Options

type Options struct {
	// contains filtered or unexported fields
}

Options provides a builder-pattern of user-facing optional functionality when constructing via venom.Initialize

func NewOptions

func NewOptions() *Options

NewOptions provides a new set of options with default command name ("docs") and formats (Markdown). The value returned here follows the builder pattern for easily discovering and applying available options.

func (*Options) DisableUserCommandOptions added in v0.0.2

func (o *Options) DisableUserCommandOptions() *Options

DisableUserCommandOptions allows the caller to define fixed options such as output directory, supported doc formats, etc. Default behavior is a documentation command which provides defaults defined by the caller, but exposing a subset of options to the user.

func (*Options) TemplateOptions

func (o *Options) TemplateOptions() TemplateOptions

TemplateOptions provides the value of current TemplateOptions

func (*Options) WithCommandName

func (o *Options) WithCommandName(name string) *Options

WithCommandName allows the caller to provide the target command name, which is used to construct a cobra.Command for documentation.

func (*Options) WithCustomTemplates added in v0.0.3

func (o *Options) WithCustomTemplates(fs fs.FS) *Options

WithCustomTemplates allows the user to provide an implementation which provide custom templates for any template-driven format.

func (*Options) WithFormats

func (o *Options) WithFormats(formats Formats) *Options

WithFormats allows the caller to define formats which differ from the Options defaults.

func (*Options) WithJsonMarshal

func (o *Options) WithJsonMarshal(fn MarshalFn) *Options

WithJsonMarshal allows the caller to define a custom JSON marshaling function, default is json.Marshal from the Go standard library.

func (*Options) WithLogger

func (o *Options) WithLogger(logger Logger) *Options

WithLogger allows the caller to define a target log implementation for any warnings or errors from the initialized command.

func (*Options) WithMaxOptionWidthInMarkdown added in v0.0.8

func (o *Options) WithMaxOptionWidthInMarkdown(width int) *Options

func (*Options) WithOutDirectory

func (o *Options) WithOutDirectory(out string) *Options

WithOutDirectory allows the caller to define an output directory which differs from the default ./docs.

func (*Options) WithShowHiddenCommands

func (o *Options) WithShowHiddenCommands() *Options

WithShowHiddenCommands allows the caller to signify whether details about hidden commands should be present in the final output

func (*Options) WithStripAnsiInMarkdown added in v0.0.2

func (o *Options) WithStripAnsiInMarkdown() *Options

WithStripAnsiInMarkdown allows the caller to require ANSI characters to be stripped when processing markdown files.

func (*Options) WithYamlMarshal

func (o *Options) WithYamlMarshal(fn MarshalFn) *Options

WithYamlMarshal allows the caller to define a custom YAML marshaling function, default is yaml.Marshal (v3) as depended by cobra.

type ParentCommand

type ParentCommand struct {
	Name     string `yaml:"name,omitempty" json:"name,omitempty"`
	Short    string `yaml:"short,omitempty" json:"short,omitempty"`
	FullPath string `yaml:"fullPath,omitempty" json:"fullPath,omitempty"`
}

ParentCommand provides the name of a command's parent

type TemplateOptions

type TemplateOptions struct {
	Logger                   Logger
	JsonMarshaler            MarshalFn
	YamlMarshaler            MarshalFn
	StripAnsiInMarkdown      bool
	MaxOptionWidthInMarkdown int
	Templates                fs.FS
}

TemplateOptions are those options provided to the templating system

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL