Add lookup command (#4)

Co-authored-by: James Mills <prologic@shortcircuit.net.au>
Reviewed-on: https://git.mills.io/prologic/salty-chat/pulls/4
This commit is contained in:
James Mills 2022-03-18 14:48:59 +00:00
parent 84d0d51231
commit 7e6c4b2dc7
14 changed files with 600 additions and 9 deletions

3
.gitignore vendored
View File

@ -3,3 +3,6 @@
**/.DS_Store
*.key
/salty-chat
/cmd/salty-chat/salty-chat

27
LICENSE
View File

@ -1,13 +1,22 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2017 James Mills
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
salty-chat is covered by the MIT license::
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
0. You just DO WHAT THE FUCK YOU WANT TO.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

72
Makefile Normal file
View File

@ -0,0 +1,72 @@
-include environ.inc
.PHONY: deps dev build install image release test clean
export CGO_ENABLED=0
VERSION=$(shell git describe --abbrev=0 --tags 2>/dev/null || echo "$VERSION")
COMMIT=$(shell git rev-parse --short HEAD || echo "$COMMIT")
BRANCH=$(shell git rev-parse --abbrev-ref HEAD)
GOCMD=go
GOVER=$(shell go version | grep -o -E 'go1\.17\.[0-9]+')
DESTDIR=/usr/local/bin
ifeq ($(BRANCH), main)
IMAGE := prologic/salty-chat
TAG := latest
else
IMAGE := prologic/salty-chat
TAG := dev
endif
all: preflight build
preflight:
@./preflight.sh
deps:
dev : DEBUG=1
dev : build
@./salty-chat -v
cli:
@$(GOCMD) build -tags "netgo static_build" -installsuffix netgo \
-ldflags "-w \
-X $(shell go list).Version=$(VERSION) \
-X $(shell go list).Commit=$(COMMIT)" \
./cmd/salty-chat/
build: cli
generate:
@if [ x"$(DEBUG)" = x"1" ]; then \
echo 'Running in debug mode...'; \
fi
install: build
@install -D -m 755 salty-chat $(DESTDIR)/salty-chat
ifeq ($(PUBLISH), 1)
image: generate
@docker build --build-arg VERSION="$(VERSION)" --build-arg COMMIT="$(COMMIT)" -t $(IMAGE):$(TAG) .
@docker push $(IMAGE):$(TAG)
else
image: generate
@docker build --build-arg VERSION="$(VERSION)" --build-arg COMMIT="$(COMMIT)" -t $(IMAGE):$(TAG) .
endif
release: generate
@./tools/release.sh
fmt:
@$(GOCMD) fmt ./...
test:
@CGO_ENABLED=1 $(GOCMD) test -v -cover -race ./...
coverage:
@CGO_ENABLED=1 $(GOCMD) test -v -cover -race -cover -coverprofile=coverage.out ./...
@$(GOCMD) tool cover -html=coverage.out
clean:
@git clean -f -d -X

52
cmd/salty-chat/lookup.go Normal file
View File

@ -0,0 +1,52 @@
package main
import (
"encoding/json"
"fmt"
"os"
"strings"
"github.com/spf13/cobra"
"go.mills.io/saltyim"
)
var lookupCmd = &cobra.Command{
Use: "lookup <user>",
Short: "Lookup a user's config",
Long: `This command attempts to lookup the user's Salty Config by using
the Salty IM Discovery process by making a request to the user's Well-Known URI
The User is expected to have a Configuration file located at a Well-Known URI
of /.well-known/salty/<user>.json
For example:
https://mills.io/.well-known/salty/prologic.json`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
user := args[0]
lookup(user)
},
}
func init() {
rootCmd.AddCommand(lookupCmd)
}
func lookup(user string) {
user = strings.TrimSpace(user)
if user == "" {
fmt.Fprintf(os.Stderr, "error: no user supplied")
os.Exit(2)
}
config, err := saltyim.Lookup(user)
if err != nil {
fmt.Fprintf(os.Stderr, "error: failed to lookup user %q: %s", user, err)
os.Exit(2)
}
data, _ := json.Marshal(config)
fmt.Fprintf(os.Stdout, string(data))
}

5
cmd/salty-chat/main.go Normal file
View File

@ -0,0 +1,5 @@
package main
func main() {
Execute()
}

99
cmd/salty-chat/root.go Normal file
View File

@ -0,0 +1,99 @@
package main
import (
"fmt"
"os"
"strings"
"github.com/mitchellh/go-homedir"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.mills.io/saltyim"
)
var configFile string
var rootCmd = &cobra.Command{
Use: "salty-chat",
Version: saltyim.FullVersion(),
Short: "Salty IM Command-line client",
Long: `salty.im is an open specification for a new Saltpack based e2e
encrypted messaging protocol and platform for secure communications with
a focus on privacy, security and being self-hosted.
See https://salty.im for more details.`,
PersistentPreRun: func(cmd *cobra.Command, args []string) {
// set logging level
if viper.GetBool("debug") {
log.SetLevel(log.DebugLevel)
} else {
log.SetLevel(log.InfoLevel)
}
},
}
// Execute adds all child commands to the root command
// and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
func init() {
cobra.OnInitialize(initConfig)
rootCmd.PersistentFlags().StringVar(
&configFile, "config", "",
"config file (default is $HOME/.saltyim.yaml)",
)
rootCmd.PersistentFlags().BoolP(
"debug", "d", false,
"Enable debug logging",
)
/* TODO: This will be use when we have a Broker
rootCmd.PersistentFlags().StringP(
"uri", "u", "http://localhost:8000",
"URI to connect to saltyim broker",
)
viper.BindPFlag("uri", rootCmd.PersistentFlags().Lookup("uri"))
viper.SetDefault("uri", "http://localhost:8000/")
*/
viper.BindPFlag("debug", rootCmd.PersistentFlags().Lookup("debug"))
viper.SetDefault("debug", false)
}
// initConfig reads in config file and ENV variables if set.
func initConfig() {
if configFile != "" {
// Use config file from the flag.
viper.SetConfigFile(configFile)
} else {
// Find home directory.
home, err := homedir.Dir()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
viper.AddConfigPath(home)
viper.SetConfigName(".saltyim.yml")
}
// from the environment
viper.SetEnvPrefix("SALTY")
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
viper.AutomaticEnv() // read in environment variables that match
// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
fmt.Println("Using config file:", viper.ConfigFileUsed())
}
}

6
config.go Normal file
View File

@ -0,0 +1,6 @@
package saltyim
type Config struct {
Endpoint string `json:"endpoint"`
Key string `json:"key"`
}

28
go.mod Normal file
View File

@ -0,0 +1,28 @@
module go.mills.io/saltyim
go 1.17
require (
github.com/mitchellh/go-homedir v1.1.0
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.4.0
github.com/spf13/viper v1.10.1
)
require (
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/magiconair/properties v1.8.5 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect
github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cast v1.4.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/ini.v1 v1.66.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

66
go.sum Normal file
View File

@ -0,0 +1,66 @@
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM=
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
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/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q=
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk=
github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 h1:A9i04dxx7Cribqbs8jf3FQLogkL/CV2YN7hj9KWJCkc=
golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI=
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=

71
lookup.go Normal file
View File

@ -0,0 +1,71 @@
package saltyim
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
log "github.com/sirupsen/logrus"
)
// User represents a Salty IM User and the componetns that make up a Salty Addr
type User struct {
User string
Domain string
}
// WellKnownURI returns the User's expected Well-Known URI
func (u User) WellKnownURI() string {
return fmt.Sprintf("https://%s/.well-known/salty/%s.json", u.Domain, u.User)
}
// ParseUser parsers a user into it's user and domain parts and returns
// a User object with the User and Domain and a method for returning the
// expected User's Well-Known URI
func ParseUser(user string) (User, error) {
parts := strings.Split(user, "@")
if len(parts) != 2 {
return User{}, fmt.Errorf("error parsing user %q, expected nick@domain", user)
}
return User{parts[0], parts[1]}, nil
}
// Lookup looks up the user's Salty Config by parsing the user's domain and
// making a request to the user's Well-Known URI expected to by located at
// https://domain/.well-known/salty/<user>.json
// If a valid config is found, it is returned otherwise an error is returned
func Lookup(user string) (Config, error) {
u, err := ParseUser(user)
if err != nil {
log.WithError(err).Error("error parsing user %q", user)
return Config{}, nil
}
res, err := http.Get(u.WellKnownURI())
if err != nil {
log.WithError(err).Error("error requesting well-known uri")
return Config{}, nil
}
defer res.Body.Close()
if res.StatusCode/100 != 2 {
return Config{}, fmt.Errorf("non-2xx response received: %s", res.Status)
}
data, err := ioutil.ReadAll(res.Body)
if err != nil {
log.WithError(err).Error("error reading response")
return Config{}, nil
}
var config Config
if err := json.Unmarshal(data, &config); err != nil {
log.WithError(err).Error("error parsing well-known config")
}
return config, nil
}

130
preflight.sh Executable file
View File

@ -0,0 +1,130 @@
#!/bin/sh
set -e
color() {
fg="$1"
bg="${2}"
ft="${3:-0}"
printf "\33[%s;%s;%s" "$ft" "$fg" "$bg"
}
color_reset() {
printf "\033[0m"
}
ok() {
if [ -t 1 ]; then
printf "%s[ OK ]%s\n" "$(color 37 42m 1)" "$(color_reset)"
else
printf "%s\n" "[ OK ]"
fi
}
err() {
if [ -t 1 ]; then
printf "%s[ ERR ]%s\n" "$(color 37 41m 1)" "$(color_reset)"
else
printf "%s\n" "[ ERR ]"
fi
}
run() {
retval=0
logfile="$(mktemp -t "run-XXXXXX")"
if "$@" 2> "$logfile"; then
ok
else
retval=$?
err
cat "$logfile" || true
fi
rm -rf "$logfile"
return $retval
}
progress() {
printf "%-40s" "$(printf "%s ... " "$1")"
}
log() {
printf "%s\n" "$1"
}
log2() {
printf "%s\n" "$1" 1>&2
}
error() {
log "ERROR: ${1}"
}
fail() {
log "FATAL: ${1}"
exit 1
}
check_goversion() {
progress "Checking Go version"
if ! command -v go > /dev/null 2>&1; then
log2 "Cannot find the Go compiler"
return 1
fi
gover="$(go version | grep -o -E 'go[0-9]+\.[0-9]+(\.[0-9]+)?')"
if ! go version | grep -E 'go1\.17(\.[0-9]+)?' > /dev/null; then
log2 "Go 1.17 is required, found ${gover}"
return 1
fi
return 0
}
check_path() {
progress "Checking \$PATH"
gobin="$(eval "$(go env | grep GOBIN)")"
gopath="$(eval "$(go env | grep GOPATH)")"
if [ -n "$gobin" ] && ! echo "$PATH" | grep "$gobin" > /dev/null; then
log2 "\$GOBIN '$gobin' is not in your \$PATH"
return 1
fi
if [ -n "$gopath" ] && ! echo "$PATH" | grep "$gopath/bin" > /dev/null; then
log2 "\$GOPATH/bin '$gopath/bin' is not in your \$PATH"
return 1
fi
if ! echo "$PATH" | grep "$HOME/go/bin" > /dev/null; then
log2 "\$HOME/go/bin is not in your \$PATH"
return 1
fi
return 0
}
check_deps() {
progress "Checking deps"
return 0
}
steps="check_goversion check_path check_deps"
_main() {
for step in $steps; do
if ! run "$step"; then
fail "🙁 preflight failed"
fi
done
log "🥳 All Done! Ready to build, run: make build"
}
if [ -n "$0" ] && [ x"$0" != x"-bash" ]; then
_main "$@"
fi

32
tools/release.sh Executable file
View File

@ -0,0 +1,32 @@
#!/bin/bash
# Get the highest tag number
VERSION="$(git describe --abbrev=0 --tags)"
VERSION=${VERSION:-'0.0.0'}
# Get number parts
MAJOR="${VERSION%%.*}"
VERSION="${VERSION#*.}"
MINOR="${VERSION%%.*}"
VERSION="${VERSION#*.}"
PATCH="${VERSION%%.*}"
VERSION="${VERSION#*.}"
# Increase version
PATCH=$((PATCH + 1))
TAG="${1}"
if [ "${TAG}" = "" ]; then
TAG="${MAJOR}.${MINOR}.${PATCH}"
fi
echo "Releasing ${TAG} ..."
git-chglog --next-tag="${TAG}" --output CHANGELOG.md
git commit -a -m "Update CHANGELOG for ${TAG}"
git tag -a -s -m "Release ${TAG}" "${TAG}"
git push && git push --tags
goreleaser release \
--rm-dist \
--release-notes <(git-chglog "${TAG}" | tail -n+5)

18
version.go Normal file
View File

@ -0,0 +1,18 @@
package saltyim
import (
"fmt"
)
var (
// Version release version
Version = "0.0.1"
// Commit will be overwritten automatically by the build system
Commit = "HEAD"
)
// FullVersion display the full version and build
func FullVersion() string {
return fmt.Sprintf("%s@%s", Version, Commit)
}