tools_build

package module
v0.13.1 Latest Latest
Warning

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

Go to latest
Published: Jul 19, 2025 License: MIT Imports: 10 Imported by: 2

README

tools-build

GoDoc Reference go.mod LICENSE

Release Code Coverage Report Go Report Card Build Status

This package provides build script tooling for Go-based projects. The tooling is in the form of code utilizing goyek build automation. goyek builds are typically set up as tasks, and this project provides some common code to perform the work of the tasks. Here is a sample set of tasks:

var (
    build = goyek.Define(goyek.Task{
        Name:  "build",
        Usage: "build the executable",
        Action: func(a *goyek.A) {
            buildExecutable(a)
        },
    })

    clean = goyek.Define(goyek.Task{
        Name:  "clean",
        Usage: "delete build products",
        Action: func(a *goyek.A) {
            fmt.Println("deleting build products")
            exec, path, _, _ := readConfig()
            workingDir := WorkingDir()
            files := []string{
                filepath.Join(workingDir, path, versionInfoFile),
                filepath.Join(workingDir, path, resourceFile),
                filepath.Join(workingDir, coverageFile),
                filepath.Join(workingDir, exec),
            }
            Clean(files)
        },
    })

    _ = goyek.Define(goyek.Task{
        Name:  "coverage",
        Usage: "run unit tests and produce a coverage report",
        Action: func(a *goyek.A) {
            GenerateCoverageReport(a, coverageFile)
        },
    })

    _ = goyek.Define(goyek.Task{
        Name:  "doc",
        Usage: "generate documentation",
        Action: func(a *goyek.A) {
            GenerateDocumentation(a)
        },
    })

    format = goyek.Define(goyek.Task{
        Name:  "format",
        Usage: "clean up source code formatting",
        Action: func(a *goyek.A) {
            Format(a)
        },
    })

    lint = goyek.Define(goyek.Task{
        Name:  "lint",
        Usage: "run the linter on source code",
        Action: func(a *goyek.A) {
            Lint(a)
        },
    })

    nilaway = goyek.Define(goyek.Task{
        Name:  "nilaway",
        Usage: "run nilaway on source code",
        Action: func(a *goyek.A) {
            NilAway(a)
        },
    })

    vulnCheck = goyek.Define(goyek.Task{
        Name:  "vulnCheck",
        Usage: "run vulnerability check on source code",
        Action: func(a *goyek.A) {
            VulnerabilityCheck(a)
        },
    })

    _ = goyek.Define(goyek.Task{
        Name:  "preCommit",
        Usage: "run all pre-commit tasks",
        Deps:  goyek.Deps{clean, lint, nilaway, format, vulnCheck, tests, build},
    })

    tests = goyek.Define(goyek.Task{
        Name:  "tests",
        Usage: "run unit tests",
        Action: func(a *goyek.A) {
            UnitTests(a)
        },
    })
)

And here is a typical build script to execute the tasks:

#!/bin/bash

set -o errexit
set -o nounset
set -o pipefail

if [[ "${TRACE-0}" == "1" ]]; then
    set -o xtrace
    tracing=true
else
    tracing=false
fi

DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
cd "${DIR}/build"
if [[ "${tracing}" == "true" ]]; then
    DIR=${DIR} go run . -v "$@"
else
    DIR=${DIR} go run . "$@"
fi

The script employs a DIR environment variable for the benefit of the WorkingDir function, which is used by this package to find the project's top level directory. If DIR is not set as an environment variable, WorkingDir will assume that ".." is the correct location, which is based on the assumption that the go code running the build is placed in a directory, one level deep, such as build (as seen in the line above cd "${DIR}/build). Regardless of whether the DIR environment variable is set, the WorkingDir function looks for the .git directory in its candidate value, and it's not found, then the WorkingDir function calls os.Exit and the build ends.

Opinionated?

Well, yes. I wrote this for my go projects, and, as such, it reflects my thinking about the proper tooling to use, and how to use that tooling. The biggest example of this is probably my use of gocritic as the tool called by the Lint function.

That said, if you find the package useful but don't like some of my choices, you can easily create your own functions to replace the ones you don't care for. Won't hurt my feelings a bit.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// SetenvFn is the os.Setenv function, set as a variable so that unit tests can override
	SetenvFn = os.Setenv
	// UnsetenvFn is the os.Unsetenv function, set as a variable so that unit tests can override
	UnsetenvFn = os.Unsetenv
)
View Source
var (
	// BuildFS is the file system used; accessible so that tests can override it
	BuildFS = afero.NewOsFs()
	// CachedWorkingDir is the cached working directory
	CachedWorkingDir = ""
)
View Source
var (
	// AggressiveFlag is a flag for the UpdateDependencies function to more aggressively get updates
	AggressiveFlag = flag.Bool(
		"aggressive",
		false,
		"set to make dependency updates more aggressive",
	)

	// NoFormatFlag is a flag to disable formatting from the deadcode command
	NoFormatFlag = flag.Bool(
		"noformat",
		false,
		"set to remove custom formatting from dead code analysis")
	// NoTestFlag is a flag to remove the -test parameter from the deadcode command
	NoTestFlag = flag.Bool(
		"notest",
		false,
		"set to remove the -test parameter from dead code analysis")
	// TemplateFlag is a flag that allows the caller to change the format template used by the deadcode command
	TemplateFlag = flag.String(
		"template",
		`{{println .Path}}{{range .Funcs}}{{printf "\t%s\t%s\n" .Position .Name}}{{end}}{{println}}`,
		"set to change the template used to format dead code analysis (ignored if -noformat is true)")
	// ExecFn is the goyek Exec function. set as a variable so that unit tests can override
	ExecFn = cmd.Exec
	// ExitFn is the os.Exit function, set as a variable so that unit tests can override
	ExitFn = os.Exit
)
View Source
var (
	// PrintlnFn is the fmt.Println function, set as a variable so that unit tests can override
	PrintlnFn = fmt.Println
)

Functions

func AllDirs added in v0.11.0

func AllDirs(top string) ([]string, error)

AllDirs returns all directories in the directory specified by the top parameter, including that directory. Recurses.

func Clean

func Clean(files []string)

Clean deletes the named files, which must be located in, or in a subdirectory of, WorkingDir(). If any of the named files contains a back directory (".."), calls os.Exit(); this is to prevent callers from deceptively removing files they shouldn't.

func Deadcode added in v0.12.0

func Deadcode(a *goyek.A) bool

Deadcode runs dead code analysis on the source code after making sure that the deadcode tool is up-to-date; returns false on failure

func EatTrailingEOL added in v0.11.0

func EatTrailingEOL(s string) string

EatTrailingEOL removes trailing \n and \r characters from the end of a string

func Format

func Format(a *goyek.A) bool

Format runs the gofmt tool to repair the formatting of each source file; returns false if the command fails

func FormatSelective added in v0.10.0

func FormatSelective(a *goyek.A, exclusions []string) bool

FormatSelective runs the gofmt tool to repair the formatting of selected source files; returns false if the command fails

func Generate added in v0.2.1

func Generate(a *goyek.A) bool

Generate runs the 'go generate' tool

func GenerateCoverageReport

func GenerateCoverageReport(a *goyek.A, coverageDataFile string) bool

GenerateCoverageReport runs the unit tests, generating a coverage profile; if the unit tests all succeed, generates the report as HTML to be displayed in the current browser window. Returns false if either the unit tests or the coverage report display fails

func GenerateDocumentation

func GenerateDocumentation(a *goyek.A, excludedDirs []string) bool

GenerateDocumentation generates documentation of the code, outputting it to stdout; returns false on error

func IncludesRelevantFiles added in v0.11.0

func IncludesRelevantFiles(dir string, fileMatcher func(string) bool) bool

IncludesRelevantFiles returns true if the provided directory contains any regular files whose names conform to the fileMatcher

func Install

func Install(a *goyek.A, packageName string) bool

Install runs the command to install the '@latest' version of a specified package; returns false on failure

func IsMalformedFileName added in v0.11.0

func IsMalformedFileName(path string) bool

IsMalformedFileName determines whether a file name is malformed, such that it could be used to access a file outside the working directory (starts with '/' or '\\', or contains a path component of '..'

func IsRelevantFile added in v0.11.0

func IsRelevantFile(entry fs.FileInfo, fileMatcher func(string) bool) bool

IsRelevantFile returns true if the entry is a file and its name is validated by the provided fileMatcher

func Lint

func Lint(a *goyek.A) bool

Lint runs lint on the source code after making sure that the lint tool is up-to-date; returns false on failure

func MatchGoSource added in v0.11.0

func MatchGoSource(name string) bool

MatchGoSource matches a file name ending in '.go', but does not match test files.

func NilAway

func NilAway(a *goyek.A) bool

NilAway runs the nilaway tool, which attempts, via static analysis, to detect potential nil access errors; returns false on errors

func PrintBuffer added in v0.11.0

func PrintBuffer(b *bytes.Buffer)

PrintBuffer sends the buffer contents to stdout, but first strips trailing EOL characters, and then only prints the remaining content if that content is not empty

func RelevantDirs added in v0.11.0

func RelevantDirs(fileMatcher func(string) bool) ([]string, error)

RelevantDirs returns the directories that contain files matching the provided fileMatcher

func RestoreEnvVars added in v0.11.0

func RestoreEnvVars(saved []EnvVarMemento)

RestoreEnvVars reverts the environment changes made by SetupEnvVars

func RunCommand

func RunCommand(a *goyek.A, command string) bool

RunCommand runs a command and displays all of its output; returns true on success

func TaskDisabled added in v0.13.0

func TaskDisabled(taskName string) (disabled bool)

TaskDisabled returns true if the provided taskName matches (case-insensitively) one of the comma-delimited values in the disable flag's value

func UnacceptableWorkingDir added in v0.11.0

func UnacceptableWorkingDir(candidate string) bool

UnacceptableWorkingDir determines whether a specified candidate directory could be the working directory for the build. The candidate cannot be empty, must be a valid directory, and must contain a valid subdirectory named '.git'

func UnitTests

func UnitTests(a *goyek.A) bool

UnitTests runs all unit tests, with code coverage enabled; returns false on failure

func UpdateDependencies added in v0.3.0

func UpdateDependencies(a *goyek.A) bool

UpdateDependencies updates module dependencies and prunes the modified go.mod and go.sum files

func VulnerabilityCheck

func VulnerabilityCheck(a *goyek.A) bool

VulnerabilityCheck runs the govulncheck tool, which checks for unresolved known vulnerabilities in the libraries used; returns false on failure

func WorkingDir

func WorkingDir() string

WorkingDir returns a 'best' guess of the working directory. If the directory found is not, in fact, a directory, or is, but does not contain a .git subdirectory, calls exit. A successful call's value is cached.

Types

type EnvVarMemento added in v0.11.0

type EnvVarMemento struct {
	// Name is the variable's name
	Name string
	// Value is what the variable should be set to
	Value string
	// Unset, if true, means the variable should be unset
	Unset bool
}

EnvVarMemento captures an environment variable's desired state

func SetupEnvVars added in v0.11.0

func SetupEnvVars(input []EnvVarMemento) ([]EnvVarMemento, bool)

SetupEnvVars executes the intent of the provided slice of EnvVarMementos, and returns a slice to be executed to revert the directed changes

Jump to

Keyboard shortcuts

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