Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support workspace for backup files #77

Merged
merged 1 commit into from
Dec 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions configs/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package configs

import (
"errors"
"fmt"
"io/ioutil"
"os"
"path"

"gopkg.in/yaml.v3"
)

const (
configFileName = `birdwatcher.yaml`
defaultWorkspace = `bw_workspace`
)

var (
errConfigPathNotExist = errors.New("config path not exist")
errConfigPathIsFile = errors.New("config path is file")
)

// Config stores birdwatcher config items.
type Config struct {
// birdwatcher configuration folder path
// default $PWD/.bw_config
ConfigPath string `yaml:"-"`
// backup workspace path, default $PWD/bw_workspace
WorkspacePath string `yaml:"WorkspacePath"`
}

func (c *Config) load() error {
err := c.checkConfigPath()
if err != nil {
return err
}

f, err := os.Open(c.getConfigPath())
if err != nil {
return err
}
defer f.Close()
bs, err := ioutil.ReadAll(f)
if err != nil {
return err
}

return yaml.Unmarshal(bs, c)
}

func (c *Config) getConfigPath() string {
return path.Join(c.ConfigPath, configFileName)
}

// checkConfigPath exists and is a directory.
func (c *Config) checkConfigPath() error {
info, err := os.Stat(c.ConfigPath)
if err != nil {
// not exist, return specified type to handle
if os.IsNotExist(err) {
return errConfigPathNotExist
}
return err
}
if !info.IsDir() {
fmt.Printf("%s is not a directory\n", c.ConfigPath)
return fmt.Errorf("%w(%s)", errConfigPathIsFile, configFileName)
}

return nil
}

func (c *Config) createDefault() error {
err := os.MkdirAll(c.ConfigPath, os.ModePerm)
if err != nil {
return err
}

file, err := os.Create(c.getConfigPath())

if err != nil {
return err
}
defer file.Close()

// setup default value
c.WorkspacePath = defaultWorkspace

bs, err := yaml.Marshal(c)
if err != nil {
fmt.Println("failed to marshal config", err.Error())
return err
}

file.Write(bs)
return nil
}

func NewConfig(configPath string) (*Config, error) {
config := &Config{
ConfigPath: configPath,
}
err := config.load()
// config path not exist, may first time to run
if errors.Is(err, errConfigPathNotExist) {
return config, config.createDefault()
}

return config, err
}
9 changes: 1 addition & 8 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ require (
github.com/samber/lo v1.28.2
github.com/spf13/cobra v1.5.0
github.com/spf13/pflag v1.0.5
github.com/streamnative/pulsarctl v0.5.0
github.com/stretchr/testify v1.8.0
go.etcd.io/etcd/api/v3 v3.5.4
go.etcd.io/etcd/client/v3 v3.5.4
Expand Down Expand Up @@ -45,9 +46,7 @@ require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/dvsekhvalnov/jose2go v0.0.0-20180829124132-7f401d37b68a // indirect
github.com/fatih/color v1.7.0 // indirect
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/goccy/go-json v0.9.6 // indirect
github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
Expand All @@ -59,7 +58,6 @@ require (
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
github.com/imdario/mergo v0.3.8 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jonboulle/clockwork v0.2.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
Expand All @@ -68,10 +66,7 @@ require (
github.com/klauspost/compress v1.14.2 // indirect
github.com/klauspost/cpuid v1.3.1 // indirect
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
github.com/kris-nova/logger v0.0.0-20181127235838-fd0d87064b06 // indirect
github.com/kris-nova/lolgopher v0.0.0-20180921204813-313b3abb0d9b // indirect
github.com/linkedin/goavro/v2 v2.11.1 // indirect
github.com/magiconair/properties v1.8.1 // indirect
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mattn/go-runewidth v0.0.9 // indirect
Expand All @@ -84,7 +79,6 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mtibben/percent v0.2.1 // indirect
github.com/olekukonko/tablewriter v0.0.1 // indirect
github.com/pierrec/lz4 v2.0.5+incompatible // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/term v1.2.0-beta.2 // indirect
Expand All @@ -97,7 +91,6 @@ require (
github.com/sirupsen/logrus v1.8.1 // indirect
github.com/soheilhy/cmux v0.1.5 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/streamnative/pulsarctl v0.5.0 // indirect
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
github.com/zeebo/xxh3 v1.0.1 // indirect
Expand Down
1 change: 0 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,6 @@ github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
Expand Down
26 changes: 26 additions & 0 deletions models/workspace.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package models

import "github.com/golang/protobuf/proto"

// WorkspaceMeta stores birdwatcher workspace information.
type WorkspaceMeta struct {
// Version semver for workspace meta
Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
// instance name, as rootPath for key prefix
Instance string `protobuf:"bytes,2,opt,name=instance,proto3" json:"instance,omitempty"`
// MetaPath used in keys
MetaPath string `protobuf:"bytes,3,opt,name=meta_path,proto3" json:"meta_path,omitempty"`
}

// Reset implements protoiface.MessageV1
func (v *WorkspaceMeta) Reset() {
*v = WorkspaceMeta{}
}

// String implements protoiface.MessageV1
func (v *WorkspaceMeta) String() string {
return proto.CompactTextString(v)
}

// String implements protoiface.MessageV1
func (v *WorkspaceMeta) ProtoMessage() {}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package states
package autocomplete

import (
"fmt"
Expand Down Expand Up @@ -112,6 +112,13 @@ func (c *flagCandidate) NextCandidates(current []acCandidate) []acCandidate {
return current
}

// SuggestInputCommands returns suggestions based on command setup.
func SuggestInputCommands(input string, commands []*cobra.Command) map[string]string {
iResult := parseInput(input)

return findCmdSuggestions(iResult.parts, commands)
}

func findCmdSuggestions(comps []cComp, commands []*cobra.Command) map[string]string {
// no suggestion if input is empty
if len(comps) == 0 {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package states
package autocomplete

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion states/cmd.go → states/autocomplete/comp.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package states
package autocomplete

type cmdCompType int

Expand Down
79 changes: 79 additions & 0 deletions states/autocomplete/input.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package autocomplete

import (
"strings"

"github.com/samber/lo"
)

func parseInput(input string) inputResult {
// check is end with space
isEndBlank := strings.HasSuffix(input, " ")

parts := strings.Split(input, " ")
parts = lo.Filter(parts, func(part string, idx int) bool {
return part != ""
})

comps := make([]cComp, 0, len(parts))
currentFlagValue := false

for _, part := range parts {
// next part is flag value
// just set last comp cValue
if currentFlagValue {
comps[len(comps)-1].cValue = part
currentFlagValue = false
continue
}
// is flag
if strings.HasPrefix(part, "-") {
raw := strings.TrimLeft(part, "-")
if strings.Contains(raw, "=") {
parts := strings.Split(raw, "=")
// a=b
if len(parts) == 2 {
comps = append(comps, cComp{
raw: part,
cTag: parts[0],
cValue: parts[1],
cType: cmdCompFlag,
})
}
// TODO handle part len != 2
} else {
currentFlagValue = true
comps = append(comps, cComp{
raw: part,
cTag: raw,
cType: cmdCompFlag,
})
}
} else {
comps = append(comps, cComp{
raw: part,
cTag: part,
cType: cmdCompCommand,
})
}
}

is := inputStateCmd
if currentFlagValue {
if isEndBlank {
is = inputStateFlagValue
} else {
is = inputStateFlagTag
}
}

// add empty comp if end with space
if isEndBlank {
comps = append(comps, cComp{cType: cmdCompCommand})
}

return inputResult{
parts: comps,
state: is,
}
}
Loading