Documentation
¶
Overview ¶
Example ¶
An app scans its script commands, puts them under its cobra root and runs a call with its own API module.
package main
import (
"context"
"fmt"
"strings"
"testing/fstest"
"github.com/spf13/cobra"
"github.com/hakastein/cliche"
)
func main() {
scripts := fstest.MapFS{
"greet.js": &fstest.MapFile{Data: []byte(`
const app = require("app");
exports.definition = {
short: "Greet someone",
long: "Greet someone by name.",
args: [{ name: "name", type: "string", usage: "who to greet" }],
flags: [{ name: "shout", type: "bool", usage: "greet loudly" }],
};
exports.command = (name, flags) => {
const text = "Hello, " + name + "!";
return flags.shout ? app.upper(text) : text;
};
`)},
}
config := cliche.Config{Name: "demo", Sources: []cliche.Source{cliche.FS("scripts", scripts)}}
env := cliche.Env{Modules: map[string]any{
"app": cliche.NewObject([]string{"upper"}, []any{
cliche.Func(func(_ context.Context, args ...any) (any, error) {
return strings.ToUpper(args[0].(string)), nil
}),
}),
}}
root := &cobra.Command{Use: "demo", SilenceUsage: true}
cliche.Merge(config.Scan()).AddTo(root, func(cmd *cobra.Command, command *cliche.Command, in cliche.Input) error {
value, err := cliche.Run(cmd.Context(), command, in, env)
if err != nil {
return err
}
fmt.Println(value)
return nil
})
root.SetArgs([]string{"greet", "world", "--shout"})
if err := root.Execute(); err != nil {
fmt.Println(err)
}
}
Output: HELLO, WORLD!
Index ¶
- func Place(ctx context.Context) (file string, line, column int)
- func Run(ctx context.Context, c *Command, in Input, env Env) (any, error)
- type Arg
- type Broken
- type Catalog
- type Command
- type Config
- type Env
- type FetchError
- type FileError
- type Flag
- type Func
- type Getter
- type Input
- type InterruptedError
- type Key
- type List
- type Literal
- type LiteralObject
- type Map
- type Node
- type Object
- type Root
- type ScriptError
- type ScriptFields
- type Slot
- type Source
- type Type
- type Undefined
- type UsageError
- type Warning
- type Word
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Arg ¶
type Arg struct {
// Line and Column are where the declaration writes the argument.
Line, Column int
Name string
Type string
Usage string
Group []Slot
Optional bool
Multiple bool
}
Arg is one element of the call: a single value of Type, or a group of Slots.
type Broken ¶
type Broken struct {
Path []string
Err *ScriptError
}
Broken is a path that is no command: a call of it ends in Err. A root that cannot be read is broken at no path.
type Catalog ¶
Catalog is the commands, the broken paths and the warnings of all roots after the rule of conflicts.
func Merge ¶
Merge is the default rule of conflicts: of two equal command paths the one of the earlier root is kept and the later one is a warning. A root that cannot be read is a broken path.
func (*Catalog) AddTo ¶
func (c *Catalog) AddTo(root *cobra.Command, run func(cmd *cobra.Command, command *Command, in Input) error)
AddTo puts the commands of c under root: each script command under the group of its path, and a hidden command per broken path whose call is its error. A group is made for a word no command of root holds yet; called without a subcommand it knows, it is a *UsageError. A group made only for broken paths is hidden. run runs a script command.
type Command ¶
type Command struct {
Path []string
Short string
Long string
Args []Arg
Flags []Flag
// Keys holds what Key.Read gave for each key of Config.Keys the declaration writes; nil when Config.Keys is
// empty.
Keys map[string]any
// contains filtered or unexported fields
}
Command is a script command, read from its declaration alone, without running the module.
type Config ¶
type Config struct {
// Name gives the directory .<Name>/scripts of the default sources.
Name string
// Builtin holds the scripts built into the app; it is always the first root, its files named "builtin:<path>".
Builtin fs.FS
// Sources nil stands for DefaultSources(Name, os.Getwd(), os.UserHomeDir()); empty stands for no sources.
Sources []Source
// Types are the types of the app beyond the base ones.
Types map[string]Type
// Keys are the keys of the app in exports.definition beside short, long, args and flags, by name.
Keys map[string]Key
}
Config is what an app gives cliche to find its script commands.
type Env ¶
type Env struct {
// Modules are the values require gives by name.
Modules map[string]any
Node Node
// Error turns an error of cliche a script may catch (*FetchError) into an error of the app before it is thrown.
Error func(error) error
}
Env is what a run gives a script.
type FetchError ¶
FetchError is a fetch that got no whole response: a failed transport, a timeout, a redirect too many, or a body longer than maxBytes. A response of any status is no error.
func (*FetchError) Error ¶
func (e *FetchError) Error() string
func (*FetchError) ScriptFields ¶
func (e *FetchError) ScriptFields() Map
ScriptFields gives a script the url of the request it caught.
type FileError ¶
FileError is an error of fs that the script left uncaught: the Node code, the syscall and the path.
type Flag ¶
type Flag struct {
Line, Column int
Name string
Type string
Usage string
Multiple bool
Choices []string
Default any
}
Flag is a flag of the call. Default is nil when the declaration gives none.
type Input ¶
type Input struct {
// Args holds a value per declared argument: a single one is its value, a group a *Object of its slots, a multiple
// one a []any; an optional one not given is Undefined.
Args []any
// Flags holds the flags given and the ones with a default.
Flags *Object
}
Input is a parsed call of a script command: the arguments in their declared order and the flags.
type InterruptedError ¶
type InterruptedError struct {
Cause error
}
InterruptedError is a script stopped by the cancellation of its context; Cause is the cause of that context.
func (*InterruptedError) Error ¶
func (e *InterruptedError) Error() string
func (*InterruptedError) Unwrap ¶
func (e *InterruptedError) Unwrap() error
type Key ¶ added in v0.2.0
type Key struct {
// Required makes the key required of every declaration.
Required bool
// Read checks the value and gives what Command.Keys holds for the key. An error makes the declaration unreadable:
// an error of Literal.Errorf names the place of that literal, any other error the value of the key. Read nil keeps
// the Literal itself.
Read func(value Literal) (any, error)
}
Key is a key of the app in exports.definition beside short, long, args and flags. cliche reads its value as the same pure literal as the rest of the declaration, without running the module; what the value may be is the app's.
type Literal ¶ added in v0.2.0
Literal is a value of a declaration and its place in the script. Value is a string, a float64, a bool, nil, a []Literal or a *LiteralObject.
type LiteralObject ¶ added in v0.2.0
LiteralObject is an object of a declaration: its keys in the order written and the value of each.
type Node ¶
type Node uint8
Node is the part of the Node subset an app gives scripts. Bytes cross the bridge as a Buffer whatever it holds.
type Object ¶
type Object struct {
// contains filtered or unexported fields
}
Object is a mapping with its keys in order: one a script built, or one an app builds with NewObject.
type Root ¶
type Root struct {
// Name names the directory or the fs.FS of the source.
Name string
Builtin bool
// Err is the source that cannot be read at all.
Err *ScriptError
Words []Word
}
Root is a source read as a catalog: its first words with their commands and broken paths.
type ScriptError ¶
ScriptError is a fault of a script: an exception it left uncaught, an unreadable declaration, a broken path, or a value it returned that the bridge does not carry. File, Line and Column are the place when it is known.
func (*ScriptError) Error ¶
func (e *ScriptError) Error() string
type ScriptFields ¶
type ScriptFields interface {
ScriptFields() Map
}
ScriptFields is implemented by an error of the app that a script reads fields of in a catch block.
type Source ¶
type Source struct {
// contains filtered or unexported fields
}
Source is a directory or an fs.FS of scripts: the path of a file in it is the path of a command.
func DefaultSources ¶
DefaultSources are the nearest .<app>/scripts at or above workingDir and <home>/.<app>/scripts, in that order. The nearest one that is the user's own is no project source. An empty workingDir or home gives no source of its own; an existing path that cannot be read is a source that fails to scan.
type Type ¶
type Type struct {
// Usage is the fixed help of a value of the type; a declaration writes none.
Usage string
// Default makes default required of a flag of the type.
Default bool
// Parse reads every value of the call; nil keeps the text as it is.
Parse func(text string) (any, error)
// Value is what command gets for a flag of the type from its default and the values given; nil leaves the key
// out. Value nil stands for the last value given, else the default.
Value func(def any, given []any) any
}
Type is a type of the app for arguments, slots and flags beyond the base ones. A base type name is never an app type.
type Undefined ¶
type Undefined struct{}
Undefined is the value a script reads as undefined: an optional argument the call did not give.
type UsageError ¶
type UsageError struct {
Message string
// Cause is the error of pflag for a flag the call wrote wrong; nil for the arguments.
Cause error
}
UsageError is a call of a script command that its declaration does not take; the script did not run.
func (*UsageError) Error ¶
func (e *UsageError) Error() string
func (*UsageError) Unwrap ¶
func (e *UsageError) Unwrap() error