Skip to content

Commit

Permalink
Add version information to binary
Browse files Browse the repository at this point in the history
Signed-off-by: Heathcliff <[email protected]>
  • Loading branch information
heathcliff26 committed Jul 14, 2024
1 parent 0e61227 commit 166b653
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 12 deletions.
7 changes: 4 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ FROM --platform=$BUILDPLATFORM docker.io/library/golang:1.22.5 AS build-stage

ARG BUILDPLATFORM
ARG TARGETARCH
ARG RELEASE_VERSION

WORKDIR /app

COPY vendor ./vendor
COPY go.mod go.sum ./
COPY cmd ./cmd
COPY pkg ./pkg
COPY hack ./hack

RUN CGO_ENABLED=0 GOOS=linux GOARCH="${TARGETARCH}" go build -ldflags="-w -s" -o /simple-fileserver ./cmd/
RUN --mount=type=bind,target=/app/.git,source=.git GOOS=linux GOARCH="${TARGETARCH}" hack/build.sh

#
# END build-stage
Expand All @@ -26,7 +27,7 @@ FROM scratch AS final-stage

WORKDIR /

COPY --from=build-stage /simple-fileserver /
COPY --from=build-stage /app/bin/simple-fileserver /

EXPOSE 8080

Expand Down
8 changes: 5 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,24 @@ REPOSITORY ?= localhost
CONTAINER_NAME ?= simple-fileserver
TAG ?= latest

GO_BUILD_FLAGS ?= -ldflags="-w -s"

default: build

build:
go build $(GO_BUILD_FLAGS) -o bin/simple-fileserver ./cmd/
hack/build.sh

build-image:
podman build -t $(REPOSITORY)/$(CONTAINER_NAME):$(TAG) .

test:
go test -v ./...

update-deps:
hack/update-deps.sh

.PHONY: \
default \
build \
build-image \
test \
update-deps \
$(NULL)
8 changes: 8 additions & 0 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ package main

import (
"flag"
"fmt"
"log"
"os"
"strconv"
"strings"

"github.com/heathcliff26/simple-fileserver/pkg/version"
)

const defaultPort = 8080
Expand All @@ -17,6 +20,7 @@ func init() {
flag.StringVar(&sslKey, "key", "", "SFILESERVER_KEY: SSL private key to use, needs cert as well. Default is no ssl.")
flag.BoolVar(&withoutIndex, "no-index", false, "SFILESERVER_NO_INDEX: Do not serve an index for directories, return index.html or 404 instead")
flag.BoolVar(&enableLogging, "log", false, "SFILESERVER_LOG: Enable logging requests")
flag.BoolVar(&showVersion, "version", false, "Show the version information and exit")
}

func envBool(target *bool, name string) {
Expand Down Expand Up @@ -67,6 +71,10 @@ func parseEnv() {
// Parse CLI Arguments and check the input.
func parseFlags() {
flag.Parse()
if showVersion {
fmt.Print(version.Version())
os.Exit(0)
}
parseEnv()

if webroot == "" {
Expand Down
26 changes: 20 additions & 6 deletions cmd/cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,14 @@ func TestCmd(t *testing.T) {
}
}

func execExitTest(t *testing.T, test string) {
func execExitTest(t *testing.T, test string, exitsError bool) {
cmd := exec.Command(os.Args[0], "-test.run="+test)
cmd.Env = append(os.Environ(), "RUN_CRASH_TEST=1")
err := cmd.Run()
if err == nil {
if exitsError && err == nil {
t.Fatal("Process exited without error")
} else if !exitsError && err == nil {
return
}
if e, ok := err.(*exec.ExitError); ok && !e.Success() {
return
Expand All @@ -160,7 +162,7 @@ func TestCmdWebrootMissing(t *testing.T) {
// Should not reach here, ensure exit with 0 if it does
os.Exit(0)
}
execExitTest(t, "TestCmdWebrootMissing")
execExitTest(t, "TestCmdWebrootMissing", true)
}

func TestCmdMalformedPortEnvVariable(t *testing.T) {
Expand All @@ -171,7 +173,7 @@ func TestCmdMalformedPortEnvVariable(t *testing.T) {
// Should not reach here, ensure exit with 0 if it does
os.Exit(0)
}
execExitTest(t, "TestCmdMalformedPortEnvVariable")
execExitTest(t, "TestCmdMalformedPortEnvVariable", true)
}

func TestCmdIncompleteSSL(t *testing.T) {
Expand All @@ -183,7 +185,7 @@ func TestCmdIncompleteSSL(t *testing.T) {
// Should not reach here, ensure exit with 0 if it does
os.Exit(0)
}
execExitTest(t, "TestCmdIncompleteSSL/NoCert")
execExitTest(t, "TestCmdIncompleteSSL/NoCert", true)
})
t.Run("NoKey", func(t *testing.T) {
if os.Getenv("RUN_CRASH_TEST") == "1" {
Expand All @@ -193,7 +195,19 @@ func TestCmdIncompleteSSL(t *testing.T) {
// Should not reach here, ensure exit with 0 if it does
os.Exit(0)
}
execExitTest(t, "TestCmdIncompleteSSL/NoKey")
execExitTest(t, "TestCmdIncompleteSSL/NoKey", true)
})
}

func TestCmdVersion(t *testing.T) {
if os.Getenv("RUN_CRASH_TEST") == "1" {
err := flag.CommandLine.Parse([]string{"-version"})
if err != nil {
t.Fatalf("Failed to parse test args: %v", err)
}
parseFlags()
// Should not reach here, ensure exit with 0 if it does
os.Exit(0)
}
execExitTest(t, "TestCmdVersion", false)
}
1 change: 1 addition & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ var (
sslKey string
withoutIndex bool
enableLogging bool
showVersion bool
)

func main() {
Expand Down
27 changes: 27 additions & 0 deletions hack/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash

set -e

base_dir="$(dirname "${BASH_SOURCE[0]}" | xargs realpath)/.."

bin_dir="${base_dir}/bin"

GOOS="${GOOS:-$(go env GOOS)}"
GOARCH="${GOARCH:-$(go env GOARCH)}"

GO_LD_FLAGS="${GO_LD_FLAGS:-"-s"}"

if [ "${RELEASE_VERSION}" != "" ]; then
echo "Building release version ${RELEASE_VERSION}"
GO_LD_FLAGS+=" -X github.com/heathcliff26/simple-fileserver/pkg/version.version=${RELEASE_VERSION}"
fi

output_name="${bin_dir}/simple-fileserver"
if [ "${GOOS}" == "windows" ]; then
output_name="${output_name}.exe"
fi

pushd "${base_dir}" >/dev/null

echo "Building $(basename "${output_name}")"
GOOS="${GOOS}" GOARCH="${GOARCH}" CGO_ENABLED=0 go build -ldflags="${GO_LD_FLAGS}" -o "${output_name}" ./cmd/...
33 changes: 33 additions & 0 deletions pkg/version/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package version

import (
"runtime"
"runtime/debug"
)

const Name = "simple-fileserver"

var version = "devel"

func Version() string {
var commit string
buildinfo, _ := debug.ReadBuildInfo()
for _, item := range buildinfo.Settings {
if item.Key == "vcs.revision" {
commit = item.Value
break
}
}
if len(commit) > 7 {
commit = commit[:7]
} else if commit == "" {
commit = "Unknown"
}

result := Name + ":\n"
result += " Version: " + version + "\n"
result += " Commit: " + commit + "\n"
result += " Go: " + runtime.Version() + "\n"

return result
}
30 changes: 30 additions & 0 deletions pkg/version/version_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package version

import (
"runtime"
"strings"
"testing"

"github.com/stretchr/testify/assert"
)

func TestVersion(t *testing.T) {
result := Version()

lines := strings.Split(result, "\n")

assert := assert.New(t)

if !assert.Equal(5, len(lines), "Should have enough lines") {
t.FailNow()
}
assert.Contains(lines[0], Name)
assert.Contains(lines[1], version)

commit := strings.Split(lines[2], ":")
assert.NotEmpty(strings.TrimSpace(commit[1]))

assert.Contains(lines[3], runtime.Version())

assert.Equal("", lines[4], "Should have trailing newline")
}

0 comments on commit 166b653

Please sign in to comment.