diff --git a/README.asciidoc b/README.asciidoc index 536c853..3948827 100644 --- a/README.asciidoc +++ b/README.asciidoc @@ -5,7 +5,7 @@ == Overview -**This project is WIP and is not meant for production use.** +**This project is in ALPHA state and is not ready for production use yet.** Pelican is a simple Kanban board for your terminal. Data is stored in a https://github.com/etcd-io/bbolt[BoltDB] database. @@ -29,7 +29,21 @@ You can visit the https://magefile.org[website] for instructions on how to insta === Install with Mage -_TBC_ +You can install pelican with Mage using the following commands: +[source,console] +---- +git clone https://codeflow.dananglin.me.uk/apollo/pelican.git +cd pelican +mage install +---- + +The default install prefix is set to `/usr/local` so pelican will be installed to `/usr/local/bin/pelican`. +If you want to change the install prefix you can set the `PELICAN_INSTALL_PREFIX` environment variable +before installing. +[source,console] +---- +PELICAN_INSTALL_PREFIX=~/.local mage install +---- === Install with Go diff --git a/cmd/pelican/main.go b/cmd/pelican/main.go index cd0d200..1cbd411 100644 --- a/cmd/pelican/main.go +++ b/cmd/pelican/main.go @@ -1,18 +1,31 @@ package main import ( + "flag" "log" - "os" "codeflow.dananglin.me.uk/apollo/pelican/internal/ui" ) func main() { - if len(os.Args) != 2 { - log.Fatalf("ERROR: Unexpected number of command-line arguments; want 1; got %d", len(os.Args)-1) + var versionFlag bool + + flag.BoolVar(&versionFlag, "version", false, "prints the application's build information") + flag.Parse() + + if versionFlag { + version() + + return } - pelican, err := ui.NewUI(os.Args[1]) + args := flag.Args() + + if len(args) != 1 { + log.Fatalf("ERROR: Unexpected number of command-line arguments; want 1; got %d", len(args)) + } + + pelican, err := ui.NewUI(args[0]) if err != nil { log.Fatalf("ERROR: Unable to initialise Pelican; %v", err) } diff --git a/cmd/pelican/version.go b/cmd/pelican/version.go new file mode 100644 index 0000000..ee48b9c --- /dev/null +++ b/cmd/pelican/version.go @@ -0,0 +1,24 @@ +package main + +import ( + "fmt" + "os" +) + +var ( + binaryVersion string + buildTime string + goVersion string + gitCommit string +) + +func version() { + fmt.Fprintf( + os.Stdout, + "Pelican\n Version: %s\n Git commit: %s\n Go version: %s\n Build date: %s\n", + binaryVersion, + gitCommit, + goVersion, + buildTime, + ) +} diff --git a/magefiles/mage.go b/magefiles/mage.go index 059c5e4..793a7a3 100644 --- a/magefiles/mage.go +++ b/magefiles/mage.go @@ -3,14 +3,20 @@ package main import ( + "fmt" "os" + "path/filepath" + "runtime" "strings" + "time" + "github.com/magefile/mage/mg" "github.com/magefile/mage/sh" ) const ( - binary = "pelican" + binary = "pelican" + defaultInstallPrefix = "/usr/local" ) var Default = Build @@ -41,8 +47,29 @@ func Lint() error { // Build build the executable func Build() error { - main := "./cmd/" + binary + "/main.go" - return sh.Run("go", "build", "-o", binary, main) + main := "./cmd/" + binary + flags := ldflags() + + return sh.Run("go", "build", "-ldflags="+flags, "-a", "-o", binary, main) +} + +func Install() error { + mg.Deps(Build) + + installPrefix := os.Getenv("PELICAN_INSTALL_PREFIX") + if installPrefix == "" { + installPrefix = defaultInstallPrefix + } + + dest := filepath.Join(installPrefix, "bin", binary) + + 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", binary, dest) + + return nil } // Clean clean the workspace @@ -71,3 +98,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 +}