From 5c08a5faf30ca445d195b497ae89599255f038fa Mon Sep 17 00:00:00 2001 From: kingeasternsun Date: Wed, 23 Jun 2021 11:57:51 +0800 Subject: [PATCH 1/8] Update main.go add external toml config support --- main.go | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 5ff7f68..e2a2811 100644 --- a/main.go +++ b/main.go @@ -15,11 +15,13 @@ import ( "io" "io/ioutil" "os" + "path/filepath" "sort" "strconv" "strings" "unicode" + "github.com/BurntSushi/toml" "github.com/fatih/camelcase" "github.com/fatih/structtag" "golang.org/x/tools/go/buildutil" @@ -69,6 +71,14 @@ type config struct { valueFormat string clear bool clearOption bool + templateMap map[string]string // give different template for each tag +} + +// use toml to config the gomodifytags +type tomlConfig struct { + Add []string // add external tags + Transform string + TemplateMap map[string]string // give different template for each tag } func main() { @@ -119,6 +129,16 @@ func realMain() error { } func parseConfig(args []string) (*config, error) { + var tomlCfg tomlConfig + + ex, err := os.Executable() + if err == nil { + exPath := filepath.Dir(ex) + if _, err := toml.DecodeFile(filepath.Join(exPath, "gomodifytags.toml"), &tomlCfg); err != nil { + panic(err) + } + } + var ( // file flags flagFile = flag.String("file", "", "Filename to be parsed") @@ -197,12 +217,35 @@ func parseConfig(args []string) (*config, error) { skipUnexportedFields: *flagSkipUnexportedFields, } + cfg.templateMap = tomlCfg.TemplateMap + if cfg.templateMap == nil { + cfg.templateMap = make(map[string]string) + } + if tomlCfg.Transform != "" { + cfg.transform = tomlCfg.Transform + } + if *flagModified { cfg.modified = os.Stdin } + // add extenal tags config if *flagAddTags != "" { - cfg.add = strings.Split(*flagAddTags, ",") + inputAdds := strings.Split(*flagAddTags, ",") + + // remove duplicate tag + addMap := make(map[string]struct{}) + for _, add := range inputAdds { + addMap[add] = struct{}{} + } + for _, add := range tomlCfg.Add { + addMap[add] = struct{}{} + } + + for add, _ := range addMap { + cfg.add = append(cfg.add, add) + } + } if *flagAddOptions != "" { @@ -435,6 +478,10 @@ func (c *config) addTags(fieldName string, tags *structtag.Tags) (*structtag.Tag return nil, fmt.Errorf("unknown transform option %q", c.transform) } + if valueFormat, ok := c.templateMap[key]; ok { + name = strings.ReplaceAll(valueFormat, "$field", name) + } + tag, err := tags.Get(key) if err != nil { // tag doesn't exist, create a new one From 644846c6e55f2976355a2067e4ceaf23feb80c2f Mon Sep 17 00:00:00 2001 From: kingeasternsun Date: Wed, 23 Jun 2021 11:59:28 +0800 Subject: [PATCH 2/8] Update README.md --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 4342cb1..4b6d659 100644 --- a/README.md +++ b/README.md @@ -600,3 +600,18 @@ GO111MODULE=on go test -v -mod=vendor ``` If everything works fine, feel free to open a pull request with your changes. + + +# Use external config file + +when we use editors like vscode to add tags, the vscode can only add json tags for us, there is no way to change the config, so I add a toml config support. +we just need add a `gomodifytags.toml` in the same directory of gomodifytags. in linux we can use `whereis gomodifytags` to get the directory. +```toml +Add = ["form", "gorm"] +Transform = "camelcase" +[TemplateMap] + gorm = "column:$field" +``` + +- the `Add` will add external tags to user tag. +- the `TemplateMap` will add template for each tag From 2c7b82e5c045ab8aba3037e607fd368ff850e065 Mon Sep 17 00:00:00 2001 From: kingeasternsun Date: Wed, 23 Jun 2021 13:09:07 +0800 Subject: [PATCH 3/8] Update main.go toml template config ,overwrite the flag template --- main.go | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/main.go b/main.go index e2a2811..c93d3bb 100644 --- a/main.go +++ b/main.go @@ -135,7 +135,7 @@ func parseConfig(args []string) (*config, error) { if err == nil { exPath := filepath.Dir(ex) if _, err := toml.DecodeFile(filepath.Join(exPath, "gomodifytags.toml"), &tomlCfg); err != nil { - panic(err) + fmt.Println(err) } } @@ -462,11 +462,10 @@ func (c *config) addTags(fieldName string, tags *structtag.Tags) (*structtag.Tag unknown = true } - if c.valueFormat != "" { - name = strings.ReplaceAll(c.valueFormat, "$field", name) - } + tagName := name for _, key := range c.add { + splitted = strings.SplitN(key, ":", 2) if len(splitted) >= 2 { key = splitted[0] @@ -477,9 +476,13 @@ func (c *config) addTags(fieldName string, tags *structtag.Tags) (*structtag.Tag // might pass a value return nil, fmt.Errorf("unknown transform option %q", c.transform) } - + // toml template config ,overwrite the flag template if valueFormat, ok := c.templateMap[key]; ok { - name = strings.ReplaceAll(valueFormat, "$field", name) + tagName = strings.ReplaceAll(valueFormat, "$field", name) + } else if c.valueFormat != "" { + tagName = strings.ReplaceAll(c.valueFormat, "$field", name) + } else { + tagName = name } tag, err := tags.Get(key) @@ -487,10 +490,10 @@ func (c *config) addTags(fieldName string, tags *structtag.Tags) (*structtag.Tag // tag doesn't exist, create a new one tag = &structtag.Tag{ Key: key, - Name: name, + Name: tagName, } } else if c.override { - tag.Name = name + tag.Name = tagName } if err := tags.Set(tag); err != nil { From c94e6c473f807bb9c06363a36166bc8f23af2185 Mon Sep 17 00:00:00 2001 From: kingeasternsun Date: Wed, 23 Jun 2021 13:10:37 +0800 Subject: [PATCH 4/8] update go mod --- go.mod | 1 + go.sum | 2 ++ 2 files changed, 3 insertions(+) diff --git a/go.mod b/go.mod index 1a60d8e..4058e45 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,7 @@ module github.com/fatih/gomodifytags require ( + github.com/BurntSushi/toml v0.3.1 // indirect github.com/fatih/camelcase v1.0.0 github.com/fatih/structtag v1.2.0 golang.org/x/tools v0.0.0-20180824175216-6c1c5e93cdc1 diff --git a/go.sum b/go.sum index 3869a39..5e2c2e8 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= From b8430f11f2ddef8070c702984e28b4f0d343324e Mon Sep 17 00:00:00 2001 From: kingeasternsun Date: Wed, 23 Jun 2021 13:13:05 +0800 Subject: [PATCH 5/8] ignore the error --- main.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/main.go b/main.go index c93d3bb..eda8228 100644 --- a/main.go +++ b/main.go @@ -134,9 +134,7 @@ func parseConfig(args []string) (*config, error) { ex, err := os.Executable() if err == nil { exPath := filepath.Dir(ex) - if _, err := toml.DecodeFile(filepath.Join(exPath, "gomodifytags.toml"), &tomlCfg); err != nil { - fmt.Println(err) - } + toml.DecodeFile(filepath.Join(exPath, "gomodifytags.toml"), &tomlCfg) } var ( From af9db965cd4a6591d5d36ed8598349dc09d0d377 Mon Sep 17 00:00:00 2001 From: kingeasternsun Date: Wed, 23 Jun 2021 14:08:16 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=F0=9F=90=9B=20=20=20remove=20duplicate=20t?= =?UTF-8?q?ag,tag=20order=20should=20not=20change?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 ++++-- main.go | 12 +++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 4b6d659..eab28b0 100644 --- a/README.md +++ b/README.md @@ -613,5 +613,7 @@ Transform = "camelcase" gorm = "column:$field" ``` -- the `Add` will add external tags to user tag. -- the `TemplateMap` will add template for each tag +- the `Add` will add external tags to flag tag. +- the `TemplateMap` will add template for each tag,overwrite the flag template. + +https://user-images.githubusercontent.com/5291739/123039779-53382900-d425-11eb-9ae9-daa84f00bb23.gif \ No newline at end of file diff --git a/main.go b/main.go index eda8228..d6e822e 100644 --- a/main.go +++ b/main.go @@ -229,19 +229,17 @@ func parseConfig(args []string) (*config, error) { // add extenal tags config if *flagAddTags != "" { - inputAdds := strings.Split(*flagAddTags, ",") + cfg.add = strings.Split(*flagAddTags, ",") // remove duplicate tag addMap := make(map[string]struct{}) - for _, add := range inputAdds { + for _, add := range cfg.add { addMap[add] = struct{}{} } for _, add := range tomlCfg.Add { - addMap[add] = struct{}{} - } - - for add, _ := range addMap { - cfg.add = append(cfg.add, add) + if _, ok := addMap[add]; !ok { + cfg.add = append(cfg.add, add) + } } } From 6a2b0115448e552f5da31af44a488e01998fec2a Mon Sep 17 00:00:00 2001 From: kingeasternsun Date: Wed, 23 Jun 2021 14:21:14 +0800 Subject: [PATCH 7/8] update doc --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eab28b0..cd572bb 100644 --- a/README.md +++ b/README.md @@ -616,4 +616,4 @@ Transform = "camelcase" - the `Add` will add external tags to flag tag. - the `TemplateMap` will add template for each tag,overwrite the flag template. -https://user-images.githubusercontent.com/5291739/123039779-53382900-d425-11eb-9ae9-daa84f00bb23.gif \ No newline at end of file +![gomodifytags](https://user-images.githubusercontent.com/5291739/123039779-53382900-d425-11eb-9ae9-daa84f00bb23.gif) \ No newline at end of file From 013263a0f595cb2af98f9159001e38d284eb1a00 Mon Sep 17 00:00:00 2001 From: kingeasternsun Date: Thu, 24 Jun 2021 10:05:22 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E2=9C=A8=20=20add=20new=20feature=20to=20s?= =?UTF-8?q?upport=20config=20transform=20for=20each=20tag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 37 ++++++++++++++++++++++--------------- main.go | 54 ++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 58 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index cd572bb..3fe6d18 100644 --- a/README.md +++ b/README.md @@ -573,6 +573,28 @@ Each archive entry consists of: - the (decimal) file size, followed by a newline - the contents of the file +## Use external config file + +when we use editors like vscode to add tags, the vscode can only add json tags for us, there is no way to change the config, so I add a toml config support. +we just need add a `gomodifytags.toml` in the same directory of gomodifytags. in linux we can use `whereis gomodifytags` to get the directory. +```toml +Add = ["form", "gorm","binding"] +Transform = "camelcase" +[TemplateMap] + gorm = "column:$field" + binding = "required" +[TransformMap] + gorm = "snakecase" + +``` + +- the `Add` will add external tags to flag tag. +- the `Transform` will config transform for all tag. +- the `TemplateMap` will config template for each tag,overwrite the flag template. +- the `TransformMap` will config transform for each tag,overwrite the flag transform and Transform. + +![gomodifytags](https://user-images.githubusercontent.com/5291739/123039779-53382900-d425-11eb-9ae9-daa84f00bb23.gif) + # Development At least Go `v1.11.x` is required. Older versions might work, but it's not @@ -602,18 +624,3 @@ GO111MODULE=on go test -v -mod=vendor If everything works fine, feel free to open a pull request with your changes. -# Use external config file - -when we use editors like vscode to add tags, the vscode can only add json tags for us, there is no way to change the config, so I add a toml config support. -we just need add a `gomodifytags.toml` in the same directory of gomodifytags. in linux we can use `whereis gomodifytags` to get the directory. -```toml -Add = ["form", "gorm"] -Transform = "camelcase" -[TemplateMap] - gorm = "column:$field" -``` - -- the `Add` will add external tags to flag tag. -- the `TemplateMap` will add template for each tag,overwrite the flag template. - -![gomodifytags](https://user-images.githubusercontent.com/5291739/123039779-53382900-d425-11eb-9ae9-daa84f00bb23.gif) \ No newline at end of file diff --git a/main.go b/main.go index d6e822e..f910ab8 100644 --- a/main.go +++ b/main.go @@ -66,19 +66,21 @@ type config struct { override bool skipUnexportedFields bool - transform string - sort bool - valueFormat string - clear bool - clearOption bool - templateMap map[string]string // give different template for each tag + transform string + sort bool + valueFormat string + clear bool + clearOption bool + templateMap map[string]string // give different template for each tag + transformMap map[string]string // give different transform for each tag } // use toml to config the gomodifytags type tomlConfig struct { - Add []string // add external tags - Transform string - TemplateMap map[string]string // give different template for each tag + Add []string // add external tags + Transform string + TemplateMap map[string]string // give different template for each tag + TransformMap map[string]string // give different transform for each tag } func main() { @@ -222,6 +224,10 @@ func parseConfig(args []string) (*config, error) { if tomlCfg.Transform != "" { cfg.transform = tomlCfg.Transform } + cfg.transformMap = tomlCfg.TransformMap + if cfg.transformMap == nil { + cfg.transformMap = make(map[string]string) + } if *flagModified { cfg.modified = os.Stdin @@ -412,16 +418,12 @@ func (c *config) addTagOptions(tags *structtag.Tags) (*structtag.Tags, error) { return tags, nil } -func (c *config) addTags(fieldName string, tags *structtag.Tags) (*structtag.Tags, error) { - if c.add == nil || len(c.add) == 0 { - return tags, nil - } +func convertFieldName(transform, fieldName string) (name string, unknown bool) { + name = "" + unknown = false splitted := camelcase.Split(fieldName) - name := "" - - unknown := false - switch c.transform { + switch transform { case "snakecase": var lowerSplitted []string for _, s := range splitted { @@ -458,11 +460,27 @@ func (c *config) addTags(fieldName string, tags *structtag.Tags) (*structtag.Tag unknown = true } + return +} + +func (c *config) addTags(fieldName string, tags *structtag.Tags) (*structtag.Tags, error) { + if c.add == nil || len(c.add) == 0 { + return tags, nil + } + + name := fieldName tagName := name + unknown := false for _, key := range c.add { - splitted = strings.SplitN(key, ":", 2) + if transform, ok := c.transformMap[key]; ok { + name, unknown = convertFieldName(transform, fieldName) + } else { + name, unknown = convertFieldName(c.transform, fieldName) + } + + splitted := strings.SplitN(key, ":", 2) if len(splitted) >= 2 { key = splitted[0] name = strings.Join(splitted[1:], "")