Skip to content

Commit

Permalink
Add magefile, version command (fixes #2)
Browse files Browse the repository at this point in the history
  • Loading branch information
David Moles committed Feb 5, 2019
1 parent a1e8081 commit 6642460
Show file tree
Hide file tree
Showing 10 changed files with 225 additions and 5 deletions.
9 changes: 9 additions & 0 deletions .idea/cos.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 14 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,20 @@ As such, it requires Go 1.11 or later, and should be cloned _outside_

### Building

From the project root:

- to build `cos`, writing the executable to the source directory, use `go build`.
- to build `cos` and install it in `$GOPATH/bin`, use `go install`.
The `cos` project can be built and installed simply with `go build` and `go
install`, but it also supports [Mage](https://magefile.org):

| Command | Purpose |
| :--- | :--- |
| `mage -l` | list available targets |
| `mage build` | builds a cos binary for the current platform. |
| `mage buildAll` | builds a cos binary for each target platform. |
| `mage clean` | removes compiled binaries from the current working directory. |
| `mage install` | installs cos in $GOPATH/bin. |
| `mage platforms` | lists target platforms for buildAll. |

Note that `mage build` is a thin wrapper around `go build` and supports the
same environment variables, e.g. `$GOOS` and `$GOARCH`.

#### Cross-compiling

Expand Down
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const (
Note that for OpenStack Swift, the API username and key must be specified
with the `+objects.SwiftUserEnvVar+` and `+objects.SwiftKeyEnvVar+` environment variables.
` // TODO: use ST_USER, ST_KEY, whatever the endpoint variable was
`
)

// rootCmd represents the base command when called without any subcommands
Expand Down
33 changes: 33 additions & 0 deletions cmd/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package cmd

import (
"fmt"

"github.com/spf13/cobra"
)

var tag string
var commitHash string
var timestamp string

func init() {
cmd := &cobra.Command{
Use: "version",
Short: "print cos version",
Args: cobra.ExactArgs(0),
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("cos " + versionStr())
},
}
rootCmd.AddCommand(cmd)
}

func versionStr() string {
// if these are blank, we were probably built with plain 'go build' or
// 'go install', bypassing the ldflags in the magefile
if tag == "" {
return "(unknown version)"
}
versionStr := fmt.Sprintf("%v (%v, %v)", tag, commitHash, timestamp)
return versionStr
}
Binary file added cos-darwin-amd64
Binary file not shown.
Binary file added cos-linux-amd64
Binary file not shown.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ require (
github.com/aws/aws-sdk-go v1.16.13
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/magefile/mage v1.8.0
github.com/minimaxir/big-list-of-naughty-strings/naughtystrings v0.0.0
github.com/ncw/swift v1.0.43
github.com/onsi/ginkgo v1.7.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/magefile/mage v1.8.0 h1:mzL+xIopvPURVBwHG9A50JcjBO+xV3b5iZ7khFRI+5E=
github.com/magefile/mage v1.8.0/go.mod h1:IUDi13rsHje59lecXokTfGX0QIzO45uVPlXnJYsXepA=
github.com/ncw/swift v1.0.43 h1:TZn2l/bPV0CqG+/G5BFh/ROWnyX7dL2D0URaOjNQRsw=
github.com/ncw/swift v1.0.43/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
Expand Down
164 changes: 164 additions & 0 deletions magefile.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// +build mage

package main

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"runtime"
"strings"
"time"

"github.com/magefile/mage/mg"
"github.com/magefile/mage/sh"
)

const (
appName = "cos"
)

var gocmd = mg.GoCmd()

var oses = []string{"darwin", "linux", "windows"}
var architectures = []string{"amd64"}

// ------------------------------------------------------------
// Targets

// Install installs cos in $GOPATH/bin.
func Install() error {
binName := appName
if runtime.GOOS == "windows" {
binName += ".exe"
}

gopath, err := sh.Output(gocmd, "env", "GOPATH")
if err != nil {
return fmt.Errorf("error determining GOPATH: %v", err)
}
binDir := filepath.Join(gopath, "bin")
binPath := filepath.Join(binDir, binName)

flags, err := ldFlags()
if err != nil {
return fmt.Errorf("error determining ldflags: %v", err)
}
return sh.RunV(gocmd, "build", "-o", binPath, "-ldflags", flags)
}

// Build builds a cos binary for the current platform.
func Build() error {
binName := appName
if runtime.GOOS == "windows" {
binName += ".exe"
}
flags, err := ldFlags()
if err != nil {
return fmt.Errorf("error determining ldflags: %v", err)
}
return sh.RunV(gocmd, "build", "-ldflags", flags)
}

// BuildAll builds a cos binary for each target platform.
func BuildAll() error {
for _, os_ := range oses {
for _, arch := range architectures {
binName := binNameFor(os_, arch)

flags, err := ldFlags()
if err != nil {
return fmt.Errorf("error determining ldflags: %v", err)
}

env := map[string]string{
"GOOS": os_,
"GOARCH": arch,
}
err = sh.RunWith(env, gocmd, "build", "-o", binName, "-ldflags", flags)
if err != nil {
return err
}
}
}
return nil
}

// Platforms lists target platforms for buildAll.
func Platforms() {
for _, os_ := range oses {
for _, arch := range architectures {
fmt.Printf("%s-%s\n", os_, arch)
}
}
}

// Clean removes compiled binaries from the current working directory.
func Clean() error {
var binRe = regexp.MustCompile("^" + appName + "(-[a-zA-Z0-9]+-[a-zA-Z0-9]+)?(.exe)?$")

rmcmd := "rm"
if runtime.GOOS == "windows" {
rmcmd = "del"
}

files, err := ioutil.ReadDir("./")
if err != nil {
return err
}

for _, f := range files {
mode := f.Mode()
isPlainFile := mode.IsRegular() && mode&os.ModeSymlink == 0
isExecutable := mode&0111 != 0
if isPlainFile && isExecutable {
name := f.Name()
if binRe.MatchString(name) {
err := sh.RunV(rmcmd, name)
if err != nil {
return err
}
}
}
}
return nil
}

// ------------------------------------------------------------
// Helper functions

func ldFlags() (string, error) {
commitHash, err := sh.Output("git", "rev-parse", "--short", "HEAD")
if err != nil {
return "", err
}
tag, err := sh.Output("git", "describe", "--tags")
if err != nil {
return "", err
}
timestamp := time.Now().Format(time.RFC3339)

flagVals := map[string]string{
"commitHash": commitHash,
"tag": tag,
"timestamp": timestamp,
}

var flags []string
for k, v := range flagVals {
flag := fmt.Sprintf("-X github.com/dmolesUC3/cos/cmd.%s=%s", k, v)
flags = append(flags, flag)
}
return strings.Join(flags, " "), nil
}

func binNameFor(os_ string, arch string) string {
binName := appName
binName = fmt.Sprintf("%s-%s-%s", binName, os_, arch)
if os_ == "windows" {
binName += ".exe"
}
return binName
}

0 comments on commit 6642460

Please sign in to comment.