Skip to content
generated from snivilised/astrolib

🍦assistant for cobra based cli applications

License

Notifications You must be signed in to change notification settings

snivilised/sundae

Repository files navigation

🍦sundae: assistant for cobra based cli applications

A B A B A B Go Reference Go report Coverage Status Sundae Continuous Integration pre-commit A B

Go

🔰 Introduction

_Cobra is an excellent framework for the development of command line applications, but is missing a few features that would make it a bit easier to work with. This package aims to fulfil this purpose, especially in regards to creation of commands, encapsulating commands into a container and providing an export mechanism to re-create cli data in a form that is free from cobra (and indeed sundae) abstractions. The aim of this last aspect to to be able to inject data into the core of an application in a way that removes tight coupling to the Cobra framework, which is achieved by representing data only in terms of client defined (native) abstractions.

📚 Usage

... tbd

🎀 Features

ginkgo ginkgo

  • Cobra container; collection of cobra commands that can be independently referenced by name as opposed to via child/parent relationship. The container also takes care of adding commands to the root or any other as required.
  • A parameter set groups together all the flag option values, so that they don't have to be handled separately. A single entity (the ParamSet) can be created and passed into the core of the client application.
  • unit testing with Ginkgo/Gomega
  • implemented with 🐍 Cobra cli framework
  • i18n with go-i18n
  • linting configuration and pre-commit hooks, (see: linting-golang).

🎁 Cobra Container

The container serves as a repository for Cobra commands and Cobrass parameter sets. Commands in Cobra are related to each other via parent child relationships. The container, flattens this hierarchy so that a command can be queried for, simply by its name, as opposed to getting the commands by parent command, ie parentCommand.Commands().

The methods on the container, should not fail. Any failures that occur are due to programming errors. For this reason, when an error scenario occurs, a panic is raised.

Registering commands/parameter sets with the container, obviates the need to use specific Cobra api calls as they are handled on the clients behalf by the container. For parameter sets, the type specific methods on the various FlagSet definitions, such as Float32Var, do not have to be called by the client. For commands, AddCommand does not have to be called explicitly either.

💎 Param Set

The rationale behind the concept of a parameter set came from initial discovery of how the Cobra api worked. Capturing user defined command line input requires binding option values into disparate variables. Having to manage independently defined variables usually at a package level could lead to a scattering of these variables on an adhoc basis. Having to then pass all these items independently into the core of a client application could easily become disorganised.

To manage this, the concept of a parameter set was introduced to bring about a consistency of design to the implementation of multiple cli applications. The aim of this is to reduce the number package level global variables that have to be managed. Instead of handling multiple option variables independently, the client can group them together into a parameter set.

Each Cobra command can define multiple parameter sets which reflects the different ways that a particular command can be invoked by the user. However, to reduce complexity, it's probably best to stick with a single parameter set per command. Option values not defined by the user can already be defaulted by the Cobra api itself, but it may be, that distinguishing the way that a command is invoked (ie what combination of flags/options appear on the command line) may be significant to the application, in which case the client can define multiple parameter sets.

The ParamSet also handles flag definition on each command. The client defines the flag info and passes this into the appropriate binder method depending on the option value type. The binder methods are of the form:

  • Bind<Type> : where <Type> represents the type, (eg BindString), the client passes in 'info', a FlagInfo object and 'to' a pointer to a variable to which Cobra will bind the option value to.

🎭 Alternative Flag Set

By default, binding a flag is performed on the default flag set. This flag set is the one you get from calling command.Flags() (this is performed automatically by NewFlagInfo). However, there are a few more options for defining flags in Cobra. There are multiple flag set methods on the Cobra command, eg command.PersistentFlags(). To utilise an alternative flag set, the client should use NewFlagInfoOnFlagSet instead of NewFlagInfo. NewFlagInfoOnFlagSet requires that an extra parameter be provided and that is the alternative flag set, which can be derived from calling the appropriate method on the command, eg:

  paramSet.BindString(
    assistant.NewFlagInfoOnFlagSet("pattern", "p", "default-pattern",
      widgetCommand.PersistentFlags()), &paramSet.Native.Pattern,
  )

The flag set defined for the flag (in the above case 'pattern'), will always override the default one defined on the parameter set.

✨ Code Generation

Please see Powershell Code Generation

About

🍦assistant for cobra based cli applications

Resources

License

Stars

Watchers

Forks

Packages

No packages published