Giter Site home page Giter Site logo

goyek's Introduction

goyek

Create build pipelines in Go

Go Reference Keep a Changelog GitHub Release go.mod LICENSE

Build Status Go Report Card codecov Mentioned in Awesome Go

Slack

Please ⭐ Star this repository if you find it valuable and worth maintaining.

Be aware that goyek is still in v0 phase, and the API is still in flux. As per Go module version numbering, you can use released versions for your projects, yet there is the potential for breaking changes in later releases. We anticipate a v1 release for a stable API. It is not yet clear when this will happen.

Table of Contents:

Description

goyek (/ˈɡɔɪæk/ 🔊 listen) is used to create build pipelines in Go. As opposed to many other tools, it is just a Go library.

Here are some good parts:

goyek API is mainly inspired by the testing, http, and flag packages.

See docs/alternatives.md if you want to compare goyek with other popular tools used for creating build pipelines.

See docs/presentations.md if you want to watch some presenentations.

See docs/contributing.md if you want to help us.

Quick start

Copy and paste the following code into build/build.go:

package main

import (
	"github.com/goyek/goyek"
)

func main() {
	flow := &goyek.Flow{}

	flow.Register(goyek.Task{
		Name:  "hello",
		Usage: "demonstration",
		Action: func(tf *goyek.TF) {
			tf.Log("Hello world!")
		},
	})

	flow.Main()
}

Run:

go mod tidy

Sample usage:

$ go run ./build -h
Usage: [flag(s) | task(s)]...
Flags:
  -v     Default: false    Verbose: log all tasks as they are run.
  -wd    Default: .        Working directory: set the working directory.
Tasks:
  hello    demonstration
$ go run ./build hello
ok     0.000s
$ go run ./build hello -v
===== TASK  hello
Hello world!
----- PASS: hello (0.00s)
ok      0.001s

Repository template

Use goyek/template to create a new repository or when adopting goyek by copying most of its files.

Examples

Wrapper scripts

Instead of executing go run ./build, you can use the wrapper scripts, which can be invoked from any location.

Simply add them to your repository's root directory:

  • goyek.sh - make sure to add +x permission (git update-index --chmod=+x goyek.sh):
#!/bin/bash
set -euo pipefail

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
cd "$DIR/build"
go run . -wd=".." $@
Push-Location "$PSScriptRoot\build" -ErrorAction Stop
& go run . -wd=".." $args
Pop-Location
exit $global:LASTEXITCODE

Features

Task registration

The registered tasks are required to have a non-empty name, matching the regular expression ^[a-zA-Z0-9_][a-zA-Z0-9_-]*$, available as TaskNamePattern. This means the following are acceptable:

  • letters (a-z and A-Z)
  • digits (0-9)
  • underscore (_)
  • hyphens (-) - except at the beginning

A task with a given name can be only registered once.

A task without description is not listed in CLI usage.

Task action

Task action is a function which is executed when a task is executed.

It is not required to set a action. Not having a action is very handy when registering "pipelines".

Task dependencies

During task registration it is possible to add a dependency to an already registered task. When the flow is processed, it makes sure that the dependency is executed before the current task is run. Take note that each task will be executed at most once.

Helpers for running programs

Use func (tf *TF) Cmd(name string, args ...string) *exec.Cmd to run a program inside a task's action.

You can use it create your own helpers, for example:

import (
	"fmt"
	"os/exec"

	"github.com/goyek/goyek"
	"github.com/mattn/go-shellwords"
)

func Cmd(tf *goyek.TF, cmdLine string) *exec.Cmd {
	args, err := shellwords.Parse(cmdLine)
	if err != nil {
		tf.Fatalf("parse command line: %v", err)
	}
	return tf.Cmd(args[0], args[1:]...)
}

func Exec(cmdLine string) func(tf *goyek.TF) {
	args, err := shellwords.Parse(cmdLine)
	if err != nil {
		panic(fmt.Sprintf("parse command line: %v", err))
	}
	return func(tf *goyek.TF) {
		if err := tf.Cmd(args[0], args[1:]...).Run(); err != nil {
			tf.Fatal(err)
		}
	}
}

Here is the explantion why argument splitting is not included out-of-the-box.

Verbose mode

Enable verbose output using the -v CLI flag. It works similar to go test -v. Verbose mode streams all logs to the output. If it is disabled, only logs from failed task are send to the output.

Use func (f *Flow) VerboseParam() BoolParam if you need to check if verbose mode was set within a task's action.

Default task

Default task can be assigned via the Flow.DefaultTask field.

When the default task is set, then it is run if no task is provided via CLI.

Parameters

The parameters can be set via CLI using the flag syntax.

On the CLI, flags can be set in the following ways:

  • -param simple - for simple single-word values
  • -param "value with blanks"
  • -param="value with blanks"
  • -param - setting boolean parameters implicitly to true

For example, ./goyek.sh test -v -pkg ./... would run the test task with v bool parameter (verbose mode) set to true, and pkg string parameter set to "./...".

Parameters must first be registered via func (f *Flow) RegisterValueParam(newValue func() ParamValue, info ParamInfo) ValueParam, or one of the provided methods like RegisterStringParam.

The registered parameters are required to have a non-empty name, matching the regular expression ^[a-zA-Z0-9][a-zA-Z0-9_-]*$, available as ParamNamePattern. This means the following are acceptable:

  • letters (a-z and A-Z)
  • digits (0-9)
  • underscore (_) - except at the beginning
  • hyphens (-) - except at the beginning

After registration, tasks need to specify which parameters they will read. Do this by assigning the RegisteredParam instance from the registration result to the Task.Params field. If a task tries to retrieve the value from an unregistered parameter, the task will fail.

When registration is done, the task's action can retrieve the parameter value using the Get(*TF) method from the registration result instance during the task's Action execution.

See examples/parameters/main.go for a detailed example.

Flow will fail execution if there are unused parameters.

Supported Go versions

Minimal supported Go version is 1.11.

goyek's People

Contributors

pellared avatar dependabot[bot] avatar dertseha avatar agabrys avatar michaelcurrin avatar victoraugustolls avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.