maestro

package module
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Mar 14, 2022 License: MIT Imports: 32 Imported by: 0

README

maestro

maestro helps to organize all the tasks and/or commands that need to be performed regularly in a project whatever its nature. It could be the development of a program, administration of a single server or a set of virtual machines,...

changelog
v0.4.0
  • conditional dependency(ies)/commands (pre-conditions such as OS, files available...)
  • hazardous command property will cause a prompt of the password of the current user
  • schedule property preserve to always use the same shell context when starting new execution of the same command
  • lint sub-command
  • reload of maestro file for the serve sub-command
  • define object variable
  • add support to redirection to command subshell
  • namespaced command: command in file(s) can be namespaced to not combined them with others having same name from same or included files
  • improve help of builtin sub commands and arguments handling (schedule, listen,...)
  • improve ssh command remote execution
  • others...
v0.3.0 (2022-03-08)

below the list of additions/modifications/deletions introduces in the v0.3.0:

  • new sub-command: schedule
  • schedule command property related to the future schedule sub-command
  • variable interpolation in string
  • support for the case instruction in script command
  • support for subshell in script command via (command list) syntax
  • handling of command that must expand on multiple lines in script command (eg: for loop, if...) without introducing any macro
  • fill shell builtins
v0.2.0 (2022-01-22)

below, the list of additions/modifications/deletions introduces in the v0.2.0:

  • internal of command execution rewritten
  • command(s) can be directly called inside the script of other command(s)
  • command options and arguments validation
  • mandatory dependency(ies)
  • new sub-commands: serve, graph
  • support for test expression in command script
  • support for break and continue keyword in command script
  • minor modifications in the execution of commands via ssh
  • command suggestion(s) when given command is not known (typo,...)
  • improved error message when syntax error is found when decoding input file
maestro file

this section describes the syntax and features offered by a maestro file to write and organize your commands.

comment

a hash symbol marks the rest of the line as a comment (except when inside of a string).

# a comment
ident = value # another comment

inside command scripts, comments are written in the same way as elsewhere in the document.

basic types

maestro supports only three different primitive types:

  • literal: a literal is a sequence of characters that start with a letter and then contains only letters (lower/uppercase), digits and/or underscore.
  • string: a string is a sequence of characters that starts with a single or a double quote and ends with the same opening quote. There are no differences in the way characters inside the string are process regarding of the delimiting quotes.
  • boolean: they are just the commons values we are used to - true or false (always lowercase).

However, in some circumstances, maestro expects that values written as literal and/or string can be casted to integer values and/or duration values.

There is also a special case for boolean values. Indeed, depending of the context a boolean value will be considered as boolean but in some other case, the value of the boolean will be treated as a literal value.

Finally, maestro supports also multiline strings by using a syntax identical to the one of heredoc string of bash

some examples:

boolean = true
ident   = literal
single_quote = 'the quick brown fox jumps over the lazy dog'  
double_quote = "the quick brown fox jumps over the lazy dog"
heredoc = <<HELP
the quick brown fox
jumps over
the lazy dog!
HELP

maestro supports also a list of strings type (kind of array of string). To declare it, just provide a sequence of values separated by blank character (space or tab)

example:

list = first second third
variables
mode = dev # single value variable
package = shell shlex wrap # multi values variable
bindir = $bin # set value of variable bin to bindir

expansion = $(echo foo bar)
meta

meta are a special kind of variables that are used by maestro in order to generate the help of the input file, specify options for SSH execution, list of commands to be executed (default, all commands, before, after),...

  • .AUTHOR: author of the maestro file
  • .EMAIL: e-mail of the author of the maestro file
  • .VERSION: current version of the maestro file
  • .USAGE: short help message of the maestro file
  • .HELP: longer description of the maestro file and description of its commands/usage
  • .DUPLICATE: behaviour of maestro when it encounters a command with a name already registered. The possible values are:
    • error: throw an error if a command with the same name is already registered
    • replace: replace the previous definition of a command by the new one
    • append: make the two commands as one
  • .TRACE: enable/disabled tracing information
  • .WORKDIR: set the working directory of maestro to the given path
  • .ALL: list of commands that will be executed when calling maestro all
  • .DEFAULT: name of the command that will be executed when calling maestro without argument or by calling maestro default
  • .BEFORE: list of commands that will always be executed before the called command and its dependencies
  • .AFTER: list of commands that will always be executed after the called command has finished whatever its exit status
  • .ERROR: list of commands that will be executed after the called command has finished and its exit status is non zero (failure)
  • SUCCESS: list of commands that will be executed after the called command has finished and its exit status is zero (success)
  • .SSH_USER: username to use when executing command to remote server(s) via SSH
  • .SSH_PASSWORD: password to use when executing command to remote server(s) via SSH
  • .SSH_PARALLEL: number of instance of a command that will be executed simultaneously
  • .SSH_PUBKEY: public key file to use when executing command to remote server(s) via SSH
  • .SSH_KNOWN_HOSTS: known_hosts file to use to validate remote server(s) key
instructions
include

the include instruction allows to "include" the command of other files into the set of the current one.

the syntax to include file(s) is:

include "path/to/file.mf"[?]
# or if multiple files should be included:
include (
  "path/to/file1.mf"[?]
  ...
  "path/to/file1N.mf"[?]
)

the question mark modifier at the end of the filename specifies that the include is optional. In other words, if the given file can not be found, no error will be returned and the processing of the maestro file will continue.

Moreover, the files will be searched relative to the paths given with -I option of the maestro command. If the file can be found, then the file will be searched relatived to the current working directory or the directory set via the .WORKDIR meta.

There is an additional feature regarding included file that can be a little bit counter intuitive.

When maestro includes a file, it creates a new state from its local state before starting decoding the included files. All variables defined into the included files will be stored into this children state and as soon as maestro gets back to the original file, this sub state is discarded and references to variables of the included files are removed.

That means that variables defined in a file that should be included by maestro are only visible to the commands defined into the included file and can not be resolved by variables and/or commands defined into the "parent" file.

export

the export instruction register variables as environment variables that will be given to each command that will be executed in command scripts

the syntax to export variable is:

export IDENT=VALUE0 ... VALUEN
# or
export (
  IDENT = VALUE
  ...
  IDENT = VALUE
)
alias

the alias instruction has the same role as defining an alias within a shell.

the syntax of alias declaration is:

alias ident = command
# or
alias (
  ident = command
  ...
  ident = command
)
delete

the delete instruction can be used to delete from the locals state of maestro variable previously defined

the syntax of delete declaration is:

delete ident0 ... identN
Command

Commands are at the heart of maestro. They are composed of four parts:

  • the command name that serve as uniquely identify the command
  • properties are used by maestro to generate help of a command but they are also used by maestro to control the behaviour of the commands in case of errors, long running tasks,...
  • dependendies are a list of command's name that should be executed every time before a specific command is executed
  • the command script that are the actual code that will be run by maestro

general syntax:

[%]command([property,...]): [dependency...] {
  [modifier...]script
}
command properties
  • short: short description of a command
  • help: longer description of a command.
  • tag: list of tags to help categorize a command in comparison with other
  • alias: list of alternative name of a command
  • workdir: set working directory for the command
  • retry: number of attempts to run a command
  • timeout: maximum time given to a command in order to fully complete
  • error: behavior of maestro when the command encounters an error. The possible values are:
    • silent: ignore all error
    • error: return the first error encounters
  • user: list of users allowed to run a command
  • group: list of groups allowed to run a command
  • options: list of list that describes the options accepted by a command
  • args: list of names that describes the arguments required by a command
  • hosts: list of remote servers where a command can be executed. The expected syntax is host:port
command options and arguments

maestro allows to define the options and/or arguments that a command can accept. In the properties section of a command, there is only needs to specify the options and/or the args properties.

The options property accept a list of list with the following property:

  • short: short option
  • long: long option
  • desc: description of the option
  • flag: wheter the option is a flag or is expecting a value
  • required: wheter a value should be provided
  • default: default value to use if the option is not set

For the args property, only a list of name is needed. The command when executed will expect that the number of arguments given matched the number of arguments given in the list. If the args property is not defined then any given arguments will be given to the command without checking its number.

example

action(
	short   = "sample action", # inline comment
	tag     = example,
	options = (
		short    = "a",
		long     = "all",
		flag     = true,
	), (
		short    = "b",
		long     = "bind",
    required = true,
	)
): {
	script...
}
command dependencies

for each command defined in the maestro file, it is possible to give a list of command dependencies - command that should be executed before the actual command get executed. Moreover, if one of the command dependencies failed, the command called will not be executed. A dependency is another command defined in the maestro file or one of the include file(s).

the syntax to specify a dependency is:

[!]depname[(arguments...)][&]

where

  • !: specify that the dependency is optional and any errors returned by it will be ignored
  • depname: is the name of the command
  • arguments: a list of arguments (mix of options + their values and arguments) that should be given to the command
  • [&]: wheter the command can be run into the background and its results does not impact the result of successfull command in the list. If the command runs in background returns an error, the rest of the dependency list and the actual command won't be executed
command help

even if there is already a desc property to command in order to specify the help of a command. It can be tedious to write a multiline string in the properties declaration of a command. Of course, we can use a variable and assign a heredoc string and then assign the variable to the desc property.

However, it exists a last way to do it. This ways is inspired by python docstring. To specify the help of a command, you can use comment at the very beginning of the command scripts to generate the command help.

example

action(properties...): dependencies...{
  # this is a sample action.
  # the first comments in the command script will be used as the description
  # of the command
  #
  # blank lines will be kept in the final formatting. However, multiple blank lines
  # will be merge as one blank line
  script...
}
command script

the script is at the heart of a command. it is as the name suggest the actual script that maestro should execute in order to accomplish the task.

a script for maestro is a succession of line. Each line can be composed of two things: the script modifier (which are describes below) and the actual commands to be executed.

maestro support also the use of predefined macros in script (see below for more information). Macros are the way for maestro to modify a script. Transformations of macro are applied to the command scripts before the command gets executed.

general syntax:

[modifier]command [option] <arguments> [\]

if a line is too long, a backslash follow by a new line character at the end of the line forces maestro to read the next line as part of the current line.

maestro executes each line of a script individually and applies if specified the modifiers to command to be executed. If a line returns an error, then maestro ends the execution of the script and exit with a non-zero exit code.

modifiers

a script modifier is a way to attach specific behaviour to the script when it is executed or after it has finished:

  • -: ignore errors if script ends with a non-zero exit code
  • !: reverse the exit code of a command. If the exit code is zero then a non zero value is returned
  • @: print on stdout the command being executed
  • <: copy the full script of a command defined elsewhere in the maestro file

multiple operators can be used simultaneously. except for the copy modifier that can only be used alone

examples:

!-echo foobar
@echo foobar
<copy
repeat macro
.repeat(foo bar) {
  echo <iter> <var>
}

will be transform by maestro into

echo 1 foo
echo 2 bar

the repeat macro has three special variables that will be replaced by their actual once the macro get executed:

  • <var>: the current identifier/variable being process
  • <iter>: the current iteration of the repeat macro with 1 based index
  • <iter0>: the current iteration of the repeat macro with 0 based index
sequence macro

the sequence macro can be used to transformed a multiline sequence of a command as a single command made of a list of command.

eg:

.sequence {
  echo foo
  echo bar
}

will be transformed into:

echo foo; echo bar;
example
.VERSION = "0.1.0"
.DEFAULT = test
.ALL     = test
.AUTHOR  = midbel
.EMAIL   = "noreply@midbel.dev"
.HELP    = <<HELP
simple is a sample maestro file that can be used for any Go project.
It provides commands to automatize building, checking and testing
your Go project.
HELP

package = "github.com/midbel/maestro"

test(
	short = "run test in current directory",
	tag   = build test,
): {
  # run go test
	go clean -testcache
	@go test -cover $package
	@go test -cover "$package/shlex"
	@go test -cover "$package/shell"
}
command execution
maestro shell

in order to execute all the command and their scripts, maestro does not called an external shell such as bash or zsh... Indeed, maestro uses its own shell with its own rules, set of builtins and the rest...

maestro use the term shell even if its shell does not implement a compliant shell.

This section will describes the supported features of the maestro shell. This shell is also available as a separated binary called tish (tiny shell).

To get a complete overview of the shell syntax, you can read the manual of one of the well known shell

general syntax

Most of the syntax of the maestro shell (aka tish) is inspired by bash. However, in comparison of bash, all the rules have been overly simplify and the maestro shell does not follow systematically and formerly the same rules of bash and other well known shells. So if you're an experienced bash/shell programmer, you can/will be regularly surprised by the behaviour of the maestro shell.

the maestro shell split command lines on blank characters. Blank characters are: a space, a tab and a newline. When multiple blank characters follow each other, they are considered as one.

quoting

As traditional shells, the maestro shell has special behaviours when it encounters quotes and adapts more or less the same behaviour: disabling meaning of special character.

enclosing string between single quote character keeps the literal value of each character between the quotes.

enclosing string between double quote only keeps the special meaning of the dollar sign $ (variables, parameters expansion, command substitution and arithmetic expansion) and preserves the literal value of all others characters.

shell expansions

the maestro shell supports 7 kind of expansions described below. It performs expansion in the order they appear in the command - from left to right. It is very different than the way traditional shells perform expansion.

literals/words

when literal word are encountered, they are kept as is by the maestro shell except if special character are present in the literal (*.[). If such characters appear in the string then maestro shell will performed filename expansion at the very end if the literal is not quoted.

variables

as any other shells and programming language, the maestro shell supports the definition and usage of variables. Variables are identifier where you can store value to be used later in your script.

A variable starts with a dollar character and its name. Its name can only be composed of underscore, digits and ascii letters (lowercase and uppercase).

example:

echo $VAR

to assign a value to a variable, uses the following syntax:

VAR = foobar
parameters expansions

parameters expansions can take multiple form:

  • length
  • replace prefix/suffix/substring/all
  • slicing
  • trim prefix/suffix
  • padding
  • lowercase and uppercase

example:

$ ${#VAR} # length
$ ${VAR:offset:length} # slicing offset+length
$ ${VAR/from/to} # replace the first instance of from by to
$ ${VAR//from/to} # replace all instances of from by to
$ ${VAR/%from/to} # replace suffix instance of from by to
$ ${VAR/#from/to} # replace prefix instance of from by to
$ ${VAR%suffix} # trim suffix
$ ${VAR%%suffix} # trim longest suffix
$ ${VAR#prefix} # trim prefix
$ ${VAR##prefix} # trim longest prefix
$ ${VAR,} # set the first character of VAR to lowercase
$ ${VAR,,} # set all characters of VAR to lowercase
$ ${VAR^} # set the first character of VAR to uppercase
$ ${VAR^^} # set all characters of VAR to uppercase
$ ${VAR:<length:char} # pad left VAR with length char
$ ${VAR:>length:char} # pad right VAR with length char
braces expansions

braces expansions is a sequence introduces by the {} operator and can take two forms:

  • as a list
  • as a range (with an optional step)

example:

$ {foo,bar}
$ foo bar
$ {1..10}
$ 1 2 3 4 5 6 7 8 9 10
$ {1..10..3}
$ 1 4 7 10
arithmetic expansions

the maestro shell allows arithmetric expression to be evaluated and generates one word resulting of the computation of the expression

it supports most of the arithmetic expression supported by any well known shell and/or programming language.

syntax:

$(( expression ))

operators:

  • ++, --: increment, decrement operators
  • +, -: addition, subtraction (also unary minus)
  • *, /, %: multiplication, division, modulo
  • **: power
  • <<, >>: left and right shift
  • &, |, ~: binary and, binary or, xor (also binary not)
  • &&, ||: relational and, or
  • ==, !=: equality operator
  • <, <=, >, >=: comparison operator
  • ?: : conditional (ternary) operator
  • (): expression group
command substitutions

command substitution is the execution of a command where everything written to stdout by the command is then splitted on blank characters.

example:

echo $(echo foo bar)
filename expansions

filename expansion is like any other filename expansion. After having expanded all others form of expansions, the maestro shell looks in each expanded word for special character (*.[). If one of these characters is found, the word is then considered as a pattern. Then, for each pattern, the maestro shell will try to find all files which their filenames match the given pattern.

shell commands
simple commands

a simple command is the simplest form of command understood by the maestro shell. It is composed of a list of words separated by blank characters and resulting of the expansion of each of the individual tokens of the line.

list of commands

a list of commands is simply the concatenation of simple command on the same line. each command is separated by a semicolon character

pipelines
loop constructs

tish supports three differents looping constructs:

  • the for loop
  • the while loop
  • the until loop

in addition, the maestro shell foreseen an optional else clause for each loop when no iteration has been performed.

the for loop iterates throught the list of expanded words given and then executes each commands in the body of loop. If the expansion of words returned an empty list then the else clause of the loop is executed.

when the second form is used, the for loop will directly iterates of the results of expanded words from the output of the command. Again, if no words are expanded, then the else clause is executed.

for ident in words; do
  commands;
else
  alternative-commands;
done
# or
for command; do
  commands;
else
  alternative-commands;
done

the while loop will executes each commands in the body of the loop while the executed command returns a zero exit code. If the command returns directly a non zero exit code, then the else clause will be executed.

while command; do
  commands
else
  alternative-commands;
done

the until loop is the exact opposite of the while loop. The body of the loop will be executed while the command returns a non-zero exit code. If the command returns directly a zero exit code, then the else clause is executed

until command; do
  commands
else
  alternative-commands;
done
conditional constructs

the maestro shell currently only supports the if. Support for the case constructs is forseen for a later release.

if command; then
  commands
elif command; then
  commands
else
  commands
fi
redirections

like traditional shell, the maestro shell supports redirections. However it does not support all kind of redirections supported by well known shells.

$ command < file # redirect file to stdin of command
$ command > file # redirect stdout of command to file
$ command >> file # redirect stdout of command and append to file
$ command 2> file # redirect stderr of command to file
$ command 2>> file # redirect stderr of command and append to file
$ command &> file # redirect stdout and stderr of command to file
$ command &>> file # redirect stdout and stderr of command and append to file

As an additional note, the order of how redirections are written is important. Indeed, if you try to redirect twice stdout/stderr/stdin to different files, only the latest declaration will be taken into account and the previous will be discarded.

Last note, if using any kind of expansions (described above) the resulting expansion should only be expanded to one and only one word otherwise an error is returned.

builtins

Documentation

Index

Constants

View Source
const (
	CmdHelp     = "help"
	CmdVersion  = "version"
	CmdAll      = "all"
	CmdDefault  = "default"
	CmdListen   = "listen"
	CmdServe    = "serve"
	CmdGraph    = "graph"
	CmdSchedule = "schedule"
)
View Source
const (
	DefaultFile     = "maestro.mf"
	DefaultVersion  = "0.1.0"
	DefaultHttpAddr = ":9090"
)
View Source
const (
	Eof rune = -(iota + 1)
	Eol
	Blank
	Comment
	Ident
	Keyword
	String
	Boolean
	Variable
	Meta
	Script
	Quote
	Assign
	Append
	Comma
	Background
	Dependency
	BegList
	EndList
	BegScript
	EndScript
	Reverse
	Invalid
	Optional
	Mandatory
	Hidden
	Resolution
)
View Source
const DefaultSSHPort = 22

Variables

This section is empty.

Functions

func ServeExecute

func ServeExecute(mst *Maestro) http.Handler

func ServeHelp

func ServeHelp(mst *Maestro) http.Handler

func ServeVersion

func ServeVersion(mst *Maestro) http.Handler

func Suggest

func Suggest(err error, name string, names []string) error

Types

type CommandArg

type CommandArg struct {
	Name  string
	Valid ValidateFunc
}

func (CommandArg) Validate

func (a CommandArg) Validate(arg string) error

type CommandDep

type CommandDep struct {
	Space     string
	Name      string
	Args      []string
	Bg        bool
	Optional  bool
	Mandatory bool
}

func (CommandDep) Key

func (c CommandDep) Key() string

type CommandOption

type CommandOption struct {
	Short    string
	Long     string
	Help     string
	Required bool
	Flag     bool

	Default     string
	DefaultFlag bool
	Target      string
	TargetFlag  bool

	Valid ValidateFunc
}

func (CommandOption) Validate

func (o CommandOption) Validate() error

type CommandScript

type CommandScript []string

func (CommandScript) Reader

func (c CommandScript) Reader() io.Reader

type CommandSettings

type CommandSettings struct {
	Visible bool

	Name       string
	Alias      []string
	Short      string
	Desc       string
	Categories []string

	Retry   int64
	WorkDir string
	Timeout time.Duration

	Hosts     []string
	Deps      []CommandDep
	Options   []CommandOption
	Args      []CommandArg
	Schedules []Schedule
	Lines     CommandScript

	As map[string]string
	Ev map[string]string
	// contains filtered or unexported fields
}

func NewCommandSettingsWithLocals

func NewCommandSettingsWithLocals(name string, locals *env.Env) (CommandSettings, error)

func NewCommmandSettings

func NewCommmandSettings(name string) (CommandSettings, error)

func (CommandSettings) About

func (s CommandSettings) About() string

func (CommandSettings) Blocked

func (s CommandSettings) Blocked() bool

func (CommandSettings) Command

func (s CommandSettings) Command() string

func (CommandSettings) Help

func (s CommandSettings) Help() (string, error)

func (CommandSettings) Prepare

func (s CommandSettings) Prepare(options ...tish.ShellOption) (Executer, error)

func (CommandSettings) Remote

func (s CommandSettings) Remote() bool

func (CommandSettings) Tags

func (s CommandSettings) Tags() []string

func (CommandSettings) Usage

func (s CommandSettings) Usage() string

type Decoder

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

func NewDecoder

func NewDecoder(r io.Reader) (*Decoder, error)

func NewDecoderWithEnv

func NewDecoderWithEnv(r io.Reader, ev *env.Env) (*Decoder, error)

func (*Decoder) CurrentLine

func (d *Decoder) CurrentLine() string

func (*Decoder) Decode

func (d *Decoder) Decode() (*Maestro, error)

type Dirs

type Dirs struct {
	List []string
}

func (*Dirs) Exists

func (d *Dirs) Exists(file string) (string, bool)

func (*Dirs) Set

func (d *Dirs) Set(str string) error

func (*Dirs) String

func (d *Dirs) String() string

type Executer

type Executer interface {
	Command() string
	Dependencies() []CommandDep

	Script([]string) ([]string, error)
	Dry([]string) error

	Execute(context.Context, []string) error
	SetOut(w io.Writer)
	SetErr(w io.Writer)
}

type Maestro

type Maestro struct {
	MetaExec
	MetaAbout
	MetaSSH
	MetaHttp

	Includes Dirs
	Locals   *env.Env
	Commands Registry

	Remote     bool
	NoDeps     bool
	WithPrefix bool
}

func Decode

func Decode(r io.Reader) (*Maestro, error)

func New

func New() *Maestro

func (*Maestro) Dry

func (m *Maestro) Dry(name string, args []string) error

func (*Maestro) Execute

func (m *Maestro) Execute(name string, args []string) error

func (*Maestro) ExecuteAll

func (m *Maestro) ExecuteAll(args []string) error

func (*Maestro) ExecuteDefault

func (m *Maestro) ExecuteDefault(args []string) error

func (*Maestro) ExecuteHelp

func (m *Maestro) ExecuteHelp(name string) error

func (*Maestro) ExecuteVersion

func (m *Maestro) ExecuteVersion() error

func (*Maestro) Graph

func (m *Maestro) Graph(name string) error

func (*Maestro) ListenAndServe

func (m *Maestro) ListenAndServe(args []string) error

func (*Maestro) Load

func (m *Maestro) Load(file string) error

func (*Maestro) Name

func (m *Maestro) Name() string

func (*Maestro) Register

func (m *Maestro) Register(cmd CommandSettings) error

func (*Maestro) Schedule

func (m *Maestro) Schedule(args []string) error

type MetaAbout

type MetaAbout struct {
	File    string
	Author  string
	Email   string
	Version string
	Help    string
	Usage   string
}

type MetaExec

type MetaExec struct {
	WorkDir   string
	Namespace string
	Dry       bool
	Ignore    bool

	Trace bool

	All     []string
	Default string
	Before  []string
	After   []string
	Error   []string
	Success []string
}

type MetaHttp

type MetaHttp struct {
	CertFile string
	KeyFile  string
	Addr     string
	Base     string
}

type MetaSSH

type MetaSSH struct {
	Parallel int64
	User     string
	Pass     string
	Key      ssh.Signer
	Hosts    []hostEntry
}

func (MetaSSH) AuthMethod

func (m MetaSSH) AuthMethod() []ssh.AuthMethod

func (MetaSSH) CheckHostKey

func (m MetaSSH) CheckHostKey(host string, addr net.Addr, key ssh.PublicKey) error

type Position

type Position struct {
	Line   int
	Column int
}

func (Position) String

func (p Position) String() string

type Registry

type Registry map[string]CommandSettings

func (Registry) Copy

func (r Registry) Copy() Registry

func (Registry) Lookup

func (r Registry) Lookup(name string) (CommandSettings, error)

func (Registry) LookupRemote

func (r Registry) LookupRemote(name string) (CommandSettings, error)

func (Registry) Prepare

func (r Registry) Prepare(name string) (Executer, error)

type Scanner

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

func Scan

func Scan(r io.Reader) (*Scanner, error)

func (*Scanner) CurrentLine

func (s *Scanner) CurrentLine() string

func (*Scanner) Scan

func (s *Scanner) Scan() Token

type Schedule

type Schedule struct {
	Sched   *schedule.Scheduler
	Args    []string
	Stdout  ScheduleRedirect
	Stderr  ScheduleRedirect
	Notify  []string
	Overlap bool
}

func (*Schedule) Run

func (s *Schedule) Run(ctx context.Context, reg Registry, cmd ScheduleContext, stdout, stderr io.Writer) error

type ScheduleContext

type ScheduleContext struct {
	CommandSettings
	Prefix bool
	Trace  bool
}

type ScheduleRedirect

type ScheduleRedirect struct {
	File      string
	Compress  bool
	Duplicate bool
	Overwrite bool
}

func (ScheduleRedirect) Option

func (s ScheduleRedirect) Option() int

func (ScheduleRedirect) Writer

func (s ScheduleRedirect) Writer(w io.Writer) (io.Writer, error)

type SuggestionError

type SuggestionError struct {
	Others []string
	Err    error
}

func (SuggestionError) Error

func (s SuggestionError) Error() string

type Token

type Token struct {
	Literal string
	Type    rune
	Position
}

func (Token) IsAssign

func (t Token) IsAssign() bool

func (Token) IsBlank

func (t Token) IsBlank() bool

func (Token) IsComment

func (t Token) IsComment() bool

func (Token) IsEOF

func (t Token) IsEOF() bool

func (Token) IsEOL

func (t Token) IsEOL() bool

func (Token) IsInvalid

func (t Token) IsInvalid() bool

func (Token) IsPrimitive

func (t Token) IsPrimitive() bool

func (Token) IsScript

func (t Token) IsScript() bool

func (Token) IsValue

func (t Token) IsValue() bool

func (Token) IsVariable

func (t Token) IsVariable() bool

func (Token) String

func (t Token) String() string

type UnexpectedError

type UnexpectedError struct {
	Line     string
	Invalid  Token
	Expected []string
}

func (UnexpectedError) Error

func (e UnexpectedError) Error() string

type ValidateFunc

type ValidateFunc func(string) error

Directories

Path Synopsis
cmd
internal
env

Jump to

Keyboard shortcuts

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