From feabf132e9699f6793037797973fbbcf068e12a7 Mon Sep 17 00:00:00 2001 From: erickYan86 Date: Thu, 4 Apr 2019 12:27:26 +0800 Subject: [PATCH] fixed Makefile and add some scripts --- .gitignore | 2 + .goreleaser.yml | 65 +++++ .travis.yml | 2 +- CHANGELOG.md | 10 + Makefile | 125 +++++++-- NOTES.md | 6 + README.md | 1 + asset/asset_object_test.go | 22 +- build/env.sh | 37 --- cmd/ft/root.go | 2 + cmd/ft/version.go | 57 ---- cmd/ftfinder/root.go | 2 + cmd/ftkey/root.go | 2 + params/gitcommit.go => cmd/project/main.go | 33 +-- cmd/utils/history.go | 51 ++++ cmd/utils/version.go | 65 +++++ consensus/dpos/database_test.go | 2 +- consensus/dpos/vote.go | 2 +- p2p/g.sh | 1 - params/unit.go | 5 + params/version.go | 52 ---- scripts/commit_hash.sh | 26 ++ scripts/env.sh | 52 ++++ scripts/is_checkout_dirty.sh | 22 ++ scripts/release.sh | 50 ++++ scripts/tag_release.sh | 56 ++++ scripts/test.sh | 30 +++ test.sh | 13 - vendor/github.com/monax/relic/CHANGELOG.md | 49 ++++ vendor/github.com/monax/relic/LICENSE | 201 +++++++++++++++ vendor/github.com/monax/relic/Makefile | 44 ++++ vendor/github.com/monax/relic/NOTES.md | 3 + vendor/github.com/monax/relic/README.md | 99 +++++++ vendor/github.com/monax/relic/conversion.go | 48 ++++ vendor/github.com/monax/relic/go.mod | 5 + vendor/github.com/monax/relic/go.sum | 7 + vendor/github.com/monax/relic/history.go | 271 ++++++++++++++++++++ vendor/github.com/monax/relic/version.go | 97 +++++++ vendor/vendor.json | 6 + 39 files changed, 1409 insertions(+), 214 deletions(-) create mode 100644 .goreleaser.yml create mode 100644 CHANGELOG.md create mode 100644 NOTES.md delete mode 100755 build/env.sh delete mode 100644 cmd/ft/version.go rename params/gitcommit.go => cmd/project/main.go (58%) create mode 100644 cmd/utils/history.go create mode 100644 cmd/utils/version.go delete mode 120000 p2p/g.sh delete mode 100644 params/version.go create mode 100755 scripts/commit_hash.sh create mode 100755 scripts/env.sh create mode 100755 scripts/is_checkout_dirty.sh create mode 100755 scripts/release.sh create mode 100755 scripts/tag_release.sh create mode 100755 scripts/test.sh delete mode 100755 test.sh create mode 100644 vendor/github.com/monax/relic/CHANGELOG.md create mode 100644 vendor/github.com/monax/relic/LICENSE create mode 100644 vendor/github.com/monax/relic/Makefile create mode 100644 vendor/github.com/monax/relic/NOTES.md create mode 100644 vendor/github.com/monax/relic/README.md create mode 100644 vendor/github.com/monax/relic/conversion.go create mode 100644 vendor/github.com/monax/relic/go.mod create mode 100644 vendor/github.com/monax/relic/go.sum create mode 100644 vendor/github.com/monax/relic/history.go create mode 100644 vendor/github.com/monax/relic/version.go diff --git a/.gitignore b/.gitignore index 395d0d4c..dacbfc34 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,5 @@ build/_workspace profile.out coverage.out + +commit_hash.txt diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 00000000..f25e14fc --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,65 @@ +# This is an example goreleaser.yaml file with some sane defaults. +# Make sure to check the documentation at http://goreleaser.com +builds: +- main: ./cmd/ft + ldflags: + - -s -w + - -X github.com/fractalplatform/fractal/utils.commit={{.Commit}} + - -X github.com/fractalplatform/fractal/utils.date={{.Date}} +archive: + replacements: + darwin: Darwin + 386: i386 + amd64: x86_64 +checksum: + name_template: 'checksums.txt' +snapshot: + name_template: "{{ .Tag }}-next" +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' + + - main: ./cmd/ftkey + ldflags: + - -s -w + - -X github.com/fractalplatform/fractal/utils.commit={{.Commit}} + - -X github.com/fractalplatform/fractal/utils.date={{.Date}} +archive: + replacements: + darwin: Darwin + 386: i386 + amd64: x86_64 +checksum: + name_template: 'checksums.txt' +snapshot: + name_template: "{{ .Tag }}-next" +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' + +- main: ./cmd/build_ftfinder + ldflags: + - -s -w + - -X github.com/fractalplatform/fractal/utils.commit={{.Commit}} + - -X github.com/fractalplatform/fractal/utils.date={{.Date}} +archive: + replacements: + darwin: Darwin + 386: i386 + amd64: x86_64 +checksum: + name_template: 'checksums.txt' +snapshot: + name_template: "{{ .Tag }}-next" +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' diff --git a/.travis.yml b/.travis.yml index f95b08e1..fe11d3a8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ language: go go: - - 1.9.2 + - 1.12 before_install: - go get golang.org/x/tools/cmd/cover diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..92f3e60a --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,10 @@ +# [fractal](https://github.com/fractalplatform/fractal) Changelog +## [0.0.5] - 2019-04-04 +### Added +- [README] add license badge +- [SCRIPTS] add is_checkout_dirty.sh release.sh tag_release.sh commit_hash.sh +### Fixed +- [MAKEFILE] add check fmt tag_release release command + + +[0.0.5]: https://github.com/fractalplatform/fractal/commits/v0.0.5 diff --git a/Makefile b/Makefile index fdafb932..b9d05665 100644 --- a/Makefile +++ b/Makefile @@ -14,31 +14,116 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +SHELL:=/bin/bash +REPO := $(shell pwd) +GOFILES_NOVENDOR := $(shell go list -f "{{.Dir}}" ./...) +PACKAGES_NOVENDOR := $(shell go list ./...) +WORK_SPACE := ${REPO}/build/_workspace +FT_DIR :=${WORK_SPACE}/src/github.com/fractalplatform -all: ft ftkey ftfinder +export GOPATH := ${WORK_SPACE} -ft: - @./build/env.sh \ - "go install ./cmd/ft" \ - "go build ./cmd/ft" \ - "mv ft ./build/bin" \ +define build + @cd ${FT_DIR}/fractal && go build -ldflags " \ + -X github.com/fractalplatform/fractal/cmd/utils.commit=$(shell cat commit_hash.txt) \ + -X github.com/fractalplatform/fractal/cmd/utils.date=$(shell date '+%Y-%m-%d') \ + -X 'github.com/fractalplatform/fractal/cmd/utils.goversion=$(shell go version)'" \ + -o ${FT_DIR}/fractal/build/bin/$(1) ./cmd/$(1) +endef -ftkey: - @./build/env.sh \ - "go install ./cmd/ftkey" \ - "go build ./cmd/ftkey" \ - "mv ftkey ./build/bin" -ftfinder: - @./build/env.sh \ - "go install ./cmd/ftfinder" \ - "go build ./cmd/ftfinder" \ - "mv ftfinder ./build/bin" +### Check and format code +# check the code for style standards; currently enforces go formatting. +# display output first, then check for success +.PHONY: check +check: + @echo "Checking code for formatting style compliance." + @gofmt -l -d ${GOFILES_NOVENDOR} + @gofmt -l ${GOFILES_NOVENDOR} | read && echo && echo "Your marmot has found a problem with the formatting style of the code." 1>&2 && exit 1 || true + +# fmt runs gofmt -w on the code, modifying any files that do not match +# the style guide. +.PHONY: fmt +fmt: + @echo "Correcting any formatting style corrections." + @gofmt -l -w ${GOFILES_NOVENDOR} + +### Building project + +# Output commit_hash but only if we have the git repo (e.g. not in docker build +.PHONY: commit_hash +commit_hash: + @git status &> /dev/null && scripts/commit_hash.sh > commit_hash.txt || true + +.PHONY: build_workspace +build_workspace: + @[ -d ${FT_DIR} ] || mkdir -p ${FT_DIR} + @[ -d ${FT_DIR}/fractal ] || ln -s ${REPO} ${FT_DIR} + +# build all targets +.PHONY: all +all:check build_workspace build_ft build_ftkey build_ftfinder + +# build ft +.PHONY: build_ft +build_ft: commit_hash check build_workspace + @echo "Building ft." + $(call build,ft) + +# build ftkey +.PHONY: build_ftkey +build_ftkey: commit_hash check build_workspace + @echo "Building ftkey." + $(call build,ftkey) + +# build ftfinder +.PHONY: build_ftfinder +build_ftfinder: commit_hash check build_workspace + @echo "Building ftfinder." + $(call build,ftfinder) + +### Test + +.PHONY: test +test: check build_workspace + @cd ${FT_DIR}/fractal && scripts/test.sh + + +### Clean up + +# clean removes the target folder containing build artefacts +.PHONY: clean clean: - rm -rf build/bin build/_workspace + -rm -rf ./build/bin ./build/_workspace + +### Release and versioning + +# Print version +.PHONY: version +version: + @go run ./cmd/project/main.go version + +# Generate full changelog of all release notes +CHANGELOG: + @go run ./cmd/project/main.go changelog > CHANGELOG.md + +# Generated release note for this version +NOTES: + @go run ./cmd/project/main.go notes > NOTES.md + +.PHONY: docs +docs: CHANGELOG NOTES + +# Tag the current HEAD commit with the current release defined in +.PHONY: tag_release +tag_release: test check docs all + @scripts/tag_release.sh + +.PHONY: release +release: test check docs all + @scripts/is_checkout_dirty.sh || (echo "checkout is dirty so not releasing!" && exit 1) + @scripts/release.sh + -test: - ./build/env.sh ./test.sh -.PHONY: all clean test ftfinder ft ftkey ftfinder diff --git a/NOTES.md b/NOTES.md new file mode 100644 index 00000000..f559efab --- /dev/null +++ b/NOTES.md @@ -0,0 +1,6 @@ +### Added +- [README] add license badge +- [SCRIPTS] add is_checkout_dirty.sh release.sh tag_release.sh commit_hash.sh +### Fixed +- [MAKEFILE] add check fmt tag_release release command + diff --git a/README.md b/README.md index c48a44db..4179360b 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![Build Status](https://travis-ci.org/fractalplatform/fractal.svg?branch=master)](https://travis-ci.org/fractalplatform/fractal) [![GoDoc](https://godoc.org/github.com/fractalplatform/fractal?status.svg)](https://godoc.org/github.com/fractalplatform/fractal) [![Coverage Status](https://coveralls.io/repos/github/fractalplatform/fractal/badge.svg?branch=master)](https://coveralls.io/github/fractalplatform/fractal?branch=master) +[![GitHub](https://img.shields.io/github/license/fractalplatform/fractal.svg)](LICENSE) Welcome to the Fractal source code repository! diff --git a/asset/asset_object_test.go b/asset/asset_object_test.go index 3e22108a..c801fcf9 100644 --- a/asset/asset_object_test.go +++ b/asset/asset_object_test.go @@ -154,8 +154,8 @@ func TestAssetObject_GetSymbol(t *testing.T) { fields fields want string }{ - // TODO: Add test cases. - // {"getexist",fields{}} + // TODO: Add test cases. + // {"getexist",fields{}} } for _, tt := range tests { ao := &AssetObject{ @@ -189,7 +189,7 @@ func TestAssetObject_SetSymbol(t *testing.T) { fields fields args args }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { ao := &AssetObject{ @@ -218,7 +218,7 @@ func TestAssetObject_GetDecimals(t *testing.T) { fields fields want uint64 }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { ao := &AssetObject{ @@ -252,7 +252,7 @@ func TestAssetObject_SetDecimals(t *testing.T) { fields fields args args }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { ao := &AssetObject{ @@ -281,7 +281,7 @@ func TestAssetObject_GetAssetName(t *testing.T) { fields fields want string }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { ao := &AssetObject{ @@ -315,7 +315,7 @@ func TestAssetObject_SetAssetName(t *testing.T) { fields fields args args }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { ao := &AssetObject{ @@ -344,7 +344,7 @@ func TestAssetObject_GetAssetAmount(t *testing.T) { fields fields want *big.Int }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { ao := &AssetObject{ @@ -378,7 +378,7 @@ func TestAssetObject_SetAssetAmount(t *testing.T) { fields fields args args }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { ao := &AssetObject{ @@ -407,7 +407,7 @@ func TestAssetObject_GetAssetOwner(t *testing.T) { fields fields want common.Name }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { ao := &AssetObject{ @@ -441,7 +441,7 @@ func TestAssetObject_SetAssetOwner(t *testing.T) { fields fields args args }{ - // TODO: Add test cases. + // TODO: Add test cases. } for _, tt := range tests { ao := &AssetObject{ diff --git a/build/env.sh b/build/env.sh deleted file mode 100755 index 98c75a85..00000000 --- a/build/env.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/sh - -set -e - -if [ ! -f "build/env.sh" ]; then - echo "$0 must be run from the root of the repository." - exit 2 -fi - -# Create fake Go workspace if it doesn't exist yet. -workspace="$PWD/build/_workspace" -root="$PWD" -ftdir="$workspace/src/github.com/fractalplatform" -bindir="$PWD/build/bin" -mkdir -p $bindir -if [ ! -L "$ftdir/fractal" ]; then - mkdir -p "$ftdir" - cd "$ftdir" - ln -s ../../../../../. fractal - cd "$root" -fi - -# Set up the environment to use the workspace. -GOPATH="$workspace" -export GOPATH - -# Run the command inside the workspace. -cd "$ftdir/fractal" -PWD="$ftdir/fractal" -# Launch the arguments with the configured environment. - -for arg in "$@" -do - echo $arg - $arg -done - diff --git a/cmd/ft/root.go b/cmd/ft/root.go index 90419916..dc1c3c59 100644 --- a/cmd/ft/root.go +++ b/cmd/ft/root.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/fractalplatform/fractal/blockchain" + "github.com/fractalplatform/fractal/cmd/utils" "github.com/fractalplatform/fractal/ftservice" "github.com/fractalplatform/fractal/metrics" "github.com/fractalplatform/fractal/metrics/influxdb" @@ -193,6 +194,7 @@ func initConfig() { } func init() { + RootCmd.AddCommand(utils.VersionCmd) cobra.OnInitialize(initConfig) falgs := RootCmd.Flags() // logging diff --git a/cmd/ft/version.go b/cmd/ft/version.go deleted file mode 100644 index 765d8567..00000000 --- a/cmd/ft/version.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2018 The Fractal Team Authors -// This file is part of the fractal project. -// -// This program 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. -// -// This program 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 this program. If not, see . - -package main - -import ( - "fmt" - "os" - "runtime" - "strings" - - "github.com/fractalplatform/fractal/params" - "github.com/spf13/cobra" -) - -// versionCmd represents the version command -var versionCmd = &cobra.Command{ - Use: "version", - Short: "Show ft current version", - Long: `Show ft current version`, - Run: func(cmd *cobra.Command, args []string) { - version() - }, -} - -func version() { - fmt.Println(strings.Title(params.ClientIdentifier)) - gitCommit := params.GitCommit() - if gitCommit != "" { - fmt.Println("Git Commit:", gitCommit) - fmt.Println("Version:", params.ArchiveVersion(gitCommit)) - } else { - fmt.Println("Version:", params.Version) - } - fmt.Println("Architecture:", runtime.GOARCH) - fmt.Println("Go Version:", runtime.Version()) - fmt.Println("Operating System:", runtime.GOOS) - fmt.Printf("GOPATH=%s\n", os.Getenv("GOPATH")) - fmt.Printf("GOROOT=%s\n", runtime.GOROOT()) -} - -func init() { - RootCmd.AddCommand(versionCmd) -} diff --git a/cmd/ftfinder/root.go b/cmd/ftfinder/root.go index 1948aa2f..eea47016 100644 --- a/cmd/ftfinder/root.go +++ b/cmd/ftfinder/root.go @@ -23,6 +23,7 @@ import ( "syscall" "github.com/ethereum/go-ethereum/log" + "github.com/fractalplatform/fractal/cmd/utils" "github.com/fractalplatform/fractal/node" "github.com/fractalplatform/fractal/p2p" "github.com/spf13/cobra" @@ -60,6 +61,7 @@ var RootCmd = &cobra.Command{ } func init() { + RootCmd.AddCommand(utils.VersionCmd) falgs := RootCmd.Flags() // p2p falgs.StringVarP(&nodeConfig.DataDir, "datadir", "d", nodeConfig.DataDir, "Data directory for the databases and keystore") diff --git a/cmd/ftkey/root.go b/cmd/ftkey/root.go index 21f2483e..e3522493 100644 --- a/cmd/ftkey/root.go +++ b/cmd/ftkey/root.go @@ -20,6 +20,7 @@ import ( "fmt" "os" + "github.com/fractalplatform/fractal/cmd/utils" "github.com/spf13/cobra" ) @@ -42,6 +43,7 @@ var RootCmd = &cobra.Command{ } func init() { + RootCmd.AddCommand(utils.VersionCmd) RootCmd.PersistentFlags().StringVar(&passphraseFlag, "passwordfile", "", "the file that contains the passphrase for the keyfile") RootCmd.PersistentFlags().BoolVar(&jsonFlag, "json", false, "output JSON instead of human-readable format") } diff --git a/params/gitcommit.go b/cmd/project/main.go similarity index 58% rename from params/gitcommit.go rename to cmd/project/main.go index a7c401d0..bf021599 100644 --- a/params/gitcommit.go +++ b/cmd/project/main.go @@ -14,29 +14,22 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -package params +package main import ( - "io/ioutil" - "path" - "strings" -) + "fmt" + "os" -// GitCommit Git SHA1 commit hash of the release (set via linker flags) -var GitCommit = func() string { - head := readGitFile("HEAD") - if splits := strings.Split(head, " "); len(splits) == 2 { - head = splits[1] - return readGitFile(head) - } - return "" -} + "github.com/fractalplatform/fractal/cmd/utils" +) -// readGitFile returns content of file in .git directory. -func readGitFile(file string) string { - content, err := ioutil.ReadFile(path.Join(".git", file)) - if err != nil { - return "" +func main() { + switch os.Args[1] { + case "changelog": + fmt.Println(utils.History.MustChangelog()) + case "notes": + fmt.Println(utils.History.CurrentNotes()) + case "version": + fmt.Println(utils.History.CurrentVersion().String()) } - return strings.TrimSpace(string(content)) } diff --git a/cmd/utils/history.go b/cmd/utils/history.go new file mode 100644 index 00000000..b6281bc3 --- /dev/null +++ b/cmd/utils/history.go @@ -0,0 +1,51 @@ +// Copyright 2018 The Fractal Team Authors +// This file is part of the fractal project. +// +// This program 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. +// +// This program 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 this program. If not, see . + +package utils + +import "github.com/monax/relic" + +// Use below as template for change notes, delete empty sections but keep order +/* +### Security + +### Changed + +### Fixed + +### Added + +### Removed + +### Deprecated +*/ + +// History the releases described by version string and changes, newest release first. +// The current release is taken to be the first release in the slice, and its +// version determines the single authoritative version for the next release. +// +// To cut a new release add a release to the front of this slice then run the +// release tagging script: ./scripts/tag_release.sh +var History relic.ImmutableHistory = relic.NewHistory("fractal", "https://github.com/fractalplatform/fractal"). + MustDeclareReleases( + "0.0.5 - 2019-04-04", + `### Added +- [README] add license badge +- [SCRIPTS] add is_checkout_dirty.sh release.sh tag_release.sh commit_hash.sh +### Fixed +- [MAKEFILE] add check fmt tag_release release command +`, + ) diff --git a/cmd/utils/version.go b/cmd/utils/version.go new file mode 100644 index 00000000..1acc6b04 --- /dev/null +++ b/cmd/utils/version.go @@ -0,0 +1,65 @@ +// Copyright 2019 LiuBan Industries Limited +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package utils + +import ( + "fmt" + "os" + "runtime" + + "github.com/spf13/cobra" +) + +var ( + commit = "" + date = "" + goversion = "" +) + +// VersionCmd represents the version command +var VersionCmd = &cobra.Command{ + Use: "version", + Short: "Show current version", + Long: `Show current version`, + Run: func(cmd *cobra.Command, args []string) { + version() + }, +} + +func version() { + if commit != "" { + fmt.Println("Git Commit:", commit) + } + fmt.Println("Version:", fullVersion()) + fmt.Println("Architecture:", runtime.GOARCH) + if goversion != "" { + fmt.Println("Go Version:", goversion) + } + fmt.Println("Operating System:", runtime.GOOS) + fmt.Printf("GOPATH=%s\n", os.Getenv("GOPATH")) + fmt.Printf("GOROOT=%s\n", runtime.GOROOT()) +} + +// fullVersion returns the version. +func fullVersion() string { + version := History.CurrentVersion().String() + if commit != "" { + version += "+commit." + commit + } + if date != "" { + version += "+" + date + } + return version +} diff --git a/consensus/dpos/database_test.go b/consensus/dpos/database_test.go index add64bf8..9865408c 100644 --- a/consensus/dpos/database_test.go +++ b/consensus/dpos/database_test.go @@ -30,7 +30,7 @@ import ( func TestDatabase(t *testing.T) { // gstate gstate := &globalState{ - Height: 10, + Height: 10, ActivatedProducerScheduleUpdate: uint64(time.Now().UnixNano()), ActivatedProducerSchedule: []string{}, ActivatedTotalQuantity: big.NewInt(1000), diff --git a/consensus/dpos/vote.go b/consensus/dpos/vote.go index 9b6481d2..eac7a4fd 100644 --- a/consensus/dpos/vote.go +++ b/consensus/dpos/vote.go @@ -369,7 +369,7 @@ func (sys *System) onblock(height uint64) error { return err } ngstate := &globalState{ - Height: height + 1, + Height: height + 1, ActivatedProducerSchedule: gstate.ActivatedProducerSchedule, ActivatedProducerScheduleUpdate: gstate.ActivatedProducerScheduleUpdate, ActivatedTotalQuantity: gstate.ActivatedTotalQuantity, diff --git a/p2p/g.sh b/p2p/g.sh deleted file mode 120000 index 78d95106..00000000 --- a/p2p/g.sh +++ /dev/null @@ -1 +0,0 @@ -/tmp/g.sh \ No newline at end of file diff --git a/params/unit.go b/params/unit.go index a3f18855..75037087 100644 --- a/params/unit.go +++ b/params/unit.go @@ -19,3 +19,8 @@ package params const ( Fractal = 1e18 ) + +const ( + //ClientIdentifier Client identifier to advertise over the network + ClientIdentifier = "ft" +) diff --git a/params/version.go b/params/version.go deleted file mode 100644 index 9cea3c12..00000000 --- a/params/version.go +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2018 The Fractal Team Authors -// This file is part of the fractal project. -// -// This program 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. -// -// This program 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 this program. If not, see . - -package params - -import "fmt" - -const ( - //ClientIdentifier Client identifier to advertise over the network - ClientIdentifier = "ft" -) - -const ( - // VersionMajor is Major version component of the current release - VersionMajor = 0 - // VersionMinor is Minor version component of the current release - VersionMinor = 0 - // VersionPatch is Patch version component of the current release - VersionPatch = 5 - // VersionMeta is Version metadata to append to the version string - VersionMeta = "unstable" -) - -// Version holds the textual version string. -var Version = func() string { - return fmt.Sprintf("%d.%d.%d", VersionMajor, VersionMinor, VersionPatch) -}() - -// ArchiveVersion holds the textual version string used for Geth archives. -func ArchiveVersion(gitCommit string) string { - vsn := Version - if VersionMeta != "stable" { - vsn += "-" + VersionMeta - } - if len(gitCommit) >= 8 { - vsn += "-" + gitCommit[:8] - } - return vsn -} diff --git a/scripts/commit_hash.sh b/scripts/commit_hash.sh new file mode 100755 index 00000000..dd3511dd --- /dev/null +++ b/scripts/commit_hash.sh @@ -0,0 +1,26 @@ +# Copyright 2018 The Fractal Team Authors +# This file is part of the fractal project. +# +# This program 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. +# +# This program 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 this program. If not, see . + +#!/usr/bin/env bash + +# Gets the git commit hash of the working dir and adds an additional hash of any tracked modified files +commit=$(git describe --tags) +dirty=$(git ls-files -m) +if [[ -n ${dirty} ]]; then + commit="$commit+dirty.$(echo ${dirty} | git hash-object --stdin | head -c8)" +fi +echo "$commit" + diff --git a/scripts/env.sh b/scripts/env.sh new file mode 100755 index 00000000..08826e56 --- /dev/null +++ b/scripts/env.sh @@ -0,0 +1,52 @@ +# Copyright 2018 The Fractal Team Authors +# This file is part of the fractal project. +# +# This program 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. +# +# This program 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 this program. If not, see . + + +#!/bin/sh + +set -e + +if [ ! -f "scripts/env.sh" ]; then + echo "$0 must be run from the root of the repository." + exit 2 +fi + +# Create fake Go workspace if it doesn't exist yet. +workspace="$PWD/build/_workspace" +root="$PWD" +ftdir="$workspace/src/github.com/fractalplatform" +bindir="$PWD/build/bin" +mkdir -p $bindir +if [ ! -L "$ftdir/fractal" ]; then + mkdir -p "$ftdir" + cd "$ftdir" + ln -s ../../../../../. fractal + cd "$root" +fi + +# Set up the environment to use the workspace. +GOPATH="$workspace" +export GOPATH + +pwd + +# Launch the arguments with the configured environment. +for arg in $@ +do + echo $arg + $arg +done + diff --git a/scripts/is_checkout_dirty.sh b/scripts/is_checkout_dirty.sh new file mode 100755 index 00000000..17ccd1d4 --- /dev/null +++ b/scripts/is_checkout_dirty.sh @@ -0,0 +1,22 @@ +# Copyright 2018 The Fractal Team Authors +# This file is part of the fractal project. +# +# This program 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. +# +# This program 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 this program. If not, see . + +#!/usr/bin/env bash +# Gives us a non-zero exit code if there are tracked or untracked changes in the working +# directory +export stat=$(git status --porcelain) +[[ -z "$stat" ]] || (echo "Dirty checkout:" && echo "$stat" && exit 1) + diff --git a/scripts/release.sh b/scripts/release.sh new file mode 100755 index 00000000..3b16e001 --- /dev/null +++ b/scripts/release.sh @@ -0,0 +1,50 @@ +# Copyright 2018 The Fractal Team Authors +# This file is part of the fractal project. +# +# This program 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. +# +# This program 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 this program. If not, see . + +#!/usr/bin/env bash + +version_regex="^v[0-9]+\.[0-9]+\.[0-9]+$" + +set -e + +function release { + notes="NOTES.md" + echo "Building and releasing $tag..." + echo "Building and pushing binaries" + [[ -e "$notes" ]] && goreleaser --release-notes "$notes" || goreleaser +} + +# If passed argument try to use that as tag otherwise read from local repo +if [[ $1 ]]; then + # Override mode, try to release this tag + export tag=$1 +else + echo "Getting tag from HEAD which is $(git rev-parse HEAD)" + export tag=$(git tag --points-at HEAD) +fi + +if [[ ! ${tag} ]]; then + echo "No tag so not releasing." + exit 0 +fi + +# Only release semantic version syntax tags +if [[ ! ${tag} =~ ${version_regex} ]] ; then + echo "Tag '$tag' does not match version regex '$version_regex' so not releasing." + exit 0 +fi + +release diff --git a/scripts/tag_release.sh b/scripts/tag_release.sh new file mode 100755 index 00000000..7ed2821f --- /dev/null +++ b/scripts/tag_release.sh @@ -0,0 +1,56 @@ +# Copyright 2018 The Fractal Team Authors +# This file is part of the fractal project. +# +# This program 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. +# +# This program 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 this program. If not, see . + +#!/usr/bin/env bash + +set -e + +# Wait a second so we don't see ephemeral file changes +sleep 1 + +# Don't tag if there is a dirty working dir +if ! git diff-index --quiet HEAD ; then + echo "Warning there appears to be uncommitted changes in the working directory:" + git diff-index HEAD + echo + echo "Please commit them or stash them before tagging a release." + echo +fi + +version=v$(go run ./cmd/project/main.go version ) +notes=$(go run ./cmd/project/main.go notes) + +echo "This command will tag the current commit $(git rev-parse --short HEAD) as version $version" +echo +echo "$notes" | sed 's/^/> /' +echo +echo "It will then push the version tag to origin." +echo +read -p "Do you want to continue? [Y\n]: " -r +# Just hitting return defaults to continuing +[[ $REPLY ]] && [[ ! $REPLY =~ ^[Yy]$ ]] && echo && exit 0 +echo + + +# Create tag +echo "Tagging version $version with message:" +echo "" +echo "$notes" +echo "" +echo "$notes" | git tag -a ${version} -F- + +# Push tag +git push origin ${version} \ No newline at end of file diff --git a/scripts/test.sh b/scripts/test.sh new file mode 100755 index 00000000..7a030f6a --- /dev/null +++ b/scripts/test.sh @@ -0,0 +1,30 @@ +# Copyright 2018 The Fractal Team Authors +# This file is part of the fractal project. +# +# This program 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. +# +# This program 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 this program. If not, see . + +#!/usr/bin/env bash + +set -e +echo "mode: count" >coverage.out + +for d in $(go list ./... | grep -v vendor | grep -v test); do + echo testing $d ... + go test -coverprofile=profile.out -covermode=count $d + if [ -f profile.out ]; then + cat profile.out | grep -v "mode: count" | cat >> coverage.out + rm profile.out + fi +done + diff --git a/test.sh b/test.sh deleted file mode 100755 index bc9ca458..00000000 --- a/test.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -set -e -echo "mode: count" >coverage.out - -for d in $(go list ./... | grep -v vendor | grep -v test); do - echo testing $d ... - go test -coverprofile=profile.out -covermode=count $d - if [ -f profile.out ]; then - cat profile.out | grep -v "mode: count" | cat >> coverage.out - rm profile.out - fi -done diff --git a/vendor/github.com/monax/relic/CHANGELOG.md b/vendor/github.com/monax/relic/CHANGELOG.md new file mode 100644 index 00000000..f0c90f93 --- /dev/null +++ b/vendor/github.com/monax/relic/CHANGELOG.md @@ -0,0 +1,49 @@ +# [Relic](https://github.com/monax/relic) Changelog +## [Unreleased] + + +## [2.1.0] - 2019-03-25 +### Changed +- Make into Go module at version 2 + + +## [2.0.0] - 2018-08-15 +### Changed +- Versions must start from 0.0.1 (0.0.0 is reserved for unreleased) +- Default changelog format follows https://keepachangelog.com/en/1.0.0/ +- NewHistory takes second parameter for project URL +- Dropped getters from Version since already passed by value so immutable + +### Added +- Optional top (most recent) release may be provided with empty Version with (via empty string in DeclareReleases) whereby its notes will be listed under 'Unreleased' +- Optional date can be appended to version using the exact format e.g. '5.4.2 - 2018-08-14' +- Default changelog format footnote references standard github compare links to see commits between version tags + + +## [1.1.0] +Add ImmutableHistory and tweak suggested usage docs + +## [1.0.1] +Documentation fixes and typos + +## [1.0.0] +Minor improvements: +- Rename DeclareReleases to DeclareReleases (breaking API change) +- Add sample snippet to readme +- Sign version tags + + +## [0.0.1] +First release of Relic extracted from various initial projects, it can: +- Generate changelogs +- Print the current version +- Ensure valid semantic version numbers + + +[Unreleased]: https://github.com/monax/relic/compare/v2.1.0...HEAD +[2.1.0]: https://github.com/monax/relic/compare/v2.0.0...v2.1.0 +[2.0.0]: https://github.com/monax/relic/compare/v1.1.0...v2.0.0 +[1.1.0]: https://github.com/monax/relic/compare/v1.0.1...v1.1.0 +[1.0.1]: https://github.com/monax/relic/compare/v1.0.0...v1.0.1 +[1.0.0]: https://github.com/monax/relic/compare/v0.0.1...v1.0.0 +[0.0.1]: https://github.com/monax/relic/commits/v0.0.1 diff --git a/vendor/github.com/monax/relic/LICENSE b/vendor/github.com/monax/relic/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/vendor/github.com/monax/relic/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/monax/relic/Makefile b/vendor/github.com/monax/relic/Makefile new file mode 100644 index 00000000..3d676e79 --- /dev/null +++ b/vendor/github.com/monax/relic/Makefile @@ -0,0 +1,44 @@ +SHELL := /bin/bash +GO_FILES := $(shell go list -f "{{.Dir}}" ./...) + +### Formatting, linting and vetting +# Run goimports (also checks formatting) first display output first, then check for success +.PHONY: check +check: + @go get golang.org/x/tools/cmd/goimports + @goimports -l -d ${GO_FILES} + @goimports -l ${GO_FILES} | read && echo && \ + echo "Your marmot has found a problem with the formatting style of the code."\ + 1>&2 && exit 1 || true + @go mod tidy + +# Just fix it +.PHONY: fix +fix: + @goimports -l -w ${GO_FILES} + +# test burrow +.PHONY: test +test: check docs + @go test ./... + +### Release and versioning +.PHONY: version +version: + @go run ./project/cmd/version/main.go + +# Generate full changelog of all release notes +CHANGELOG.md: ./project/releases.go history.go + @go run ./project/cmd/changelog/main.go > CHANGELOG.md + +# Generated release notes for this version +NOTES.md: ./project/releases.go history.go + @go run ./project/cmd/notes/main.go > NOTES.md + +.PHONY: docs +docs: CHANGELOG.md NOTES.md + +# Tag a release a push it +.PHONY: tag_release +tag_release: test check docs + @scripts/tag_release.sh diff --git a/vendor/github.com/monax/relic/NOTES.md b/vendor/github.com/monax/relic/NOTES.md new file mode 100644 index 00000000..89b6a737 --- /dev/null +++ b/vendor/github.com/monax/relic/NOTES.md @@ -0,0 +1,3 @@ +### Changed +- Make into Go module at version 2 + diff --git a/vendor/github.com/monax/relic/README.md b/vendor/github.com/monax/relic/README.md new file mode 100644 index 00000000..1281f519 --- /dev/null +++ b/vendor/github.com/monax/relic/README.md @@ -0,0 +1,99 @@ +# Relic +Relic is a library to help with versioning your projects by storing release metadata +and versions as code. + +## Purpose +Relic allows you define your project version history in a declarative style by +defining a `History` object somewhere in your project whose methods allow you to +declare releases defined by a version number and release note. It ensures your releases +have monotonically increasing unique versions. + +Relic can generate the current version and a complete [changelog](CHANGELOG.md) using this information. + +Relic can be used by CI systems to output version numbers for tagging artefacts and automatically pushing releases, +such as [goreleaser](https://github.com/goreleaser/goreleaser). + +By keeping the changelog with the version they are synchronised and you are reminded to produce +the changelog. + +![relic marmot](docs/images/relic.png) + +## Usage +```go +// Add file to your project in which to record your projects revision history +package project + +import ( + "fmt" + "text/template" + "github.com/monax/relic" +) + +// Create a global variable in which to store your project history. +// MustDeclareReleases allows you to declare your releases by specifying a version and release note +// for each release. To add a new release just insert it at the top. +var History relic.ImmutableHistory = relic.NewHistory("Relic", "https://github.com/monax/relic"). + MustDeclareReleases( + "2.0.0 - 2018-08-15", + `### Changed +- Versions must start from 0.0.1 (0.0.0 is reserved for unreleased) +- Default changelog format follows https://keepachangelog.com/en/1.0.0/ +- NewHistory takes second parameter for project URL +- Dropped getters from Version since already passed by value so immutable + +### Added +- Optional top (most recent) release may be provided with empty Version with (via empty string in DeclareReleases) whereby its notes will be listed under 'Unreleased' +- Optional date can be appended to version using the exact format e.g. '5.4.2 - 2018-08-14' +- Default changelog format footnote references standard github compare links to see commits between version tags +`, + "1.1.0", + `Add ImmutableHistory and tweak suggested usage docs`, + "1.0.1", + `Documentation fixes and typos`, + "1.0.0", + `Minor improvements: +- Rename DeclareReleases to DeclareReleases (breaking API change) +- Add sample snippet to readme +- Sign version tags +`, + "0.0.1", + `First release of Relic extracted from various initial projects, it can: +- Generate changelogs +- Print the current version +- Ensure valid semantic version numbers +`) + +func PrintReleaseInfo() { + // Print the current version + fmt.Printf("%s (Version: %v)\n", History.Project(), History.CurrentVersion().String()) + // Print the complete changelog + fmt.Println(History.Changelog()) + // Get specific release + release, err := History.Release("0.0.1") + if err != nil { + panic(err) + } + // Print major version of release + fmt.Printf("Release Major version: %v", release.Version.Major) +} + +// You can also define histories with a custom template +var ProjectWithTemplate = relic.NewHistory("Test Project", "https://github.com/test/project"). + WithChangelogTemplate(template.Must(template.New("tests"). + Parse("{{range .Releases}}{{$.Name}} (v{{.Version}}): {{.Notes}}\n{{end}}"))). + MustDeclareReleases( + // Releases may optionally have a date which is included in the changelog + "0.1.0 - 2016-07-12", + "Basic functionality", + "0.0.2", + "Build scripts", + "0.0.1", + "Proof of concept", + ) + +``` + +See Relic's own [`project` package](project/releases.go) and [Makefile](Makefile) for suggested usage within a project. + +## Dependencies +Go standard library and tooling plus Make and Bash for builds (but not required). diff --git a/vendor/github.com/monax/relic/conversion.go b/vendor/github.com/monax/relic/conversion.go new file mode 100644 index 00000000..f26c0282 --- /dev/null +++ b/vendor/github.com/monax/relic/conversion.go @@ -0,0 +1,48 @@ +package relic + +import ( + "fmt" + "time" +) + +var DefaultDateLayout = "2006-01-02" + +func AsString(stringLike interface{}) (string, error) { + switch s := stringLike.(type) { + case string: + return s, nil + case fmt.Stringer: + return s.String(), nil + default: + return "", fmt.Errorf("unsupported type for string: %t, must string or fmt.Stringer", s) + } +} + +func AsDate(dateLike interface{}) (time.Time, error) { + switch d := dateLike.(type) { + case time.Time: + return d, nil + default: + s, err := AsString(d) + if err != nil { + return time.Time{}, err + } + return time.Parse(DefaultDateLayout, s) + } +} +func AsVersion(versionLike interface{}) (Version, error) { + switch v := versionLike.(type) { + case Version: + return v, nil + default: + s, err := AsString(v) + if err != nil { + return Version{}, err + } + if s == "" { + // for unreleased notes + return Version{}, nil + } + return ParseDatedVersion(s) + } +} diff --git a/vendor/github.com/monax/relic/go.mod b/vendor/github.com/monax/relic/go.mod new file mode 100644 index 00000000..7b06db7d --- /dev/null +++ b/vendor/github.com/monax/relic/go.mod @@ -0,0 +1,5 @@ +module github.com/monax/relic/v2 + +go 1.12 + +require github.com/stretchr/testify v1.3.0 diff --git a/vendor/github.com/monax/relic/go.sum b/vendor/github.com/monax/relic/go.sum new file mode 100644 index 00000000..4347755a --- /dev/null +++ b/vendor/github.com/monax/relic/go.sum @@ -0,0 +1,7 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= diff --git a/vendor/github.com/monax/relic/history.go b/vendor/github.com/monax/relic/history.go new file mode 100644 index 00000000..c7dffd74 --- /dev/null +++ b/vendor/github.com/monax/relic/history.go @@ -0,0 +1,271 @@ +package relic + +import ( + "bytes" + "fmt" + "text/template" +) + +// Provides the read-only methods of History to ensure releases are not accidentally mutated when it is not intended +type ImmutableHistory interface { + // Get latest version + CurrentVersion() Version + // Get latest release note + CurrentNotes() string + // Get the project name + Project() string + // Get complete changelog + Changelog() (string, error) + // Get complete changelog or panic if error + MustChangelog() string + // Find the release specified by Version struct or version string + Release(versionLike interface{}) (Release, error) +} + +// The purpose of History is to capture version changes and change logs +// in a single location and use that data to generate releases and print +// changes to the command line to automate releases and provide a single +// source of truth for improved certainty around versions and releases +type History struct { + ProjectName string + ProjectURL string + Releases []Release + ChangelogTemplate *template.Template +} + +var _ ImmutableHistory = &History{} + +type Release struct { + Version Version + Notes string +} + +type ReleasePair struct { + Release + Previous Release +} + +var DefaultChangelogTemplate = template.Must(template.New("default_changelog_template"). + Parse(`# [{{ .Project }}]({{ .ProjectURL }}) Changelog{{ range .Releases }} +## [{{ .Version }}]{{ if .Version.Dated }} - {{ .Version.FormatDate }}{{ end }} +{{ .Notes }} +{{ end }} +{{ range .ReleasePairs }}[{{ .Version }}]: {{ $.URL }}/compare/{{ .Previous.Version.Ref }}...{{ .Version.Ref }} +{{ end }}[{{ .FirstRelease.Version }}]: {{ $.URL }}/commits/{{ .FirstRelease.Version.Ref }}`)) + +// Define a new project history to which releases can be added in code +// e.g. var history = relic.NewHistory().MustDeclareReleases(...) +func NewHistory(projectName, projectURL string) *History { + return &History{ + ProjectName: projectName, + ProjectURL: projectURL, + ChangelogTemplate: DefaultChangelogTemplate, + } +} + +// Change the default changelog template from DefaultChangelogTemplate +func (h *History) WithChangelogTemplate(tmpl *template.Template) *History { + h.ChangelogTemplate = tmpl + return h +} + +// Adds releases to the History with the newest releases provided first (so latest is at top). +// Releases can be specified by pairs of version (string or struct), notes (string) or by sequence of Release (struct) +// or mixtures thereof. +func (h *History) DeclareReleases(releaseLikes ...interface{}) (*History, error) { + var rs []Release + var err error + for len(releaseLikes) > 0 { + r, ok := releaseLikes[0].(Release) + if ok { + releaseLikes = releaseLikes[1:] + } else { + r, releaseLikes, err = readRelease(releaseLikes) + if err != nil { + return nil, err + } + } + rs = append(rs, r) + } + // Check we still have a valid sequence of releases + rs = append(rs, h.Releases...) + err = ValidateReleases(rs) + if err != nil { + return h, err + } + + h.Releases = rs + return h, err +} + +func readRelease(releaseLikes []interface{}) (rel Release, tail []interface{}, err error) { + const fields = 2 + if len(releaseLikes) < fields { + return rel, releaseLikes, fmt.Errorf("readRelease expects exactly 3 elements of version, date, notes") + } + rel.Version, err = AsVersion(releaseLikes[0]) + if err != nil { + return rel, releaseLikes, err + } + rel.Notes, err = AsString(releaseLikes[1]) + if err != nil { + return rel, releaseLikes, err + } + return rel, releaseLikes[fields:], nil +} + +// Like DeclareReleases but will panic if the Releases list becomes invalid +func (h *History) MustDeclareReleases(releaseLikes ...interface{}) *History { + h, err := h.DeclareReleases(releaseLikes...) + if err != nil { + panic(fmt.Errorf("could not register releases: %v", err)) + } + return h +} + +func (h *History) CurrentRelease() Release { + for _, r := range h.Releases { + if r.Version != ZeroVersion { + return r + } + } + return Release{} +} + +func (h *History) FirstRelease() Release { + l := len(h.Releases) + if l == 0 { + return Release{} + } + return h.Releases[l-1] +} + +func (h *History) CurrentVersion() Version { + return h.CurrentRelease().Version +} + +// Gets the release notes for the current version +func (h *History) CurrentNotes() string { + return h.CurrentRelease().Notes +} + +func (h *History) Project() string { + return h.ProjectName +} + +func (h *History) URL() string { + return h.ProjectURL +} + +func (h *History) ReleasePairs() []ReleasePair { + pairs := make([]ReleasePair, len(h.Releases)-1) + for i := 0; i < len(pairs); i++ { + pairs[i] = ReleasePair{ + Release: h.Releases[i], + Previous: h.Releases[i+1], + } + } + return pairs +} + +// Gets the Release for version given in versionString +func (h *History) Release(versionLike interface{}) (Release, error) { + version, err := AsVersion(versionLike) + if err != nil { + return Release{}, err + } + for _, r := range h.Releases { + if r.Version == version { + return r, nil + } + } + return Release{}, fmt.Errorf("could not find release with version %v", version) +} + +// Get the changelog for the complete history +func (h *History) Changelog() (string, error) { + buf := new(bytes.Buffer) + err := h.ChangelogTemplate.Execute(buf, h) + if err != nil { + return "", err + } + return buf.String(), nil +} + +// Generates changelog, panicking if there is an error +func (h *History) MustChangelog() string { + changelog, err := h.Changelog() + if err != nil { + panic(err) + } + return changelog +} + +// Checks that a sequence of releases are monotonically decreasing with each +// version being a simple major, minor, or patch bump of its successor in the +// slice +func ValidateReleases(rs []Release) error { + if len(rs) == 0 { + return fmt.Errorf("at least one release must be defined") + } + // Allow the first version to be zero indicating unreleased as an place to document features + if rs[0].Version == ZeroVersion { + rs = rs[1:] + } + return EnsureReleasesUniqueValidAndMonotonic(rs) +} + +func EnsureReleasesUniqueValidAndMonotonic(rs []Release) error { + if len(rs) == 0 { + return nil + } + version := rs[0].Version + if version == ZeroVersion { + return fmt.Errorf("only the top release may have an empty version to indicate unreleased, all" + + "additional (earlier) releases must have a non-zero version") + } + for i := 1; i < len(rs); i++ { + // The numbers of the lower version (expect descending sort) + previousVersion := rs[i].Version + if previousVersion == ZeroVersion { + return fmt.Errorf("%v has version 0.0.0 but versions must start from 0.0.1", previousVersion) + } + // Check versions are consecutive + if version.Major == previousVersion.Major+1 { + // Major bump, so minor and patch versions must be reset + if version.Minor != 0 || version.Patch != 0 { + return fmt.Errorf("minor and patch versions must be reset to "+ + "0 after a major bump, but they are not in %s -> %s", + rs[i].Version, rs[i-1].Version) + } + } else if version.Major == previousVersion.Major { + // Same major number + if version.Minor == previousVersion.Minor+1 { + // Minor bump so patch version must be reset + if version.Patch != 0 { + return fmt.Errorf("patch version must be reset to "+ + "0 after a minor bump, but they are not in %s -> %s", + rs[i].Version, rs[i-1].Version) + } + } else if version.Minor == previousVersion.Minor { + // Same minor number so must be patch bump to be valid + if version.Patch != previousVersion.Patch+1 { + return fmt.Errorf("consecutive patch versions must be equal "+ + "or incremented by 1, but they are not in %s -> %s", + rs[i].Version, rs[i-1].Version) + } + } else { + return fmt.Errorf("consecutive minor versions must be equal or "+ + "incremented by 1, but they are not in %s -> %s", + rs[i].Version, rs[i-1].Version) + } + } else { + return fmt.Errorf("consecutive major versions must be equal or "+ + "incremented by 1, but they are not in %s -> %s", + rs[i].Version, rs[i-1].Version) + } + + version = previousVersion + } + return nil +} diff --git a/vendor/github.com/monax/relic/version.go b/vendor/github.com/monax/relic/version.go new file mode 100644 index 00000000..76bb003d --- /dev/null +++ b/vendor/github.com/monax/relic/version.go @@ -0,0 +1,97 @@ +package relic + +import ( + "fmt" + "strconv" + "strings" + "time" +) + +const ( + VersionDateSeparator = " - " + // Base of minor, major, and patch version numbers + NumberBase = 10 + // Number of bits to represent version numbers + UintBits = 8 +) + +var ZeroVersion = Version{} + +type Version struct { + Major uint8 + Minor uint8 + Patch uint8 + Date time.Time +} + +func (v Version) String() string { + if v == ZeroVersion { + return "Unreleased" + } + return v.Semver() +} + +func (v Version) Semver() string { + return fmt.Sprintf("%v.%v.%v", v.Major, v.Minor, v.Patch) +} + +func (v Version) Ref() string { + if v == ZeroVersion { + return "HEAD" + } + return fmt.Sprintf("v%s", v.Semver()) +} + +func (v Version) Dated() bool { + return v.Date != time.Time{} +} + +func (v Version) FormatDate() string { + return v.Date.Format(DefaultDateLayout) +} + +func ParseDatedVersion(versionString string) (Version, error) { + parts := strings.Split(versionString, VersionDateSeparator) + switch len(parts) { + case 1: + return ParseVersion(versionString) + case 2: + v, err := ParseVersion(parts[0]) + if err != nil { + return Version{}, err + } + v.Date, err = AsDate(parts[1]) + if err != nil { + return Version{}, err + } + return v, nil + default: + return Version{}, fmt.Errorf("could interpret %v as date version, should be be of the form '2.3.4 - 2018-08-14'", + versionString) + } +} + +func ParseVersion(versionString string) (Version, error) { + parts := strings.Split(versionString, ".") + if len(parts) != 3 { + return Version{}, + fmt.Errorf("version string must have three '.' separated parts but '%s' does not", versionString) + } + maj, err := strconv.ParseUint(parts[0], NumberBase, UintBits) + if err != nil { + return Version{}, err + } + min, err := strconv.ParseUint(parts[1], NumberBase, UintBits) + if err != nil { + return Version{}, err + } + pat, err := strconv.ParseUint(parts[2], NumberBase, UintBits) + if err != nil { + return Version{}, err + } + return Version{ + Major: uint8(maj), + Minor: uint8(min), + Patch: uint8(pat), + }, err +} diff --git a/vendor/vendor.json b/vendor/vendor.json index fc09eced..435ddc48 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -242,6 +242,12 @@ "revision": "3536a929edddb9a5b34bd6861dc4a9647cb459fe", "revisionTime": "2018-10-05T04:51:35Z" }, + { + "checksumSHA1": "HdErR3OssPwsqWIH8culQoxfUbc=", + "path": "github.com/monax/relic", + "revision": "d583255174bbccaecbbfa58ecbdd3a4f319a0fcc", + "revisionTime": "2019-03-25T19:38:13Z" + }, { "checksumSHA1": "A6nZdZ1/lTOVINhIndyw2ZWN9JU=", "path": "github.com/naoina/go-stringutil",