浏览代码

Added build script written in go that adds build symbols for version, commit and build date

Torkel Ödegaard 11 年之前
父节点
当前提交
d06174fb56
共有 7 个文件被更改,包括 276 次插入9 次删除
  1. 246 0
      build.go
  2. 1 1
      grafana
  3. 12 2
      main.go
  4. 5 0
      pkg/api/frontendsettings.go
  5. 3 1
      pkg/cmd/web.go
  6. 5 1
      pkg/setting/setting.go
  7. 4 4
      wercker.yml

+ 246 - 0
build.go

@@ -0,0 +1,246 @@
+// +build ignore
+
+package main
+
+import (
+	"bytes"
+	"crypto/md5"
+	"flag"
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"regexp"
+	"runtime"
+	"strconv"
+	"strings"
+	"time"
+)
+
+var (
+	versionRe = regexp.MustCompile(`-[0-9]{1,3}-g[0-9a-f]{5,10}`)
+	goarch    string
+	goos      string
+	noupgrade bool
+	version   string = "2.0.0-alpha"
+	race      bool
+)
+
+const minGoVersion = 1.3
+
+func main() {
+	log.SetOutput(os.Stdout)
+	log.SetFlags(0)
+
+	if os.Getenv("GOPATH") == "" {
+		cwd, err := os.Getwd()
+		if err != nil {
+			log.Fatal(err)
+		}
+		gopath := filepath.Clean(filepath.Join(cwd, "../../../../"))
+		log.Println("GOPATH is", gopath)
+		os.Setenv("GOPATH", gopath)
+	}
+
+	//os.Setenv("PATH", fmt.Sprintf("%s%cbin%c%s", os.Getenv("GOPATH"), os.PathSeparator, os.PathListSeparator, os.Getenv("PATH")))
+
+	flag.StringVar(&goarch, "goarch", runtime.GOARCH, "GOARCH")
+	flag.StringVar(&goos, "goos", runtime.GOOS, "GOOS")
+	flag.BoolVar(&race, "race", race, "Use race detector")
+	flag.Parse()
+
+	if flag.NArg() == 0 {
+		log.Println("Usage: go run build.go build")
+		return
+	}
+
+	for _, cmd := range flag.Args() {
+		switch cmd {
+		case "setup":
+			setup()
+
+		case "build":
+			pkg := "."
+			var tags []string
+			if noupgrade {
+				tags = []string{"noupgrade"}
+			}
+			build(pkg, tags)
+
+		case "test":
+			pkg := "./..."
+			test(pkg)
+
+		case "clean":
+			clean()
+
+		default:
+			log.Fatalf("Unknown command %q", cmd)
+		}
+	}
+}
+
+func setup() {
+	runPrint("go", "get", "-v", "github.com/tools/godep")
+}
+
+func test(pkg string) {
+	setBuildEnv()
+	runPrint("go", "test", "-short", "-timeout", "60s", pkg)
+}
+
+func build(pkg string, tags []string) {
+	binary := "./bin/grafana"
+	if goos == "windows" {
+		binary += ".exe"
+	}
+
+	rmr(binary, binary+".md5")
+	args := []string{"build", "-ldflags", ldflags()}
+	if len(tags) > 0 {
+		args = append(args, "-tags", strings.Join(tags, ","))
+	}
+	if race {
+		args = append(args, "-race")
+	}
+
+	args = append(args, "-o", binary)
+	args = append(args, pkg)
+	setBuildEnv()
+	runPrint("go", args...)
+
+	// Create an md5 checksum of the binary, to be included in the archive for
+	// automatic upgrades.
+	err := md5File(binary)
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+func ldflags() string {
+	var b bytes.Buffer
+	b.WriteString("-w")
+	b.WriteString(fmt.Sprintf(" -X main.version '%s'", version))
+	b.WriteString(fmt.Sprintf(" -X main.commit '%s'", getGitSha()))
+	b.WriteString(fmt.Sprintf(" -X main.buildstamp %d", buildStamp()))
+	return b.String()
+}
+
+func rmr(paths ...string) {
+	for _, path := range paths {
+		log.Println("rm -r", path)
+		os.RemoveAll(path)
+	}
+}
+
+func clean() {
+	rmr("bin", "Godeps/_workspace/pkg", "Godeps/_workspace/bin")
+	rmr(filepath.Join(os.Getenv("GOPATH"), fmt.Sprintf("pkg/%s_%s/github.com/grafana-pro", goos, goarch)))
+}
+
+func setBuildEnv() {
+	os.Setenv("GOOS", goos)
+	if strings.HasPrefix(goarch, "armv") {
+		os.Setenv("GOARCH", "arm")
+		os.Setenv("GOARM", goarch[4:])
+	} else {
+		os.Setenv("GOARCH", goarch)
+	}
+	if goarch == "386" {
+		os.Setenv("GO386", "387")
+	}
+	wd, err := os.Getwd()
+	if err != nil {
+		log.Println("Warning: can't determine current dir:", err)
+		log.Println("Build might not work as expected")
+	}
+	os.Setenv("GOPATH", fmt.Sprintf("%s%c%s", filepath.Join(wd, "Godeps", "_workspace"), os.PathListSeparator, os.Getenv("GOPATH")))
+	log.Println("GOPATH=" + os.Getenv("GOPATH"))
+}
+
+func getGitSha() string {
+	v, err := runError("git", "describe", "--always", "--dirty")
+	if err != nil {
+		return "unknown-dev"
+	}
+	v = versionRe.ReplaceAllFunc(v, func(s []byte) []byte {
+		s[0] = '+'
+		return s
+	})
+	return string(v)
+}
+
+func buildStamp() int64 {
+	bs, err := runError("git", "show", "-s", "--format=%ct")
+	if err != nil {
+		return time.Now().Unix()
+	}
+	s, _ := strconv.ParseInt(string(bs), 10, 64)
+	return s
+}
+
+func buildArch() string {
+	os := goos
+	if os == "darwin" {
+		os = "macosx"
+	}
+	return fmt.Sprintf("%s-%s", os, goarch)
+}
+
+func run(cmd string, args ...string) []byte {
+	bs, err := runError(cmd, args...)
+	if err != nil {
+		log.Println(cmd, strings.Join(args, " "))
+		log.Println(string(bs))
+		log.Fatal(err)
+	}
+	return bytes.TrimSpace(bs)
+}
+
+func runError(cmd string, args ...string) ([]byte, error) {
+	ecmd := exec.Command(cmd, args...)
+	bs, err := ecmd.CombinedOutput()
+	if err != nil {
+		return nil, err
+	}
+	return bytes.TrimSpace(bs), nil
+}
+
+func runPrint(cmd string, args ...string) {
+	log.Println(cmd, strings.Join(args, " "))
+	ecmd := exec.Command(cmd, args...)
+	ecmd.Stdout = os.Stdout
+	ecmd.Stderr = os.Stderr
+	err := ecmd.Run()
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+func md5File(file string) error {
+	fd, err := os.Open(file)
+	if err != nil {
+		return err
+	}
+	defer fd.Close()
+
+	h := md5.New()
+	_, err = io.Copy(h, fd)
+	if err != nil {
+		return err
+	}
+
+	out, err := os.Create(file + ".md5")
+	if err != nil {
+		return err
+	}
+
+	_, err = fmt.Fprintf(out, "%x\n", h.Sum(nil))
+	if err != nil {
+		return err
+	}
+
+	return out.Close()
+}

+ 1 - 1
grafana

@@ -1 +1 @@
-Subproject commit d1b31bb3d699f674da4b02d34421edc03bf9e275
+Subproject commit 72d953220756e1ebf03c2a4d3aa108e2fc11a969

+ 12 - 2
main.go

@@ -3,23 +3,33 @@ package main
 import (
 	"os"
 	"runtime"
+	"strconv"
 
 	"github.com/torkelo/grafana-pro/pkg/cmd"
+	"github.com/torkelo/grafana-pro/pkg/setting"
 
 	"github.com/codegangsta/cli"
 )
 
-const APP_VER = "0.1.0 Alpha"
+var version = "master"
+var commit = "NA"
+var buildstamp string
 
 func init() {
 	runtime.GOMAXPROCS(runtime.NumCPU())
 }
 
 func main() {
+	buildstampInt64, _ := strconv.ParseInt(buildstamp, 10, 64)
+
+	setting.BuildVersion = version
+	setting.BuildCommit = commit
+	setting.BuildStamp = buildstampInt64
+
 	app := cli.NewApp()
 	app.Name = "Grafana Backend"
 	app.Usage = "grafana web"
-	app.Version = APP_VER
+	app.Version = version
 	app.Commands = []cli.Command{cmd.CmdWeb}
 	app.Flags = append(app.Flags, []cli.Flag{}...)
 	app.Run(os.Args)

+ 5 - 0
pkg/api/frontendsettings.go

@@ -63,6 +63,11 @@ func getFrontendSettings(c *middleware.Context) (map[string]interface{}, error)
 	jsonObj := map[string]interface{}{
 		"datasources": datasources,
 		"appSubUrl":   setting.AppSubUrl,
+		"buildInfo": map[string]interface{}{
+			"version":    setting.BuildVersion,
+			"commit":     setting.BuildCommit,
+			"buildstamp": setting.BuildStamp,
+		},
 	}
 
 	return jsonObj, nil

+ 3 - 1
pkg/cmd/web.go

@@ -7,6 +7,7 @@ import (
 	"fmt"
 	"net/http"
 	"path"
+	"time"
 
 	"github.com/Unknwon/macaron"
 	"github.com/codegangsta/cli"
@@ -68,7 +69,8 @@ func mapStatic(m *macaron.Macaron, dir string, prefix string) {
 }
 
 func runWeb(c *cli.Context) {
-	log.Info("Starting Grafana 2.0-alpha")
+	log.Info("Starting Grafana")
+	log.Info("Version: %v, Commit: %v, Build date: %v", setting.BuildVersion, setting.BuildCommit, time.Unix(setting.BuildStamp, 0))
 
 	setting.NewConfigContext()
 	setting.InitServices()

+ 5 - 1
pkg/setting/setting.go

@@ -34,11 +34,15 @@ const (
 var (
 	// App settings.
 	Env       string = DEV
-	AppVer    string
 	AppName   string
 	AppUrl    string
 	AppSubUrl string
 
+	// build
+	BuildVersion string
+	BuildCommit  string
+	BuildStamp   int64
+
 	// Log settings.
 	LogRootPath string
 	LogModes    []string

+ 4 - 4
wercker.yml

@@ -15,14 +15,14 @@ build:
           go install github.com/tools/godep
     # Build the project
     - script:
-        name: godep build
+        name: build backend
         code: |
-          godep go build -o bin/grafana .
+          go run build.go build
     # Test the project
     - script:
-        name: godep go test
+        name: test backend
         code: |
-          godep go test ./pkg/...
+          go run build.go test
     # frontend
     - npm-install:
         cwd: grafana/