shogun

command module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Oct 30, 2017 License: MIT Imports: 21 Imported by: 0

README

Shogun

Shogun

Shogun provides Functions as Commands(FACM), which allows the execution of Go functions from the terminal. Such functions receive data through the standard input, respond through standard output and standard error channels of your termianl or pty terminal.

Shogun also creates project files and binaries for all packages, which lets you quickly generate Go binaries for your functions, which can be moved and run anywhere individually.

Inspired by mage and Amazon Lambda functions as Runnable items

Shogun follows the strict requirement that every information to be received by a function must come through the standard input file stdin, this ensures you can pass arbitrary data in or even JSON payloads to be loaded into a Struct type.

More so, all response must either be an error returned which will be delivered through the standard error file stderr or be a response written to a io.WriteCloser to deliver to the standard output file stdout.

Introduction and Demo Video

Shogun Intro

Install

go install -u github.com/influx6/shogun

Then run shogun to validate successful install:

> shogun
⠙ Nothing to do...

⡿ Run `shogun -h` to see what it takes to make me work.

Requirements

Shogun only requires that you have a working installation of Go (>= 1.2) installed with your GOPATH set accordingly.

Writing Shogun Packages

Writing Go package which are to be used by Shogun to generate binaries are rather simple, and only require that each package has all it files tagged with the following build tag above it's package declaration with space in between:

// +build shogun

package something

Your are free to use any other build tag as well and will be sorted accordingly.

Shogun by default will save binaries into the GOBIN or GOPATH/bin path extracted from the environment, however this can be changed by setting a SHOGUNBIN environment variable. More so, Shogun names all binaries the name of the parent package unless one declares an explicit annotation @binaryName at the package level.

// +build shogun

// Package do does something.
//
//@binaryName(name => shogunate_bin)
package do

If you wished to add a description for the binary command, we can add a desc attribute in a json block of the @binaryName annotation.

// +build shogun

/* Package do does something.

@binaryName(asJSON, name => shogunate_bin, {
  {
    "desc": "shogunate_bin provides a nice means"
  }
})
*/
package do

All binaries created by shogun are self complete and can equally be called directly without the shogun command, which makes it very usable for easy deployable self contained binaries that can be used in place where behaviors need to be exposed as functions.

Shogun packages are normal Go packages and all directories within the root where shogun is executed will be parsed and processed for identification of possible shogun packages, where those identified will each have a binary generated and the main package if any found will combine all other binaries into a single one if so desired.

Writing Functions for Shogun

Shogun focuses on the execution of functions, that supports a limited set of formats. More so, each format allows the use of Context or CancelContext objects as first place arguments.

  • No Argument Functions
func()
func() error
  • Context Only Functions
func(Context)
func(Context) error
  • String based Functions
func(string)
func(string) error
func(Context, string) error
func(Context, string, io.WriteCloser) error
  • StringSlice based Functions
func([]string)
func([]string) error
func(Context, []string) error
func(Context, []string, io.WriteCloser) error
  • Map based Functions
func(map[string]interface{})
func(map[string]interface{}) error
func(Context, map[string]interface{}) error
func(Context, map[string]interface{}, io.WriteCloser) error
  • Struct based Functions
func(Struct)
func(Struct) error
func(Context, Struct) error
func(Struct, io.WriteCloser) error
func(Context, Struct, io.WriteCloser) error
  • Struct Pointer based Functions
func(*Struct)
func(*Struct) error
func(Context, *Struct) error
func(*Struct, io.WriteCloser) error
func(Context, *Struct, io.WriteCloser) error
  • Imported Struct based Functions
func(package.Struct)
func(package.Struct) error
func(Context, package.Struct) error
func(package.Struct, io.WriteCloser) error
func(Context, package.Struct, io.WriteCloser) error
  • Imported Struct Pointer based Functions
func(*package.Struct)
func(*package.Struct) error
func(Context, *package.Struct) error
func(*package.Struct, io.WriteCloser) error
func(Context, *package.Struct, io.WriteCloser) error
  • io.Reader based Functions
func(io.Reader)
func(io.Reader) error
func(Context, io.Reader) error
  • io.Writer based Functions
func(io.WriteCloser)
func(io.WriteCloser) error
func(Context, io.WriteCloser) error
  • io.Reader and io.Writer based Functions
func(io.Reader, io.WriteCloser)
func(io.Reader, io.WriteCloser) error
func(Context, io.Reader, io.WriteCloser) error

Where Context => represents the context package used of the 2 allowed.

Where Struct => represents any struct declared in package

where package.Struct => represents Struct type imported from other package

Any other thing beyond this type formats won't be allowed and will be ignored in function list and execution.

// +build shogun

// Package katanas provides exported functions as tasks runnable from commandline.
//
// @binaryName(name => katana-shell)
//
package katanas

import (
	"fmt"
	"io"

	"github.com/influx6/faux/context"
	ty "github.com/influx6/shogun/examples/types"
)

type wondra struct {
	Name string
}

func Draw() {}

// Slash is the default tasks due to below annotation.
// @default
func Slash() error {
	fmt.Println("Welcome to Katana slash!")
	return nil
}

func Bob(ctx context.CancelContext, name string) error {
  fmt.Printf("Welcome to bob %q.\n",name)
	return nil
}

//@flag(name => time, env => JIJA_TIME, type => Duration, desc => specifies time for jija)
func Jija(ctx context.Context, mp ty.Woofer) error {
  jijatime, found := ctx.Bag().GetDuration("time")

	return nil
}

In shogun, you can tag a function as the default function to be executed every it's binary is called without argument through shogun or through it's generated binary, by tagging it with a @default annotation.

Shogun also supports function level flags, where a function using annotation can specify particular flags which it will access from the either the Context package if passed in, except for CancelContext which only functions for cancelation.

Using Context

Only the following packages are allowed for usage. If you need context, then it must always be the first argument.

  • context "context.Context"
  • github.com/influx6/fuax/context "context.CancelContext"

When using context.Context package from the internal Go packages, only its ability to be used as a timeout will be set if the -t or -timeout flag has a value. Support of filling context with values is not planned or desired.

Shogun will use the -time flag received through the commandline to set lifetime timeout for the 2 giving context else the context will not have expiration deadlines.

Note that shogun by default does not respect Context timeouts, it's up to you to write your function source to take Context into account for the lifetime of your function.

CLI Usage

Before using any other command apart from shogun list in a package, always execute:

> shogun build

Shogun by defaults will process both the root and all first level directories that have shogun files within, generating appropriate binaries based on package name or if binaryName annotation is declared, and will also generate a single binary if there exists any shogun files within the root directory, with subcommands that will connect to other binaries in the first level directories.

This allows you to have a single binary that is bundled with all commands for executing functions from any other subpackage, but this can be changed to only allow single binaries, incase you want truly separate binaries.

Note, this only applies, if you have Go files that have the +build shogun within the root, where shogun build gets executed.

Shogun will hash shogun files and ensure only when changes occur will a new build be made and binary will be stored in binary location as dictated by environment variable SHOGUNBIN or default GOBIN/GOPATH/bin .


Using the shogun command, we can do the following:

  • Build shogun based package files

Run this if the shogun files and directories exists right in the root directory.

shogun build
  • Build shogun based package files and remove generated package
shogun build -rm
  • Build shogun based package files without generating binaries

Run this if the shogun files and directories exists right in the root directory.

shogun build -skip
  • Build a shogun based package files from a directory
shogun build -d=./examples
  • Build a shogun based package files in a directory and only generate binary for root shogun files
shogun build -skipsub -d=./examples
  • Build a shogun based package files in a directory and split binaries as single
shogun build -single -d=./examples -cmd=./cmd
  • Build a shogun based package files in a directory and store generated packages in directory cmd
shogun build -d=./examples -cmd=./cmd
  • Build a shogun based package files in a directory without generating binaries
shogun build -skip -d=./examples
  • Force rebuild a shogun based package files in a directory
shogun build -f -d=./examples
  • Add new shogun file to current package
shogun add vuz.go
  • Add new shogun file into a directory in current package
shogun add -dir=vuz vuz.go
  • Add new shogun files into package
shogun add vuz.go ball.go wreck.go

You can also add more files into a directory when using -dir flag in this manner.

  • Add new shogun files into package but use main as package name
shogun add -m vuz.go
  • List all functions in the root
shogun list
  • List all functions in from a directory
shogun list -dir=./examples
  • List all functions with short commentary
shogun help {{BINARYNAME}} {{FunctionName}}
  • List all functions with full commentary and source
shogun help -s {{BINARYNAME}} {{FunctionName}}
  • Run function of package binary that expects no input
shogun {{BINARYNAME}} {{FUNCTIONNAME}}
  • Run function of package binary expecting string input with standard input
echo "We lost the war" | shogun {{BINARYNAME}} {{FUNCTIONNAME}}
  • Run function of package binary using remaining arguments apart from {{BINARYNAME}} and {{FUNCTIONNAME}} has input
shogun {{BINARYNAME}} {{FUNCTIONNAME}} "We lost the war"
  • Run function of package binary expecting json input with standard input
{"name":"bat"} | shogun {{BINARYNAME}} {{FUNCTIONNAME}}

FAQ

Must all commands before run with the shogun CLI?

No, every binary that is built is self contained and the shogun CLI only proxies calls to the binary which it expects to be in the SHOGUNBIN or GOBIN/GOPATH/bin. You can call the binary directly without shogun and will work as expected if the path is added into your environment paths.

Do I need to re-run shogun build -dir on each change ?

With the latest update to shogun, if you have shogun marked package files in your root directory of your package or within the area where shogun build gets called, then any change will be rebuilt automatically. But for others, you would need to specifically run shogun build -dir='' to build a given directory.

What differentiates shogun from mage ?

While mage focuses on using Go functions like make or rake tasks, shogun expands the usage of functions not just as task runners, but as self contained pure behaviors that can receive input and respond. This allows you to build commandline apps quicker with shogun and even quickly test out function behaviours.

More so, I envision shogun for the purpose of being able to deploy shogun built binaries into docker images as pure functions, that can be used to support a service or serve a service like a static file server which only ever runs when needed, ..etc

Of course, you can use shogun functions like tasks similar to mage, but in effect that is a side benefit of the approach.

Contributions

Contributions are welcome, do please checkout the Contribution Guidlines.

Logo is a work of Shadow Fight Wiki.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
examples
types
Package types do something.
Package types do something.
kensho
Package kensho provides a series of tests case which can be used to validate that a giving generated shogun package meet it's design and expected operation.
Package kensho provides a series of tests case which can be used to validate that a giving generated shogun package meet it's design and expected operation.

Jump to

Keyboard shortcuts

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