From 4fd8e37f68dd34f8e07a07f8d81feba2db68978d Mon Sep 17 00:00:00 2001 From: Dan Anglin Date: Thu, 30 May 2024 11:51:54 +0100 Subject: [PATCH] chore: update project template - update the Go version in forgejo workflow - add a __build directory - build the binary to the __build directory - by default, do quick builds (builds without rebuilding all packages) - add the install target - add functions to generate the binary's build information - add a skeleton run function in main.go --- .forgejo/workflows/workflow.yaml | 4 +- .gitignore | 2 + __build/.gitkeep | 0 magefiles/mage.go | 95 +++++++++++++++++++++++++++++--- main.go | 20 +++++++ 5 files changed, 112 insertions(+), 9 deletions(-) create mode 100644 __build/.gitkeep diff --git a/.forgejo/workflows/workflow.yaml b/.forgejo/workflows/workflow.yaml index b4b5e20..e08ccb4 100644 --- a/.forgejo/workflows/workflow.yaml +++ b/.forgejo/workflows/workflow.yaml @@ -18,7 +18,7 @@ jobs: - name: Setup Go uses: https://code.forgejo.org/actions/setup-go@v5 with: - go-version: '1.21' + go-version: '1.22' - name: Test run: go run magefiles/main.go -v test @@ -30,7 +30,7 @@ jobs: - name: Setup Go uses: https://code.forgejo.org/actions/setup-go@v5 with: - go-version: '1.21' + go-version: '1.22' - name: Lint uses: https://github.com/golangci/golangci-lint-action@v3 with: diff --git a/.gitignore b/.gitignore index e69de29..e200850 100644 --- a/.gitignore +++ b/.gitignore @@ -0,0 +1,2 @@ +/__build/* +!__build/.gitkeep diff --git a/__build/.gitkeep b/__build/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/magefiles/mage.go b/magefiles/mage.go index 567949c..1a12267 100644 --- a/magefiles/mage.go +++ b/magefiles/mage.go @@ -3,28 +3,44 @@ package main import ( + "fmt" "os" + "path/filepath" + "runtime" + "time" + "github.com/magefile/mage/mg" "github.com/magefile/mage/sh" ) -var Default = Build +const ( + app = "binary" + defaultInstallPrefix = "/usr/local" + envInstallPrefix = "PROJECT_INSTALL_PREFIX" + envTestVerbose = "PROJECT_TEST_VERBOSE" + envTestCover = "PROJECT_TEST_COVER" + envBuildRebuildAll = "PROJECT_BUILD_REBUILD_ALL" + envBuildVerbose = "PROJECT_BUILD_VERBOSE" +) -var binary = "app" +var ( + Default = Build + binary = "./__build/" + app +) // Test run the go tests. -// To enable verbose mode set GO_TEST_VERBOSE=1. -// To enable coverage mode set GO_TEST_COVER=1. +// To enable verbose mode set PROJECT_TEST_VERBOSE=1. +// To enable coverage mode set PROJECT_TEST_COVER=1. func Test() error { goTest := sh.RunCmd("go", "test") args := []string{"./..."} - if os.Getenv("GO_TEST_VERBOSE") == "1" { + if os.Getenv(envTestVerbose) == "1" { args = append(args, "-v") } - if os.Getenv("GO_TEST_COVER") == "1" { + if os.Getenv(envTestCover) == "1" { args = append(args, "-cover") } @@ -37,9 +53,46 @@ func Lint() error { } // Build build the executable. +// To rebuild packages that are already up-to-date set PROJECT_BUILD_REBUILD_ALL=1 +// To enable verbose mode set PROJECT_BUILD_VERBOSE=1 func Build() error { main := "main.go" - return sh.Run("go", "build", "-o", binary, main) + flags := ldflags() + build := sh.RunCmd("go", "build") + args := []string{"-ldflags=" + flags, "-o", binary} + + if os.Getenv(envBuildRebuildAll) == "1" { + args = append(args, "-a") + } + + if os.Getenv(envBuildVerbose) == "1" { + args = append(args, "-v") + } + + args = append(args, main) + + return build(args...) +} + +// Install install the executable. +func Install() error { + mg.Deps(Build) + + installPrefix := os.Getenv(envInstallPrefix) + + if installPrefix == "" { + installPrefix = defaultInstallPrefix + } + + dest := filepath.Join(installPrefix, "bin", app) + + if err := sh.Copy(dest, binary); err != nil { + return fmt.Errorf("unable to install %s; %w", dest, err) + } + + fmt.Printf("%s successfully installed to %s\n", app, dest) + + return nil } // Clean clean the workspace. @@ -54,3 +107,31 @@ func Clean() error { return nil } + +// ldflags returns the build flags. +func ldflags() string { + ldflagsfmt := "-s -w -X main.binaryVersion=%s -X main.gitCommit=%s -X main.goVersion=%s -X main.buildTime=%s" + buildTime := time.Now().UTC().Format(time.RFC3339) + + return fmt.Sprintf(ldflagsfmt, version(), gitCommit(), runtime.Version(), buildTime) +} + +// version returns the latest git tag using git describe. +func version() string { + version, err := sh.Output("git", "describe", "--tags") + if err != nil { + version = "N/A" + } + + return version +} + +// gitCommit returns the current git commit +func gitCommit() string { + commit, err := sh.Output("git", "rev-parse", "--short", "HEAD") + if err != nil { + commit = "N/A" + } + + return commit +} diff --git a/main.go b/main.go index da29a2c..a3255e8 100644 --- a/main.go +++ b/main.go @@ -1,4 +1,24 @@ package main +import ( + "fmt" + "os" +) + +var ( + binaryVersion string + buildTime string + goVersion string + gitCommit string +) + func main() { + if err := run(); err != nil { + fmt.Printf("ERROR: %v.\n", err) + os.Exit(1) + } +} + +func run() error { + return nil }