diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1b8f75df221fc3d6c7ae6bb85a08b09192904977..860a09321676254c52bd980fdc9476a26a67ebb2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -20,8 +20,8 @@ test:go1.8: verify: stage: test script: - - make notice-up-to-date - - make verify + - ./run notice-up-to-date + - ./run verify package: stage: package diff --git a/Makefile b/Makefile index 3acb0c2e8a695e173a5f0f3f92c9b9b74bf62324..0f85c1df2317353cec5bbaf4e7c4f451027e1841 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,6 @@ BIN_BUILD_DIR=${BUILD_DIR}/_build/bin PKG_BUILD_DIR:=${BUILD_DIR}/_build/src/${PKG} CMDS:=$(shell cd cmd && ls) TEST_REPO=internal/testhelper/testdata/data/gitlab-test.git -VERSION=$(shell git describe)-$(shell date -u +%Y%m%d.%H%M%S) export GOPATH=${BUILD_DIR}/_build export GO15VENDOREXPERIMENT=1 @@ -14,61 +13,30 @@ export PATH:=${GOPATH}/bin:$(PATH) .PHONY: all all: build -.PHONY: ${BUILD_DIR}/_build -${BUILD_DIR}/_build: - mkdir -p $@/src/${PKG} - tar -cf - --exclude _build --exclude .git . | (cd $@/src/${PKG} && tar -xf -) - touch $@ - -build: clean-build ${BUILD_DIR}/_build $(shell find . -name '*.go' -not -path './vendor/*' -not -path './_build/*') - rm -f -- "${BIN_BUILD_DIR}/*" - go install -ldflags "-X main.version=${VERSION}" ${PKG}/cmd/... - cp ${BIN_BUILD_DIR}/* ${BUILD_DIR}/ +build: + ./run build install: build mkdir -p $(DESTDIR)${PREFIX}/bin/ cd ${BIN_BUILD_DIR} && install ${CMDS} ${DESTDIR}${PREFIX}/bin/ -verify: lint check-formatting govendor-status - -check-formatting: install-developer-tools - go run _support/gofmt-all.go -n - -govendor-status: ${BUILD_DIR}/_build install-developer-tools - cd ${PKG_BUILD_DIR} && govendor status - ${TEST_REPO}: git clone --bare https://gitlab.com/gitlab-org/gitlab-test.git $@ -test: clean-build ${TEST_REPO} ${BUILD_DIR}/_build +test: ${TEST_REPO} + ./run prepare-build go test ${PKG}/... -lint: install-developer-tools - go run _support/lint.go - package: build ./_support/package/package ${CMDS} -notice: ${BUILD_DIR}/_build install-developer-tools +notice: + ./run prepare-build + ./run install-developer-tools rm -f ${PKG_BUILD_DIR}/NOTICE # Avoid NOTICE-in-NOTICE cd ${PKG_BUILD_DIR} && govendor license -template _support/notice.template -o ${BUILD_DIR}/NOTICE -notice-up-to-date: notice - git ls-files --error-unmatch NOTICE # NOTICE is a tracked file - git diff --exit-code # there are no changed files - -clean: clean-build +clean: + ./run clean-build rm -rf internal/testhelper/testdata rm -f $(foreach cmd,${CMDS},./${cmd}) - -clean-build: - rm -rf ${BUILD_DIR}/_build - -.PHONY: format -format: - @go run _support/gofmt-all.go -f - -.PHONY: install-developer-tools -install-developer-tools: - @go run _support/go-get-if-missing.go govendor github.com/kardianos/govendor - @go run _support/go-get-if-missing.go golint github.com/golang/lint/golint diff --git a/_run/build b/_run/build new file mode 100644 index 0000000000000000000000000000000000000000..d747ab634d1b849ad3b8e8832c6ee6f33ca72c37 --- /dev/null +++ b/_run/build @@ -0,0 +1,2 @@ +./run prepare-build +GOPATH=$(pwd)/_run go run _support/build.go diff --git a/_run/check-formatting b/_run/check-formatting new file mode 100644 index 0000000000000000000000000000000000000000..ffb28f1c7491f646f388341827a313fee53851a5 --- /dev/null +++ b/_run/check-formatting @@ -0,0 +1,2 @@ +./run install-developer-tools +go run _support/gofmt-all.go -n diff --git a/_run/clean-build b/_run/clean-build new file mode 100644 index 0000000000000000000000000000000000000000..0a09c1ecee4d1c6baaf1040460854374a86e5af7 --- /dev/null +++ b/_run/clean-build @@ -0,0 +1 @@ +GOPATH=$(pwd)/_run go run _support/clean-build.go diff --git a/_run/format b/_run/format new file mode 100644 index 0000000000000000000000000000000000000000..775a53e14a6927f88a7b9927daa2fe81b032a8cd --- /dev/null +++ b/_run/format @@ -0,0 +1 @@ +go run _support/gofmt-all.go -f diff --git a/_run/govendor-status b/_run/govendor-status new file mode 100644 index 0000000000000000000000000000000000000000..f156b7bf018617797e1bd48078769098db342161 --- /dev/null +++ b/_run/govendor-status @@ -0,0 +1,3 @@ +./run prepare-build +./run install-developer-tools +./run with-gopath govendor status diff --git a/_run/install-developer-tools b/_run/install-developer-tools new file mode 100644 index 0000000000000000000000000000000000000000..a9490d2ccf49c7ec4b94993468280c3ea57bda4b --- /dev/null +++ b/_run/install-developer-tools @@ -0,0 +1,2 @@ +go run _support/go-get-if-missing.go govendor github.com/kardianos/govendor +go run _support/go-get-if-missing.go golint github.com/golang/lint/golint diff --git a/_run/lint b/_run/lint new file mode 100644 index 0000000000000000000000000000000000000000..44a9cb4826331436cf112f0fc021768241e2288e --- /dev/null +++ b/_run/lint @@ -0,0 +1,2 @@ +./run install-developer-tools +go run _support/lint.go diff --git a/_run/notice-up-to-date b/_run/notice-up-to-date new file mode 100644 index 0000000000000000000000000000000000000000..e4de130512c8266afd22e07187c0fe352490c203 --- /dev/null +++ b/_run/notice-up-to-date @@ -0,0 +1,2 @@ +git ls-files --error-unmatch NOTICE # NOTICE is a tracked file +git diff --exit-code # there are no changed files diff --git a/_run/prepare-build b/_run/prepare-build new file mode 100644 index 0000000000000000000000000000000000000000..426a285c8354398862f696e62ae63a036c991f25 --- /dev/null +++ b/_run/prepare-build @@ -0,0 +1 @@ +GOPATH=$(pwd)/_run go run _support/prepare-build.go diff --git a/_run/src/build/config.go b/_run/src/build/config.go new file mode 100644 index 0000000000000000000000000000000000000000..4593810cb52048e185e2c0e8294a1fd83030b276 --- /dev/null +++ b/_run/src/build/config.go @@ -0,0 +1,57 @@ +package build + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" + "os" + "os/exec" + "path" +) + +type Config struct { + BuildDir string `json:"build_dir"` + Package string `json:"package"` + BuildGopath string +} + +func ReadConfig() (*Config, error) { + data, err := ioutil.ReadFile("build_config.json") + if err != nil { + return nil, err + } + result := &Config{} + err = json.Unmarshal(data, result) + if err != nil { + return nil, err + } + + for _, s := range []string{result.BuildDir, result.Package} { + if len(s) == 0 { + return nil, fmt.Errorf("invalid build config: %q", data) + } + } + cwd, err := os.Getwd() + if err != nil { + return nil, err + } + result.BuildGopath = path.Join(cwd, result.BuildDir) + return result, nil +} + +func (c *Config) PackageBuildDir() string { + return path.Join(c.BuildGopath, "src", c.Package) +} + +func Version() (string, error) { + describe, err := exec.Command("git", "describe").Output() + if err != nil { + return "", err + } + date, err := exec.Command("date", "-u", "+%Y%m%d.%H%M%S").Output() // TODO use package 'time' + if err != nil { + return "", err + } + return fmt.Sprintf("%s-%s", bytes.TrimSpace(describe), bytes.TrimSpace(date)), nil +} diff --git a/_run/verify b/_run/verify new file mode 100644 index 0000000000000000000000000000000000000000..17c38e3300a07d83aa47b00b26e8eee265ca6f5e --- /dev/null +++ b/_run/verify @@ -0,0 +1,3 @@ +./run lint +./run check-formatting +./run govendor-status diff --git a/_run/with-gopath b/_run/with-gopath new file mode 100644 index 0000000000000000000000000000000000000000..8298efcf0a3b3da3720bd40aa965508d0e6e4337 --- /dev/null +++ b/_run/with-gopath @@ -0,0 +1 @@ +GOPATH=$(pwd)/_run go run _support/with-gopath.go "$@" diff --git a/_support/build.go b/_support/build.go new file mode 100644 index 0000000000000000000000000000000000000000..6f1e9a604f5c56d0c327f6f4710fa100bb870fdc --- /dev/null +++ b/_support/build.go @@ -0,0 +1,51 @@ +package main + +import ( + "build" + "fmt" + "os" + "os/exec" + "path" + "strings" +) + +func main() { + if err := run(); err != nil { + fmt.Fprintf(os.Stderr, "fatal: %v\n", err) + os.Exit(1) + } +} + +func run() error { + config, err := build.ReadConfig() + if err != nil { + return err + } + + binDir := path.Join(config.BuildDir, "bin") + if err := os.RemoveAll(binDir); err != nil { + return err + } + version, err := build.Version() + if err != nil { + return err + } + goInstall := exec.Command("go", "install", "-ldflags", "-X main.version="+version, config.Package+"/cmd/...") + goInstall.Stdout = os.Stdout + goInstall.Stderr = os.Stderr + env := []string{} + for _, s := range os.Environ() { + if strings.HasPrefix(s, "GOPATH=") { + continue + } + env = append(env, s) + } + goInstall.Env = append(env, "GOPATH="+config.BuildGopath) + if err := goInstall.Run(); err != nil { + return err + } + cp := exec.Command("sh", "-c", fmt.Sprintf("cp %s/* .", binDir)) + cp.Stdout = os.Stdout + cp.Stderr = os.Stderr + return cp.Run() +} diff --git a/_support/clean-build.go b/_support/clean-build.go new file mode 100644 index 0000000000000000000000000000000000000000..2d5419f10dd623871778b67cdacc1d906099602a --- /dev/null +++ b/_support/clean-build.go @@ -0,0 +1,23 @@ +package main + +import ( + "build" + "fmt" + "os" +) + +func main() { + if err := run(); err != nil { + fmt.Fprintf(os.Stderr, "fatal: %v\n", err) + os.Exit(1) + } +} + +func run() error { + config, err := build.ReadConfig() + if err != nil { + return err + } + + return os.RemoveAll(config.BuildDir) +} diff --git a/_support/gofmt-all.go b/_support/gofmt-all.go index 32a1a1753c7a66c40fb45d5ef41e38031a49d952..631bda0412cdc58317bb7b7199bc6b0ad1d2ce64 100644 --- a/_support/gofmt-all.go +++ b/_support/gofmt-all.go @@ -52,7 +52,7 @@ func gofmt(write bool) error { fmt.Printf("%s", output) if !write && len(output) > 0 { - return fmt.Errorf("Please run 'make format'") + return fmt.Errorf("Please run './run format'") } return nil } diff --git a/_support/prepare-build.go b/_support/prepare-build.go new file mode 100644 index 0000000000000000000000000000000000000000..32a8053a1e9283574209068deca1bab6e1f19655 --- /dev/null +++ b/_support/prepare-build.go @@ -0,0 +1,63 @@ +package main + +import ( + "build" + "context" + "fmt" + "os" + "os/exec" +) + +func main() { + if err := run(); err != nil { + fmt.Fprintf(os.Stderr, "fatal: %v\n", err) + os.Exit(1) + } +} + +func run() error { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + config, err := build.ReadConfig() + if err != nil { + return err + } + + if err := os.RemoveAll(config.BuildDir); err != nil { + return err + } + if err := os.MkdirAll(config.PackageBuildDir(), 0755); err != nil { + return err + } + + tarSource := exec.CommandContext(ctx, "tar", "-cf", "-", "--exclude", config.BuildDir, "--exclude", ".git", ".") + tarSource.Stderr = os.Stderr + sourcePipe, err := tarSource.StdoutPipe() + if err != nil { + return err + } + + tarDest := exec.CommandContext(ctx, "tar", "-xf", "-") + tarDest.Stdin = sourcePipe + tarDest.Stderr = os.Stderr + tarDest.Dir = config.PackageBuildDir() + + for _, err := range []error{tarSource.Start(), tarDest.Start()} { + if err != nil { + return err + } + } + + if err := sourcePipe.Close(); err != nil { + return err + } + + for _, err := range []error{tarSource.Wait(), tarDest.Wait()} { + if err != nil { + return err + } + } + + return nil +} diff --git a/_support/release b/_support/release index 091004639b7986f1690ab9cf4f54fc2dd6835195..92913448eee3f9eaf781ce4529a8823d500e0556 100755 --- a/_support/release +++ b/_support/release @@ -4,7 +4,7 @@ require 'erb' require_relative 'run.rb' def main(version) - run!(%w[make notice-up-to-date]) + run!(%w[./run notice-up-to-date]) run!(%w[make test]) puts 'Testing for changed files' diff --git a/_support/with-gopath.go b/_support/with-gopath.go new file mode 100644 index 0000000000000000000000000000000000000000..d85930410b31a3f80ddd498bc95dc5575c7c5ec7 --- /dev/null +++ b/_support/with-gopath.go @@ -0,0 +1,36 @@ +package main + +import ( + "build" + "fmt" + "os" + "os/exec" + "syscall" +) + +func main() { + if err := run(); err != nil { + fmt.Fprintf(os.Stderr, "fatal: %v\n", err) + os.Exit(1) + } +} + +func run() error { + if len(os.Args) <= 1 { + return fmt.Errorf("need at least one argument") + } + config, err := build.ReadConfig() + if err != nil { + return err + } + + executable, err := exec.LookPath(os.Args[1]) + if err != nil { + return err + } + os.Setenv("GOPATH", config.BuildGopath) + if err := os.Chdir(config.PackageBuildDir()); err != nil { + return err + } + return syscall.Exec(executable, os.Args[1:], os.Environ()) +} diff --git a/build_config.json b/build_config.json new file mode 100644 index 0000000000000000000000000000000000000000..146eefdeea3b986ff8f630ff786216c7eca60eff --- /dev/null +++ b/build_config.json @@ -0,0 +1,4 @@ +{ +"build_dir": "_build", +"package":"gitlab.com/gitlab-org/gitaly" +} \ No newline at end of file diff --git a/run b/run new file mode 100755 index 0000000000000000000000000000000000000000..63f9919ca653cde145c79a15b5ee44fadf113294 --- /dev/null +++ b/run @@ -0,0 +1,4 @@ +#!/bin/sh +sub_command=$1 +shift +exec sh -e -x -- ./_run/"$sub_command" "$@"