diff --git a/HomebrewFormula/age.rb b/HomebrewFormula/age.rb index 74a31e1c..7641e6b8 100644 --- a/HomebrewFormula/age.rb +++ b/HomebrewFormula/age.rb @@ -13,8 +13,9 @@ class Age < Formula depends_on "go" => :build def install + mkdir bin - system "go", "build", "-trimpath", "-o", bin, "filippo.io/age/cmd/..." + system "go", "build", "-trimpath", "-o", bin, "-ldflags", "-X main.version=v#{version}", "filippo.io/age/cmd/..." prefix.install_metafiles end end diff --git a/README.md b/README.md index 0f15b3e6..eef01e1b 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,8 @@ Options: -r, --recipient RECIPIENT Encrypt to the specified RECIPIENT. Can be repeated. -d, --decrypt Decrypt the input to the output. -i, --identity KEY Use the private key file at path KEY. Can be repeated. + -h, --help Print this message and exit + --version Print the version string and exit INPUT defaults to standard input, and OUTPUT defaults to standard output. @@ -89,8 +91,13 @@ If your system has [Go 1.13+](https://golang.org/dl/), you can build from source ``` git clone https://filippo.io/age && cd age -go build -o . filippo.io/age/cmd/... +./build_age #(Use build_age.ps1 with Powershell) ``` +The build script is just a wrapper around `go build` that automatically inserts version information. The same result can be achieved by running: +``` +go build --ldflags "-X main.version=$VERSION -X main.commit=$HASH" -o . filippo.io/age/cmd/... +``` +Where `$VERSION` is the current git tag and `$HASH` is the current (short) git hash On Arch Linux, age is available from AUR as [`age`](https://aur.archlinux.org/packages/age/) or [`age-git`](https://aur.archlinux.org/packages/age-git/): diff --git a/build_age b/build_age new file mode 100644 index 00000000..d617fe3e --- /dev/null +++ b/build_age @@ -0,0 +1,25 @@ +#!/bin/bash + +function usage() { + echo "usage: ./build_age [--release]" + exit 1 +} +# --release doesn't use a hash to allow for minor post-tag commits (e.g. README updates) without having to revert or retag +if [[ $# -eq 1 ]] && [[ $1 == "--release" ]]; then + AGE_VER=$(git describe --tags) +elif [[ $# -ne 0 ]]; then + usage +else + AV=$(git describe --tags) + AGE_VER=${AV%-*-g*} + AGE_COMMIT=$(git rev-parse --short HEAD) +fi + +go build --ldflags "-X main.version=$AGE_VER -X main.commit=$AGE_COMMIT" -o . filippo.io/age/cmd/... +if [[ $? ]]; then + echo "age build success" +else + echo "age build failure" + exit 1 +fi + diff --git a/build_age.ps1 b/build_age.ps1 new file mode 100644 index 00000000..b2fd2ed4 --- /dev/null +++ b/build_age.ps1 @@ -0,0 +1,26 @@ +param([switch] $release = $false) + +if($args.count -ne 0){ + Write-Output "Usage: ./build_age.ps1 [-release]" + exit 1 +} + +$AV=git describe --tags +$AV=$AV -split '-\d*-g' +$AGE_VER=$av[0] +# -release doesn't use a hash to allow for minor post-tag commits (e.g. README updates) without having to revert or retag +if($release.IsPresent){ + $verstring="`"-X main.version=$AGE_VER`"" +} else{ + $verstring="`"-X main.version=$AGE_VER -X main.commit=$($AV[1])`"" +} + +go build --ldflags $verstring -o . filippo.io/age/cmd/... + +if($?){ + Write-Output "build success" +} else{ + Write-Output "build failure" + exit 1 +} + diff --git a/cmd/age-keygen/keygen.go b/cmd/age-keygen/keygen.go index 80f2d697..2ed2c618 100644 --- a/cmd/age-keygen/keygen.go +++ b/cmd/age-keygen/keygen.go @@ -17,13 +17,51 @@ import ( "golang.org/x/crypto/ssh/terminal" ) +var version = "not compiled with version information" +var commit string + +const usage = `Usage: + age-keygen + age-keygen -o OUTPUT + +Options: + -o OUTPUT Write the result to the file at path OUTPUT. + -h, --help Print this message and exit + --version Print the version string and exit + +If -o is not provided, OUTPUT defaults to standard output + +Example: + $ age-keygen -o key.txt + Public key: age12d695gkxyk07dfng0ght8thsc9yhug74um2hnydslpunjvjpvd7s3dzp6m + $ cat key.txt|grep KEY + AGE-SECRET-KEY-1L3W64GQX6H8YPG7HXW7EMTXHSJ97Q3G8HGGPXS2N5PRT9H6TDD6S7LRZZS` + func main() { log.SetFlags(0) + flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s\n", usage) } + var verFlag, helpFlag bool + flag.BoolVar(&verFlag, "version", false, "print version and quit") + flag.BoolVar(&helpFlag, "h", false, "print usage and quit") + flag.BoolVar(&helpFlag, "help", false, "print usage and quit") outFlag := flag.String("o", "", "output to `FILE` (default stdout)") flag.Parse() + switch { + case helpFlag: + fmt.Printf("%s\n", usage) + os.Exit(0) + case verFlag: + if commit != "" { + fmt.Printf("Version: %s\nHash: %s\n", version, commit) + } else { + fmt.Printf("Version: %s\n", version) + } + os.Exit(0) + } if len(flag.Args()) != 0 { - log.Fatalf("age-keygen takes no arguments") + log.Fatalf("age-keygen takes no arguments.\n"+ + "Run age-keygen -h for help") } out := os.Stdout diff --git a/cmd/age/age.go b/cmd/age/age.go index a604bb63..a318fbf1 100644 --- a/cmd/age/age.go +++ b/cmd/age/age.go @@ -28,6 +28,9 @@ func (f *multiFlag) Set(value string) error { return nil } +var version = "not compiled with version information" +var commit string + const usage = `Usage: age -r RECIPIENT [-a] [-o OUTPUT] [INPUT] age --decrypt [-i KEY] [-o OUTPUT] [INPUT] @@ -39,6 +42,8 @@ Options: -r, --recipient RECIPIENT Encrypt to the specified RECIPIENT. Can be repeated. -d, --decrypt Decrypt the input to the output. -i, --identity KEY Use the private key file at path KEY. Can be repeated. + -h, --help Print this message and exit + --version Print the version string and exit INPUT defaults to standard input, and OUTPUT defaults to standard output. @@ -60,9 +65,9 @@ func main() { flag.Usage = func() { fmt.Fprintf(os.Stderr, "%s\n", usage) } var ( - outFlag string - decryptFlag, armorFlag, passFlag bool - recipientFlags, identityFlags multiFlag + outFlag string + decryptFlag, armorFlag, passFlag, verFlag, helpFlag bool + recipientFlags, identityFlags multiFlag ) flag.BoolVar(&decryptFlag, "d", false, "decrypt the input") @@ -77,13 +82,30 @@ func main() { flag.Var(&recipientFlags, "recipient", "recipient (can be repeated)") flag.Var(&identityFlags, "i", "identity (can be repeated)") flag.Var(&identityFlags, "identity", "identity (can be repeated)") + flag.BoolVar(&verFlag, "version", false, "print version and quit") + flag.BoolVar(&helpFlag, "h", false, "print usage and quit") + flag.BoolVar(&helpFlag, "help", false, "print usage and quit") flag.Parse() - if flag.NArg() > 1 { + if flag.NArg()+flag.NFlag() == 0 { + logFatalf("%s\n", usage) + } else if flag.NArg() > 1 { logFatalf("Error: too many arguments.\n" + - "age accepts a single optional argument for the input file.") + "age accepts a single optional argument for the input file.\n" + + "Run age -h for help") } + switch { + case helpFlag: + fmt.Printf("%s\n", usage) + os.Exit(0) + case verFlag: + if commit != "" { + fmt.Printf("Version: %s\nHash: %s\n", version, commit) + } else { + fmt.Printf("Version: %s\n", version) + } + os.Exit(0) case decryptFlag: if armorFlag { logFatalf("Error: -a/--armor can't be used with -d/--decrypt.\n" +