From 2235198650d8dfadded525cc308ae8dfa786da52 Mon Sep 17 00:00:00 2001 From: Taylor Blau Date: Thu, 19 Jul 2018 13:02:25 -0500 Subject: [PATCH] Makefile: replace script/bootstrap with 'make', 'make all' --- CONTRIBUTING.md | 10 +- Makefile | 90 ++++++ appveyor.yml | 6 +- rpm/SPECS/git-lfs.spec | 4 +- rpm/build_rpms.bsh | 2 +- script/bootstrap | 27 -- script/build.go | 337 ---------------------- script/{install.sh.example => install.sh} | 0 script/release.go | 2 +- script/script.go | 2 - test/testhelpers.sh | 7 - 11 files changed, 103 insertions(+), 384 deletions(-) delete mode 100755 script/bootstrap delete mode 100644 script/build.go rename script/{install.sh.example => install.sh} (100%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 53f571d0..4174cf6b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -58,7 +58,7 @@ In general, contributors should develop on branches based off of `master` and pu ## Submitting a pull request 0. [Fork][] and clone the repository -0. Configure and install the dependencies: `script/bootstrap` +0. Configure and install the dependencies: `make` 0. Make sure the tests pass on your machine: `make test` 0. Create a new branch based on `master`: `git checkout -b master` 0. Make your change, add tests, and make sure the tests still pass @@ -107,8 +107,8 @@ your projects in a specific directory, you can symlink it from `$GOPATH`: $ cd ~/path/to/your/projects $ ln -s $GOPATH/src/github.com/git-lfs/git-lfs -From here, run `script/bootstrap` to build Git LFS in the `./bin` directory. -Before submitting changes, be sure to run the Go tests and the shell integration +From here, run `make` to build Git LFS in the `./bin` directory. Before +submitting changes, be sure to run the Go tests and the shell integration tests: $ make test # runs just the Go tests @@ -128,11 +128,11 @@ If you are the current maintainer: * Create a [new draft Release](https://github.com/git-lfs/git-lfs/releases/new). List any changes with links to related PRs. -* Make sure your local dependencies are up to date: `script/bootstrap` +* Make sure your local dependencies are up to date: `make vendor` * Ensure that tests are green: `script/cibuild` * Bump the version in `lfs/lfs.go`, [like this](https://github.com/git-lfs/git-lfs/commit/dd17828e4a6f2394cbba8621037199dc28f046e8). * Add the new version to the top of CHANGELOG.md -* Build for all platforms with `script/bootstrap -all` (you need Go setup for +* Build for all platforms with `make release` (you need Go setup for cross compiling with Mac, Linux, FreeBSD, and Windows support). * Test the command locally. The compiled version will be in `bin/releases/{os}-{arch}/git-lfs-{version}/git-lfs` * Get the draft Release ID from the GitHub API: `curl -in https://api.github.com/repos/git-lfs/git-lfs/releases` diff --git a/Makefile b/Makefile index 58f2888e..ed786c01 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,23 @@ +GIT_LFS_SHA ?= $(shell git rev-parse --short HEAD) +VERSION ?= $(shell git describe HEAD) + GO ?= go GO_TEST_EXTRA_ARGS = +BUILTIN_LD_FLAGS = +BUILTIN_LD_FLAGS += -X github.com/git-lfs/git-lfs/config.GitCommit=$(GIT_LFS_SHA) +ifneq ("$(DWARF)","YesPlease") +BUILTIN_LD_FLAGS += -s +BUILTIN_LD_FLAGS += -w +endif +EXTRA_LD_FLAGS = +LD_FLAGS = $(BUILTIN_LD_FLAGS) $(EXTRA_LD_FLAGS) + +BUILTIN_GC_FLAGS = +EXTRA_GC_FLAGS = +GC_FLAGS = $(BUILTIN_GC_FLAGS) $(EXTRA_GC_FLAGS) + GLIDE ?= glide GREP ?= grep @@ -33,6 +49,78 @@ PKGS += tools/kv PKGS += tq endif +ifeq ($(OS),Windows_NT) +X ?= .exe +else +X ?= +endif +.DEFAULT_GOAL := bin/git-lfs$(X) + +BUILD = GOOS=$(1) GOARCH=$(2) \ + $(GO) build \ + -ldflags="$(LD_FLAGS)" \ + -gcflags="$(GC_FLAGS)" \ + -o ./bin/git-lfs$(3) ./git-lfs.go + +BUILD_TARGETS = bin/git-lfs-darwin-amd64 bin/git-lfs-darwin-386 \ + bin/git-lfs-linux-amd64 bin/git-lfs-linux-386 \ + bin/git-lfs-freebsd-amd64 bin/git-lfs-freebsd-386 \ + bin/git-lfs-windows-amd64.exe bin/git-lfs-windows-386.exe + +.PHONY : all build +all build : $(BUILD_TARGETS) + +bin/git-lfs-darwin-amd64 : fmt + $(call BUILD,darwin,amd64,-darwin-amd64) +bin/git-lfs-darwin-386 : fmt + $(call BUILD,darwin,386,-darwin-386) +bin/git-lfs-linux-amd64 : fmt + $(call BUILD,linux,amd64,-linux-amd64) +bin/git-lfs-linux-386 : fmt + $(call BUILD,linux,386,-linux-386) +bin/git-lfs-freebsd-amd64 : fmt + $(call BUILD,freebsd,amd64,-freebsd-amd64) +bin/git-lfs-freebsd-386 : fmt + $(call BUILD,freebsd,386,-freebsd-386) +bin/git-lfs-windows-amd64.exe : version-info fmt + $(call BUILD,windows,amd64,-windows-amd64.exe) +bin/git-lfs-windows-386.exe : version-info fmt + $(call BUILD,windows,386,-windows-386.exe) + +bin/git-lfs : git-lfs.go $(PKGS) + $(call BUILD,$(GOOS),$(GOARCH),) + +bin/git-lfs.exe : git-lfs.go $(PKGS) version-info + $(call BUILD,$(GOOS),$(GOARCH),.exe) + +.PHONY : version-info +version-info: + go get github.com/josephspurrier/goversioninfo/cmd/goversioninfo + PATH=$$PATH:$$GOPATH/bin/windows_386 $(GO) generate + +RELEASE_TARGETS = bin/releases/git-lfs-darwin-amd64-$(VERSION).tar.gz \ + bin/releases/git-lfs-darwin-386-$(VERSION).tar.gz \ + bin/releases/git-lfs-linux-amd64-$(VERSION).tar.gz \ + bin/releases/git-lfs-linux-386-$(VERSION).tar.gz \ + bin/releases/git-lfs-freebsd-amd64-$(VERSION).tar.gz \ + bin/releases/git-lfs-freebsd-386-$(VERSION).tar.gz \ + bin/releases/git-lfs-windows-amd64-$(VERSION).zip \ + bin/releases/git-lfs-windows-386-$(VERSION).zip + +RELEASE_INCLUDES = README.md CHANGELOG.md script/install.sh + +.PHONY : release +release : $(RELEASE_TARGETS) + shasum -a 256 $(RELEASE_TARGETS) + +bin/releases/git-lfs-%-$(VERSION).tar.gz : $(RELEASE_INCLUDES) bin/git-lfs-% + @mkdir -p bin/releases + tar -s '!bin/git-lfs-.*!git-lfs!' -s '!script/!!' -czf $@ $^ + +bin/releases/git-lfs-%-$(VERSION).zip : $(RELEASE_INCLUDES) bin/git-lfs-%.exe + @mkdir -p bin/releases + zip -j -l $@ $^ + TEST_TARGETS := test-bench test-verbose test-race .PHONY : $(TEST_TARGETS) test $(TEST_TARGETS) : test @@ -53,9 +141,11 @@ vendor : glide.lock $(RM) -r vendor/github.com/davecgh/go-spew $(RM) -r vendor/github.com/pmezard/go-difflib +.PHONY : fmt fmt : $(PKGS) | lint $(GOIMPORTS) $(GOIMPORTS_EXTRA_OPTS) $? +.PHONY : lint lint : $(PKGS) $(GO) list -f '{{ join .Deps "\n" }}' . \ | $(XARGS) $(GO) list -f '{{ if not .Standard }}{{ .ImportPath }}{{ end }}' \ diff --git a/appveyor.yml b/appveyor.yml index dd30a527..7e3612a7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,8 @@ skip_branch_with_pr: true environment: + CYGWIN: "$(CYGWIN) winsymlinks:nativestrict" + MSYS: "$(MSYS) winsymlinks:nativestrict" GOPATH: $(HOMEDRIVE)$(HOMEPATH)\go MSYSTEM: MINGW64 @@ -22,9 +24,9 @@ install: go version build_script: - - bash --login -c 'GOARCH=386 script/bootstrap' + - bash --login -c 'GOARCH=386 make -B bin/git-lfs.exe' - mv bin\git-lfs.exe git-lfs-x86.exe - - bash --login -c 'GOARCH=amd64 script/bootstrap' + - bash --login -c 'GOARCH=amd64 make -B bin/git-lfs.exe' - mv bin\git-lfs.exe git-lfs-x64.exe after_build: diff --git a/rpm/SPECS/git-lfs.spec b/rpm/SPECS/git-lfs.spec index 25c01e86..ebfd3401 100644 --- a/rpm/SPECS/git-lfs.spec +++ b/rpm/SPECS/git-lfs.spec @@ -35,9 +35,9 @@ ln -s $(pwd) src/github.com/git-lfs/%{name} pushd src/github.com/git-lfs/%{name} %if %{_arch} == i386 - GOARCH=386 ./script/bootstrap + GOARCH=386 make %else - GOARCH=amd64 ./script/bootstrap + GOARCH=amd64 make %endif popd ./script/man diff --git a/rpm/build_rpms.bsh b/rpm/build_rpms.bsh index cc3fd62e..839b3e88 100755 --- a/rpm/build_rpms.bsh +++ b/rpm/build_rpms.bsh @@ -140,7 +140,7 @@ fi pushd ${CURDIR}/.. #Yes, compile lfs before compiling lfs... - ./script/bootstrap + make #Use the version output to grab the version number and short sha #(that yes, I could have gotten from git myself) LFS_VERSION=$(./bin/git-lfs version | sed -r 's|.*/([0-9.]*).*|\1|') diff --git a/script/bootstrap b/script/bootstrap deleted file mode 100755 index 8da991f4..00000000 --- a/script/bootstrap +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash -set -e - -if uname -s | grep -q "_NT-"; then - # Tell Cygwin / MSYS to really create symbolic links. - export CYGWIN="$CYGWIN winsymlinks:nativestrict" - export MSYS="$MSYS winsymlinks:nativestrict" -fi - -if [ -z "$GOPATH" ]; then - export GOPATH="$(pwd)" - mkdir -p src/github.com/git-lfs - [ -h src/github.com/git-lfs/git-lfs ] || - ln -s "$GOPATH" src/github.com/git-lfs/git-lfs -fi - -if uname -s | grep -q "_NT-"; then - echo "Installing goversioninfo to embed resources into Windows executables..." - go get github.com/josephspurrier/goversioninfo/cmd/goversioninfo - export PATH=$PATH:$GOPATH/bin/windows_386 - echo "Creating the resource.syso version information file..." - go generate -fi - -make fmt -rm -rf bin/* -GO15VENDOREXPERIMENT=1 go run script/*.go -cmd build "$@" diff --git a/script/build.go b/script/build.go deleted file mode 100644 index 4553a2c8..00000000 --- a/script/build.go +++ /dev/null @@ -1,337 +0,0 @@ -package main - -import ( - "crypto/sha256" - "encoding/hex" - "encoding/json" - "flag" - "fmt" - "io" - "io/ioutil" - "log" - "os" - "os/exec" - "path/filepath" - "runtime" - "strings" - - "github.com/git-lfs/git-lfs/config" -) - -var ( - BuildOS = flag.String("os", "", "OS to target: darwin,freebsd,linux,windows") - BuildArch = flag.String("arch", "", "Arch to target: 386,amd64") - BuildAll = flag.Bool("all", false, "Builds all architectures") - BuildDwarf = flag.Bool("dwarf", false, "Includes DWARF tables in build artifacts") - BuildLdFlags = flag.String("ldflags", "", "-ldflags to pass to the compiler") - BuildGcFlags = flag.String("gcflags", "", "-gcflags to pass to the compiler") - ShowHelp = flag.Bool("help", false, "Shows help") - matrixKeys = map[string]string{ - "darwin": "Mac", - "freebsd": "FreeBSD", - "linux": "Linux", - "windows": "Windows", - "amd64": "AMD64", - } - LdFlags []string -) - -func mainBuild() { - if *ShowHelp { - fmt.Println("usage: script/bootstrap [-os] [-arch] [-all]") - flag.PrintDefaults() - return - } - - fmt.Printf("Using %s\n", runtime.Version()) - - genOut, err := exec.Command("go", "generate", "./commands").CombinedOutput() - if err != nil { - fmt.Fprintf(os.Stderr, "go generate failed:\n%v", string(genOut)) - os.Exit(1) - } - cmd, _ := exec.Command("git", "rev-parse", "--short", "HEAD").Output() - - if len(cmd) > 0 { - LdFlags = append(LdFlags, "-X", strings.TrimSpace( - "github.com/git-lfs/git-lfs/config.GitCommit="+string(cmd), - )) - } - if !*BuildDwarf { - LdFlags = append(LdFlags, "-s", "-w") - } - - buildMatrix := make(map[string]Release) - errored := false - - var platforms, arches []string - if len(*BuildOS) > 0 { - platforms = strings.Split(*BuildOS, ",") - } - if len(*BuildArch) > 0 { - arches = strings.Split(*BuildArch, ",") - } - if *BuildAll { - platforms = []string{"linux", "darwin", "freebsd", "windows"} - arches = []string{"amd64", "386"} - } - - if len(platforms) < 1 || len(arches) < 1 { - if err := build("", "", buildMatrix); err != nil { - log.Fatalln(err) - } - return // skip build matrix stuff - } - - for _, buildos := range platforms { - for _, buildarch := range arches { - err := build(strings.TrimSpace(buildos), strings.TrimSpace(buildarch), buildMatrix) - if err != nil { - errored = true - } - } - } - - if errored { - os.Exit(1) - } - - by, err := json.Marshal(buildMatrix) - if err != nil { - log.Fatalln("Error encoding build matrix to json:", err) - } - - file, err := os.Create("bin/releases/build_matrix.json") - if err != nil { - log.Fatalln("Error creating build_matrix.json:", err) - } - - written, err := file.Write(by) - file.Close() - - if err != nil { - log.Fatalln("Error writing build_matrix.json", err) - } - - if jsonSize := len(by); written != jsonSize { - log.Fatalf("Expected to write %d bytes, actually wrote %d.\n", jsonSize, written) - } -} - -func build(buildos, buildarch string, buildMatrix map[string]Release) error { - addenv := len(buildos) > 0 && len(buildarch) > 0 - name := "git-lfs-" + config.Version - dir := "bin" - - if addenv { - fmt.Printf("Building for %s/%s\n", buildos, buildarch) - dir = filepath.Join(dir, "releases", buildos+"-"+buildarch, name) - } - - if err := buildCommand(dir, buildos, buildarch); err != nil { - return err - } - - if addenv { - err := os.MkdirAll(dir, 0755) - if err != nil { - log.Println("Error setting up installer:\n", err.Error()) - return err - } - - err = setupInstaller(buildos, buildarch, dir, buildMatrix) - if err != nil { - log.Println("Error setting up installer:\n", err.Error()) - return err - } - } - - return nil -} - -func buildCommand(dir, buildos, buildarch string) error { - addenv := len(buildos) > 0 && len(buildarch) > 0 - - bin := filepath.Join(dir, "git-lfs") - - cmdOS := runtime.GOOS - if len(buildos) > 0 { - cmdOS = buildos - } - if cmdOS == "windows" { - bin = bin + ".exe" - } - - args := make([]string, 1, 6) - args[0] = "build" - if len(*BuildLdFlags) > 0 { - args = append(args, "-ldflags", *BuildLdFlags) - } else if len(LdFlags) > 0 { - args = append(args, "-ldflags", strings.Join(LdFlags, " ")) - } - - if len(*BuildGcFlags) > 0 { - args = append(args, "-gcflags", *BuildGcFlags) - } - - args = append(args, "-o", bin, ".") - - cmd := exec.Command("go", args...) - if addenv { - cmd.Env = buildGoEnv(buildos, buildarch) - } - - output, err := cmd.CombinedOutput() - if len(output) > 0 { - fmt.Println(string(output)) - } - return err -} - -func buildGoEnv(buildos, buildarch string) []string { - env := make([]string, 6, 9) - env[0] = "GOOS=" + buildos - env[1] = "GOARCH=" + buildarch - env[2] = "GOPATH=" + os.Getenv("GOPATH") - env[3] = "GOROOT=" + os.Getenv("GOROOT") - env[4] = "PATH=" + os.Getenv("PATH") - env[5] = "GO15VENDOREXPERIMENT=" + os.Getenv("GO15VENDOREXPERIMENT") - for _, key := range []string{"TMP", "TEMP", "TEMPDIR"} { - v := os.Getenv(key) - if len(v) == 0 { - continue - } - env = append(env, key+"="+v) - } - return env -} - -func setupInstaller(buildos, buildarch, dir string, buildMatrix map[string]Release) error { - textfiles := []string{ - "README.md", "CHANGELOG.md", - } - - if buildos == "windows" { - return winInstaller(textfiles, buildos, buildarch, dir, buildMatrix) - } else { - return unixInstaller(textfiles, buildos, buildarch, dir, buildMatrix) - } -} - -func unixInstaller(textfiles []string, buildos, buildarch, dir string, buildMatrix map[string]Release) error { - for _, filename := range textfiles { - cmd := exec.Command("cp", filename, filepath.Join(dir, filename)) - if err := logAndRun(cmd); err != nil { - return err - } - } - - fullInstallPath := filepath.Join(dir, "install.sh") - cmd := exec.Command("cp", "script/install.sh.example", fullInstallPath) - if err := logAndRun(cmd); err != nil { - return err - } - - if err := os.Chmod(fullInstallPath, 0755); err != nil { - return err - } - - name := zipName(buildos, buildarch) + ".tar.gz" - cmd = exec.Command("tar", "czf", "../"+name, filepath.Base(dir)) - cmd.Dir = filepath.Dir(dir) - if err := logAndRun(cmd); err != nil { - return nil - } - - addToMatrix(buildMatrix, buildos, buildarch, name) - return nil -} - -func winInstaller(textfiles []string, buildos, buildarch, dir string, buildMatrix map[string]Release) error { - for _, filename := range textfiles { - by, err := ioutil.ReadFile(filename) - if err != nil { - return err - } - - winEndings := strings.Replace(string(by), "\n", "\r\n", -1) - err = ioutil.WriteFile(filepath.Join(dir, filename), []byte(winEndings), 0644) - if err != nil { - return err - } - } - - installerPath := filepath.Dir(filepath.Dir(dir)) - name := zipName(buildos, buildarch) + ".zip" - full := filepath.Join(installerPath, name) - matches, err := filepath.Glob(dir + "/*") - if err != nil { - return err - } - - args := make([]string, len(matches)+2) - args[0] = "-j" // junk the zip paths - args[1] = full - copy(args[2:], matches) - - cmd := exec.Command("zip", args...) - if err := logAndRun(cmd); err != nil { - return err - } - - addToMatrix(buildMatrix, buildos, buildarch, name) - return nil -} - -func addToMatrix(buildMatrix map[string]Release, buildos, buildarch, name string) { - buildMatrix[fmt.Sprintf("%s-%s", buildos, buildarch)] = Release{ - Label: releaseLabel(buildos, buildarch), - Filename: name, - SHA256: hashRelease(name), - } -} - -func hashRelease(name string) string { - full := filepath.Join("bin/releases", name) - file, err := os.Open(full) - if err != nil { - fmt.Printf("unable to open release %q: %+v\n", full, err) - os.Exit(1) - } - - defer file.Close() - - h := sha256.New() - if _, err = io.Copy(h, file); err != nil { - fmt.Printf("error reading release %q: %+v\n", full, err) - os.Exit(1) - } - - return hex.EncodeToString(h.Sum(nil)) -} - -func logAndRun(cmd *exec.Cmd) error { - fmt.Printf(" - %s\n", strings.Join(cmd.Args, " ")) - if len(cmd.Dir) > 0 { - fmt.Printf(" - in %s\n", cmd.Dir) - } - - output, err := cmd.CombinedOutput() - fmt.Println(string(output)) - return err -} - -func zipName(os, arch string) string { - return fmt.Sprintf("git-lfs-%s-%s-%s", os, arch, config.Version) -} - -func releaseLabel(buildos, buildarch string) string { - return fmt.Sprintf("%s %s", key(buildos), key(buildarch)) -} - -func key(k string) string { - if s, ok := matrixKeys[k]; ok { - return s - } - return k -} diff --git a/script/install.sh.example b/script/install.sh similarity index 100% rename from script/install.sh.example rename to script/install.sh diff --git a/script/release.go b/script/release.go index 8cc2a9ca..85f2be28 100644 --- a/script/release.go +++ b/script/release.go @@ -25,7 +25,7 @@ func mainRelease() { file, err := os.Open("bin/releases/build_matrix.json") if err != nil { log.Println("Error opening build_matrix.json:", err) - log.Fatalln("Ensure `script/bootstrap -all` has completed successfully") + log.Fatalln("Ensure `make release` has completed successfully") } defer file.Close() diff --git a/script/script.go b/script/script.go index 7c2ad85e..4ed198ce 100644 --- a/script/script.go +++ b/script/script.go @@ -16,8 +16,6 @@ var SubCommand = flag.String("cmd", "", "Command: build or release") func main() { flag.Parse() switch *SubCommand { - case "build": - mainBuild() case "release": mainRelease() case "integration": diff --git a/test/testhelpers.sh b/test/testhelpers.sh index b8cdb1e8..92fdc246 100644 --- a/test/testhelpers.sh +++ b/test/testhelpers.sh @@ -493,13 +493,6 @@ setup() { rm -rf "$REMOTEDIR" mkdir "$REMOTEDIR" - if [ -z "$SKIPCOMPILE" ] && [ -z "$LFS_BIN" ]; then - echo "compile git-lfs for $0" - script/bootstrap || { - return $? - } - fi - echo "Git LFS: ${LFS_BIN:-$(which git-lfs)}" git lfs version git version