adding custom config library, can read/write TOML, started config validation
This commit is contained in:
25
client/.gvcconfig.toml
Normal file
25
client/.gvcconfig.toml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
rootPath = "client"
|
||||||
|
version = "0.1.5"
|
||||||
|
|
||||||
|
[ignore]
|
||||||
|
files = [ "file1.txt", "file2.txt" ]
|
||||||
|
exts = [ ".jpg", ".png" ]
|
||||||
|
folders = []
|
||||||
|
|
||||||
|
|
||||||
|
[nocompress]
|
||||||
|
files = [ "fileA.log", "fileB.txt" ]
|
||||||
|
exts = [ ".exe", ".jpg" ]
|
||||||
|
folders = ["binaries"]
|
||||||
|
|
||||||
|
[[remote]]
|
||||||
|
name = "origin"
|
||||||
|
host = "testorigin.com"
|
||||||
|
port = 8694
|
||||||
|
|
||||||
|
[[remote]]
|
||||||
|
name = "secondOrigin"
|
||||||
|
host = "170.5.95.195"
|
||||||
|
port = 4253
|
||||||
|
|
||||||
|
|
28
client/.gvcconfigNew.toml
Normal file
28
client/.gvcconfigNew.toml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
version = 1.0
|
||||||
|
RootPath = "client"
|
||||||
|
|
||||||
|
[[remote]]
|
||||||
|
name = "origin"
|
||||||
|
host = ""
|
||||||
|
port = 8694
|
||||||
|
|
||||||
|
[[remote]]
|
||||||
|
name = "secondOrigin"
|
||||||
|
host = ""
|
||||||
|
port = 4253
|
||||||
|
|
||||||
|
[[remote]]
|
||||||
|
name = "my new Remote"
|
||||||
|
host = "hostname.com"
|
||||||
|
port = 1234
|
||||||
|
|
||||||
|
[ignore]
|
||||||
|
files = ["file1.txt", "file2.txt"]
|
||||||
|
exts = [".jpg", ".png"]
|
||||||
|
folders = []
|
||||||
|
|
||||||
|
[nocompress]
|
||||||
|
files = ["fileA.log", "fileB.txt"]
|
||||||
|
exts = [".exe", ".jpg"]
|
||||||
|
folders = ["binaries"]
|
||||||
|
|
0
client/.gvcignore.toml
Normal file
0
client/.gvcignore.toml
Normal file
BIN
client/client.exe
Normal file
BIN
client/client.exe
Normal file
Binary file not shown.
95
client/client.go
Normal file
95
client/client.go
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
clir "github.com/deranjer/clir"
|
||||||
|
clientcmd "github.com/deranjer/gvc/client/clientcmd"
|
||||||
|
clientconfig "github.com/deranjer/gvc/client/clientconfig"
|
||||||
|
"github.com/deranjer/store"
|
||||||
|
)
|
||||||
|
|
||||||
|
var version = "0.1.5"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var conf clientconfig.Gvcconfig
|
||||||
|
|
||||||
|
err := store.Load(".gvcconfig.toml", &conf)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error loading config file into struct! ", err)
|
||||||
|
}
|
||||||
|
clientconfig.ValidateConfig(&conf, version)
|
||||||
|
|
||||||
|
// Initialize our new cli
|
||||||
|
cli := clir.NewCli("gvcc", "Version control client for GVC", version)
|
||||||
|
|
||||||
|
// Adding the init command
|
||||||
|
initCommand(cli, &conf)
|
||||||
|
|
||||||
|
// Adding all the "add" commands
|
||||||
|
addCommands(cli, &conf)
|
||||||
|
|
||||||
|
err = cli.Run()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error occurred: : %v\n", err)
|
||||||
|
}
|
||||||
|
// After the cli is finished running and writing new values, then validate the input and write it back to the TOML config file
|
||||||
|
clientconfig.ValidateConfig(&conf, version)
|
||||||
|
err = store.Save(".gvcconfigNew.toml", &conf)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error saving config back to toml file: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// validateRepo just ensures that the command is being run against an actual repo (bool yes or no)
|
||||||
|
func validateRepo() bool {
|
||||||
|
if _, err := os.Stat(".gvcconfig.toml"); os.IsNotExist(err) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func initCommand(cli *clir.Cli, conf *clientconfig.Gvcconfig) {
|
||||||
|
//The init subcommand
|
||||||
|
initCmd := cli.NewSubCommand("init", "initializes a new gvc repo")
|
||||||
|
initCmd.LongDescription("This will create the .gvcconfig.toml (with defaults) file in this directory. You can edit this file directly (unsafe) or with the client(safe)")
|
||||||
|
initCmd.Action(func() error {
|
||||||
|
isRepo := validateRepo()
|
||||||
|
if !isRepo {
|
||||||
|
err := clientcmd.InitializeRepo()
|
||||||
|
if err != nil {
|
||||||
|
err = fmt.Errorf("unable to initialize repo: %s", err)
|
||||||
|
fmt.Println(err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
fmt.Println("appears that this directory is already a gvc repo")
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func addCommands(cli *clir.Cli, conf *clientconfig.Gvcconfig) {
|
||||||
|
//All the add commands and subcommands
|
||||||
|
//The add subcommand
|
||||||
|
addCmd := cli.NewSubCommand("add", "adds file(s)/folder(s) (recursively for folder) to repo")
|
||||||
|
addCmd.LongDescription("You can add all: all, a -file: file.txt, or a -folder: folder, or a -wildcard: *.txt")
|
||||||
|
//File/Folder/Wildcard adding
|
||||||
|
addCmd.Action(clientcmd.AddFiles)
|
||||||
|
//Add all files recursively to repo
|
||||||
|
addall := addCmd.NewSubCommand("all", "add all of the file(s)/folders(s) recursively to repo")
|
||||||
|
addall.Action(clientcmd.AddAll)
|
||||||
|
//The remote command
|
||||||
|
remoteCmd := cli.NewSubCommand("remote", "add/delete/show remotes")
|
||||||
|
var name string
|
||||||
|
var host string
|
||||||
|
var port int
|
||||||
|
remoteAddCmd := remoteCmd.NewSubCommand("add", "add a remote, requires -name -host and -port")
|
||||||
|
remoteAddCmd.LongDescription("Adds a remote to the .gvcconfig.toml. Requires the -name, -host and -port flags. Example: gvc remote add -name exampleRemote -host examplehost.com -port 8080")
|
||||||
|
remoteAddCmd.StringFlag("name", "the name you want for your remote server", &name)
|
||||||
|
remoteAddCmd.StringFlag("host", "the hostname or IP Address of the remote", &host)
|
||||||
|
remoteAddCmd.IntFlag("port", "the port the remote server is listening on", &port)
|
||||||
|
|
||||||
|
}
|
18
client/clientcmd/add.go
Normal file
18
client/clientcmd/add.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package clientcmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
//AddFiles adds files to the repo
|
||||||
|
func AddFiles() error {
|
||||||
|
fmt.Println("File/folder/wildcard to add", os.Args[2])
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//AddAll adds all files in working dir
|
||||||
|
func AddAll() error {
|
||||||
|
fmt.Println("Adding all files", os.Args[2])
|
||||||
|
return nil
|
||||||
|
}
|
1
client/clientcmd/commonlib.go
Normal file
1
client/clientcmd/commonlib.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package clientcmd
|
12
client/clientcmd/ignore.go
Normal file
12
client/clientcmd/ignore.go
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package clientcmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
//IgnoreFiles ignores file(s)/folder based on name/wildcard, etc
|
||||||
|
func IgnoreFiles() error {
|
||||||
|
fmt.Println("File/folder/wildcard to ignore", os.Args[2])
|
||||||
|
return nil
|
||||||
|
}
|
16
client/clientcmd/init.go
Normal file
16
client/clientcmd/init.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package clientcmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
//AddFiles adds files to the repo
|
||||||
|
func InitializeRepo() error {
|
||||||
|
cwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println("Initializing repo in dir: ", cwd)
|
||||||
|
return nil
|
||||||
|
}
|
87
client/clientconfig/config.go
Normal file
87
client/clientconfig/config.go
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ValidateConfig will go through the entire config and do basic sanity checks
|
||||||
|
func ValidateConfig(conf *Gvcconfig, version string) error {
|
||||||
|
if conf.Version == "" { // No version found, should we update it?
|
||||||
|
fmt.Printf("No version found, inputing current client version: %s", version)
|
||||||
|
conf.Version = version
|
||||||
|
}
|
||||||
|
if conf.RootPath == "" {
|
||||||
|
path, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to get current working directory, and rootpath of repo is not set: %s", err)
|
||||||
|
}
|
||||||
|
fmt.Printf("No root path found, inputting current working directory: %s", path)
|
||||||
|
}
|
||||||
|
err := validateRemotes(conf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = validateCompress(conf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
//TODO validate ignores (pretty similar to compress)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// validateCompress checks the compression settings to make sure they are valid //TODO return error needed?
|
||||||
|
func validateCompress(conf *Gvcconfig) error {
|
||||||
|
compress := conf.NoCompress
|
||||||
|
for i, file := range compress.Files {
|
||||||
|
if file == "" {
|
||||||
|
fmt.Println("empty file in compress files, removing... ")
|
||||||
|
compress.Files[i] = compress.Files[len(compress.Files)-1]
|
||||||
|
}
|
||||||
|
// TODO: write more validation
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for i, folder := range compress.Folders {
|
||||||
|
file, err := os.Stat(folder) // TODO: check to see if it returns ABS or not, might need to convert
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("unable to find folder listed in array, removing it: ", folder)
|
||||||
|
compress.Folders[i] = compress.Folders[len(compress.Folders)-1]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fileType := file.Mode()
|
||||||
|
if fileType.IsRegular() { // Not a folder
|
||||||
|
fmt.Println("compressed folder in array is not actually a folder, moving it to file compress: ", folder)
|
||||||
|
compress.Folders[i] = compress.Folders[len(compress.Folders)-1]
|
||||||
|
compress.Files = append(compress.Files, folder)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i, ext := range compress.Exts {
|
||||||
|
if ext == "" {
|
||||||
|
fmt.Println("empty ext in compress exts, removing... ")
|
||||||
|
compress.Exts[i] = compress.Exts[len(compress.Exts)-1]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// TODO: validate there is a "." in front of the ext, if not add it?
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// validateRemotes ranges through all of the remotes and validates them
|
||||||
|
func validateRemotes(conf *Gvcconfig) error {
|
||||||
|
remotes := conf.Remotes
|
||||||
|
for _, remote := range remotes {
|
||||||
|
if remote.Name == "" {
|
||||||
|
return fmt.Errorf("Unnamed remote found in config, all remotes require name")
|
||||||
|
}
|
||||||
|
if remote.Host == "" {
|
||||||
|
return fmt.Errorf("Host cannot be empty: %s in %s", remote.Name, remote.Host)
|
||||||
|
} // Checking for a valid port // TODO: might need to move this function to common library, feel like we will need this in the future?
|
||||||
|
if remote.Port == 0 || remote.Port == 1 || remote.Port > 65535 { // TODO: edit the config library to allow default options?
|
||||||
|
fmt.Printf("Remote %s did not have a valid port set, setting it to the default port 8888", remote.Name)
|
||||||
|
remote.Port = 8888
|
||||||
|
conf.Remotes = append(conf.Remotes, remote)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
24
client/clientconfig/structures.go
Normal file
24
client/clientconfig/structures.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
//Gvcconfig will be the struct that holds the entire client settings
|
||||||
|
type Gvcconfig struct {
|
||||||
|
Version string `toml:"version"`
|
||||||
|
RootPath string `toml:rootPath`
|
||||||
|
Remotes []Remote `toml:"remote"` //The remote servers for the repo
|
||||||
|
Ignores Ignore `toml:"ignore"` //These files will be ignored for all add functions
|
||||||
|
NoCompress Ignore `toml:"nocompress"` //For binary compression some files should be ignored because the performance hit isn't worth the size savings
|
||||||
|
}
|
||||||
|
|
||||||
|
//Remote will be a slice of remote server information
|
||||||
|
type Remote struct {
|
||||||
|
Name string `toml:"name"`
|
||||||
|
Host string `toml:"host"`
|
||||||
|
Port int `toml:"port"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//Ignore is for ignoring files to add or ignoring compress
|
||||||
|
type Ignore struct {
|
||||||
|
Files []string `toml:"files"`
|
||||||
|
Exts []string `toml:"exts"`
|
||||||
|
Folders []string `toml:"folders"`
|
||||||
|
}
|
12
client/go.mod
Normal file
12
client/go.mod
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
module github.com/deranjer/gvc/client
|
||||||
|
|
||||||
|
go 1.14
|
||||||
|
|
||||||
|
replace derajnet.duckdns.org/git/deranjer/gvc => ../gvc //alias for local development
|
||||||
|
|
||||||
|
replace github.com/deranjer/gvc => ../gvc
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/deranjer/clir v1.0.5
|
||||||
|
github.com/deranjer/store v0.0.0-20200526205429-464dd59c6031
|
||||||
|
)
|
10
client/go.sum
Normal file
10
client/go.sum
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
github.com/deranjer/clir v1.0.5 h1:tEunZj5qJLYNBtzMQ/vH8hEAIv4NptWFmTldsP9U2qY=
|
||||||
|
github.com/deranjer/clir v1.0.5/go.mod h1:x/FAjr5CHGsBT0yjs+NYxX3qFxx8G15gbeCcN6FFuyU=
|
||||||
|
github.com/deranjer/store v0.0.0-20200526205429-464dd59c6031 h1:sPjxPMNILoBbu6uhDfa97AhlUhTgtPY2HqySAzuLd4o=
|
||||||
|
github.com/deranjer/store v0.0.0-20200526205429-464dd59c6031/go.mod h1:wPOs9IJ77lRTXyjEOQeegCFjIlm21qOFcv33lXmU7gE=
|
||||||
|
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/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
24
client/test/test.go
Normal file
24
client/test/test.go
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/deranjer/clir"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// Create new cli
|
||||||
|
cli := clir.NewCli("Other Args", "A basic example", "v0.0.1")
|
||||||
|
|
||||||
|
// Set long description
|
||||||
|
cli.LongDescription("This app shows positional arguments")
|
||||||
|
|
||||||
|
name := cli.NewSubCommand("name", "Shows your name!")
|
||||||
|
name.Action(func() error {
|
||||||
|
fmt.Printf("The remaining arguments were: %+v\n", name.OtherArgs())
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
// Run!
|
||||||
|
cli.Run()
|
||||||
|
}
|
Reference in New Issue
Block a user