From 324e9bb91a20228c4528fc464dcdea48817face0 Mon Sep 17 00:00:00 2001 From: Tuna Date: Thu, 26 Jul 2018 16:20:10 +0700 Subject: [PATCH 1/3] clean up Makefile add build puppeth directly --- Makefile | 79 +---- build/ci.go | 711 -------------------------------------- internal/build/archive.go | 185 ---------- internal/build/azure.go | 111 ------ internal/build/pgp.go | 59 ---- internal/build/util.go | 38 -- 6 files changed, 6 insertions(+), 1177 deletions(-) delete mode 100644 internal/build/archive.go delete mode 100644 internal/build/azure.go delete mode 100644 internal/build/pgp.go diff --git a/Makefile b/Makefile index 6b3cc8a0e578..4492228ac811 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,6 @@ -# This Makefile is meant to be used by people that do not usually work -# with Go source code. If you know what GOPATH is then you probably -# don't need to bother with make. - -.PHONY: tomo android ios tomo-cross swarm evm all test clean +.PHONY: tomo tomo-cross evm all test clean .PHONY: tomo-linux tomo-linux-386 tomo-linux-amd64 tomo-linux-mips64 tomo-linux-mips64le -.PHONY: tomo-linux-arm tomo-linux-arm-5 tomo-linux-arm-6 tomo-linux-arm-7 tomo-linux-arm64 .PHONY: tomo-darwin tomo-darwin-386 tomo-darwin-amd64 -.PHONY: tomo-windows tomo-windows-386 tomo-windows-amd64 GOBIN = $(shell pwd)/build/bin GOFMT = gofmt @@ -26,50 +20,27 @@ bootnode: @echo "Done building." @echo "Run \"$(GOBIN)/bootnode\" to launch a bootnode." -swarm: - build/env.sh go run build/ci.go install ./cmd/swarm +puppeth: + build/env.sh go run build/ci.go install ./cmd/puppeth @echo "Done building." - @echo "Run \"$(GOBIN)/swarm\" to launch swarm." + @echo "Run \"$(GOBIN)/puppeth\" to launch puppeth." all: build/env.sh go run build/ci.go install -android: - build/env.sh go run build/ci.go aar --local - @echo "Done building." - @echo "Import \"$(GOBIN)/tomo.aar\" to use the library." - -ios: - build/env.sh go run build/ci.go xcode --local - @echo "Done building." - @echo "Import \"$(GOBIN)/tomo.framework\" to use the library." - test: all build/env.sh go run build/ci.go test clean: rm -fr build/_workspace/pkg/ $(GOBIN)/* -# The devtools target installs tools required for 'go generate'. -# You need to put $GOBIN (or $GOPATH/bin) in your PATH to use 'go generate'. - -devtools: - env GOBIN= go get -u golang.org/x/tools/cmd/stringer - env GOBIN= go get -u github.com/kevinburke/go-bindata/go-bindata - env GOBIN= go get -u github.com/fjl/gencodec - env GOBIN= go get -u github.com/golang/protobuf/protoc-gen-go - env GOBIN= go install ./cmd/abigen - @type "npm" 2> /dev/null || echo 'Please install node.js and npm' - @type "solc" 2> /dev/null || echo 'Please install solc' - @type "protoc" 2> /dev/null || echo 'Please install protoc' - # Cross Compilation Targets (xgo) -tomo-cross: tomo-linux tomo-darwin tomo-windows tomo-android tomo-ios +tomo-cross: tomo-linux tomo-darwin @echo "Full cross compilation done:" @ls -ld $(GOBIN)/tomo-* -tomo-linux: tomo-linux-386 tomo-linux-amd64 tomo-linux-arm tomo-linux-mips64 tomo-linux-mips64le +tomo-linux: tomo-linux-386 tomo-linux-amd64 tomo-linux-mips64 tomo-linux-mips64le @echo "Linux cross compilation done:" @ls -ld $(GOBIN)/tomo-linux-* @@ -83,30 +54,6 @@ tomo-linux-amd64: @echo "Linux amd64 cross compilation done:" @ls -ld $(GOBIN)/tomo-linux-* | grep amd64 -tomo-linux-arm: tomo-linux-arm-5 tomo-linux-arm-6 tomo-linux-arm-7 tomo-linux-arm64 - @echo "Linux ARM cross compilation done:" - @ls -ld $(GOBIN)/tomo-linux-* | grep arm - -tomo-linux-arm-5: - build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=linux/arm-5 -v ./cmd/tomo - @echo "Linux ARMv5 cross compilation done:" - @ls -ld $(GOBIN)/tomo-linux-* | grep arm-5 - -tomo-linux-arm-6: - build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=linux/arm-6 -v ./cmd/tomo - @echo "Linux ARMv6 cross compilation done:" - @ls -ld $(GOBIN)/tomo-linux-* | grep arm-6 - -tomo-linux-arm-7: - build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=linux/arm-7 -v ./cmd/tomo - @echo "Linux ARMv7 cross compilation done:" - @ls -ld $(GOBIN)/tomo-linux-* | grep arm-7 - -tomo-linux-arm64: - build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=linux/arm64 -v ./cmd/tomo - @echo "Linux ARM64 cross compilation done:" - @ls -ld $(GOBIN)/tomo-linux-* | grep arm64 - tomo-linux-mips: build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=linux/mips --ldflags '-extldflags "-static"' -v ./cmd/tomo @echo "Linux MIPS cross compilation done:" @@ -141,20 +88,6 @@ tomo-darwin-amd64: @echo "Darwin amd64 cross compilation done:" @ls -ld $(GOBIN)/tomo-darwin-* | grep amd64 -tomo-windows: tomo-windows-386 tomo-windows-amd64 - @echo "Windows cross compilation done:" - @ls -ld $(GOBIN)/tomo-windows-* - -tomo-windows-386: - build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=windows/386 -v ./cmd/tomo - @echo "Windows 386 cross compilation done:" - @ls -ld $(GOBIN)/tomo-windows-* | grep 386 - -tomo-windows-amd64: - build/env.sh go run build/ci.go xgo -- --go=$(GO) --targets=windows/amd64 -v ./cmd/tomo - @echo "Windows amd64 cross compilation done:" - @ls -ld $(GOBIN)/geth-windows-* | grep amd64 - gofmt: $(GOFMT) -s -w $(GO_FILES) $(GIT) checkout vendor diff --git a/build/ci.go b/build/ci.go index 1d95ca0bf0e0..487f386896c9 100644 --- a/build/ci.go +++ b/build/ci.go @@ -26,14 +26,8 @@ Available commands are: install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables test [ -coverage ] [ packages... ] -- runs the tests lint -- runs certain pre-selected linters - archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -upload dest ] -- archives build artefacts importkeys -- imports signing keys from env - debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package - nsis -- creates a Windows NSIS installer - aar [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an Android archive - xcode [ -local ] [ -sign key-id ] [-deploy repo] [ -upload dest ] -- creates an iOS XCode framework xgo [ -alltools ] [ options ] -- cross builds according to options - purge [ -store blobstore ] [ -days threshold ] -- purges old archives from the blobstore For all commands, -n prevents execution of external programs (dry run mode). @@ -41,9 +35,6 @@ For all commands, -n prevents execution of external programs (dry run mode). package main import ( - "bufio" - "bytes" - "encoding/base64" "flag" "fmt" "go/parser" @@ -53,21 +44,13 @@ import ( "os" "os/exec" "path/filepath" - "regexp" "runtime" "strings" - "time" "github.com/ethereum/go-ethereum/internal/build" ) var ( - // Files that end up in the geth*.zip archive. - gethArchiveFiles = []string{ - "COPYING", - executablePath("geth"), - } - // Files that end up in the geth-alltools*.zip archive. allToolsArchiveFiles = []string{ "COPYING", @@ -80,49 +63,6 @@ var ( executablePath("swarm"), executablePath("wnode"), } - - // A debian package is created for all executables listed here. - debExecutables = []debExecutable{ - { - Name: "abigen", - Description: "Source code generator to convert Ethereum contract definitions into easy to use, compile-time type-safe Go packages.", - }, - { - Name: "bootnode", - Description: "Ethereum bootnode.", - }, - { - Name: "evm", - Description: "Developer utility version of the EVM (Ethereum Virtual Machine) that is capable of running bytecode snippets within a configurable environment and execution mode.", - }, - { - Name: "geth", - Description: "Ethereum CLI client.", - }, - { - Name: "puppeth", - Description: "Ethereum private network manager.", - }, - { - Name: "rlpdump", - Description: "Developer utility tool that prints RLP structures.", - }, - { - Name: "swarm", - Description: "Ethereum Swarm daemon and tools", - }, - { - Name: "wnode", - Description: "Ethereum Whisper diagnostic tool", - }, - } - - // Distros for which packages are created. - // Note: vivid is unsupported because there is no golang-1.6 package for it. - // Note: wily is unsupported because it was officially deprecated on lanchpad. - // Note: yakkety is unsupported because it was officially deprecated on lanchpad. - // Note: zesty is unsupported because it was officially deprecated on lanchpad. - debDistros = []string{"trusty", "xenial", "artful", "bionic"} ) var GOBIN, _ = filepath.Abs(filepath.Join("build", "bin")) @@ -150,20 +90,8 @@ func main() { doTest(os.Args[2:]) case "lint": doLint(os.Args[2:]) - case "archive": - doArchive(os.Args[2:]) - case "debsrc": - doDebianSource(os.Args[2:]) - case "nsis": - doWindowsInstaller(os.Args[2:]) - case "aar": - doAndroidArchive(os.Args[2:]) - case "xcode": - doXCodeFramework(os.Args[2:]) case "xgo": doXgo(os.Args[2:]) - case "purge": - doPurge(os.Args[2:]) default: log.Fatal("unknown command ", os.Args[1]) } @@ -345,586 +273,6 @@ func doLint(cmdline []string) { } } -// Release Packaging - -func doArchive(cmdline []string) { - var ( - arch = flag.String("arch", runtime.GOARCH, "Architecture cross packaging") - atype = flag.String("type", "zip", "Type of archive to write (zip|tar)") - signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. LINUX_SIGNING_KEY)`) - upload = flag.String("upload", "", `Destination to upload the archives (usually "gethstore/builds")`) - ext string - ) - flag.CommandLine.Parse(cmdline) - switch *atype { - case "zip": - ext = ".zip" - case "tar": - ext = ".tar.gz" - default: - log.Fatal("unknown archive type: ", atype) - } - - var ( - env = build.Env() - base = archiveBasename(*arch, env) - geth = "geth-" + base + ext - alltools = "geth-alltools-" + base + ext - ) - maybeSkipArchive(env) - if err := build.WriteArchive(geth, gethArchiveFiles); err != nil { - log.Fatal(err) - } - if err := build.WriteArchive(alltools, allToolsArchiveFiles); err != nil { - log.Fatal(err) - } - for _, archive := range []string{geth, alltools} { - if err := archiveUpload(archive, *upload, *signer); err != nil { - log.Fatal(err) - } - } -} - -func archiveBasename(arch string, env build.Environment) string { - platform := runtime.GOOS + "-" + arch - if arch == "arm" { - platform += os.Getenv("GOARM") - } - if arch == "android" { - platform = "android-all" - } - if arch == "ios" { - platform = "ios-all" - } - return platform + "-" + archiveVersion(env) -} - -func archiveVersion(env build.Environment) string { - version := build.VERSION() - if isUnstableBuild(env) { - version += "-unstable" - } - if env.Commit != "" { - version += "-" + env.Commit[:8] - } - return version -} - -func archiveUpload(archive string, blobstore string, signer string) error { - // If signing was requested, generate the signature files - if signer != "" { - pgpkey, err := base64.StdEncoding.DecodeString(os.Getenv(signer)) - if err != nil { - return fmt.Errorf("invalid base64 %s", signer) - } - if err := build.PGPSignFile(archive, archive+".asc", string(pgpkey)); err != nil { - return err - } - } - // If uploading to Azure was requested, push the archive possibly with its signature - if blobstore != "" { - auth := build.AzureBlobstoreConfig{ - Account: strings.Split(blobstore, "/")[0], - Token: os.Getenv("AZURE_BLOBSTORE_TOKEN"), - Container: strings.SplitN(blobstore, "/", 2)[1], - } - if err := build.AzureBlobstoreUpload(archive, filepath.Base(archive), auth); err != nil { - return err - } - if signer != "" { - if err := build.AzureBlobstoreUpload(archive+".asc", filepath.Base(archive+".asc"), auth); err != nil { - return err - } - } - } - return nil -} - -// skips archiving for some build configurations. -func maybeSkipArchive(env build.Environment) { - if env.IsPullRequest { - log.Printf("skipping because this is a PR build") - os.Exit(0) - } - if env.IsCronJob { - log.Printf("skipping because this is a cron job") - os.Exit(0) - } - if env.Branch != "master" && !strings.HasPrefix(env.Tag, "v1.") { - log.Printf("skipping because branch %q, tag %q is not on the whitelist", env.Branch, env.Tag) - os.Exit(0) - } -} - -// Debian Packaging - -func doDebianSource(cmdline []string) { - var ( - signer = flag.String("signer", "", `Signing key name, also used as package author`) - upload = flag.String("upload", "", `Where to upload the source package (usually "ppa:ethereum/ethereum")`) - workdir = flag.String("workdir", "", `Output directory for packages (uses temp dir if unset)`) - now = time.Now() - ) - flag.CommandLine.Parse(cmdline) - *workdir = makeWorkdir(*workdir) - env := build.Env() - maybeSkipArchive(env) - - // Import the signing key. - if b64key := os.Getenv("PPA_SIGNING_KEY"); b64key != "" { - key, err := base64.StdEncoding.DecodeString(b64key) - if err != nil { - log.Fatal("invalid base64 PPA_SIGNING_KEY") - } - gpg := exec.Command("gpg", "--import") - gpg.Stdin = bytes.NewReader(key) - build.MustRun(gpg) - } - - // Create the packages. - for _, distro := range debDistros { - meta := newDebMetadata(distro, *signer, env, now) - pkgdir := stageDebianSource(*workdir, meta) - debuild := exec.Command("debuild", "-S", "-sa", "-us", "-uc") - debuild.Dir = pkgdir - build.MustRun(debuild) - - changes := fmt.Sprintf("%s_%s_source.changes", meta.Name(), meta.VersionString()) - changes = filepath.Join(*workdir, changes) - if *signer != "" { - build.MustRunCommand("debsign", changes) - } - if *upload != "" { - build.MustRunCommand("dput", *upload, changes) - } - } -} - -func makeWorkdir(wdflag string) string { - var err error - if wdflag != "" { - err = os.MkdirAll(wdflag, 0744) - } else { - wdflag, err = ioutil.TempDir("", "geth-build-") - } - if err != nil { - log.Fatal(err) - } - return wdflag -} - -func isUnstableBuild(env build.Environment) bool { - if env.Tag != "" { - return false - } - return true -} - -type debMetadata struct { - Env build.Environment - - // go-ethereum version being built. Note that this - // is not the debian package version. The package version - // is constructed by VersionString. - Version string - - Author string // "name ", also selects signing key - Distro, Time string - Executables []debExecutable -} - -type debExecutable struct { - Name, Description string -} - -func newDebMetadata(distro, author string, env build.Environment, t time.Time) debMetadata { - if author == "" { - // No signing key, use default author. - author = "Ethereum Builds " - } - return debMetadata{ - Env: env, - Author: author, - Distro: distro, - Version: build.VERSION(), - Time: t.Format(time.RFC1123Z), - Executables: debExecutables, - } -} - -// Name returns the name of the metapackage that depends -// on all executable packages. -func (meta debMetadata) Name() string { - if isUnstableBuild(meta.Env) { - return "ethereum-unstable" - } - return "ethereum" -} - -// VersionString returns the debian version of the packages. -func (meta debMetadata) VersionString() string { - vsn := meta.Version - if meta.Env.Buildnum != "" { - vsn += "+build" + meta.Env.Buildnum - } - if meta.Distro != "" { - vsn += "+" + meta.Distro - } - return vsn -} - -// ExeList returns the list of all executable packages. -func (meta debMetadata) ExeList() string { - names := make([]string, len(meta.Executables)) - for i, e := range meta.Executables { - names[i] = meta.ExeName(e) - } - return strings.Join(names, ", ") -} - -// ExeName returns the package name of an executable package. -func (meta debMetadata) ExeName(exe debExecutable) string { - if isUnstableBuild(meta.Env) { - return exe.Name + "-unstable" - } - return exe.Name -} - -// ExeConflicts returns the content of the Conflicts field -// for executable packages. -func (meta debMetadata) ExeConflicts(exe debExecutable) string { - if isUnstableBuild(meta.Env) { - // Set up the conflicts list so that the *-unstable packages - // cannot be installed alongside the regular version. - // - // https://www.debian.org/doc/debian-policy/ch-relationships.html - // is very explicit about Conflicts: and says that Breaks: should - // be preferred and the conflicting files should be handled via - // alternates. We might do this eventually but using a conflict is - // easier now. - return "ethereum, " + exe.Name - } - return "" -} - -func stageDebianSource(tmpdir string, meta debMetadata) (pkgdir string) { - pkg := meta.Name() + "-" + meta.VersionString() - pkgdir = filepath.Join(tmpdir, pkg) - if err := os.Mkdir(pkgdir, 0755); err != nil { - log.Fatal(err) - } - - // Copy the source code. - build.MustRunCommand("git", "checkout-index", "-a", "--prefix", pkgdir+string(filepath.Separator)) - - // Put the debian build files in place. - debian := filepath.Join(pkgdir, "debian") - build.Render("build/deb.rules", filepath.Join(debian, "rules"), 0755, meta) - build.Render("build/deb.changelog", filepath.Join(debian, "changelog"), 0644, meta) - build.Render("build/deb.control", filepath.Join(debian, "control"), 0644, meta) - build.Render("build/deb.copyright", filepath.Join(debian, "copyright"), 0644, meta) - build.RenderString("8\n", filepath.Join(debian, "compat"), 0644, meta) - build.RenderString("3.0 (native)\n", filepath.Join(debian, "source/format"), 0644, meta) - for _, exe := range meta.Executables { - install := filepath.Join(debian, meta.ExeName(exe)+".install") - docs := filepath.Join(debian, meta.ExeName(exe)+".docs") - build.Render("build/deb.install", install, 0644, exe) - build.Render("build/deb.docs", docs, 0644, exe) - } - - return pkgdir -} - -// Windows installer - -func doWindowsInstaller(cmdline []string) { - // Parse the flags and make skip installer generation on PRs - var ( - arch = flag.String("arch", runtime.GOARCH, "Architecture for cross build packaging") - signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. WINDOWS_SIGNING_KEY)`) - upload = flag.String("upload", "", `Destination to upload the archives (usually "gethstore/builds")`) - workdir = flag.String("workdir", "", `Output directory for packages (uses temp dir if unset)`) - ) - flag.CommandLine.Parse(cmdline) - *workdir = makeWorkdir(*workdir) - env := build.Env() - maybeSkipArchive(env) - - // Aggregate binaries that are included in the installer - var ( - devTools []string - allTools []string - gethTool string - ) - for _, file := range allToolsArchiveFiles { - if file == "COPYING" { // license, copied later - continue - } - allTools = append(allTools, filepath.Base(file)) - if filepath.Base(file) == "geth.exe" { - gethTool = file - } else { - devTools = append(devTools, file) - } - } - - // Render NSIS scripts: Installer NSIS contains two installer sections, - // first section contains the geth binary, second section holds the dev tools. - templateData := map[string]interface{}{ - "License": "COPYING", - "Geth": gethTool, - "DevTools": devTools, - } - build.Render("build/nsis.geth.nsi", filepath.Join(*workdir, "geth.nsi"), 0644, nil) - build.Render("build/nsis.install.nsh", filepath.Join(*workdir, "install.nsh"), 0644, templateData) - build.Render("build/nsis.uninstall.nsh", filepath.Join(*workdir, "uninstall.nsh"), 0644, allTools) - build.Render("build/nsis.pathupdate.nsh", filepath.Join(*workdir, "PathUpdate.nsh"), 0644, nil) - build.Render("build/nsis.envvarupdate.nsh", filepath.Join(*workdir, "EnvVarUpdate.nsh"), 0644, nil) - build.CopyFile(filepath.Join(*workdir, "SimpleFC.dll"), "build/nsis.simplefc.dll", 0755) - build.CopyFile(filepath.Join(*workdir, "COPYING"), "COPYING", 0755) - - // Build the installer. This assumes that all the needed files have been previously - // built (don't mix building and packaging to keep cross compilation complexity to a - // minimum). - version := strings.Split(build.VERSION(), ".") - if env.Commit != "" { - version[2] += "-" + env.Commit[:8] - } - installer, _ := filepath.Abs("geth-" + archiveBasename(*arch, env) + ".exe") - build.MustRunCommand("makensis.exe", - "/DOUTPUTFILE="+installer, - "/DMAJORVERSION="+version[0], - "/DMINORVERSION="+version[1], - "/DBUILDVERSION="+version[2], - "/DARCH="+*arch, - filepath.Join(*workdir, "geth.nsi"), - ) - - // Sign and publish installer. - if err := archiveUpload(installer, *upload, *signer); err != nil { - log.Fatal(err) - } -} - -// Android archives - -func doAndroidArchive(cmdline []string) { - var ( - local = flag.Bool("local", false, `Flag whether we're only doing a local build (skip Maven artifacts)`) - signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. ANDROID_SIGNING_KEY)`) - deploy = flag.String("deploy", "", `Destination to deploy the archive (usually "https://oss.sonatype.org")`) - upload = flag.String("upload", "", `Destination to upload the archive (usually "gethstore/builds")`) - ) - flag.CommandLine.Parse(cmdline) - env := build.Env() - - // Sanity check that the SDK and NDK are installed and set - if os.Getenv("ANDROID_HOME") == "" { - log.Fatal("Please ensure ANDROID_HOME points to your Android SDK") - } - if os.Getenv("ANDROID_NDK") == "" { - log.Fatal("Please ensure ANDROID_NDK points to your Android NDK") - } - // Build the Android archive and Maven resources - build.MustRun(goTool("get", "golang.org/x/mobile/cmd/gomobile", "golang.org/x/mobile/cmd/gobind")) - build.MustRun(gomobileTool("init", "--ndk", os.Getenv("ANDROID_NDK"))) - build.MustRun(gomobileTool("bind", "--target", "android", "--javapkg", "org.ethereum", "-v", "github.com/ethereum/go-ethereum/mobile")) - - if *local { - // If we're building locally, copy bundle to build dir and skip Maven - os.Rename("geth.aar", filepath.Join(GOBIN, "geth.aar")) - return - } - meta := newMavenMetadata(env) - build.Render("build/mvn.pom", meta.Package+".pom", 0755, meta) - - // Skip Maven deploy and Azure upload for PR builds - maybeSkipArchive(env) - - // Sign and upload the archive to Azure - archive := "geth-" + archiveBasename("android", env) + ".aar" - os.Rename("geth.aar", archive) - - if err := archiveUpload(archive, *upload, *signer); err != nil { - log.Fatal(err) - } - // Sign and upload all the artifacts to Maven Central - os.Rename(archive, meta.Package+".aar") - if *signer != "" && *deploy != "" { - // Import the signing key into the local GPG instance - if b64key := os.Getenv(*signer); b64key != "" { - key, err := base64.StdEncoding.DecodeString(b64key) - if err != nil { - log.Fatalf("invalid base64 %s", *signer) - } - gpg := exec.Command("gpg", "--import") - gpg.Stdin = bytes.NewReader(key) - build.MustRun(gpg) - } - // Upload the artifacts to Sonatype and/or Maven Central - repo := *deploy + "/service/local/staging/deploy/maven2" - if meta.Develop { - repo = *deploy + "/content/repositories/snapshots" - } - build.MustRunCommand("mvn", "gpg:sign-and-deploy-file", - "-settings=build/mvn.settings", "-Durl="+repo, "-DrepositoryId=ossrh", - "-DpomFile="+meta.Package+".pom", "-Dfile="+meta.Package+".aar") - } -} - -func gomobileTool(subcmd string, args ...string) *exec.Cmd { - cmd := exec.Command(filepath.Join(GOBIN, "gomobile"), subcmd) - cmd.Args = append(cmd.Args, args...) - cmd.Env = []string{ - "GOPATH=" + build.GOPATH(), - "PATH=" + GOBIN + string(os.PathListSeparator) + os.Getenv("PATH"), - } - for _, e := range os.Environ() { - if strings.HasPrefix(e, "GOPATH=") || strings.HasPrefix(e, "PATH=") { - continue - } - cmd.Env = append(cmd.Env, e) - } - return cmd -} - -type mavenMetadata struct { - Version string - Package string - Develop bool - Contributors []mavenContributor -} - -type mavenContributor struct { - Name string - Email string -} - -func newMavenMetadata(env build.Environment) mavenMetadata { - // Collect the list of authors from the repo root - contribs := []mavenContributor{} - if authors, err := os.Open("AUTHORS"); err == nil { - defer authors.Close() - - scanner := bufio.NewScanner(authors) - for scanner.Scan() { - // Skip any whitespace from the authors list - line := strings.TrimSpace(scanner.Text()) - if line == "" || line[0] == '#' { - continue - } - // Split the author and insert as a contributor - re := regexp.MustCompile("([^<]+) <(.+)>") - parts := re.FindStringSubmatch(line) - if len(parts) == 3 { - contribs = append(contribs, mavenContributor{Name: parts[1], Email: parts[2]}) - } - } - } - // Render the version and package strings - version := build.VERSION() - if isUnstableBuild(env) { - version += "-SNAPSHOT" - } - return mavenMetadata{ - Version: version, - Package: "geth-" + version, - Develop: isUnstableBuild(env), - Contributors: contribs, - } -} - -// XCode frameworks - -func doXCodeFramework(cmdline []string) { - var ( - local = flag.Bool("local", false, `Flag whether we're only doing a local build (skip Maven artifacts)`) - signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. IOS_SIGNING_KEY)`) - deploy = flag.String("deploy", "", `Destination to deploy the archive (usually "trunk")`) - upload = flag.String("upload", "", `Destination to upload the archives (usually "gethstore/builds")`) - ) - flag.CommandLine.Parse(cmdline) - env := build.Env() - - // Build the iOS XCode framework - build.MustRun(goTool("get", "golang.org/x/mobile/cmd/gomobile", "golang.org/x/mobile/cmd/gobind")) - build.MustRun(gomobileTool("init")) - bind := gomobileTool("bind", "--target", "ios", "--tags", "ios", "-v", "github.com/ethereum/go-ethereum/mobile") - - if *local { - // If we're building locally, use the build folder and stop afterwards - bind.Dir, _ = filepath.Abs(GOBIN) - build.MustRun(bind) - return - } - archive := "geth-" + archiveBasename("ios", env) - if err := os.Mkdir(archive, os.ModePerm); err != nil { - log.Fatal(err) - } - bind.Dir, _ = filepath.Abs(archive) - build.MustRun(bind) - build.MustRunCommand("tar", "-zcvf", archive+".tar.gz", archive) - - // Skip CocoaPods deploy and Azure upload for PR builds - maybeSkipArchive(env) - - // Sign and upload the framework to Azure - if err := archiveUpload(archive+".tar.gz", *upload, *signer); err != nil { - log.Fatal(err) - } - // Prepare and upload a PodSpec to CocoaPods - if *deploy != "" { - meta := newPodMetadata(env, archive) - build.Render("build/pod.podspec", "Geth.podspec", 0755, meta) - build.MustRunCommand("pod", *deploy, "push", "Geth.podspec", "--allow-warnings", "--verbose") - } -} - -type podMetadata struct { - Version string - Commit string - Archive string - Contributors []podContributor -} - -type podContributor struct { - Name string - Email string -} - -func newPodMetadata(env build.Environment, archive string) podMetadata { - // Collect the list of authors from the repo root - contribs := []podContributor{} - if authors, err := os.Open("AUTHORS"); err == nil { - defer authors.Close() - - scanner := bufio.NewScanner(authors) - for scanner.Scan() { - // Skip any whitespace from the authors list - line := strings.TrimSpace(scanner.Text()) - if line == "" || line[0] == '#' { - continue - } - // Split the author and insert as a contributor - re := regexp.MustCompile("([^<]+) <(.+)>") - parts := re.FindStringSubmatch(line) - if len(parts) == 3 { - contribs = append(contribs, podContributor{Name: parts[1], Email: parts[2]}) - } - } - } - version := build.VERSION() - if isUnstableBuild(env) { - version += "-unstable." + env.Buildnum - } - return podMetadata{ - Archive: archive, - Version: version, - Commit: env.Commit, - Contributors: contribs, - } -} - // Cross compilation func doXgo(cmdline []string) { @@ -976,62 +324,3 @@ func xgoTool(args []string) *exec.Cmd { } return cmd } - -// Binary distribution cleanups - -func doPurge(cmdline []string) { - var ( - store = flag.String("store", "", `Destination from where to purge archives (usually "gethstore/builds")`) - limit = flag.Int("days", 30, `Age threshold above which to delete unstalbe archives`) - ) - flag.CommandLine.Parse(cmdline) - - if env := build.Env(); !env.IsCronJob { - log.Printf("skipping because not a cron job") - os.Exit(0) - } - // Create the azure authentication and list the current archives - auth := build.AzureBlobstoreConfig{ - Account: strings.Split(*store, "/")[0], - Token: os.Getenv("AZURE_BLOBSTORE_TOKEN"), - Container: strings.SplitN(*store, "/", 2)[1], - } - blobs, err := build.AzureBlobstoreList(auth) - if err != nil { - log.Fatal(err) - } - // Iterate over the blobs, collect and sort all unstable builds - for i := 0; i < len(blobs); i++ { - if !strings.Contains(blobs[i].Name, "unstable") { - blobs = append(blobs[:i], blobs[i+1:]...) - i-- - } - } - for i := 0; i < len(blobs); i++ { - for j := i + 1; j < len(blobs); j++ { - iTime, err := time.Parse(time.RFC1123, blobs[i].Properties.LastModified) - if err != nil { - log.Fatal(err) - } - jTime, err := time.Parse(time.RFC1123, blobs[j].Properties.LastModified) - if err != nil { - log.Fatal(err) - } - if iTime.After(jTime) { - blobs[i], blobs[j] = blobs[j], blobs[i] - } - } - } - // Filter out all archives more recent that the given threshold - for i, blob := range blobs { - timestamp, _ := time.Parse(time.RFC1123, blob.Properties.LastModified) - if time.Since(timestamp) < time.Duration(*limit)*24*time.Hour { - blobs = blobs[:i] - break - } - } - // Delete all marked as such and return - if err := build.AzureBlobstoreDelete(auth, blobs); err != nil { - log.Fatal(err) - } -} diff --git a/internal/build/archive.go b/internal/build/archive.go deleted file mode 100644 index ac680ba63de8..000000000000 --- a/internal/build/archive.go +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package build - -import ( - "archive/tar" - "archive/zip" - "compress/gzip" - "fmt" - "io" - "os" - "path/filepath" - "strings" -) - -type Archive interface { - // Directory adds a new directory entry to the archive and sets the - // directory for subsequent calls to Header. - Directory(name string) error - - // Header adds a new file to the archive. The file is added to the directory - // set by Directory. The content of the file must be written to the returned - // writer. - Header(os.FileInfo) (io.Writer, error) - - // Close flushes the archive and closes the underlying file. - Close() error -} - -func NewArchive(file *os.File) (Archive, string) { - switch { - case strings.HasSuffix(file.Name(), ".zip"): - return NewZipArchive(file), strings.TrimSuffix(file.Name(), ".zip") - case strings.HasSuffix(file.Name(), ".tar.gz"): - return NewTarballArchive(file), strings.TrimSuffix(file.Name(), ".tar.gz") - default: - return nil, "" - } -} - -// AddFile appends an existing file to an archive. -func AddFile(a Archive, file string) error { - fd, err := os.Open(file) - if err != nil { - return err - } - defer fd.Close() - fi, err := fd.Stat() - if err != nil { - return err - } - w, err := a.Header(fi) - if err != nil { - return err - } - if _, err := io.Copy(w, fd); err != nil { - return err - } - return nil -} - -// WriteArchive creates an archive containing the given files. -func WriteArchive(name string, files []string) (err error) { - archfd, err := os.Create(name) - if err != nil { - return err - } - - defer func() { - archfd.Close() - // Remove the half-written archive on failure. - if err != nil { - os.Remove(name) - } - }() - archive, basename := NewArchive(archfd) - if archive == nil { - return fmt.Errorf("unknown archive extension") - } - fmt.Println(name) - if err := archive.Directory(basename); err != nil { - return err - } - for _, file := range files { - fmt.Println(" +", filepath.Base(file)) - if err := AddFile(archive, file); err != nil { - return err - } - } - return archive.Close() -} - -type ZipArchive struct { - dir string - zipw *zip.Writer - file io.Closer -} - -func NewZipArchive(w io.WriteCloser) Archive { - return &ZipArchive{"", zip.NewWriter(w), w} -} - -func (a *ZipArchive) Directory(name string) error { - a.dir = name + "/" - return nil -} - -func (a *ZipArchive) Header(fi os.FileInfo) (io.Writer, error) { - head, err := zip.FileInfoHeader(fi) - if err != nil { - return nil, fmt.Errorf("can't make zip header: %v", err) - } - head.Name = a.dir + head.Name - head.Method = zip.Deflate - w, err := a.zipw.CreateHeader(head) - if err != nil { - return nil, fmt.Errorf("can't add zip header: %v", err) - } - return w, nil -} - -func (a *ZipArchive) Close() error { - if err := a.zipw.Close(); err != nil { - return err - } - return a.file.Close() -} - -type TarballArchive struct { - dir string - tarw *tar.Writer - gzw *gzip.Writer - file io.Closer -} - -func NewTarballArchive(w io.WriteCloser) Archive { - gzw := gzip.NewWriter(w) - tarw := tar.NewWriter(gzw) - return &TarballArchive{"", tarw, gzw, w} -} - -func (a *TarballArchive) Directory(name string) error { - a.dir = name + "/" - return a.tarw.WriteHeader(&tar.Header{ - Name: a.dir, - Mode: 0755, - Typeflag: tar.TypeDir, - }) -} - -func (a *TarballArchive) Header(fi os.FileInfo) (io.Writer, error) { - head, err := tar.FileInfoHeader(fi, "") - if err != nil { - return nil, fmt.Errorf("can't make tar header: %v", err) - } - head.Name = a.dir + head.Name - if err := a.tarw.WriteHeader(head); err != nil { - return nil, fmt.Errorf("can't add tar header: %v", err) - } - return a.tarw, nil -} - -func (a *TarballArchive) Close() error { - if err := a.tarw.Close(); err != nil { - return err - } - if err := a.gzw.Close(); err != nil { - return err - } - return a.file.Close() -} diff --git a/internal/build/azure.go b/internal/build/azure.go deleted file mode 100644 index 2081a9a0b1b8..000000000000 --- a/internal/build/azure.go +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package build - -import ( - "fmt" - "os" - - storage "github.com/Azure/azure-storage-go" -) - -// AzureBlobstoreConfig is an authentication and configuration struct containing -// the data needed by the Azure SDK to interact with a speicifc container in the -// blobstore. -type AzureBlobstoreConfig struct { - Account string // Account name to authorize API requests with - Token string // Access token for the above account - Container string // Blob container to upload files into -} - -// AzureBlobstoreUpload uploads a local file to the Azure Blob Storage. Note, this -// method assumes a max file size of 64MB (Azure limitation). Larger files will -// need a multi API call approach implemented. -// -// See: https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx#Anchor_3 -func AzureBlobstoreUpload(path string, name string, config AzureBlobstoreConfig) error { - if *DryRunFlag { - fmt.Printf("would upload %q to %s/%s/%s\n", path, config.Account, config.Container, name) - return nil - } - // Create an authenticated client against the Azure cloud - rawClient, err := storage.NewBasicClient(config.Account, config.Token) - if err != nil { - return err - } - client := rawClient.GetBlobService() - - // Stream the file to upload into the designated blobstore container - in, err := os.Open(path) - if err != nil { - return err - } - defer in.Close() - - info, err := in.Stat() - if err != nil { - return err - } - return client.CreateBlockBlobFromReader(config.Container, name, uint64(info.Size()), in, nil) -} - -// AzureBlobstoreList lists all the files contained within an azure blobstore. -func AzureBlobstoreList(config AzureBlobstoreConfig) ([]storage.Blob, error) { - // Create an authenticated client against the Azure cloud - rawClient, err := storage.NewBasicClient(config.Account, config.Token) - if err != nil { - return nil, err - } - client := rawClient.GetBlobService() - - // List all the blobs from the container and return them - container := client.GetContainerReference(config.Container) - - blobs, err := container.ListBlobs(storage.ListBlobsParameters{ - MaxResults: 1024 * 1024 * 1024, // Yes, fetch all of them - Timeout: 3600, // Yes, wait for all of them - }) - if err != nil { - return nil, err - } - return blobs.Blobs, nil -} - -// AzureBlobstoreDelete iterates over a list of files to delete and removes them -// from the blobstore. -func AzureBlobstoreDelete(config AzureBlobstoreConfig, blobs []storage.Blob) error { - if *DryRunFlag { - for _, blob := range blobs { - fmt.Printf("would delete %s (%s) from %s/%s\n", blob.Name, blob.Properties.LastModified, config.Account, config.Container) - } - return nil - } - // Create an authenticated client against the Azure cloud - rawClient, err := storage.NewBasicClient(config.Account, config.Token) - if err != nil { - return err - } - client := rawClient.GetBlobService() - - // Iterate over the blobs and delete them - for _, blob := range blobs { - if err := client.DeleteBlob(config.Container, blob.Name, nil); err != nil { - return err - } - } - return nil -} diff --git a/internal/build/pgp.go b/internal/build/pgp.go deleted file mode 100644 index 79ab9c06f1b5..000000000000 --- a/internal/build/pgp.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2016 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -// signFile reads the contents of an input file and signs it (in armored format) -// with the key provided, placing the signature into the output file. - -package build - -import ( - "bytes" - "fmt" - "os" - - "golang.org/x/crypto/openpgp" -) - -// PGPSignFile parses a PGP private key from the specified string and creates a -// signature file into the output parameter of the input file. -// -// Note, this method assumes a single key will be container in the pgpkey arg, -// furthermore that it is in armored format. -func PGPSignFile(input string, output string, pgpkey string) error { - // Parse the keyring and make sure we only have a single private key in it - keys, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(pgpkey)) - if err != nil { - return err - } - if len(keys) != 1 { - return fmt.Errorf("key count mismatch: have %d, want %d", len(keys), 1) - } - // Create the input and output streams for signing - in, err := os.Open(input) - if err != nil { - return err - } - defer in.Close() - - out, err := os.Create(output) - if err != nil { - return err - } - defer out.Close() - - // Generate the signature and return - return openpgp.ArmoredDetachSign(out, keys[0], in, nil) -} diff --git a/internal/build/util.go b/internal/build/util.go index c6e059f0dfde..a24099acfb0e 100644 --- a/internal/build/util.go +++ b/internal/build/util.go @@ -29,7 +29,6 @@ import ( "path/filepath" "runtime" "strings" - "text/template" ) var DryRunFlag = flag.Bool("n", false, "dry run, don't execute commands") @@ -60,15 +59,6 @@ func GOPATH() string { return os.Getenv("GOPATH") } -// VERSION returns the content of the VERSION file. -func VERSION() string { - version, err := ioutil.ReadFile("VERSION") - if err != nil { - log.Fatal(err) - } - return string(bytes.TrimSpace(version)) -} - var warnedAboutGit bool // RunGit runs a git subcommand and returns its output. @@ -98,34 +88,6 @@ func readGitFile(file string) string { return strings.TrimSpace(string(content)) } -// Render renders the given template file into outputFile. -func Render(templateFile, outputFile string, outputPerm os.FileMode, x interface{}) { - tpl := template.Must(template.ParseFiles(templateFile)) - render(tpl, outputFile, outputPerm, x) -} - -// RenderString renders the given template string into outputFile. -func RenderString(templateContent, outputFile string, outputPerm os.FileMode, x interface{}) { - tpl := template.Must(template.New("").Parse(templateContent)) - render(tpl, outputFile, outputPerm, x) -} - -func render(tpl *template.Template, outputFile string, outputPerm os.FileMode, x interface{}) { - if err := os.MkdirAll(filepath.Dir(outputFile), 0755); err != nil { - log.Fatal(err) - } - out, err := os.OpenFile(outputFile, os.O_CREATE|os.O_WRONLY|os.O_EXCL, outputPerm) - if err != nil { - log.Fatal(err) - } - if err := tpl.Execute(out, x); err != nil { - log.Fatal(err) - } - if err := out.Close(); err != nil { - log.Fatal(err) - } -} - // CopyFile copies a file. func CopyFile(dst, src string, mode os.FileMode) { if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil { From 792fd8350167100713a23e55411ed21fbf46e98d Mon Sep 17 00:00:00 2001 From: Tuna Date: Mon, 30 Jul 2018 11:51:39 +0700 Subject: [PATCH 2/3] remove unused files in build/ --- VERSION | 1 - build/deb.changelog | 5 - build/deb.control | 25 --- build/deb.copyright | 14 -- build/deb.docs | 1 - build/deb.install | 1 - build/deb.rules | 13 -- build/mvn.pom | 57 ----- build/mvn.settings | 24 -- build/nsis.envvarupdate.nsh | 327 --------------------------- build/nsis.geth.nsi | 70 ------ build/nsis.install.nsh | 103 --------- build/nsis.pathupdate.nsh | 153 ------------- build/nsis.simplefc.dll | Bin 179712 -> 0 bytes build/nsis.simplefc.source.zip | Bin 23209 -> 0 bytes build/nsis.uninstall.nsh | 33 --- build/pod.podspec | 22 -- build/update-license.go | 395 --------------------------------- 18 files changed, 1244 deletions(-) delete mode 100644 VERSION delete mode 100644 build/deb.changelog delete mode 100644 build/deb.control delete mode 100644 build/deb.copyright delete mode 100644 build/deb.docs delete mode 100644 build/deb.install delete mode 100644 build/deb.rules delete mode 100644 build/mvn.pom delete mode 100644 build/mvn.settings delete mode 100644 build/nsis.envvarupdate.nsh delete mode 100644 build/nsis.geth.nsi delete mode 100644 build/nsis.install.nsh delete mode 100644 build/nsis.pathupdate.nsh delete mode 100644 build/nsis.simplefc.dll delete mode 100644 build/nsis.simplefc.source.zip delete mode 100644 build/nsis.uninstall.nsh delete mode 100644 build/pod.podspec delete mode 100644 build/update-license.go diff --git a/VERSION b/VERSION deleted file mode 100644 index bfa363e76ed7..000000000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.8.4 diff --git a/build/deb.changelog b/build/deb.changelog deleted file mode 100644 index 83f804a83384..000000000000 --- a/build/deb.changelog +++ /dev/null @@ -1,5 +0,0 @@ -{{.Name}} ({{.VersionString}}) {{.Distro}}; urgency=low - - * git build of {{.Env.Commit}} - - -- {{.Author}} {{.Time}} diff --git a/build/deb.control b/build/deb.control deleted file mode 100644 index 33c1a779f4ab..000000000000 --- a/build/deb.control +++ /dev/null @@ -1,25 +0,0 @@ -Source: {{.Name}} -Section: science -Priority: extra -Maintainer: {{.Author}} -Build-Depends: debhelper (>= 8.0.0), golang-1.10 -Standards-Version: 3.9.5 -Homepage: https://ethereum.org -Vcs-Git: git://github.com/ethereum/go-ethereum.git -Vcs-Browser: https://github.com/ethereum/go-ethereum - -Package: {{.Name}} -Architecture: any -Depends: ${misc:Depends}, {{.ExeList}} -Description: Meta-package to install geth and other tools - Meta-package to install geth and other tools - -{{range .Executables}} -Package: {{$.ExeName .}} -Conflicts: {{$.ExeConflicts .}} -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Built-Using: ${misc:Built-Using} -Description: {{.Description}} - {{.Description}} -{{end}} diff --git a/build/deb.copyright b/build/deb.copyright deleted file mode 100644 index 513be45b193d..000000000000 --- a/build/deb.copyright +++ /dev/null @@ -1,14 +0,0 @@ -Copyright 2016 The go-ethereum Authors - -go-ethereum is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -go-ethereum is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with go-ethereum. If not, see . diff --git a/build/deb.docs b/build/deb.docs deleted file mode 100644 index 62deb04972da..000000000000 --- a/build/deb.docs +++ /dev/null @@ -1 +0,0 @@ -AUTHORS diff --git a/build/deb.install b/build/deb.install deleted file mode 100644 index 7dc76e1f5673..000000000000 --- a/build/deb.install +++ /dev/null @@ -1 +0,0 @@ -build/bin/{{.Name}} usr/bin diff --git a/build/deb.rules b/build/deb.rules deleted file mode 100644 index 7f286569ea6e..000000000000 --- a/build/deb.rules +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - -override_dh_auto_build: - build/env.sh /usr/lib/go-1.10/bin/go run build/ci.go install -git-commit={{.Env.Commit}} -git-branch={{.Env.Branch}} -git-tag={{.Env.Tag}} -buildnum={{.Env.Buildnum}} -pull-request={{.Env.IsPullRequest}} - -override_dh_auto_test: - -%: - dh $@ diff --git a/build/mvn.pom b/build/mvn.pom deleted file mode 100644 index 7670246ba9f1..000000000000 --- a/build/mvn.pom +++ /dev/null @@ -1,57 +0,0 @@ - - 4.0.0 - - org.ethereum - geth - {{.Version}} - aar - - Android Ethereum Client - Android port of the go-ethereum libraries and node - https://github.com/ethereum/go-ethereum - 2015 - - - - GNU Lesser General Public License, Version 3.0 - https://www.gnu.org/licenses/lgpl-3.0.en.html - repo - - - - - Ethereum - https://ethereum.org - - - - - karalabe - Péter Szilágyi - peterke@gmail.com - https://github.com/karalabe - - https://www.gravatar.com/avatar/2ecbf0f5b4b79eebf8c193e5d324357f?s=256 - - - - - {{range .Contributors}} - - {{.Name}} - {{.Email}} - {{end}} - - - - GitHub Issues - https://github.com/ethereum/go-ethereum/issues/ - - - - https://github.com/ethereum/go-ethereum - - diff --git a/build/mvn.settings b/build/mvn.settings deleted file mode 100644 index 406b409b9b5d..000000000000 --- a/build/mvn.settings +++ /dev/null @@ -1,24 +0,0 @@ - - - - ossrh - ${env.ANDROID_SONATYPE_USERNAME} - ${env.ANDROID_SONATYPE_PASSWORD} - - - - - ossrh - - true - - - gpg - - - - - diff --git a/build/nsis.envvarupdate.nsh b/build/nsis.envvarupdate.nsh deleted file mode 100644 index 9c3ecbe3372f..000000000000 --- a/build/nsis.envvarupdate.nsh +++ /dev/null @@ -1,327 +0,0 @@ -/** - * EnvVarUpdate.nsh - * : Environmental Variables: append, prepend, and remove entries - * - * WARNING: If you use StrFunc.nsh header then include it before this file - * with all required definitions. This is to avoid conflicts - * - * Usage: - * ${EnvVarUpdate} "ResultVar" "EnvVarName" "Action" "RegLoc" "PathString" - * - * Credits: - * Version 1.0 - * * Cal Turney (turnec2) - * * Amir Szekely (KiCHiK) and e-circ for developing the forerunners of this - * function: AddToPath, un.RemoveFromPath, AddToEnvVar, un.RemoveFromEnvVar, - * WriteEnvStr, and un.DeleteEnvStr - * * Diego Pedroso (deguix) for StrTok - * * Kevin English (kenglish_hi) for StrContains - * * Hendri Adriaens (Smile2Me), Diego Pedroso (deguix), and Dan Fuhry - * (dandaman32) for StrReplace - * - * Version 1.1 (compatibility with StrFunc.nsh) - * * techtonik - * - * http://nsis.sourceforge.net/Environmental_Variables:_append%2C_prepend%2C_and_remove_entries - * - */ - - -!ifndef ENVVARUPDATE_FUNCTION -!define ENVVARUPDATE_FUNCTION -!verbose push -!verbose 3 -!include "LogicLib.nsh" -!include "WinMessages.NSH" -!include "StrFunc.nsh" - -; ---- Fix for conflict if StrFunc.nsh is already includes in main file ----------------------- -!macro _IncludeStrFunction StrFuncName - !ifndef ${StrFuncName}_INCLUDED - ${${StrFuncName}} - !endif - !ifndef Un${StrFuncName}_INCLUDED - ${Un${StrFuncName}} - !endif - !define un.${StrFuncName} "${Un${StrFuncName}}" -!macroend - -!insertmacro _IncludeStrFunction StrTok -!insertmacro _IncludeStrFunction StrStr -!insertmacro _IncludeStrFunction StrRep - -; ---------------------------------- Macro Definitions ---------------------------------------- -!macro _EnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString - Push "${EnvVarName}" - Push "${Action}" - Push "${RegLoc}" - Push "${PathString}" - Call EnvVarUpdate - Pop "${ResultVar}" -!macroend -!define EnvVarUpdate '!insertmacro "_EnvVarUpdateConstructor"' - -!macro _unEnvVarUpdateConstructor ResultVar EnvVarName Action Regloc PathString - Push "${EnvVarName}" - Push "${Action}" - Push "${RegLoc}" - Push "${PathString}" - Call un.EnvVarUpdate - Pop "${ResultVar}" -!macroend -!define un.EnvVarUpdate '!insertmacro "_unEnvVarUpdateConstructor"' -; ---------------------------------- Macro Definitions end------------------------------------- - -;----------------------------------- EnvVarUpdate start---------------------------------------- -!define hklm_all_users 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' -!define hkcu_current_user 'HKCU "Environment"' - -!macro EnvVarUpdate UN - -Function ${UN}EnvVarUpdate - - Push $0 - Exch 4 - Exch $1 - Exch 3 - Exch $2 - Exch 2 - Exch $3 - Exch - Exch $4 - Push $5 - Push $6 - Push $7 - Push $8 - Push $9 - Push $R0 - - /* After this point: - ------------------------- - $0 = ResultVar (returned) - $1 = EnvVarName (input) - $2 = Action (input) - $3 = RegLoc (input) - $4 = PathString (input) - $5 = Orig EnvVar (read from registry) - $6 = Len of $0 (temp) - $7 = tempstr1 (temp) - $8 = Entry counter (temp) - $9 = tempstr2 (temp) - $R0 = tempChar (temp) */ - - ; Step 1: Read contents of EnvVarName from RegLoc - ; - ; Check for empty EnvVarName - ${If} $1 == "" - SetErrors - DetailPrint "ERROR: EnvVarName is blank" - Goto EnvVarUpdate_Restore_Vars - ${EndIf} - - ; Check for valid Action - ${If} $2 != "A" - ${AndIf} $2 != "P" - ${AndIf} $2 != "R" - SetErrors - DetailPrint "ERROR: Invalid Action - must be A, P, or R" - Goto EnvVarUpdate_Restore_Vars - ${EndIf} - - ${If} $3 == HKLM - ReadRegStr $5 ${hklm_all_users} $1 ; Get EnvVarName from all users into $5 - ${ElseIf} $3 == HKCU - ReadRegStr $5 ${hkcu_current_user} $1 ; Read EnvVarName from current user into $5 - ${Else} - SetErrors - DetailPrint 'ERROR: Action is [$3] but must be "HKLM" or HKCU"' - Goto EnvVarUpdate_Restore_Vars - ${EndIf} - - ; Check for empty PathString - ${If} $4 == "" - SetErrors - DetailPrint "ERROR: PathString is blank" - Goto EnvVarUpdate_Restore_Vars - ${EndIf} - - ; Make sure we've got some work to do - ${If} $5 == "" - ${AndIf} $2 == "R" - SetErrors - DetailPrint "$1 is empty - Nothing to remove" - Goto EnvVarUpdate_Restore_Vars - ${EndIf} - - ; Step 2: Scrub EnvVar - ; - StrCpy $0 $5 ; Copy the contents to $0 - ; Remove spaces around semicolons (NOTE: spaces before the 1st entry or - ; after the last one are not removed here but instead in Step 3) - ${If} $0 != "" ; If EnvVar is not empty ... - ${Do} - ${${UN}StrStr} $7 $0 " ;" - ${If} $7 == "" - ${ExitDo} - ${EndIf} - ${${UN}StrRep} $0 $0 " ;" ";" ; Remove ';' - ${Loop} - ${Do} - ${${UN}StrStr} $7 $0 "; " - ${If} $7 == "" - ${ExitDo} - ${EndIf} - ${${UN}StrRep} $0 $0 "; " ";" ; Remove ';' - ${Loop} - ${Do} - ${${UN}StrStr} $7 $0 ";;" - ${If} $7 == "" - ${ExitDo} - ${EndIf} - ${${UN}StrRep} $0 $0 ";;" ";" - ${Loop} - - ; Remove a leading or trailing semicolon from EnvVar - StrCpy $7 $0 1 0 - ${If} $7 == ";" - StrCpy $0 $0 "" 1 ; Change ';' to '' - ${EndIf} - StrLen $6 $0 - IntOp $6 $6 - 1 - StrCpy $7 $0 1 $6 - ${If} $7 == ";" - StrCpy $0 $0 $6 ; Change ';' to '' - ${EndIf} - ; DetailPrint "Scrubbed $1: [$0]" ; Uncomment to debug - ${EndIf} - - /* Step 3. Remove all instances of the target path/string (even if "A" or "P") - $6 = bool flag (1 = found and removed PathString) - $7 = a string (e.g. path) delimited by semicolon(s) - $8 = entry counter starting at 0 - $9 = copy of $0 - $R0 = tempChar */ - - ${If} $5 != "" ; If EnvVar is not empty ... - StrCpy $9 $0 - StrCpy $0 "" - StrCpy $8 0 - StrCpy $6 0 - - ${Do} - ${${UN}StrTok} $7 $9 ";" $8 "0" ; $7 = next entry, $8 = entry counter - - ${If} $7 == "" ; If we've run out of entries, - ${ExitDo} ; were done - ${EndIf} ; - - ; Remove leading and trailing spaces from this entry (critical step for Action=Remove) - ${Do} - StrCpy $R0 $7 1 - ${If} $R0 != " " - ${ExitDo} - ${EndIf} - StrCpy $7 $7 "" 1 ; Remove leading space - ${Loop} - ${Do} - StrCpy $R0 $7 1 -1 - ${If} $R0 != " " - ${ExitDo} - ${EndIf} - StrCpy $7 $7 -1 ; Remove trailing space - ${Loop} - ${If} $7 == $4 ; If string matches, remove it by not appending it - StrCpy $6 1 ; Set 'found' flag - ${ElseIf} $7 != $4 ; If string does NOT match - ${AndIf} $0 == "" ; and the 1st string being added to $0, - StrCpy $0 $7 ; copy it to $0 without a prepended semicolon - ${ElseIf} $7 != $4 ; If string does NOT match - ${AndIf} $0 != "" ; and this is NOT the 1st string to be added to $0, - StrCpy $0 $0;$7 ; append path to $0 with a prepended semicolon - ${EndIf} ; - - IntOp $8 $8 + 1 ; Bump counter - ${Loop} ; Check for duplicates until we run out of paths - ${EndIf} - - ; Step 4: Perform the requested Action - ; - ${If} $2 != "R" ; If Append or Prepend - ${If} $6 == 1 ; And if we found the target - DetailPrint "Target is already present in $1. It will be removed and" - ${EndIf} - ${If} $0 == "" ; If EnvVar is (now) empty - StrCpy $0 $4 ; just copy PathString to EnvVar - ${If} $6 == 0 ; If found flag is either 0 - ${OrIf} $6 == "" ; or blank (if EnvVarName is empty) - DetailPrint "$1 was empty and has been updated with the target" - ${EndIf} - ${ElseIf} $2 == "A" ; If Append (and EnvVar is not empty), - StrCpy $0 $0;$4 ; append PathString - ${If} $6 == 1 - DetailPrint "appended to $1" - ${Else} - DetailPrint "Target was appended to $1" - ${EndIf} - ${Else} ; If Prepend (and EnvVar is not empty), - StrCpy $0 $4;$0 ; prepend PathString - ${If} $6 == 1 - DetailPrint "prepended to $1" - ${Else} - DetailPrint "Target was prepended to $1" - ${EndIf} - ${EndIf} - ${Else} ; If Action = Remove - ${If} $6 == 1 ; and we found the target - DetailPrint "Target was found and removed from $1" - ${Else} - DetailPrint "Target was NOT found in $1 (nothing to remove)" - ${EndIf} - ${If} $0 == "" - DetailPrint "$1 is now empty" - ${EndIf} - ${EndIf} - - ; Step 5: Update the registry at RegLoc with the updated EnvVar and announce the change - ; - ClearErrors - ${If} $3 == HKLM - WriteRegExpandStr ${hklm_all_users} $1 $0 ; Write it in all users section - ${ElseIf} $3 == HKCU - WriteRegExpandStr ${hkcu_current_user} $1 $0 ; Write it to current user section - ${EndIf} - - IfErrors 0 +4 - MessageBox MB_OK|MB_ICONEXCLAMATION "Could not write updated $1 to $3" - DetailPrint "Could not write updated $1 to $3" - Goto EnvVarUpdate_Restore_Vars - - ; "Export" our change - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 - - EnvVarUpdate_Restore_Vars: - ; - ; Restore the user's variables and return ResultVar - Pop $R0 - Pop $9 - Pop $8 - Pop $7 - Pop $6 - Pop $5 - Pop $4 - Pop $3 - Pop $2 - Pop $1 - Push $0 ; Push my $0 (ResultVar) - Exch - Pop $0 ; Restore his $0 - -FunctionEnd - -!macroend ; EnvVarUpdate UN -!insertmacro EnvVarUpdate "" -!insertmacro EnvVarUpdate "un." -;----------------------------------- EnvVarUpdate end---------------------------------------- - -!verbose pop -!endif \ No newline at end of file diff --git a/build/nsis.geth.nsi b/build/nsis.geth.nsi deleted file mode 100644 index 1034f30235dd..000000000000 --- a/build/nsis.geth.nsi +++ /dev/null @@ -1,70 +0,0 @@ -# Builds a Windows installer with NSIS. -# It expects the following command line arguments: -# - OUTPUTFILE, filename of the installer (without extension) -# - MAJORVERSION, major build version -# - MINORVERSION, minor build version -# - BUILDVERSION, build id version -# -# The created installer executes the following steps: -# 1. install geth for all users -# 2. install optional development tools such as abigen -# 3. create an uninstaller -# 4. configures the Windows firewall for geth -# 5. create geth, attach and uninstall start menu entries -# 6. configures the registry that allows Windows to manage the package through its platform tools -# 7. adds the environment system wide variable ETHEREUM_SOCKET -# 8. adds the install directory to %PATH% -# -# Requirements: -# - NSIS, http://nsis.sourceforge.net/Main_Page -# - NSIS Large Strings build, http://nsis.sourceforge.net/Special_Builds -# - SFP, http://nsis.sourceforge.net/NSIS_Simple_Firewall_Plugin (put dll in NSIS\Plugins\x86-ansi) -# -# After intalling NSIS extra the NSIS Large Strings build zip and replace the makensis.exe and the -# files found in Stub. -# -# based on: http://nsis.sourceforge.net/A_simple_installer_with_start_menu_shortcut_and_uninstaller -# -# TODO: -# - sign installer -CRCCheck on - -!define GROUPNAME "Ethereum" -!define APPNAME "Geth" -!define DESCRIPTION "Official Go implementation of the Ethereum protocol" -!addplugindir .\ - -# Require admin rights on NT6+ (When UAC is turned on) -RequestExecutionLevel admin - -# Use LZMA compression -SetCompressor /SOLID lzma - -!include LogicLib.nsh -!include PathUpdate.nsh -!include EnvVarUpdate.nsh - -!macro VerifyUserIsAdmin -UserInfo::GetAccountType -pop $0 -${If} $0 != "admin" # Require admin rights on NT4+ - messageBox mb_iconstop "Administrator rights required!" - setErrorLevel 740 # ERROR_ELEVATION_REQUIRED - quit -${EndIf} -!macroend - -function .onInit - # make vars are global for all users since geth is installed global - setShellVarContext all - !insertmacro VerifyUserIsAdmin - - ${If} ${ARCH} == "amd64" - StrCpy $InstDir "$PROGRAMFILES64\${APPNAME}" - ${Else} - StrCpy $InstDir "$PROGRAMFILES32\${APPNAME}" - ${Endif} -functionEnd - -!include install.nsh -!include uninstall.nsh diff --git a/build/nsis.install.nsh b/build/nsis.install.nsh deleted file mode 100644 index 57ef5a37c6a4..000000000000 --- a/build/nsis.install.nsh +++ /dev/null @@ -1,103 +0,0 @@ -Name "geth ${MAJORVERSION}.${MINORVERSION}.${BUILDVERSION}" # VERSION variables set through command line arguments -InstallDir "$InstDir" -OutFile "${OUTPUTFILE}" # set through command line arguments - -# Links for "Add/Remove Programs" -!define HELPURL "https://github.com/ethereum/go-ethereum/issues" -!define UPDATEURL "https://github.com/ethereum/go-ethereum/releases" -!define ABOUTURL "https://github.com/ethereum/go-ethereum#ethereum-go" -!define /date NOW "%Y%m%d" - -PageEx license - LicenseData {{.License}} -PageExEnd - -# Install geth binary -Section "Geth" GETH_IDX - SetOutPath $INSTDIR - file {{.Geth}} - - # Create start menu launcher - createDirectory "$SMPROGRAMS\${APPNAME}" - createShortCut "$SMPROGRAMS\${APPNAME}\${APPNAME}.lnk" "$INSTDIR\geth.exe" "--fast" "--cache=512" - createShortCut "$SMPROGRAMS\${APPNAME}\Attach.lnk" "$INSTDIR\geth.exe" "attach" "" "" - createShortCut "$SMPROGRAMS\${APPNAME}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "" "" - - # Firewall - remove rules (if exists) - SimpleFC::AdvRemoveRule "Geth incoming peers (TCP:30303)" - SimpleFC::AdvRemoveRule "Geth outgoing peers (TCP:30303)" - SimpleFC::AdvRemoveRule "Geth UDP discovery (UDP:30303)" - - # Firewall - add rules - SimpleFC::AdvAddRule "Geth incoming peers (TCP:30303)" "" 6 1 1 2147483647 1 "$INSTDIR\geth.exe" "" "" "Ethereum" 30303 "" "" "" - SimpleFC::AdvAddRule "Geth outgoing peers (TCP:30303)" "" 6 2 1 2147483647 1 "$INSTDIR\geth.exe" "" "" "Ethereum" "" 30303 "" "" - SimpleFC::AdvAddRule "Geth UDP discovery (UDP:30303)" "" 17 2 1 2147483647 1 "$INSTDIR\geth.exe" "" "" "Ethereum" "" 30303 "" "" - - # Set default IPC endpoint (https://github.com/ethereum/EIPs/issues/147) - ${EnvVarUpdate} $0 "ETHEREUM_SOCKET" "R" "HKLM" "\\.\pipe\geth.ipc" - ${EnvVarUpdate} $0 "ETHEREUM_SOCKET" "A" "HKLM" "\\.\pipe\geth.ipc" - - # Add instdir to PATH - Push "$INSTDIR" - Call AddToPath -SectionEnd - -# Install optional develop tools. -Section /o "Development tools" DEV_TOOLS_IDX - SetOutPath $INSTDIR - {{range .DevTools}}file {{.}} - {{end}} -SectionEnd - -# Return on top of stack the total size (as DWORD) of the selected/installed sections. -Var GetInstalledSize.total -Function GetInstalledSize - StrCpy $GetInstalledSize.total 0 - - ${if} ${SectionIsSelected} ${GETH_IDX} - SectionGetSize ${GETH_IDX} $0 - IntOp $GetInstalledSize.total $GetInstalledSize.total + $0 - ${endif} - - ${if} ${SectionIsSelected} ${DEV_TOOLS_IDX} - SectionGetSize ${DEV_TOOLS_IDX} $0 - IntOp $GetInstalledSize.total $GetInstalledSize.total + $0 - ${endif} - - IntFmt $GetInstalledSize.total "0x%08X" $GetInstalledSize.total - Push $GetInstalledSize.total -FunctionEnd - -# Write registry, Windows uses these values in various tools such as add/remove program. -# PowerShell: Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, InstallLocation, InstallDate | Format-Table –AutoSize -function .onInstSuccess - # Save information in registry in HKEY_LOCAL_MACHINE branch, Windows add/remove functionality depends on this - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "DisplayName" "${GROUPNAME} - ${APPNAME} - ${DESCRIPTION}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "InstallLocation" "$INSTDIR" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "InstallDate" "${NOW}" - # Wait for Alex - #WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "DisplayIcon" "$\"$INSTDIR\logo.ico$\"" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "Publisher" "${GROUPNAME}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "HelpLink" "${HELPURL}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "URLUpdateInfo" "${UPDATEURL}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "URLInfoAbout" "${ABOUTURL}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "DisplayVersion" "${MAJORVERSION}.${MINORVERSION}.${BUILDVERSION}" - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "VersionMajor" ${MAJORVERSION} - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "VersionMinor" ${MINORVERSION} - # There is no option for modifying or repairing the install - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "NoModify" 1 - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "NoRepair" 1 - - Call GetInstalledSize - Pop $0 - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${GROUPNAME} ${APPNAME}" "EstimatedSize" "$0" - - # Create uninstaller - writeUninstaller "$INSTDIR\uninstall.exe" -functionEnd - -Page components -Page directory -Page instfiles diff --git a/build/nsis.pathupdate.nsh b/build/nsis.pathupdate.nsh deleted file mode 100644 index f54b7e3e13b2..000000000000 --- a/build/nsis.pathupdate.nsh +++ /dev/null @@ -1,153 +0,0 @@ -!include "WinMessages.nsh" - -; see https://support.microsoft.com/en-us/kb/104011 -!define Environ 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"' -; HKEY_LOCAL_MACHINE = 0x80000002 - -; AddToPath - Appends dir to PATH -; (does not work on Win9x/ME) -; -; Usage: -; Push "dir" -; Call AddToPath -Function AddToPath - Exch $0 - Push $1 - Push $2 - Push $3 - Push $4 - - ; NSIS ReadRegStr returns empty string on string overflow - ; Native calls are used here to check actual length of PATH - ; $4 = RegOpenKey(HKEY_LOCAL_MACHINE, "SYSTEM\CurrentControlSet\Control\Session Manager\Environment", &$3) - System::Call "advapi32::RegOpenKey(i 0x80000002, t'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', *i.r3) i.r4" - IntCmp $4 0 0 done done - - ; $4 = RegQueryValueEx($3, "PATH", (DWORD*)0, (DWORD*)0, &$1, ($2=NSIS_MAX_STRLEN, &$2)) - ; RegCloseKey($3) - System::Call "advapi32::RegQueryValueEx(i $3, t'PATH', i 0, i 0, t.r1, *i ${NSIS_MAX_STRLEN} r2) i.r4" - System::Call "advapi32::RegCloseKey(i $3)" - - IntCmp $4 234 0 +4 +4 ; $4 == ERROR_MORE_DATA - DetailPrint "AddToPath: original length $2 > ${NSIS_MAX_STRLEN}" - MessageBox MB_OK "PATH not updated, original length $2 > ${NSIS_MAX_STRLEN}" - Goto done - - IntCmp $4 0 +5 ; $4 != NO_ERROR - IntCmp $4 2 +3 ; $4 != ERROR_FILE_NOT_FOUND - DetailPrint "AddToPath: unexpected error code $4" - Goto done - StrCpy $1 "" - - ; Check if already in PATH - Push "$1;" - Push "$0;" - Call StrStr - Pop $2 - StrCmp $2 "" 0 done - Push "$1;" - Push "$0\;" - Call StrStr - Pop $2 - StrCmp $2 "" 0 done - - ; Prevent NSIS string overflow - StrLen $2 $0 - StrLen $3 $1 - IntOp $2 $2 + $3 - IntOp $2 $2 + 2 ; $2 = strlen(dir) + strlen(PATH) + sizeof(";") - IntCmp $2 ${NSIS_MAX_STRLEN} +4 +4 0 - DetailPrint "AddToPath: new length $2 > ${NSIS_MAX_STRLEN}" - MessageBox MB_OK "PATH not updated, new length $2 > ${NSIS_MAX_STRLEN}." - Goto done - - ; Append dir to PATH - DetailPrint "Add to PATH: $0" - StrCpy $2 $1 1 -1 - StrCmp $2 ";" 0 +2 - StrCpy $1 $1 -1 ; remove trailing ';' - StrCmp $1 "" +2 ; no leading ';' - StrCpy $0 "$1;$0" - - WriteRegExpandStr ${Environ} "PATH" $0 - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 - -done: - Pop $4 - Pop $3 - Pop $2 - Pop $1 - Pop $0 -FunctionEnd - - -; RemoveFromPath - Removes dir from PATH -; -; Usage: -; Push "dir" -; Call RemoveFromPath -Function un.RemoveFromPath - Exch $0 - Push $1 - Push $2 - Push $3 - Push $4 - Push $5 - Push $6 - - ; NSIS ReadRegStr returns empty string on string overflow - ; Native calls are used here to check actual length of PATH - ; $4 = RegOpenKey(HKEY_LOCAL_MACHINE, "SYSTEM\CurrentControlSet\Control\Session Manager\Environment", &$3) - System::Call "advapi32::RegOpenKey(i 0x80000002, t'SYSTEM\CurrentControlSet\Control\Session Manager\Environment', *i.r3) i.r4" - IntCmp $4 0 0 done done - - ; $4 = RegQueryValueEx($3, "PATH", (DWORD*)0, (DWORD*)0, &$1, ($2=NSIS_MAX_STRLEN, &$2)) - ; RegCloseKey($3) - System::Call "advapi32::RegQueryValueEx(i $3, t'PATH', i 0, i 0, t.r1, *i ${NSIS_MAX_STRLEN} r2) i.r4" - System::Call "advapi32::RegCloseKey(i $3)" - - IntCmp $4 234 0 +4 +4 ; $4 == ERROR_MORE_DATA - DetailPrint "RemoveFromPath: original length $2 > ${NSIS_MAX_STRLEN}" - MessageBox MB_OK "PATH not updated, original length $2 > ${NSIS_MAX_STRLEN}" - Goto done - - IntCmp $4 0 +5 ; $4 != NO_ERROR - IntCmp $4 2 +3 ; $4 != ERROR_FILE_NOT_FOUND - DetailPrint "RemoveFromPath: unexpected error code $4" - Goto done - StrCpy $1 "" - - ; length < ${NSIS_MAX_STRLEN} -> ReadRegStr can be used - ReadRegStr $1 ${Environ} "PATH" - StrCpy $5 $1 1 -1 - StrCmp $5 ";" +2 - StrCpy $1 "$1;" ; ensure trailing ';' - Push $1 - Push "$0;" - Call un.StrStr - Pop $2 ; pos of our dir - StrCmp $2 "" done - - DetailPrint "Remove from PATH: $0" - StrLen $3 "$0;" - StrLen $4 $2 - StrCpy $5 $1 -$4 ; $5 is now the part before the path to remove - StrCpy $6 $2 "" $3 ; $6 is now the part after the path to remove - StrCpy $3 "$5$6" - StrCpy $5 $3 1 -1 - StrCmp $5 ";" 0 +2 - StrCpy $3 $3 -1 ; remove trailing ';' - WriteRegExpandStr ${Environ} "PATH" $3 - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 - -done: - Pop $6 - Pop $5 - Pop $4 - Pop $3 - Pop $2 - Pop $1 - Pop $0 -FunctionEnd - - diff --git a/build/nsis.simplefc.dll b/build/nsis.simplefc.dll deleted file mode 100644 index 73b7d9634deddc41966698106dfcf3950c3cfb65..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 179712 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ν51={dZ1BY4A`^N;@_Z7WppVw&qD2_?OGw@eIc_w%^l<9ZW6-6g zfF*(WL&Y5wUo7UhL&ZWR^;NQu1}{DFqACvSe8PcHzQbC|X9%J!3Fnp>%vn;LODIkw zI`HWxDOMZy)Zj9El4CC(S>7ST*l&PdHe=ELb%a&D@NfnXIOh0~PT<{%V1{TlA+1V$ zfppMhB2!$DMieZ8u9 za^*UDP6I(6ya`R?IHM3}@M~Or<=S;EoW5`A@xJsCMw*B~Xyv*XDb{NDHSS`h`jLq!$hS1v63sECUOxs=p8=R@wUxGQ;CLqSl3de zAOG23X?jbC1B**LR4Z>L-Ol^2#Upo9RC+%yz6K?Duc@PCg+a;M#bj_tp=kwzDEa_Y z%j3O-2=aBMc4F^KSMl>otZj%T5%U)igY$nTu%c7;8~E>FmtOp@M**m(=nE1^d)rS2 zY43`}x#)xgiQ!oE#6CA{*5c>+@E*JbA}a^HDhJHLLKOUj1{BT^v&lETQzGWgRY4jp z8KqFXaVQnv{}P3~gLu;n@VknV9a?hB3^5i@PuZb5$a^;&wR6DaJ!DjgJc#&HdW6Zk zxU`}1l`uqGK&k2E;%g+OGfPCnhv=O-OZ?*I$B6Q|ae5pmC9){8r?kNgRe`m^*-IvD zqv9ZmVicmDKJ-)r%#3ZFSYs{0ZT4;xuhpZ^dd8F#U-xEQ`#9BGWQaVCpOUtp_`XO< zTXy+-2W!DAXOQ2Zs(G3a0@vazr@C~w@Ehfs?BJYr-2(|8gM z2t99i#o;@i1k?cU-#i+^B$hA;xA^zAPzOpq<pz-5byCOxKL}X+R@q=RUvF}>5oVt zz6O<2L2jj>C3srWR}26RPtgFpq_^mT*HbhAFBvFK(ld>|*{XZVI1#r{#L4gwQRqR7 zc8{U8yyaLX6Vccp@f6i}(e7x)^K2VDsp`R=-;*bCfffoOeWH>&BXQWjE|>`e<|)#M zevcXCL2TV!C9t)p8h^H>P^o+Fz_{W50e)-oXWLxzdj@`NZ&G`%I2~xu&B#FERS5z- z-XSRgUQuwEht?t2V(v?Los8GZ_ BC*}K5P`+D&^F74*?m_?Xw*du*dDI>MzQ0m9 z&Fkm@zW;P5NjNVSZsnec6A=m%?fO+zPt>Q@&A@?~D~ioHhDrYf#?7&&ZB{ zzat#qwyEsE|0!>>(Nrojy}REXGmvYud|?(Zl%eDDy4ARXj6(NPEIT0u`O%v0c&tm)vV689CiZlyun`s&GW90`A(tAT90E-^b^J<82^_+0Xa#(LFfn(V`SZ z;}#scY-c$h75cnPU#A$%q&=4i(tPqZg$9%tL>O&Tz?c2e^qv`GweDSXdlD%=qewi9 zl+ycrFku9CUBEP@Ne;cEhQC}Fnw${-H=OnJe->@R`9u^@8)HOR4h$P4AL{xgq*Tb< zgaovYq;oQHFr3Nc_q~w+8JJV}C}*BQ;B`E0udyveM%hhBwxl=OFeNS;wlrl+?`Log zAVfwLL5-qP)$?D~_!-$VJ5ilSXsZc*)-^wSKHM|JMtD561$r*q&F+=t-b(JZ?9L^3 z6}h*vdoH=Rle>o9lgYh<+y~fgC-+XcK|+3RmQFi1GdCABByq2{HMbp;Y$-zEDX^*Tm*k?E`Sojmf%$kAoVzAXzghLoBTmt*^ z=n!&o5(Wac$01@Hyjsu)MGJYQwm<~8kO+Q+LDL(D(OMCh!=P9>8*moJ50ot}*L-vn zIdC=?D&X z&+8Vtchj@mRph0~+;GLel72`~JFaVAAbA!U((ErrAvstkSEk2SMMaT8P4LWx_tQ`Qnh*>P;hZ>xyL z>7W}fkTybYm=-~Y62M~`HhAL`29z6B>S~Lkul*o%?Hi(*SgCTLrT5BV_}lm1!H5I~ zFx%ub5y`f*gV*8hURUKhsohY~j?(&w4X%S5Rzbg&kH?Z#GtCIGu2tTrv?HQ8zM_(% zuKt!*!b^YcSKPanmj5wo><>c~yGoZHjOcPTA0JxU5mr1HrxOn-#TBIP-nF!n2K|*< zJq;h-O{+|8nubodEee8_Hr?NGXw@yUGQC=iK8{M!NtJ8ABIcp`*vv4nA`;s` za5bqo3I&S|M=eT6ISav+(hQkYA*D$Zsn}JASSN7)uND2{8zuG#NPeI{j6h$;`S%p% z2aFE1=|uWoo)&p{qdz7GxZSi5lmp1F7&u?r$U;_*c;~O^5CupppOI49(8`?-x0-iu zfK1-nsq5O1g?!o*@g4QG4d}r564oPbz6X-zqn(4ZFbqKhWn!;MBCmZ3-D<|_$C??)dYDTrEwHcdm*r^%U&L?$c=ZHxA&r2P&nrq|au+E%p} zSJKcbsBCnPPif`K0i15W-}9j!3=U0lCU^xn#%}CTo(UBUgWd$vITnKpym>5@JIaj_4 z4mYFXV{5O;j7U_8v3O9#vkt^5ihe%E1CRGJ6Cz3n{9%^~Wh$-&gD~&Xy}KtCy-RGm z7V#wAU)sBYrTZd}kL+3&)wL{=eM7AUe@& z`&SeX?Q*a0oKXDh;9Ubsf5nYkOMdIZxg>Y@>gVo*zXOYVv;N$W)jl2jpVOvI=WlCn z!DpB;s3_doH3dmHz6!DfBNXCD%3x4sdeci`&=?V3)V^zjd`{rr;WWPC9M5P?eHwln zTF@**)6%+hmC3#FWpI@E6|q5G1h)6!vxQ$Gl2niPmf%rf0t>(iaLITQ@NEE!N8v?5 zZol6bxQ*fXpT45M>EGny@6?K3pt4Vz_zv9)3%!xJuo%aRvLDp}cTch3H5(3zBN(o6 zX5fZi(t>aV2Vrj)ZkWIgr^ne%*E(bWi(?1oa4L77u3_|0>Zpc|)#aXC>L6oHF?D-dmAt@zj02tAN9{ZO316;(Dwl6hH~kHm+?$ksUuI%049yq68XW?8g4D z+8U6-XLwf(qluUht{^FY1SNUAzv&^^SU}iRdOZ~vRy0Xi@zqQ1%y205VU+KNa4u)R zssRmI+X~~eVi-{Xe;@Lv8ehDv8I)A0o+6I%^L|wono#Z!RIg!u1NEv#ETyx>Ai(2Y zCX+$y7!(}l>ALE`!^pF~>#9Z>H^{hN#&t5Tm2nMYnUCv&%Bu-3ZzGr2C#XCM4wKFd zX!Re;(J5Nl4ouHZiS!drRvNAvK8`noKj2;JZM10JdVHGvjqCD0bZTc?>8du`&*ti| zxqQWa5IgMnknA(0AU=5poW>`-IP4$a?jbcSsMUMb*j8ZMyKDgR4BPK&zZ_HFl2yl5 z#eGUv{h)F`rLbud$RK<3@1*a&H|mg=j~2W9-z3quT9^YN#%P&v5kh#!5-fRUcfe2V zq0TIwF|y2tm2#x%i!>ON+SA0-9LQG+EyG<9cteJTKwMlWRQ;*GG?1o=`I6U<{n$&P z@h6$aeoW(2T8YLEq7e+BU%w>P1^s7^D_o4pM4r2d=K1u4CdFzC-tEx5BWGb&GB$7( z=I7E7)CId#HA;>{&#?fsF^%&&%+Omm+$wO(y>c==)#h5*$0T#A0sf{VP7Uj%%J1eW zBApW)z0Y+*#fPTvbNz%i{Sh{7XNftscu>iz6RP4!_=F*Z_)}sYReVvo>x4e6%yokN zIR;(;|AeO>RmGTq!20VfA0kem>M#_bRD}mdNy)08uzj6q`a4_`2Cv%;>WLVYmzKOId4y(h>W%5ErU$7kWtv%sX;8je5PyA|>=1Ttp#{HLS6nL0liEum8 z`Y#n$Do=}62en$KxLzs{_BGDc$1^T-TzLiTwD$e34wOM{MxPZ%Y!Zhr1C_20T&!69 zgF;Uk(}T~jx$*0G-rt`H_<^KSk|X+xPr9Lt={OE1qyLJdz$8T#QGO}nF0>U+aVOqJ z;8in!(!PEz$XF6h1lA)7HB_3I#}QZ?ESs5LnJSp^9U=+FG^P~-v80)(NI^^tSwob= znTt4SJGxwDAL?K2>4+~rLgi>ak|vJAv_fEk6v(ADNnW=~UP|R30;wdKQsv)*q`<nJah zWTzpTm<5Vt9W!|Sl@Pxr@x-9NAuCiJD#XDNWDfoW4nk^RM+h?TQA<)wU}Imzf&i`~ z7NY=o3h~J$#1*U_Nbx0RDk(n2{0Ot3%jy%$Tt`Y)9l?NIx~f&R%mIe4t6!FYZ~gYW znyEivYe)qyT^k~9f>>6#YDGA-4eG@!b{Ap77Kf=+SL&hS&%o{Q-mL0MRvm?9z$f=Z zK_68WUyuDKeqyJiXl_aF(5UTmJRR>qa!&*&=Q>>pUwBpfy}*oU$?LC@m(qSWf|H<9 z?1r|duKE%%&Od_*fN$ZUij_v=HfsuuUGZ$qre_Zt9Nc2r1~E8qX?u?U%fi zS`7mMRGXt1A3WYwV^AAkkO*>Je1W>mg%Tm@yGN;uJmB`_=HjEWilfjIQ45?SqoN_U zV_(p_&~b6o;28Uigfywizzb z59j?-&?SK&TE*!Ub1_I_3A?s~Vjaav!4&IXL;QL2>RE>{QY_aYT1Yz$;i+&Pf~2(Y z^dVM+O{KttG$MV;fd`eqc+rZKgI{x2YEblS5K1(W(~d93_^c9H>Z- z71V$5Ew2*AEVLX2CzvCb#)|Y9(VL?*Dp9hCQs*xq z4fkDg6uf>$6lk|7F^{9vDpBT$Y>tAdGNNDyT%@pZlo}<@jf1pDu1WMi-k~Cx;BZ^H&DDy zqzbljyuy%pxa9GRtEGFY=>32Vsdzc884GV1cti(cD|zmd@~jv(7t!{!>nWXc8VUnXSvMNf?UOdd-Noi2# zQ#Sf4UexhR;1bdJ!jii5DM+FJx;dpS;;dG zp_Jz-WJJ_FgOwc+DU3WU`oyE`?hp?_wNruX;r4jrsK7=jSE-%wJzdXj1l_-z-pBe? zG_4?FF_&gL9pW&|MPk;o7yFq-ti`Ph--MBOf5n^FTMw6b2}kTx(61NyQ{V*!u{VM# zZ4j+^Q3%G?i^KFlo zg^?MP&2Lo47eO~vrZ~&IY zbQ;1ndw9CBi#_Yadc5}`=HA1&K`dk3D0Xq;R~g_2`Ld*l*7wG^Qq5h@yc zy*sWV9W5Fq*0OnmC0tiC7ibnom^=)&KJhyGmo(T)fwAHp1j^=tfdbN0{A1 z@oI=ng`rA*iQ*xIAD71FL*jbQk;Y~z`2v2mwo}I`<#;!T#Dngv9~tO4Gm#3fj4JS78W_JpY^Ch) zq&$NM#-rS48pLfWBq5Db-wB7*k(AuTp3NeOaf`4rZWUU_J~8$hiWf3QKFs+=i3<_r z@%}v)b;8>Y|L{oLQFsg_6F4wFrY!;!lm$kAWEi_NBUnwZF+#(^dDGy^mx~y z2?K49Hf_5+(5CT7MK7=LpW4(X27s$dp7+RkevgcZnn$tEj_PnfV;oY?xJ}%{xKk_x z_IQUjlFoXhpQ5wwSK?BHC`1U>Sxqd~&`|B-5*QYt8tO`BEhYj!(Mh@vgRx)P#EU)% zq=i4yRX@qP>L(@KEWQUxq^mGVI3!kca+)Ma@{=g`BREu7sl_Ys!~3leT{S`cmFq^j zs$M*p$gGldRhn4CL6RjAE8Lu=td1T*wMkdK5J_V38x|9Tbk!ROBs1ZbIFi?D(p6nx zgva|S#S7@F?>JtS&~m&glIzbo-rqywL9T~lS&kM&$cR^=sX}y>4nnWU^`i*I1R_{h znP8Jp?Ot&bZjiQK%!0I$u6lw!A^(ga|BPG3dd9L*zikvn4pCS~*iMWR3lQY-c7nd+ zWdVgnb|Be`=j$8fKQcsLjVpF%=NDpIP3E|Q0+{?6{Qc*7beC*Q-hZ{!Q&O++cMHW% z|0>q+MLi`O5k&T3sizzW1i9Ewe;w=fbR^(kXx*M{;)kRKe91zO5v5>3px+cr45A@? z3inttADhKIDUD=&rirPX#;?W3!KJj!Cn%q^Sjs3xi+N!Rdc1F48Y~rP?W?gk=Wp#3 zNCnFUtd*^L7g(+2ITID6JYz9f6E#hk1Ckb-&m&B$sAqSZsAcRE)r>pDPN+f>w<@@? z|CI=+4Osa-w;k)XU?X2L!f=sX(6I8vmHsxMW@&?t!%EUV*XL~MU!(+51J%MM_J1KY zQ13txzX=eRGPSMZ3|7*?>^ku;dI;FvM-YyW)nxPQAjhs12c+0F!Xw4@&$??kHm2x2 zFL;Jr{3+Y+Mk3-%L_U5OR$@?4Jx>axMwBN7pR11FiY{H5UN6RwjY++_W%nUUS%s7^ zr$LvbH}v8rE@>yOYbb_>+M$Gu5o!+EG5EFgQ?|YSqqd;{%fd@mea>?MAI}Bc=p#xa zN1>ET*A|RlBsg2B-Kx>0J>K=hy9v&Z7X<|88l>8Q#Txvl;jc|ZL8_EIpO*7H#=4gU2DN@xO@ibI`e;RtYr)lVY z;1Mk|ZMvL9Zxe~00mOK`10ZREkqkPkaA-jEowVCz>@1(=XICSGgH5R^_{&_Ql1JsJ5Lo>lEykQXl?p@DzPEn zFNWt)iFPHBWV8h?QFBm|(b0h*NhS8>`m~B;SZ`z*{hA&EDv|0RkkPj}Hr{%N z6x**7w{dL0j6O^*NhSJ-i2aD{eF(kp-)Y5SSu0*dW1^%LRo5bMITD9zMLieBS}`$H zD_+VWvQ{j<5~7V7Nu6P`_zfB1g1GJUHi|VRMiQ)?e2x!IGK00G79>}?HjD2rB~jf> zja?p3jXnRuZlb#Xf`F)|B2|c%{2s9tQGH*|^KE2A2HhQ)Nzx=VhjFdQU|c6|W?V1+ z%<-DVM0U4`ag1Aqg|QGC#(1|5?D6g&(oIYL_cHh&^dzroDr;}IT`nog)uV%ju$!Vh zc%46xgs=)x#SI@zLg)zuNs4j}F8~X%0GNgFW_k!HO6gsoe_Xb6rE7&=id`c{OR@cm zG6vyTGLy&ULFAGYWi=6zgvj2fSqRUkDEra(<9v;;EQe$p%DS?i(uX5G>B=c1m_)y> zd=}oau8h5u%4c2qDc-jP>B@cNBwe`z+JoeBD=I1FkRq~>1LSh6B$w@F;Y3Nvs>6`W zX~A;&9=KQO+9*h%tH@;qYDRfpi^`G; z{pupAk~wH;bS+7Rwy|fmsN)sh8d1ZzR_tV4C$=-L7pdF4mec$loCg?xz^cWx=&m;)zHsDNsq`^x`CZAf04Z z+9d@lg^UqjaEM=ljx1UAi#*AdBBY60M4-}moktSV>|i0y2b;*m+%ZfsF;hX0$9pAK zCqu^h@~D82mLpY&kUodlijYR47L?~&WJJnSkEtyw&oPW^MI7Tg5yQA%%;k73B8uIu zB7(6HojkW`6YY#UMH{fkTRu=yp8l1X|7*GvHfCA+X?dm@H(XMkHEO?vbrZe5N&tyo z6I`O>fFydSZt$m(UtCP$3J5V8m_=_CJp|O|g{W{q^m=pkYsGJvBO-Qlq_6S;Jg#`Ium{0*EV3-Qtm6|3_tSgUyd zHK3a`c48sQKT{qKxe-zxF^1yTi#XkkTV?q<(wv4IzIYs6~C zwPFS1I&lZ%dhrrx(jqe0-70QoEW|X%ZDJy0to3t#ox%dQ$NPEzb5tg3ecm;a|H9@B zUe~30k#tLwPU{ysWl7|)#_vTUIvEi}I!==%?f70GNLmuv!PC4pQ3ed5YZdp>1FU3u zj$MF?_=mt4v4E=yLrs477Aw-=gF&%H8WcOq0(;s%LQ%BdH2wl=(>c@@Xq0**S)P?dKh1m`f`!TOcwTbr_`@~+xonjBL$2*4#Y6`4! z^u&9bbM{8h2zrlM=EB{n>Dl+`{G3#ndxPS|W)obZqfuh+h(M6U+(|Ndqk);Zqv#>P z+zY|$0CRi8RkG@=+;ybkDNg)^Buf3SLJ9Ov_vgXHQ+`kU7%TvfcPUsH!qbC&0z6Gb zst}%@L~JF``{g`8U{j)1+`|*BHnEJcPvkMi-M_#dZv++ehj@Bee-2Me6))mxJ6vKr z&h(@fC=3KiJUx9KHGP}-9GH3f0X+nG`WDCx@bo3Py7P35_zQfM`maC<#M37RDLhTa zTomU&^zFvelHLKHZbqsQp8gH7l{}BgdEUj7+E#I$O!O$mK5;4IPB8@7~ zdbbnM0Vd-)Ed9pd_ac_2A%d8;Ph#l@fgp*c+cA?PmaYY6mflSd0hZ>1$^c8}G3@~z z5HBXf=lnY0Qxrx0HEE!t1CGJ?_ITd_D?{WpE+W8NA5w+zHW>_3c$I>6j8xXN8;^mG@WV_6C>@9&c}|xbi*+t6;fd0S@m#st^uWAhyEcQ*xe* z*#2l07s)jk#MmeLFzyt;V|Ir7@6dAprQG6sKUM{_4I2xg#I7pvF0+enudJ;nHV(n$ z2*-Gg#BLhN%pO(eiyRY@bdcB7^&3pQvnuf@ zD2E7RA(*}`q%oJ;KeeD}#rC2H))1TEUTBg$&x@2cF1Du)Vr8s!2n`oE>1iZ7bK5&Aa13rMLdHY!IkMP zWS>nMMxu9xs+)|Lp;mtTY$H*8yYw z10r&~1#8kldxOsRzVKX~A)8|cM=&#Zo8G5(zZZ{lh#+#_l9{9Zyqh^$6JSJg8%^^(RNKZF0ZWE1+vA2M6r>F(?cxO?8 zLA&|>7dQUb`7KBl!t*Z> zTgkIp&a(y?5zjMu64)x{GHw$y8T-U!#+@Ps*yBCY`G5A$D-_ZzS{gy-YW1bF@dQibq53k*~8j6=;R&qSU`w+J7mj3noRahqsi>=TC= zcZw!poc~D${xLa!aGamPikxc{FXH)5xWvHMC7#Cyf+U{Lm+4CcW}chqA;9x^a5cd5 zOW_LUd4DOgpXX=c^vk(f{0NuApKDMs@y8dY@ca?1B73~IgT)~{|F|Q-^CYAS;rYK1 zTgh{aoaX^#L~_1To(Z}cw~1WFK9R{7-#Gw#yk~y>!#wYud=Af_PV##Z&tnlm{CT&; z^UZ-EiRW!RyJ`~$fSKnWdI<2m26P5^{tR5fJbzS*?C1G?99fd{M6m)cg+G5m!Nl{G zSnZZqGOidzEI17ohwyyf=>X4nAyo*^SAk(lo>8b7jXQ84i*vJ3o?R*(K3MJy-bxKp@+asC+<_{Vtuqw5@=S1Mk_^T_ew z`AfSbp05l9Nj#5`>1(B>St9tbv_|V+qdS1`0MFlqE12gmN|F6M{~Je^c#bo4;Zpch zih_yfn}1VyZW%x<7<{T5&zH3ac>V-Zh4B0l#8&cbm-8$@M#S@2d44&Zahr%{>=TiU zJB13^<9z~c`UiQQapO5W4^zB|=PTh7j#nj~`_KT=gb5!3li|FHXK9%K0yEDS(?dYc z=YY-t&u@Y&nCDh0vY+RpIkLp_IpT7-6#kq>!Nl{}PKD?1^dlDh1uPDc^YD`ao(}=- zAw0hV3{&#VMkwV;YvsiAofi{s726rZ{$=bFn;GMtM_`ZlIx6sw$@!-f{9IIYOR?fb zJomvR-hD;ld1fF;;(3frUnkxoFwalYLxAV42oLc5Gq{3zzE6tm=lN?KS>pM8@f=(V ze{M&?#GjpK6rN9uBoZ_9R`P6?^DIL~#B(#KA)c!lw~2Vh zJ`u|p_fP|Syt{t>!#tmO(>Xl%PV{>b&odE0q`xfj{7@iB;`t7qsbT#en0bCLJp_1O z06GIaUjSDy&!7KiZsQeS}QXOJp{ z=N2$b$ukW#qdbT9m3ZF3bE8&K#~Ai6W1rZ`xKnHg_IQ)1!2edxr|qT#ze2u0DN8+x zubePD!n|7i0>hK$DgiRs?%bfUdu`Han{nDBzK2Z#M7jr8L zqz{1hoF?w?q$&Arh~)7a!0Zt2Z#@y<{&J)W+E3pmUPo+&`(Ma;K8lR!wffgE<57CW zu-s_>cYyy;Q4rpLV)jeR0oPz;pt3LH+3@b4Q1%;`-AT&BpA7sP7<`zVA$h$3K;tf**#SF#a znbD9OoM0r(Fu+J>WwTk60qZuWEzY7wa%)FKQBTC~A+inbtI*sob!0lzZW zFW5UKu4b=8Vi0?sq?Ze1>(Qe101i4R&f;W-GFN-K>lc=Dn&g*bp=wb@>M1&z0yX;$ zw_V~CgU$804p-$xPYaHc)n4K1YKuM)kjUBkc*}xdO4jB4b zY{$#PGHQ<&@f>@#hzHs0G}Y-*j@>No=b&bB4`?lO{Z#Hc&8oiK^;258!gmd?i^_bj z!{Ls^_bo`N)arE*iI(THH^efiWGdq(#_~ZK8F1kJ_iEOG)f_V9O%C!p7H|2q|VoO(fUyHBHX5A{&) zI4;*G?%;BL;%2;Yl^cE@d$o!2@S=vVO#Rj0_D7q7+Wt`-J_0E%cl|0p$0IRpF(+*o zw*f1R`-TY?65||9@GC#~#esMfxU2s5Y3JwC!)%y#3J>9Q3__ivk(Z^JQ8>GvNg-7r zCNn8G+XhidG7kbPq!c25G@Hb`m!a5+_3ME>-dG~(oW8?6jG2CZs(yogMM7{r7v&Sf z@P<|9;ic@=Cc@#>jfbyb)2q^drsL2OnTHSKk$8BeO!#HNgkK2~FsMj8{1pn{d=+Dd$2*z`X0;S5hbMcWmiB{Fb#07&LdWFz1fA0Y z>w{kgky0R&GC7!(Gfaxi!|Ol_W%@g`x5vBXSO^bEO-dTXJ@fn=ypxSt+|Appl-eQA z;Fv=kBaPc!giR*keZ-@!@g87>CwC)L7%5VR*v150Oav%A36$U7L;0uK8iSp~`L~OU zQ6B6LDtgOTK_o4vlNV8ba&Y-)gUi2y%YW?q^Ox^V@1g#3`OgBAus()za$L(UIzpc!ByO(?I<(NO`;$_fUR&59Oa`JFiR3_$H{ZyHJ?S|JS+Pb}@B6mSn+MAETex6*ttOd(8-fWK zj7*g_8OQ{bwg&SgP=09-j`l z`EfYNBT#?2{Mo_f9}6zuz~#U2Z4dRorHA?tmg^79^+!2!{fB=aRQ}n2$@NFPK>d+v zp#ISEsDBUTxAai{0J(gdT>j`l`B6A0CQyI5{Mo_f9}6zuz~#Tt(nJ0K)Ifb~8Ej^S!KrY`Vmp?jCetU5Fcgy9^4le&# zaQOx<|AlXQsQ=s^>OW9!e_*aZ%8~0YyutPVNv=QQ1?rDX1NDbWNBw&!zom!r2gv2y zzfk8&n^V86mX=oEBrlC!Y#A{8^K=ac$4iX}UgM^6S zAWTM2VMz;9{?yZ$<&$CbSertuPfP)^IP$UFbxJ(IbhnC;lu>#M)(ON)_QLl9oTpDj z04r5W0*#pc?xBsm;s|s(QLziy<4yYttPRX(f|vBDcD1*izjoL1D~nEXGvf|1jd8u0 z2#n)~ga+?rVT@zWT_+6eS0^rqUzzI|eYiM^y=uh}P+jKwo;LIkW-ol(h_{P4m5aWS z=w}<0kPo;{#$h<3{lkaJlOkmQlXP ztiBoeFfi6;X|<3xbkoiW*FiuN-~ga8c)6v#T4{&|@eW!Ahp>rl$WvkQTVNDumd*sb z7vlx3Hq2lwBpYc7JLC!Zt#Ej}pBx7B-|fBzFna#^dHyQDvgj1w0n>Oru0|oML#Uak z4iObhlomNDYXCn$iR1e}Dzf_;0JZd6J(TK{OU)-NOV!}IqD0ju zfIBl$6$|LVb0c6&PNFIsuwzN0YB`_2we!Bd;{*+iB9ryO-JG;6PA40?ahhN9?M2=Cm zDp9o=fL{q95l|1{AJIh1YcvJQ&P`Mm01#!F_4WZ@TN5kl>Gg;c?J;3#qACqA2QVLy z4JZIC2b2KH0Gj|?09Ak;fNDT3pdQc&XaXDpv;YLa2j~E(Aj6S>XuxnlEFd1B2ABbf zfC+#!z#PDQKsKNNK(y13=%-(Vgj6(4&@WR$I7?9aEs^osI}-V+S;qQ8$t`4@SR}c( z$k-?2?QY3`Zn1>xWL&UJau1bp8nZ36Txr^z_VW5w4_#hw@A$bSsMwvqEM{9GMV0=b`(L;^063x<8+fev0g; zlM?x#NgssCKdEH;iy!%i_v#f9(L1t_O4XOr^y<~GUqAR$rz5xgL$rwAefmb?rVam3 z)r*<00z{E#9-)tBP+rL>XZkQ{!wF5YtdsxeF;>~CO{QnX4-gqeRiH- z*uc~ou`@FAiehnWea@ou#2~LZt)LS)8<-wek{fs7sp^ZI10E8I1D)Ad)yTY90NQQSPcyMFPQ+0Guuk$0`~(h0LCx24EQp* zw*toi*8yJu+yacf(IxG`=qDwS$Hu8H1&#&Ak%%RFVCb}xG~f$?bAe$mlxzgP7`O^J z0=Ncv1aJfJ<-mu4A@n6aV2Jz32;38iU&&D5VZiag7Xc>%Lr0d(1V%q8$p%K>Dk%Y` zACAhT`l@i`0Sj>la4OuGT?2%+ku}1t^LfFp2cNJdXiZ0n>OEiDw$?=+c>N_^IITK-xoq zjj+pFkcWCa%0ZlX0F8$+h?5GaM%aAB+W}mLv;vsM^A39=mTU18FxAM*4Wr<%2sK&s%_- zfU6PKgy$6GTMu^&z>Ii1;Gc%)O@LVBDG=un@*NI;AD|KbRd83sKOSzf17d+&;Eu#| z9P%5EI8E>?1CTwiwk%0yhF^S9lBx-5Bk?>OWeMPDgl|T@CQ~{*Z$X+^Ja-_!T0E-} zrykGI;CmzRa=2pwTL6dPCOcy*(pTYm4*bkW6OFvZE6w;*f+{N})|22=r}2|#-ZZ~?{t|9`534~MIUKNuduiJC{lRrTHc&cN?r zH$UrR;i}ederw>@-p#KWe$fwwma*&ca8+G5zlg2jswmJC{JRT&>TZ4q;Fr?P?+pCX zy7@)_HC#2Pn_txv;i{T$e*W@~!2b+j$mVd>b%61JnSe|{0pK3MX24EB1K=Rw2Y~7k z&|?HvtC#Uju#sbO0j2+gN}WkOY_lxCM|4SP3WxYymt2 zpkF=k$AA{V3E3|aJdOd30nl#(@Eky%?A`?Y1Yjp%7ho^o0|5Pg06ql>--0>-;sI8` zc)%<`CZGVY9X-FW_Uq5x^-x z6l7sIU=%1jqx>Z!Penfad{qvfr1$KgiFKkTd#?0M-L; z0?Y?218f950jLJ-1snvl0!{(?Ko*As;sItr5@0f50l*Dd19%8PzZZeu1RMmk0!{&< z{|24`=yyA=Q_sp(u3%NA;1*SPR&pWkTwR!vI|J9H=H%xg-sG%|W#{o$x$V84V;xz=q}F4m9I&bUE^|d^A{3Dlk-uq9LCQ|$c;FnzPPXu*DuY?#znE26Ei9P zM4|v`Z_mn1$y!*LC11uI>_0It$X_mRT5(q43Q9jaCo?Mzpp zo|*5D0N>mqcVTW;9+^A*ys%&eJ0|C6WKPamP?%A;!nK@3L90Y0SAlYb&kQ#%i!Lsh zn71gOBEg3)upO6~Stwm%OFpUjnK)#BLPlO@Zk9hM$!~m4Zq}5HrHZeVvp+LRJ2|7s zEiITxxhLl@U5bn*=j3rBVya9f!pG<2Wsc7&EOJx6ToU;t=jIm?wXWqkOq@j6Y{)|v z#Y0GXUN#e#>GI!&jQ}(Of>blIIJdO?9BLHV$CZ~kb&;G{HQk+?o_8k-Lf~|?q2iyB zQ-lkC7fQElQ%dGnro;%@O_68d#8N4gTr*b`kW0EZm^`Q=Tn9N}aZy%bK)R9Vq^uPS z@-qrE<&@NNGu(wad5bA!Dyo~YI4dci8T~ez=GVQq&de>02{z@NWp*c_Q>Yg)6x?j43TYq*&j(dE5;S4Y=H%q!t86|h`Q|Fh1 zWzse2BqgCTkyQjAe`v5&oWB>sHzj8oitSM={X6Y*V{ZO}3pj}Unh|8ku(N0#|(F<-2Y$J5~N^f zV$oHmsk_!l$tk*>rL!PoA@?WL<2-toeA7t#5YMvQ&PikBv5 zKx<}Z6#A7_PoqXpqffW~&9{WJz;Fpra|QU4Jx!@H#wmWO7oB?=In3Gi`hqxhUft(OGC5x{W%qWm!$SskUUxXo=B#lau z_!dYfxl@uUOyXTyR^G(C%$!0H8t_wUAoCY@7y2U+rIK$_VR2Em-&+-`Pvtw;xu8(p z8LC&wHF04+kCjUOWu6d?lAoW!RBIwVpnpSdiJv@UV#@f!{H5p>izlW~yl(f#Q;x~` z>3KQI&GC{?Kr5)u(a0#1M^0IwN%wLe;Gy9hD``eG*))li8iH5`0qWfUeskrTI) z^7C^;eNr-5dV}I5lR-po#HBRoQScz2j)%%=cz0dBxXz|(-&0iOW`;4C0|JLXUT z8z2>MGhi`b1z;^;Ghl=&Rz@m9!p8YoPtHB6=ZKnJ>nQ?+~mSU#7YQ zYrccAN*aSTW_q_c2rH;Fa+Vh4W{poCo0*%d!aO1Pq<%R0x{-02%kaoIbKwzody%`y z@0y;q6l0O(!u;w^4DA_&6+^oS-IC0gJF_xXjQuetE?kOv$^ueBu7%n8)3fd<&MI>E z7$-HO==T2}I-B5HBZ>uPxwlePMRS0?bg(sfIs( zS_bBb?wR@dNjZ!EU93XPu|Oz>7i71z=a@6{iwhTKL8;^|%YQi$zEP=66|lqQyg_hh!KU#1b{J zC@4e77K#h;^3yP}$e;hYKC%kL>wOHvi;Psjr;$B+TbPHd{X-Ai`4PzMD=9#Ty?H` zrFyG+hkB>FT3w^ARoAKO)eY(<^;c@2I#zRoraNE|SM$G|Dljfl2 zkfvGFqG{E1YA(@UtsSd1Y7?~MwNtdSwDYu!w0YWP+IzI?wfAcu)jpwpM*E_6m-bEV zKJ5qE&$M4_zt^77p3?rV?V}r{yGS=eceQS;&ZtY!jn_@l&C<=&Ez;%b9@jmodtUdl zZjWxS?mgYdy2H9oU4%YYU!;HCpf#>G?l*pEOfzjZeQN4w9%fdXJ?0_SDc0Mq%dD%d z8>|mo|7v~K`i9kG{m9yCJz;IPhT9@-(Y8^xu{MWoqHUUOu5E!W-&SmU!1k!E%J#gi z##V28-_~q9V*A0?ZW~~~$ZoPvwddK_+wZr3U~jeS95WnuIR28bBjIquw+UwwdO4$< z7dvB}*Eo$%hx0aPt+U>V;X>66_PW#y)!FJi^_S`vaPe1lg62let(sEJ1DeM)?`hgK zgS2MtIPEm;&Dz_v+1h-qTYHzb5}c~h?$PemwrPLXM(AR6@jA8cM(|^iZoTda=0cP1 zGhL*9jQ%G5E&BQTZ2eySKlPvKoAqt_U-aV*sfJq(iw#Q+#fG~Ls|{s_hYS{DhVfow zh4EqIkH(Y6v&NAor)jaN#Pny=@1_gQvF1c`p5;!V&%!?oW6!;ZTA|IFZl}-ghPR zb`Elma9-(*cV6$*Iuo5YIg6e5IM+Gbob65!nTR`ofMV67)f3dy)px2_t1HwGtN*Ni zR=rpKx%yl6_v+r7{+huWjmD*UUh|6P3(fbMXN_J95@8lhR{t>d2=%qL=9Cs9#j?QopJG5N&)!{e${v^%-?IavY)=skvG+Rx`qKhh?>8 zob5K-D%)eW?`(bTe{($NsBttn-gjJ{FczFGPPi}O>4X;(_9VQW@H5doAMasdY?vSe zN44{G_vv2LU8C3Ot@;%G6n&O{nf_k=dVRTmlYX=Qas4*^)B3mcjrx!DN6`AG^uO!- z7zPZJ1(MZg|-6SHlj&>jsZO7<`7`4ZVyp#xX{RaiVcH%fwpaW5%b9)yBQX z4~>V7!g$6QZt8CuV!G5c%5OgEXPn{F{JFfB0^n(i{KF_oJhGCgj3()7IP zWz!zhUekM~kI~*oOh1@@Hk~nroBNxGm@hStGGB+bx0;j8H<_oKZ!s@0FEJNF64sc@ z%@3I$hdexQe%ZXoyx07m`D62!<|F1G%s-pYn8PjoEki7qT1Hv&Eq7bWERS1WvAk~a zSl+iBv9wtttk+m?uqIh=wdPpwwN_ZSSf97PhTh#|Jz^D*-2S#9wh^|g(YuYd1lxG< z{dU`OTe)qMZ3}w$4qLUY7X7=?)?_j6*(2@I_Tlzed%Rt3H`^2K6YOdB zIrjPXY7932i-LS#a8 z!tjLHgm}ofIUzA&LPA=?oP_xa*$D*+_a;;%Y)N=Np*o>1p$W3zoY0cciXPCG;6oqi zNa*7n?leR4Q=Ai=lbvbKna(-Rxz71cw{x>|tFy|v-MPcL(^>7Tfo7_6HlYW1I6Fzs z3b67`My)zR9jT5|N2`abhhsFDpiWcIRL{YPFkhVs?Uk!8P?xBy&KVgRq0>~FNKKR` zS~FBLToa>-)x>GyHD=8m&3sL!CR>v$j~Od9B^WoVHMJNw>O)2jp^4N+YlmuwYh$#r z+Bj{zc8pf7P0?m*bF~G~hRd}pwI$lM+A{4%?N)7_wn5vdJ)mvU9@HMvHfvk7t=e|& zP-w_lT^zLJ80bm8&aAWRChKx_ZryU-N?nO=t*%VBQMXCAS+`x+pgW*z(jC+t(lzT^ zbgep}Yr|*~qmR?aLz}Agdc9e1*C(Q<&CxH{m+05(%k&$$r)|-1)mQ0j^ar73TlB4Z zf!^lRx9dCfo%(2l+F&-=4T**n!vw=*Lz-cxVUD4|u*tB+u+>my*p42!(@<@wG1M9w zxgWM0It-l#l`+B?X^b*P8{>>A#>vJs<4ofm<6Pr>W2Q0Nm}^{V+-lrz++o~_{#j$J zHP#vHjSa>_#tx&(6k&=qMVX>aLrud?F{W6P*)+#A-;`;}HszWMOm5S1(@N;~&88Yt zovGf`U}`iSFg2MDnhu$oO+Hh!dAK>v zI!nE!)8fE*xx;?Kp5r(O?VaRQm9V&}_Gw(YiMmwXG+nyxX5Fp23|$sRjHS9ebj7+A zx>dT>x^=n@x|8}d7~5T@J4`D~t4$kB4`L*_3S(3XXq;?LGe2PYzNkz{)l_QC-5RS!{LuFh9~rnyu*5>oZ0_N;awq+^=yHr*QC zOS%R6d-U(<52H1I)OYD`GAuB-4I9x)M$;724AX7Ub^ibdKQNs{`L~&K%nz7ffVOHj z_kn(zWVr=n*m}#`mTxWntVPxx*0-%6SdU>G8*IDImT5ED@3gP9ueHBue+&9zmE%6g zUdLCC?;Up~JeOd07CKc`7@ODzyBK53jp`{FTb81yZBf6beoOsN^BW|G7UL~ ze8V!sN>~8*p-vAO{%rW0;W@+0hBq-5955U*d}a9F@Dt=P%-G+kHd>5H#z~OCa^v&H zgT@oaDAQG@R8xlOKGR=Jk(Q~@#Lrp&Y5BtPGg`Ngb-49 z^@;Ug)(4jG$`Eyh-ii)}`qu^m0H^E`bo&J=GNV^W*+=!JGuqAA5R!8F;FW|}GYN$Qc* zAJ>}7OqjJd-GHZ#o+`8HNgtgkb-};I5u=P8u&)Q-A&3dKnMvS|6!lHiG z_Ll8y+xNB;Hr$(S>ti1TYkGwJYWrBb(Vk!*Z=YhH1({d`ZL!RL4=n75?SHfHw7+Tp z-u?r$M<2&fjH-Hv9V2QA#?;A>l$jV;=VD~d#MqjP(bbLdbtOjFwHRYJVwByCakd)c z>j8|eG_FQrWF3mJH3p+=9LCp_gv^9ojH>R0FjF^<|biJBD61kGek8phI%n$4OmJp0{LB7xq;JL(7-6OiEFsphOy2PX(ufJ8lPXDm} zN&Rm9G5s3DgU}OiLq{Bg#W)b7lg@aP@n+*v^qx(|zhM;m(D=P^nrRuVz>iGdz|!w+ zc3bzL-Djca@32jQwNjf9=^TaL`m^(t^NjO%(#cH{Z^G4m)cw_ipqVdHUkclLl=^D* zb+E6sYNOh!PEaSQ$E$DCRA_`IOnaGjrnV3>qGz=)X#WBFU(>#>eM{@n?$^GLImaj3 z&$WlO-@r;frai9xNqbUz8v1>O?iGE6VWi=Np`US-@mk|JqYKtC>554t?^K<86=Qqxy&STEw&Yzqoou{2=on6G67L{r)1B3gBqVGl-ty@q{;_Y5BxJ~n)2_|ovT z!DYP1^r2}y#<)Apr(lEs4lBG5?C?Rb#4o~FHv-o9)t2ilV=Y>X(PFhESduK`EjMA# zxY4rBvdi*k%(AyxpSC_{{k!!g%;$Dv#{IVS9qYT8*L`ID)cS?>E939Fj8sYidUfmK`wySRaSZWFAAL$DiKFz*u>*L{w5SjnB}&k?YT7dRI=mpJn< zf-ZC3g}L4uj1A?^`<)LtA9X(Ne8Tx8MvCX1FFIewc=0Ro)+dd#zo=Jg`oIb>YinUi z)}P0g6qs@QU{Q8xJGClZgf3DS1smlq*a&NQ#&y5`A^oG6b3K86@{Im@{fqjS^}Ffe~0`jj&F#-eJAjUTEK7ALh_F3=WIKfw9!( znCM7#Omn0=Zg$-2$Z%viavV#sUQz5=;aG)HcAaCTv&6a9S?1gbJ+}Egnye1%7Y)uv z=K;(WXvMo0EZnY%z{<`x%t$}d-W+19Rq7suCi%1Ouexozr*+Ti{tm0^Ro!mg8@ji3 z??AiM8yaBq9xyZ+4nm(a8(Ivluz=ez7wv8X4>bzYDy$Q{ZO%lGyU{uqHr1WhyD`fv zwcdxB-UF~ORR5>FGY_w#KKJ;9O=L3^ki}4rvP*z7XJ*baGiMH~0wPifOA#r7KoWr% zlCTyj_~2HsMvDqoEn3uCL2+qCr8cz+R=qT>Vr^AKixvu47mA{x-p@O8Cg&vQ1nl$N zf9`W{@{n17Gw<*BdzbI~eP;$sx2mk8R(~SLDo|DH__X-y_=EAi@f@dzqdM0(3$Zi= z&dpKoVi709@1;&t?^Him&CriS`$89y5By2{ht^!r(>IeF-)r0tD%x&5X8h84+W0kI z??vO$@Dt&u!q0|(6aF3S(kpno*TR1$JN_F!Z%X8fNLloH^4CYmUVlaY`WzYTZcyP~ zve-AGZ^ZJ6Q$>vRo$=lAbDg1%nOMt+{t>HBT6-WzX`Nx~y@ChSejyW|eJwf89CDSN z+J{;f_?>6m48vi>dWO#rzZ)JLQ6okq7KulOM@C1+g3?5)?;=-WWL~5+vIyL~1mt`* z*ts;iD7rYhB)TGcb#!g?+USkZo1(WwZ;Nh@-W|OcoqH&{J^C03|7kFOZ7j!Z32$~f z+x^7+mwA#1pJTPO&bHcHuaZZ7(S+$3c8`U3Fb%&s$8c&t=4IM^_%ps^g3g1cw1yal>eqO+K${mUEf=q?Z6?O z!JZFTk6O=L&Fu|IobaiA!sh?D#hbK>w~2R%mpUuSn72F6J9~)f$DQ0nm&D>?>f2Ka7{z3gfJ*74aMPM!`!&@$fv)oOL`5<(j)?d@KI5G25 zZJIWRymB=fzZqSB49{DGj=zlG-KYH(ulu3)k#<7+x7JGUpr5OMTkoe2(Zjk!be*72 z)o1DR^)lF-)%cPh;YaSlhdhG+cn;sO7xr$yewcjnYrT!p#RwRKjIc4BTymOmB{|7j zH<#Q(9=U_;qy~$s#hMPdx#Sn*k*&!gyM+Vc0U-Hk_~P(na>xoeolnEQ;mGPp z=jg!bX!FmWiMOw3U>HCL1i z$^U)CvJQ@`xq6n`7RIcT+Ep!8KhwUZzq$H(`e1rGN-u($E!V5ao>$f9&s+2w7^+wG zTC(Ri>+|P2Jy2&>y$uhN=|5V4O!DcmPM_`Y zFmmWIWYIH0DVYd=Cs;lc$>)OFGckKPD1DQQ(zm)eeTR$GUyU3En>Y63`DCO8(djNG zFLF_Nd0Gx#4Iba=;_(+;L|*G+@*ky0+vWi{@k8cO zaQktPdma9@1?+e``0>tGH!F`!u8%dq%C~~}-Kb?-!>m!(7;C&W(JFwaoe#5i9o*Vo z)-U1IYF$3?t*>WVgJ^C5#CK0w-#`2?O@$HlOg26y!C;5%ZGi_;ood>1!3N*vg8JL!NP5Y zhua3)5dN(px@ep)=uUw%6CSPzCT?Ly)==$i#Lw)=%F5L_N}@%gHMN1dhGHHxn~B zJI`i+NKHpkTcq)HLGp>|>P(lRtD>T_MqQ`gKz31`CBN9&fU(;TTbIf*0`+{I4yLk0 z!{F@-+^l1H=ngQ}>o9b6)Gq`@zE5VzVCwaQZ!3(w8dXVZv z#@pe;;UF=t4DM$W3`}k09k}JMBQ2u6$%Nz4%dof-_^ImXMmO)>;%2_vu(j4?w;I^= z2UyOdvFFHL6)@@J=JV)xC$#uh>ptsQsyiVnIv?3Za5DGCpMaGqao%xyBz`JU0-`EM z=qh;sS;3#c#e5m;LEg1TZ5#SlXkchb==ZRWBdAT4QIYysy8#CNus+IIj2A9~TZrH{ zHo$Fv673MPV99Qe{WIp67n@V4LY)KZ6<*|^^`*6#T;e7BxIF~CcD8ew^D`tkCvmyt zkZW?3RouS=HH#Ve-krgH!L!xgFhT3o!|GW?s0ARI`^n{wgz~f>Xb%v5j%efbVi?L} z`dARY7A}S1coW8=mYUd;FacM`ZUaSrV74b3&%?%Q>}Wg@zcs!YE2t%FnVl$3+zU^v zRObjSrHoT&sY}(X)#=RV@_GigIIW@FD5x3if){-ARruESW>2ZCyK3X5EU#fpcU$1Z0 zAJl)T{|Vd_3Evdn8{P+t(-nqhTx2eFul2Bbg5drhT@c$G+Z+2VHrKqCjOAZu=d9jt zrZpQ@uY?S@91ObLI%TgS2izCG)cLhDCb0}oDo5GH*!6=mUmv`Z4EARA$H@2-^`~Hr z2i1qwN2xD8r9P|vM*SW7^a`lsHTBQxTk5;&U&%N6Xp^Yz)oHV+@vMTi+HUM2JNwWG z64~y70e&j{0kxU_SjFw+-S<#`d4LMcBh+AiMHS{b>M*;h#O$RO^9I$J{nTSV#A) zXa+jJM;lJw)7`klsDL+Y2~$`e-V8QA7Osp0qN}5;sm-*63#=yVYeV&A6gAaZFrP2j z!^uCMCxe?x7JS(0m6(&bMQp4VY{4QFY^&a)J_9>DI&^dBAEEqu27j0~N*e=HI}vX& zy@9_ttSS0gRKpy71juR}*lH5!Y6objZMaAH!f+yd87z5MSh!2b_4h2v|iL99HgH~{b7@~1tkA-ZJV}3 zdlE#y3&i-d=o8UpWHj5%m(4$$g;oXp*bz9=8FsOKt^F*v`ER>z{64apT0GO&@d1wE zT;a@dZgg&Uwt;3_COT4W9-4S4@gg}I!hW2ii~`qA4}M$yquM;wDKsuLFSI^Xji>5K zMfP(1>@sq+m$koW`@yGQf!Df#*L1x=pGoz&i288~v*jD(jP=GH_~C7Mk{69X7=JPT zW*jpK!Jmqp`qbhP;WP{6qZjC$<`3*IR{p83k;5u^~<-|6KDicp_!qe}B-AqSQZ^LnZ z1Z(jM-rg{O1l!Qby2M&#JwXNkQ|pw~%x-Ug%kF7kU=OxKb{ro1Qu{0W_W1VrsdyWw zrxS8wj=ar(T;@IaMzDq2ULC29!>>4KWqD{BPbW;!=4wk}UGC67p~8L=&z57fG|o2K z8y!LG-Ho2c`9@!3AS}FU7>wP+(_q?1f>Ni1zej~< zS@=dg;e+Ar)OVg?6kmjQek1%&_)aaI5s6TbxH|e4yzYY7 z%2+pZzj?k@2J8A5SZo0p>KXezdl0B)jgte1xtQqoFr3J)#BMPDKinLdXWQuWJaVDy zsEKb2J{@cYKbS+l6QMpci~i2i7gKHCKyH$2bT&d{$hELVM+}4P;=ORENLOZeK-7wk zjZP(_`~~^%J}Lw~%<<+#vyAM0k9m>xU8@*>`H>Z{`!M!z+yAsr*==AbX2pLPU+diC z?52iUNA&Ft8d3s0r-w|fc($N_Q0F<652>lQR`13~yhIh`($MuhY0yjStqs@O=>zo$ z8OJW>qr_#ob{RXu|K(P(XGiYlxrWimRU9>9lVY<$(;vk8nh(1?)Ys;}tPbR)1MPe5 z{r1H8H9TdoHC~Q|-QjF?@~EEfm+=Ymt{974>Y|}wcQs!%d3xh#Q5B2dtK4)BVWcwjufZ;NTUo z-gn|F0?s67Dy;S~aA$|ac`!S>@n~dmJOjbIXDkZI;;zB7x27Ks_-`NmIDx-d#WOjN z6U)cqv982Ze5_qS<~mCMHTl|p{fJ)Va)>((mHcWFTKi_WO{4?$j{B)z?2fz^8IS+J zhF)~1qF_=_sG$cZVx7&Og1c(q{~R}7-U{wH%kBgZ5Q4k8!oJgfh-XVavpd3;baBQx zPf_i;$>VN#2Go1*Vq|c4@RQ(o)a$WDBXk@2_ynqif6?0Ob6^YJ*V|LCyUBPThI&c( z-tdX=`7j@MM~+3hfDc!|$DE8#h^-*9pNvf~S5TWfX-=?KSbMFL)&zS6&+?qKC&1I3 z?_BPzgPm1o^PDK-)IB&lcz^IUH17*yU_UlRSKI!WI$~oM zVi-|kBK7Rq)UwN|ysZI~R#S1?f)(tbnq3oqi5i<^<%dA3QqyjYzw1UVdw`pj52K1U z(XF7Bxb?F&ZuM-FTRYo z+-g|13_QKgJv}xP|4|exq2gUm#dkSX?=|EXH^6;Ylbvs(YPKb#2L8es`P&qqCHZ_ilM7?yn{(ADrQ2@6$k^MthmNYsp zH3#`w<1Omj`TMJz*uSNT{X3f2U(>|?+9viNXk!1zP3%{sqx_`C(K|7h{bSy5rtn%p z{m;>Z&6K(p^_$9}!@T#OysqpmI?_xzm^!SCIm&zWY3;Xt#Jlck?ejh(hQi(YKO0YQ zJZ-zhm%R7jA7t5??apcUYo&}*rYa+q@e1GZ;EjigEJrGr@b_Y6v@%wipj@O}M!UiM zE$3@r6-ptovsAfCDN_Q)<8dm(Fbp9o7N12%-#4olbkyG?gB&|R@ zrF}pdp!DG}=)TA}P|>gpnJL~P%Mi#3d3xsrdL#+N1M?{wNc$89Ms zs*rgob|=#K*YmVnBr9f&e5(?xlYOGOqqs-8du#!t=1G;VA0k&uvwL&CcUCEFJsXpD zW$s-YxASaxA?>A)%UnrCvNGkHUq{CB1bR20R^CjcUuS^QpI?zfmVsmsQ?n&=S?Atg zyoEQ$*=9oI_jIP0GKKZbRuhq+&>b<~bIFX$H5+=K^O|U%{p`x*s8lKa(2zoAqR_Rh zDzqqFFH#;c)ko=#=krd`&hvT$7>gqGtv7yW3FEO88RyY|(MOS>p@zzKN>|eF;a}&% zG`o=56`c{E8emjC&GRJiJf?3eMf5_v@1-m~3ti%RDgUY?kY%~sSGk_&M?9OBt4qtt z92K1wuOR&t&z$npo-TP~pLwqM1DQeTce=L^Aj1jviyg>y1C2be^hdmj#2=BulSn+Q zjFRY>|IbWrcWfZl;QDqA<3{$G7adL6%@Wu8J(*MYPS^DF+`A9qj`R3kfCTB*CUT1v z&toZaOPrN)lU(&oKfKXMANi&YZDd{kj&k>0#1)!x$3os^oa~N+T)B`jY~{A`w_3Yx zJxlP8w|1{1-g6o4WVGA3*AzSR^wvA?Eat%19l5UDN9<5MhivyE4hcRG+bdz2!VSLF zHyj5U!TGM&^!!Xechnk=bwe}}NY15)Eu_6f*X(o94I33-DCk2hO7!9M_dnCvHwO(! zOl}TZx(aJ;&L~L)Xr+wfKH~o+n#m~5!`>vG%XSM!_aMuayk*L_&{z{3(wx18thJ!6 zL`{E9^u3jf5Q^C^BYU>1MdhrCzIb+gR#Fl{3Nk~jlMpoQ63nsjf*WKur2h@Q!wA=(7P})Yv8a-{lC$JGf|x||V%m59=#rep#g!Y14MJBJmBiz1-E{U#*7^x#k&v1~lo*M{~b)jq@X(SZ+g%JD9sx z@LTBi+e1>~MI_qE@=PrPv|OUR%b6AUD$&O|X)R@RJx?dzu#&gFo4$K0#(SgcWl!SG zv!RpBeiYDya%5SAFB30Pge;zhW0p>I%SzF87CQ6i2y!AI5*3A z(wBxZ4pw~0GPNQ-6FsvZ_jFIjOSIC<^?hI4_?{B){M@*+>;Jto#a9WE&5Q?q+1H0Y zN`&)pQ&m#uy)hQM_anF5`}CgcOb(|f9EbRRiD;sAi};o7pp^NPEX((j;^!-pXmbMV z5~IGAwXKh*eI4tR^(@gTZzTNlx@Vb1Kgx;ss6e{L>`T|IZM=ET<~8*Hf#~XPX0> z&?K>z%vkNkXW#PsGODTgD#s+&=Awb#UBv5pcd4w8ks?ckNF|6?^hLDLM*tqvk)C%3 zIM4Sl>DJ}xo5z|6OXcM`K9kVc%6sCQJP(xV0a9o>yG#Qzd_hA_N^)kw5k8tomolZP z5`BGMsbzhRROX^kiG^NNlzzxp@J|18LE3nEY{uzx{jo`V@hrjj3;*d=rh!^SPH#T_ ztMqeaDdz9#W$+jiv8zgS+M8!#UOXf!8IoYgZmx}akw?Z+(4@?zr*DFqg(;Jnlra-c zYLE5~<(y0=u?Su>ou^5k7a58445@P#Um#H+)!t`DdL$)G=M>~>>FkVn=Tu9X(XMIR zf|FAiTKux~!?Q_mhN?iTQ{BB{qtep=|HKykNFf#>IeNpp$X+jl3%Gt+PuC7E4^omw2XdR=NesH6;g=h$()>!?#`p5}Ar=Df80_X}*c)?~xUydaPeM zHk6F6E;&oZFvbnFxN)TDnN{v=@hLMBoZi|L<-QH?Zu-7$uIRToarQYE_U)R(e+M9K zy74dPum1Onl-wth-(g99Axp`7a9U~EKJc9(Fh=&EIvO70Z- zL=2zhYR0iCRiz8rbvLVAg^v&A&Y8gXMVHAbe8%*91>;BXiElps$9M0P+{LUUPaB#1 zh!~Cgu$sJ1<#4`byL8@kB~MF!s*dAF`PAank>i!zK^IpPmY48}J|%aLdl^<{ja*n* tS&2Bg7fdP`@9+H%_xHXMH_rd&42P;J(F#fMR{@>MIEK>jg diff --git a/build/nsis.simplefc.source.zip b/build/nsis.simplefc.source.zip deleted file mode 100644 index d7476022ad9949b5e84585ade092c4e499f28677..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23209 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 'GNU Lesser General Public License, Version 3.0' } - spec.homepage = 'https://github.com/ethereum/go-ethereum' - spec.authors = { {{range .Contributors}} - '{{.Name}}' => '{{.Email}}',{{end}} - } - spec.summary = 'iOS Ethereum Client' - spec.source = { :git => 'https://github.com/ethereum/go-ethereum.git', :commit => '{{.Commit}}' } - - spec.platform = :ios - spec.ios.deployment_target = '9.0' - spec.ios.vendored_frameworks = 'Frameworks/Geth.framework' - - spec.prepare_command = <<-CMD - curl https://gethstore.blob.core.windows.net/builds/{{.Archive}}.tar.gz | tar -xvz - mkdir Frameworks - mv {{.Archive}}/Geth.framework Frameworks - rm -rf {{.Archive}} - CMD -end diff --git a/build/update-license.go b/build/update-license.go deleted file mode 100644 index 22e403342808..000000000000 --- a/build/update-license.go +++ /dev/null @@ -1,395 +0,0 @@ -// +build none - -/* -This command generates GPL license headers on top of all source files. -You can run it once per month, before cutting a release or just -whenever you feel like it. - - go run update-license.go - -All authors (people who have contributed code) are listed in the -AUTHORS file. The author names are mapped and deduplicated using the -.mailmap file. You can use .mailmap to set the canonical name and -address for each author. See git-shortlog(1) for an explanation of the -.mailmap format. - -Please review the resulting diff to check whether the correct -copyright assignments are performed. -*/ - -package main - -import ( - "bufio" - "bytes" - "fmt" - "io/ioutil" - "log" - "os" - "os/exec" - "path/filepath" - "regexp" - "runtime" - "sort" - "strconv" - "strings" - "sync" - "text/template" - "time" -) - -var ( - // only files with these extensions will be considered - extensions = []string{".go", ".js", ".qml"} - - // paths with any of these prefixes will be skipped - skipPrefixes = []string{ - // boring stuff - "vendor/", "tests/testdata/", "build/", - // don't relicense vendored sources - "cmd/internal/browser", - "consensus/ethash/xor.go", - "crypto/bn256/", - "crypto/ecies/", - "crypto/secp256k1/curve.go", - "crypto/sha3/", - "internal/jsre/deps", - "log/", - "common/bitutil/bitutil", - // don't license generated files - "contracts/chequebook/contract/code.go", - } - - // paths with this prefix are licensed as GPL. all other files are LGPL. - gplPrefixes = []string{"cmd/"} - - // this regexp must match the entire license comment at the - // beginning of each file. - licenseCommentRE = regexp.MustCompile(`^//\s*(Copyright|This file is part of).*?\n(?://.*?\n)*\n*`) - - // this text appears at the start of AUTHORS - authorsFileHeader = "# This is the official list of go-ethereum authors for copyright purposes.\n\n" -) - -// this template generates the license comment. -// its input is an info structure. -var licenseT = template.Must(template.New("").Parse(` -// Copyright {{.Year}} The go-ethereum Authors -// This file is part of {{.Whole false}}. -// -// {{.Whole true}} is free software: you can redistribute it and/or modify -// it under the terms of the GNU {{.License}} as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// {{.Whole true}} is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU {{.License}} for more details. -// -// You should have received a copy of the GNU {{.License}} -// along with {{.Whole false}}. If not, see . - -`[1:])) - -type info struct { - file string - Year int64 -} - -func (i info) License() string { - if i.gpl() { - return "General Public License" - } - return "Lesser General Public License" -} - -func (i info) ShortLicense() string { - if i.gpl() { - return "GPL" - } - return "LGPL" -} - -func (i info) Whole(startOfSentence bool) string { - if i.gpl() { - return "go-ethereum" - } - if startOfSentence { - return "The go-ethereum library" - } - return "the go-ethereum library" -} - -func (i info) gpl() bool { - for _, p := range gplPrefixes { - if strings.HasPrefix(i.file, p) { - return true - } - } - return false -} - -func main() { - var ( - files = getFiles() - filec = make(chan string) - infoc = make(chan *info, 20) - wg sync.WaitGroup - ) - - writeAuthors(files) - - go func() { - for _, f := range files { - filec <- f - } - close(filec) - }() - for i := runtime.NumCPU(); i >= 0; i-- { - // getting file info is slow and needs to be parallel. - // it traverses git history for each file. - wg.Add(1) - go getInfo(filec, infoc, &wg) - } - go func() { - wg.Wait() - close(infoc) - }() - writeLicenses(infoc) -} - -func skipFile(path string) bool { - if strings.Contains(path, "/testdata/") { - return true - } - for _, p := range skipPrefixes { - if strings.HasPrefix(path, p) { - return true - } - } - return false -} - -func getFiles() []string { - cmd := exec.Command("git", "ls-tree", "-r", "--name-only", "HEAD") - var files []string - err := doLines(cmd, func(line string) { - if skipFile(line) { - return - } - ext := filepath.Ext(line) - for _, wantExt := range extensions { - if ext == wantExt { - goto keep - } - } - return - keep: - files = append(files, line) - }) - if err != nil { - log.Fatal("error getting files:", err) - } - return files -} - -var authorRegexp = regexp.MustCompile(`\s*[0-9]+\s*(.*)`) - -func gitAuthors(files []string) []string { - cmds := []string{"shortlog", "-s", "-n", "-e", "HEAD", "--"} - cmds = append(cmds, files...) - cmd := exec.Command("git", cmds...) - var authors []string - err := doLines(cmd, func(line string) { - m := authorRegexp.FindStringSubmatch(line) - if len(m) > 1 { - authors = append(authors, m[1]) - } - }) - if err != nil { - log.Fatalln("error getting authors:", err) - } - return authors -} - -func readAuthors() []string { - content, err := ioutil.ReadFile("AUTHORS") - if err != nil && !os.IsNotExist(err) { - log.Fatalln("error reading AUTHORS:", err) - } - var authors []string - for _, a := range bytes.Split(content, []byte("\n")) { - if len(a) > 0 && a[0] != '#' { - authors = append(authors, string(a)) - } - } - // Retranslate existing authors through .mailmap. - // This should catch email address changes. - authors = mailmapLookup(authors) - return authors -} - -func mailmapLookup(authors []string) []string { - if len(authors) == 0 { - return nil - } - cmds := []string{"check-mailmap", "--"} - cmds = append(cmds, authors...) - cmd := exec.Command("git", cmds...) - var translated []string - err := doLines(cmd, func(line string) { - translated = append(translated, line) - }) - if err != nil { - log.Fatalln("error translating authors:", err) - } - return translated -} - -func writeAuthors(files []string) { - merge := make(map[string]bool) - // Add authors that Git reports as contributorxs. - // This is the primary source of author information. - for _, a := range gitAuthors(files) { - merge[a] = true - } - // Add existing authors from the file. This should ensure that we - // never lose authors, even if Git stops listing them. We can also - // add authors manually this way. - for _, a := range readAuthors() { - merge[a] = true - } - // Write sorted list of authors back to the file. - var result []string - for a := range merge { - result = append(result, a) - } - sort.Strings(result) - content := new(bytes.Buffer) - content.WriteString(authorsFileHeader) - for _, a := range result { - content.WriteString(a) - content.WriteString("\n") - } - fmt.Println("writing AUTHORS") - if err := ioutil.WriteFile("AUTHORS", content.Bytes(), 0644); err != nil { - log.Fatalln(err) - } -} - -func getInfo(files <-chan string, out chan<- *info, wg *sync.WaitGroup) { - for file := range files { - stat, err := os.Lstat(file) - if err != nil { - fmt.Printf("ERROR %s: %v\n", file, err) - continue - } - if !stat.Mode().IsRegular() { - continue - } - if isGenerated(file) { - continue - } - info, err := fileInfo(file) - if err != nil { - fmt.Printf("ERROR %s: %v\n", file, err) - continue - } - out <- info - } - wg.Done() -} - -func isGenerated(file string) bool { - fd, err := os.Open(file) - if err != nil { - return false - } - defer fd.Close() - buf := make([]byte, 2048) - n, _ := fd.Read(buf) - buf = buf[:n] - for _, l := range bytes.Split(buf, []byte("\n")) { - if bytes.HasPrefix(l, []byte("// Code generated")) { - return true - } - } - return false -} - -// fileInfo finds the lowest year in which the given file was committed. -func fileInfo(file string) (*info, error) { - info := &info{file: file, Year: int64(time.Now().Year())} - cmd := exec.Command("git", "log", "--follow", "--find-renames=80", "--find-copies=80", "--pretty=format:%ai", "--", file) - err := doLines(cmd, func(line string) { - y, err := strconv.ParseInt(line[:4], 10, 64) - if err != nil { - fmt.Printf("cannot parse year: %q", line[:4]) - } - if y < info.Year { - info.Year = y - } - }) - return info, err -} - -func writeLicenses(infos <-chan *info) { - for i := range infos { - writeLicense(i) - } -} - -func writeLicense(info *info) { - fi, err := os.Stat(info.file) - if os.IsNotExist(err) { - fmt.Println("skipping (does not exist)", info.file) - return - } - if err != nil { - log.Fatalf("error stat'ing %s: %v\n", info.file, err) - } - content, err := ioutil.ReadFile(info.file) - if err != nil { - log.Fatalf("error reading %s: %v\n", info.file, err) - } - // Construct new file content. - buf := new(bytes.Buffer) - licenseT.Execute(buf, info) - if m := licenseCommentRE.FindIndex(content); m != nil && m[0] == 0 { - buf.Write(content[:m[0]]) - buf.Write(content[m[1]:]) - } else { - buf.Write(content) - } - // Write it to the file. - if bytes.Equal(content, buf.Bytes()) { - fmt.Println("skipping (no changes)", info.file) - return - } - fmt.Println("writing", info.ShortLicense(), info.file) - if err := ioutil.WriteFile(info.file, buf.Bytes(), fi.Mode()); err != nil { - log.Fatalf("error writing %s: %v", info.file, err) - } -} - -func doLines(cmd *exec.Cmd, f func(string)) error { - stdout, err := cmd.StdoutPipe() - if err != nil { - return err - } - if err := cmd.Start(); err != nil { - return err - } - s := bufio.NewScanner(stdout) - for s.Scan() { - f(s.Text()) - } - if s.Err() != nil { - return s.Err() - } - if err := cmd.Wait(); err != nil { - return fmt.Errorf("%v (for %s)", err, strings.Join(cmd.Args, " ")) - } - return nil -} From 813c3eb01c8b86963b5de42a19d431a21306927c Mon Sep 17 00:00:00 2001 From: Tuna Date: Tue, 31 Jul 2018 14:47:00 +0700 Subject: [PATCH 3/3] tiny improve on travis --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index cbbc5a6a67b1..597c036a0a9b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,8 +42,7 @@ jobs: - stage: Github release script: - - make tomo - - mv build/bin/tomo build/bin/tomo-linux-amd64 + - make tomo-linux-amd64 deploy: provider: releases api_key: $GITHUB_TOKEN