Split out Command from Library

This commit is contained in:
2018-02-15 07:45:53 -06:00
commit 8dd7c1e1bf
301 changed files with 144867 additions and 0 deletions

22
vendor/github.com/br0xen/boltease/.gitignore generated vendored Executable file
View File

@@ -0,0 +1,22 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe

4
vendor/github.com/br0xen/boltease/README.md generated vendored Normal file
View File

@@ -0,0 +1,4 @@
boltease
========
A library for easing the use of bolt databases

400
vendor/github.com/br0xen/boltease/boltease.go generated vendored Normal file
View File

@@ -0,0 +1,400 @@
package boltease
import (
"fmt"
"os"
"strconv"
"strings"
"time"
"github.com/boltdb/bolt"
)
// This is a library for easing the use of bolt dbs
// DB is a struct for accomplishing this
type DB struct {
filename string
boltDB *bolt.DB
mode os.FileMode
options *bolt.Options
dbIsOpen bool
}
// Create makes sure we can get open the file and returns the DB object
func Create(fn string, m os.FileMode, opts *bolt.Options) (*DB, error) {
var err error
b := DB{filename: fn, mode: m, options: opts}
b.boltDB, err = bolt.Open(fn, m, opts)
if err != nil {
return nil, err
}
defer b.boltDB.Close()
return &b, nil
}
func (b *DB) OpenDB() error {
if b.dbIsOpen {
// DB is already open, that's fine.
return nil
}
var err error
if b.boltDB, err = bolt.Open(b.filename, b.mode, b.options); err != nil {
return err
}
b.dbIsOpen = true
return err
}
func (b *DB) CloseDB() error {
if !b.dbIsOpen {
// DB is already closed, that's fine.
return nil
}
var err error
if err = b.boltDB.Close(); err != nil {
return err
}
b.dbIsOpen = false
return err
}
// MkBucketPath builds all buckets in the string slice
func (b *DB) MkBucketPath(path []string) error {
var err error
if !b.dbIsOpen {
if err = b.OpenDB(); err != nil {
return err
}
defer b.CloseDB()
}
err = b.boltDB.Update(func(tx *bolt.Tx) error {
var err error
bkt := tx.Bucket([]byte(path[0]))
if bkt == nil {
// Create it
bkt, err = tx.CreateBucket([]byte(path[0]))
if err != nil {
// error creating
return err
}
}
if len(path) > 1 {
path = path[1:]
for i := range path {
nextBkt := bkt.Bucket([]byte(path[i]))
if nextBkt == nil {
// Create it
nextBkt, err = bkt.CreateBucket([]byte(path[i]))
if err != nil {
return err
}
}
bkt = nextBkt
}
}
return err
})
return err
}
// GetValue returns the value at path
// path is a slice of strings
// key is the key to get
func (b *DB) GetValue(path []string, key string) (string, error) {
var err error
var ret string
if !b.dbIsOpen {
if err = b.OpenDB(); err != nil {
return ret, err
}
defer b.CloseDB()
}
err = b.boltDB.View(func(tx *bolt.Tx) error {
bkt := tx.Bucket([]byte(path[0]))
if bkt == nil {
return fmt.Errorf("Couldn't find bucket " + path[0])
}
for idx := 1; idx < len(path); idx++ {
bkt = bkt.Bucket([]byte(path[idx]))
if bkt == nil {
return fmt.Errorf("Couldn't find bucket " + strings.Join(path[:idx], "/"))
}
}
// newBkt should have the last bucket in the path
ret = string(bkt.Get([]byte(key)))
return nil
})
return ret, err
}
// SetValue sets the value of key at path to val
// path is a slice of tokens
func (b *DB) SetValue(path []string, key, val string) error {
var err error
if !b.dbIsOpen {
if err = b.OpenDB(); err != nil {
return err
}
defer b.CloseDB()
}
err = b.MkBucketPath(path)
if err != nil {
return err
}
err = b.boltDB.Update(func(tx *bolt.Tx) error {
bkt := tx.Bucket([]byte(path[0]))
if bkt == nil {
return fmt.Errorf("Couldn't find bucket " + path[0])
}
for idx := 1; idx < len(path); idx++ {
bkt, err = bkt.CreateBucketIfNotExists([]byte(path[idx]))
if err != nil {
return err
}
}
// bkt should have the last bucket in the path
return bkt.Put([]byte(key), []byte(val))
})
return err
}
// GetInt returns the value at path
// If the value cannot be parsed as an int, error
func (b *DB) GetInt(path []string, key string) (int, error) {
var ret int
r, err := b.GetValue(path, key)
if err == nil {
ret, err = strconv.Atoi(r)
}
return ret, err
}
// SetInt Sets an integer value
func (b *DB) SetInt(path []string, key string, val int) error {
return b.SetValue(path, key, strconv.Itoa(val))
}
// GetBool returns the value at 'path'
// If the value cannot be parsed as a bool, error
// We check 'true/false' and '1/0', else error
func (b *DB) GetBool(path []string, key string) (bool, error) {
var ret bool
r, err := b.GetValue(path, key)
if err == nil {
if r == "true" || r == "1" {
ret = true
} else if r != "false" && r != "0" {
err = fmt.Errorf("Cannot parse as a boolean")
}
}
return ret, err
}
// SetBool Sets a boolean value
func (b *DB) SetBool(path []string, key string, val bool) error {
if val {
return b.SetValue(path, key, "true")
}
return b.SetValue(path, key, "false")
}
// GetTimestamp returns the value at 'path'
// If the value cannot be parsed as a RFC3339, error
func (b *DB) GetTimestamp(path []string, key string) (time.Time, error) {
r, err := b.GetValue(path, key)
if err == nil {
return time.Parse(time.RFC3339, r)
}
return time.Unix(0, 0), err
}
// SetTimestamp saves a timestamp into the db
func (b *DB) SetTimestamp(path []string, key string, val time.Time) error {
return b.SetValue(path, key, val.Format(time.RFC3339))
}
// GetBucketList returns a list of all sub-buckets at path
func (b *DB) GetBucketList(path []string) ([]string, error) {
var err error
var ret []string
if !b.dbIsOpen {
if err = b.OpenDB(); err != nil {
return ret, err
}
defer b.CloseDB()
}
err = b.boltDB.Update(func(tx *bolt.Tx) error {
bkt := tx.Bucket([]byte(path[0]))
if bkt == nil {
return fmt.Errorf("Couldn't find bucket " + path[0])
}
var berr error
if len(path) > 1 {
for idx := 1; idx < len(path); idx++ {
bkt = bkt.Bucket([]byte(path[idx]))
if bkt == nil {
return fmt.Errorf("Couldn't find bucket " + strings.Join(path[:idx], " / "))
}
}
}
// bkt should have the last bucket in the path
berr = bkt.ForEach(func(k, v []byte) error {
if v == nil {
// Must be a bucket
ret = append(ret, string(k))
}
return nil
})
return berr
})
return ret, err
}
// GetKeyList returns a list of all keys at path
func (b *DB) GetKeyList(path []string) ([]string, error) {
var err error
var ret []string
if !b.dbIsOpen {
if err = b.OpenDB(); err != nil {
return ret, err
}
defer b.CloseDB()
}
err = b.boltDB.Update(func(tx *bolt.Tx) error {
bkt := tx.Bucket([]byte(path[0]))
if bkt == nil {
return fmt.Errorf("Couldn't find bucket " + path[0])
}
var berr error
if len(path) > 1 {
for idx := 1; idx < len(path); idx++ {
bkt = bkt.Bucket([]byte(path[idx]))
if bkt == nil {
return fmt.Errorf("Couldn't find bucket " + strings.Join(path[:idx], " / "))
}
}
}
// bkt should have the last bucket in the path
berr = bkt.ForEach(func(k, v []byte) error {
if v != nil {
// Must be a key
ret = append(ret, string(k))
}
return nil
})
return berr
})
return ret, err
}
// DeletePair deletes the pair with key at path
func (b *DB) DeletePair(path []string, key string) error {
var err error
if !b.dbIsOpen {
if err = b.OpenDB(); err != nil {
return err
}
defer b.CloseDB()
}
err = b.boltDB.Update(func(tx *bolt.Tx) error {
bkt := tx.Bucket([]byte(path[0]))
if bkt == nil {
return fmt.Errorf("Couldn't find bucket " + path[0])
}
if len(path) > 1 {
var newBkt *bolt.Bucket
for idx := 1; idx < len(path); idx++ {
newBkt = bkt.Bucket([]byte(path[idx]))
if newBkt == nil {
return fmt.Errorf("Couldn't find bucket " + strings.Join(path[:idx], "/"))
}
}
bkt = newBkt
}
// bkt should have the last bucket in the path
// Test to make sure that key is a pair, if so, delete it
if tst := bkt.Bucket([]byte(key)); tst == nil {
return bkt.Delete([]byte(key))
}
return nil
})
return err
}
// DeleteBucket deletes the bucket key at path
func (b *DB) DeleteBucket(path []string, key string) error {
var err error
if !b.dbIsOpen {
if err = b.OpenDB(); err != nil {
return err
}
defer b.CloseDB()
}
err = b.boltDB.Update(func(tx *bolt.Tx) error {
bkt := tx.Bucket([]byte(path[0]))
if bkt == nil {
return fmt.Errorf("Couldn't find bucket " + path[0])
}
for idx := 1; idx < len(path); idx++ {
bkt = bkt.Bucket([]byte(path[idx]))
if bkt == nil {
return fmt.Errorf("Couldn't find bucket " + strings.Join(path[:idx], "/"))
}
}
// bkt should have the last bucket in the path
// Test to make sure that key is a bucket, if so, delete it
if tst := bkt.Bucket([]byte(key)); tst != nil {
return bkt.DeleteBucket([]byte(key))
}
return nil
})
return err
}
// GetValueList returns a string slice of all values in the bucket at path
func (b *DB) GetValueList(path []string) ([]string, error) {
var err error
var ret []string
if !b.dbIsOpen {
if err = b.OpenDB(); err != nil {
return ret, err
}
defer b.CloseDB()
}
err = b.boltDB.Update(func(tx *bolt.Tx) error {
bkt := tx.Bucket([]byte(path[0]))
if bkt == nil {
return fmt.Errorf("Couldn't find bucket " + path[0])
}
var berr error
if len(path) > 1 {
for idx := 1; idx < len(path); idx++ {
bkt = bkt.Bucket([]byte(path[idx]))
if bkt == nil {
return fmt.Errorf("Couldn't find bucket " + strings.Join(path[:idx], " / "))
}
}
}
// bkt should have the last bucket in the path
berr = bkt.ForEach(func(k, v []byte) error {
if v != nil {
// Must be a key
ret = append(ret, string(v))
}
return nil
})
return berr
})
return ret, err
}

24
vendor/github.com/br0xen/user-config/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,24 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof

21
vendor/github.com/br0xen/user-config/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Brian Buller
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:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
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.

3
vendor/github.com/br0xen/user-config/README.md generated vendored Normal file
View File

@@ -0,0 +1,3 @@
# user-config
A go library for easily managing config files/directories in your XDGConfig directory

108
vendor/github.com/br0xen/user-config/addon_config.go generated vendored Normal file
View File

@@ -0,0 +1,108 @@
package userConfig
import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"os"
"strings"
)
// AddonConfig is an additional ConfigFile
type AddonConfig struct {
Name string `toml:"-"`
Path string `toml:"-"`
Values map[string]map[string]string `toml:"-"`
}
// NewAddonConfig generates a Additional Config struct
func NewAddonConfig(name, path string) (*AddonConfig, error) {
af := &AddonConfig{Name: name, Path: path}
af.Values = make(map[string]map[string]string)
// Check if file exists
//var f os.FileInfo
var err error
if _, err = os.Stat(af.GetFullPath()); os.IsNotExist(err) {
if err = af.Save(); err != nil {
return af, err
}
}
if err := af.Load(); err != nil {
return af, err
}
return af, nil
}
/** START of ConfigFile Interface Implementation **/
// GetName returns the name of this config file
func (af *AddonConfig) GetName() string {
return af.Name
}
// GetPath returns the path of this config file
func (af *AddonConfig) GetPath() string {
return af.Path
}
// Load loads config files into the config
func (af *AddonConfig) Load() error {
if strings.TrimSpace(af.Name) == "" || strings.TrimSpace(af.Path) == "" {
return errors.New("Invalid ConfigFile Name: " + af.GetFullPath())
}
// Config files end with .toml
tomlData, err := ioutil.ReadFile(af.GetFullPath())
if err != nil {
return err
}
fmt.Println(tomlData)
// TODO: Figure out loading this into the struct
//if _, err := toml.Decode(string(tomlData), &af); err != nil {
// return err
//}
return nil
}
// Save writes the config to file(s)
func (af *AddonConfig) Save() error {
buf := new(bytes.Buffer)
// TODO: Figure out writing struct to buf
//if err := toml.NewEncoder(buf).Encode(af); err != nil {
// return err
//}
return ioutil.WriteFile(af.GetFullPath(), buf.Bytes(), 0644)
}
// Set sets a key/value pair in af, if unable to save, revert to old value
// (and return the error)
func (af *AddonConfig) Set(category, k, v string) error {
if _, ok := af.Values[category]; !ok {
af.Values[category] = make(map[string]string)
}
oldVal := af.Values[category][k]
af.Values[category][k] = v
if err := af.Save(); err != nil {
af.Values[category][k] = oldVal
return err
}
return nil
}
// Get gets a key/value pair from af
func (af *AddonConfig) Get(category, k string) string {
if _, ok := af.Values[category]; !ok {
return ""
}
return af.Values[category][k]
}
// GetFullPath returns the full path & filename to the config file
func (af *AddonConfig) GetFullPath() string {
return af.Path + "/" + af.Name + ".toml"
}
/** END of ConfigFile Interface Implementation **/

147
vendor/github.com/br0xen/user-config/config.go generated vendored Normal file
View File

@@ -0,0 +1,147 @@
// Package userConfig eases the use of config files in a user's home directory
package userConfig
import (
"errors"
"os"
"strings"
"time"
"github.com/casimir/xdg-go"
)
// Config is a stuct for managing the config
type Config struct {
name string
generalConfig *GeneralConfig
}
// NewConfig generates a Config struct
func NewConfig(name string) (*Config, error) {
c := &Config{name: name}
if err := c.Load(); err != nil {
return c, err
}
return c, nil
}
// GetKeyList at the config level returns all keys in the <c.name>.toml file
func (c *Config) GetKeyList() []string {
return c.generalConfig.GetKeyList()
}
// Set at the config level sets a value in the <c.name>.toml file
func (c *Config) Set(k, v string) error {
return c.generalConfig.Set(k, v)
}
// SetBytes at the config level sets a value in the <c.name>.toml file
func (c *Config) SetBytes(k string, v []byte) error {
return c.generalConfig.SetBytes(k, v)
}
// SetInt saves an integer (as a string) in the <c.name>.toml file
func (c *Config) SetInt(k string, v int) error {
return c.generalConfig.SetInt(k, v)
}
// SetDateTime saves a time.Time (as a string) in the <c.name>.toml file
func (c *Config) SetDateTime(k string, v time.Time) error {
return c.generalConfig.SetDateTime(k, v)
}
// SetArray saves a string slice in the <c.name>.toml file
func (c *Config) SetArray(k string, v []string) error {
return c.generalConfig.SetArray(k, v)
}
// Get at the config level retrieves a value from the <c.name>.toml file
func (c *Config) Get(k string) string {
return c.generalConfig.Get(k)
}
// GetBytes at the config level retrieves a value from the <c.name>.toml file
// and returns it as a byte slice
func (c *Config) GetBytes(k string) []byte {
return c.generalConfig.GetBytes(k)
}
// GetInt at the config level retrieves a value from the <c.name>.toml file
// and returns it as an integer (or an error if conversion fails)
func (c *Config) GetInt(k string) (int, error) {
return c.generalConfig.GetInt(k)
}
// GetDateTime at the config level retrieves a value from the <c.name>.toml file
func (c *Config) GetDateTime(k string) (time.Time, error) {
return c.generalConfig.GetDateTime(k)
}
func (c *Config) GetArray(k string) ([]string, error) {
return c.generalConfig.GetArray(k)
}
// DeleteKey at the config level removes a key from the <c.name>.toml file
func (c *Config) DeleteKey(k string) error {
return c.generalConfig.DeleteKey(k)
}
// GetConfigPath just returns the config path
func (c *Config) GetConfigPath() string {
return c.generalConfig.Path
}
// Load loads config files into the config
func (c *Config) Load() error {
var err error
if strings.TrimSpace(c.name) == "" {
return errors.New("Invalid Config Name: " + c.name)
}
var cfgPath string
app := xdg.App{Name: c.name}
cfgPath = app.ConfigPath("")
if cfgPath != "" {
if err = c.verifyOrCreateDirectory(cfgPath); err != nil {
return err
}
}
// Load general config
if c.generalConfig, err = NewGeneralConfig(c.name, cfgPath); err != nil {
return err
}
return nil
}
// Save writes the config to file(s)
func (c *Config) Save() error {
if c.generalConfig == nil {
return errors.New("Bad setup.")
}
return c.generalConfig.Save()
}
// verifyOrCreateDirectory is a helper function for building an
// individual directory
func (c *Config) verifyOrCreateDirectory(path string) error {
var tstDir *os.File
var tstDirInfo os.FileInfo
var err error
if tstDir, err = os.Open(path); err != nil {
if err = os.Mkdir(path, 0755); err != nil {
return err
}
if tstDir, err = os.Open(path); err != nil {
return err
}
}
if tstDirInfo, err = tstDir.Stat(); err != nil {
return err
}
if !tstDirInfo.IsDir() {
return errors.New(path + " exists and is not a directory")
}
// We were able to open the path and it was a directory
return nil
}

154
vendor/github.com/br0xen/user-config/config_file.go generated vendored Normal file
View File

@@ -0,0 +1,154 @@
// Package userConfig eases the use of config files in a user's home directory
package userConfig
import (
"bytes"
"encoding/json"
"errors"
"io/ioutil"
"os"
"strconv"
"strings"
"time"
"github.com/BurntSushi/toml"
)
// GeneralConfig is the basic config structure
// All configs make with package userConfig will have this file
type GeneralConfig struct {
Name string `toml:"-"`
Path string `toml:"-"`
ConfigFiles []string `toml:"additional_config"`
RawFiles []string `toml:"raw_files"`
Values map[string]string `toml:"general"`
}
// NewGeneralConfig generates a General Config struct
func NewGeneralConfig(name, path string) (*GeneralConfig, error) {
gf := &GeneralConfig{Name: name, Path: path}
gf.ConfigFiles = []string{}
gf.RawFiles = []string{}
gf.Values = make(map[string]string)
if err := gf.Load(); err != nil {
return gf, err
}
return gf, nil
}
// Load loads config files into the config
func (gf *GeneralConfig) Load() error {
if strings.TrimSpace(gf.Name) == "" || strings.TrimSpace(gf.Path) == "" {
return errors.New("Invalid ConfigFile Name: " + gf.Path + string(os.PathSeparator) + gf.Name)
}
// Config files end with .toml
cfgPath := gf.Path + string(os.PathSeparator) + gf.Name + ".toml"
tomlData, err := ioutil.ReadFile(cfgPath)
if err != nil {
// Couldn't find the file, save a new one
if err = gf.Save(); err != nil {
return err
}
}
if _, err := toml.Decode(string(tomlData), &gf); err != nil {
return err
}
return nil
}
// Save writes the config to file(s)
func (gf *GeneralConfig) Save() error {
buf := new(bytes.Buffer)
cfgPath := gf.Path + string(os.PathSeparator) + gf.Name + ".toml"
if err := toml.NewEncoder(buf).Encode(gf); err != nil {
return err
}
return ioutil.WriteFile(cfgPath, buf.Bytes(), 0644)
}
// GetKeyList returns a list of all keys in the config file
func (gf *GeneralConfig) GetKeyList() []string {
var ret []string
for k, _ := range gf.Values {
ret = append(ret, k)
}
return ret
}
// Set sets a key/value pair in gf, if unable to save, revert to old value
// (and return the error)
func (gf *GeneralConfig) Set(k, v string) error {
oldVal := gf.Values[k]
gf.Values[k] = v
if err := gf.Save(); err != nil {
gf.Values[k] = oldVal
return err
}
return nil
}
// SetBytes at the config level sets a value in the <c.name>.toml file
func (gf *GeneralConfig) SetBytes(k string, v []byte) error {
return gf.Set(k, string(v))
}
// SetInt sets an integer value (as a string) in the config file
func (gf *GeneralConfig) SetInt(k string, v int) error {
return gf.Set(k, strconv.Itoa(v))
}
// SetDateTime sets a DateTime value (as a string) in the config file
func (gf *GeneralConfig) SetDateTime(k string, v time.Time) error {
return gf.Set(k, v.Format(time.RFC3339))
}
// SetArray sets a string slice value (as a string) in the config file
func (gf *GeneralConfig) SetArray(k string, v []string) error {
b, e := json.Marshal(v)
if e != nil {
return e
}
return gf.SetBytes(k, b)
}
// Get gets a key/value pair from gf
func (gf *GeneralConfig) Get(k string) string {
return gf.Values[k]
}
// GetInt gets a key/value pair from gf and return it as an integer
// An error if it can't be converted
func (gf *GeneralConfig) GetInt(k string) (int, error) {
return strconv.Atoi(gf.Get(k))
}
// GetDateTime gets a key/value pair from gf and returns it as a time.Time
// An error if it can't be converted
func (gf *GeneralConfig) GetDateTime(k string) (time.Time, error) {
return time.Parse(time.RFC3339, gf.Get(k))
}
// GetBytes gets a key/value pair from gf and returns it as a byte slice
// Or an error if it fails for whatever reason
func (gf *GeneralConfig) GetBytes(k string) []byte {
return []byte(gf.Get(k))
}
func (gf *GeneralConfig) GetArray(k string) ([]string, error) {
var ret []string
err := json.Unmarshal(gf.GetBytes(k), &ret)
return ret, err
}
// DeleteKey removes a key from the file
func (gf *GeneralConfig) DeleteKey(k string) error {
oldVal := gf.Get(k)
delete(gf.Values, k)
if err := gf.Save(); err != nil {
gf.Values[k] = oldVal
return err
}
return nil
}