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 @@
[](https://travis-ci.org/fractalplatform/fractal)
[](https://godoc.org/github.com/fractalplatform/fractal)
[](https://coveralls.io/github/fractalplatform/fractal?branch=master)
+[](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.
+
+
+
+## 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",