Browse Source

Add version command

tags/v1.0.0
dtluna 4 months ago
parent
commit
41dc175203
8 changed files with 260 additions and 1 deletions
  1. 13
    0
      api/client.go
  2. 44
    0
      api/version.go
  3. 21
    0
      commands/version.go
  4. 62
    0
      config/config.go
  5. 7
    0
      constants/constants.go
  6. 12
    0
      go.mod
  7. 29
    0
      go.sum
  8. 72
    1
      main.go

+ 13
- 0
api/client.go View File

@@ -0,0 +1,13 @@
package api

import (
"git.dtluna.net/dtluna/syncthing-cli/config"

"gopkg.in/h2non/gentleman.v2"
)

func NewClient(cfg *config.Config) *gentleman.Client {
return gentleman.New().
BaseURL("http://"+cfg.Address).
AddHeader("X-API-KEY", cfg.APIKey)
}

+ 44
- 0
api/version.go View File

@@ -0,0 +1,44 @@
package api

import (
"fmt"

"git.dtluna.net/dtluna/syncthing-cli/config"
)

const (
VersionPath = "/rest/system/version"
)

type VersionInfo struct {
Architecture string `json:"arch"`
Codename string
IsBeta bool
IsCandidate bool
IsRelease bool
LongVersion string
OS string
Version string
}

func Version(cfg *config.Config) (*VersionInfo, error) {
req := NewClient(cfg).
Request().
Path(VersionPath)
resp, err := req.Send()
if err != nil {
return nil, err
}

if !resp.Ok {
return nil, fmt.Errorf("%v %v", resp.StatusCode, resp.String())
}

info := new(VersionInfo)
err = resp.JSON(info)
if err != nil {
return nil, err
}

return info, nil
}

+ 21
- 0
commands/version.go View File

@@ -0,0 +1,21 @@
package commands

import (
"fmt"

"git.dtluna.net/dtluna/syncthing-cli/api"
"git.dtluna.net/dtluna/syncthing-cli/config"

"github.com/hashicorp/errwrap"
)

func Version(cfg *config.Config) error {
info, err := api.Version(cfg)
if err != nil {
return errwrap.Wrapf("requesting version: {{err}}", err)

}
fmt.Println(info.LongVersion)

return nil
}

+ 62
- 0
config/config.go View File

@@ -0,0 +1,62 @@
package config

import (
"net"

"git.dtluna.net/dtluna/syncthing-cli/constants"
"gopkg.in/ini.v1"
)

type Config struct {
APIKey string `ini:"api-key"`
Address string `ini:"address"`
}

func CreateBlankConfigFile(path string) error {
file := ini.Empty()
section := file.Section("")

key, err := section.NewKey("api-key", "")
if err != nil {
return err
}
key.Comment = "Specify the API key below"

_, err = section.NewKey("address", constants.DefaultAddress)
if err != nil {
return err
}

return file.SaveTo(path)
}

func Parse(path string) (*Config, error) {
file, err := ini.Load(path)
if err != nil {
return nil, err
}

cfg := new(Config)
err = file.MapTo(cfg)
if err != nil {
return nil, err
}
return cfg, nil
}

func Merge(old Config, address *net.TCPAddr, APIKey string) (*Config, error) {
if APIKey != "" {
old.APIKey = APIKey
}
if address != nil {
old.Address = address.String()
}

//validate the specified address
_, err := net.ResolveTCPAddr("tcp", old.Address)
if err != nil {
return nil, err
}

return &old, nil
}

+ 7
- 0
constants/constants.go View File

@@ -0,0 +1,7 @@
package constants

const (
AppName = "syncthing-cli"
Version = "dev"
DefaultAddress = "127.0.0.1:8384"
)

+ 12
- 0
go.mod View File

@@ -1,3 +1,15 @@
module git.dtluna.net/dtluna/syncthing-cli

go 1.12

require (
github.com/OpenPeeDeeP/xdg v0.2.0
github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc // indirect
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf // indirect
github.com/hashicorp/errwrap v1.0.0
golang.org/x/net v0.0.0-20190327214358-63eda1eb0650 // indirect
gopkg.in/alecthomas/kingpin.v2 v2.2.6
gopkg.in/h2non/gentleman.v2 v2.0.3
gopkg.in/ini.v1 v1.42.0
)

+ 29
- 0
go.sum View File

@@ -0,0 +1,29 @@
github.com/OpenPeeDeeP/xdg v0.2.0 h1:xr89rnllbkRkM7SV9Y++FJ8TGkbdkhhBQm5kOkGT7AE=
github.com/OpenPeeDeeP/xdg v0.2.0/go.mod h1:tMoSueLQlMf0TCldjrJLNIjAc5qAOIcHt5REi88/Ygo=
github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755 h1:1B7wb36fHLSwZfHg6ngZhhtIEHQjiC5H4p7qQGBEffg=
github.com/Unknwon/com v0.0.0-20190321035513-0fed4efef755/go.mod h1:voKvFVpXBJxdIPeqjoJuLK+UVcRlo/JLjeToGxPYu68=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190327214358-63eda1eb0650 h1:XCbwcsP09zrBt1aYht0fASw+ynbEpYr8NnCkIN9nMM0=
golang.org/x/net v0.0.0-20190327214358-63eda1eb0650/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/h2non/gentleman.v2 v2.0.3 h1:exsUPKJDFwNjJykboVj8+BKPWMNOxR/AmPL3f7Hutwo=
gopkg.in/h2non/gentleman.v2 v2.0.3/go.mod h1:A1c7zwrTgAyyf6AbpvVksYtBayTB4STBUGmdkEtlHeA=
gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk=
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=

+ 72
- 1
main.go View File

@@ -2,8 +2,79 @@ package main

import (
"fmt"
"os"
"path"

"git.dtluna.net/dtluna/syncthing-cli/commands"
"git.dtluna.net/dtluna/syncthing-cli/config"
"git.dtluna.net/dtluna/syncthing-cli/constants"

"github.com/OpenPeeDeeP/xdg"
"github.com/Unknwon/com"
"gopkg.in/alecthomas/kingpin.v2"
)

func printToStderr(v interface{}) {
fmt.Fprintf(
os.Stderr,
"%v: error: creating default config file: %v\n",
constants.AppName,
v,
)
}

func fatalIfError(err error) {
if err != nil {
printToStderr(err)
os.Exit(1)
}
}

func main() {
fmt.Println("Name chef")
x := xdg.New("", constants.AppName)
configDir := x.ConfigHome()
defaultConfigPath := path.Join(configDir, "config.ini")
if !com.IsExist(defaultConfigPath) {
if !com.IsExist(configDir) {
err := os.MkdirAll(configDir, os.ModePerm)
fatalIfError(err)
}
err := config.CreateBlankConfigFile(defaultConfigPath)
fatalIfError(err)
}

app := kingpin.New(constants.AppName, "CLI client for Syncthing")
app.Version(constants.Version)

configPath := app.Flag("config", "Location of the config file.").
Short('c').
Default(defaultConfigPath).
ExistingFile()

address := app.Flag("address", "Address of the Syncthing daemon.").
Short('a').
TCP()

apiKey := app.Flag("api-key", "API key to access the REST API of the Syncthing daemon.").
Short('k').
String()

version := app.Command("version", "Show the current Syncthing version information.").Alias("v")

commandName := kingpin.MustParse(app.Parse(os.Args[1:]))

cfg, err := config.Parse(*configPath)
app.FatalIfError(err, "parsing config")

cfg, err = config.Merge(*cfg, *address, *apiKey)
app.FatalIfError(err, "merging config with arguments")

err = func() error {
switch commandName {
case version.FullCommand():
return commands.Version(cfg)
}
return nil
}()
app.FatalIfError(err, "")
}

Loading…
Cancel
Save