Giter Site home page Giter Site logo

go_fmt's Introduction

Go 代码格式化

1 功能说明

  • 格式化 import 部分:分3段式,依默认为 标准库第三方库项目自身库
  • 格式化单行注释:若为 //注释内容,调整为 //{空格}注释内容
  • 默认只对 git 项目库里有修改的进行格式化
  • 支持将多行的 copyright 注释修改为单行格式(默认不调整)
  • 简化代码
  • struct 赋值表达式,自动补齐 key
  • 补充空行、移除多余的空行

对于 import 部分:

1.可使用-mi参数来控制是否将多段import合并为一段(默认否)。
2.对于注释的import path,会按照其实际路径参与分组和排序。
3.对于非末行的注释的位置会和其下面紧挨的import path绑定在一起。
4.末行的注释则会放入import的头部。
5.import path 不要使用相对路径(如./../)。

会忽略当前目录以及子目录下的 testdatavendor 目录。
若需要可进入其目录里执行该命令。

Example 1:补齐 struct key
- u2 := User{"hello", 12}
+ u2 := User{Name: "hello", Age: 12}
Example 2:注释格式化
- //User 注释内容
+ // User 注释内容
type User struct{
Example 3:简化代码

1.简化循环逻辑:

- s[a:len(s)]
+ s[a:]

- for x, _ = range v {...}
+ for x = range v {...}

- for _ = range v {...}
+ for range v {...}

- for {
+ for ok{
-   if !ok {
-     break
-   }
   // do something
 }

2.简化判断逻辑:

- if b == true {
+ if b { 

- if b == false {
+ if !b {

- if b != true {
+ if !b {

- if b != false {
+ if b {

- for b == true {
+ for b {

- _ = 1 == index
+ _ = index == 1

- _ = 1 < index
+ _ = index > 1

 func ok() bool {
- 	if a > b {
- 		return true
- 	}else{
- 		return false
+ 	return a > b
} 

func ok() bool {
- 	if a > b {
- 		return true
- 	return false
+ 	return a > b
} 

- if val!=nil && len(val)!=0 {
+ if len(val)!=0 {
   // do something
}

3.使用 strings.Contains 替换 strings.Countstrings.Index

- strings.Count(s, "a") == 0
+ !strings.Contains(s, "a")

- strings.Count(s, "a") > 0
+ strings.Contains(s, "a")

- strings.Count(s, "a") != 0
+ strings.Contains(s, "a")

bytes.Count 具有和 strings.Count 一样的规则。

- strings.Index(s, "a") == -1
+ !strings.Contains(s, "a")

- strings.Index(s, "a") != -1
+ strings.Contains(s, "a")

bytes.Index 具有和 strings.Index 一样的规则。

4.字符串的比较:

使用 bytes.Equal 替换 bytes.Compare

- bytes.Compare(s,a) == 0
+ bytes.Equal(s, a)

- bytes.Compare(s,a) != 0
+ !bytes.Equal(s, a)

使用 == 替换 strings.Compare

- strings.Compare("abc","a") == 0
+ "abc" == "a"

- strings.Compare("abc","a") != 0
+ "abc" != "a"

5.递增 1、递减 1:

- i += 1
+ i++

- i -= 1
+ i--

6.time.Since 和 time.Until time.Since 替换 time.Now().Sub:

- time.Now().Sub( t1 )
+ time.Since( t1 )

time.Until 替换 t.Sub( time.Now() ):

- t1.Sub( time.Now() )
+ time.Until( t1 )

7.channel:

- _ = <-chan
+ <-done

8.map:

- x, _ := someMap["key"]
+ x := someMap["key"]

9.fmt:

- fmt.Errorf("hello")
+ errors.New("hello")

- fmt.Printf("abc")
+ fmt.Print("abc")

- log.Printf("abc")
+ log.Print("abc")

- _ = errors.New(fmt.Sprintf("hello"))
+ _ = errors.New("hello")

- _ = errors.New(fmt.Sprintf("hello %s", "world"))
+ _ = fmt.Errorf("hello %s", "world")

- bf.Write([]byte(fmt.Sprintf("hello %d", 1)))
+ fmt.Fprintf(bf,"hello %d",1)

- fmt.Sprintf("%d",123)  // 性能  1
+ strconv.Atoi(123)      // 性能  3

- fmt.Sprintf("%v",123)
+ strconv.Atoi(123)   

- fmt.Sprintf("%d",int32Num)
+ strconv.FormatInt(int64(int32Num), 10)

- fmt.Sprintf("%d",uint32Num)
+ strconv.FormatUint(uint64(uint32Num), 10)

10.raw string :

- regexp.Compile("\\A(\\w+) profile: total \\d+\\n\\z")
+ regexp.Compile(`\A(\w+) profile: total \d+\n\z`)

11.sort :

- sort.Sort(sort.StringSlice(x))
+ sort.Strings(x)
Example 4:基于表达式规则,重写代码 使用 `-rr=false` 可以使用默认内置规则不生效。
  1. 替换废弃的 ioutil 的函数调用:
import (
-	"io/ioutil"
+	"io
)

- buf, err := ioutil.ReadAll(f)
+ buf, err := io.ReadAll(f)
Example 5:移除多余的空行
  1. 移除 struct 内部前后多余的空行:
type userfn91 struct{
-				
	name string
-				
}
  1. 移除 func 内部前后多余的空行:
fn1() {
-				
	println("hello")
-				
}
  1. 空 func 变为一行:
- fn1() {
- }
+ fn1() {}
Example 6:补充空行 在适当的位置添加空行可以增加代码的可读性。
  1. struct 有文档的字段前后添加换行:
type User1 struct {
-				
	// on Name
	Name string
+				
	// on Age
	Age int
+				
	Grade int
	Class int

	Address string // 前面有空行,会保持
}
  1. interface 有文档的方法前后添加换行:
type Group1 interface {
-				
	// Register 注册延迟函数
	Register(fn func())
+				
	Add()
+				
	// on Delete
	Delete()
+				
	Fn1()

	Fn2() // 前面有空行,会保持
-				
}
  1. 多个定义之间添加空行:
type (
	User1 struct {
		name string
	}
+				
	User1 struct {
-				
		name string
	}
)
  1. 全局的,不同类型定义之间添加空行:
var a="hello"
var b="world" // after b
+				
const c01="say"
+ 				
var a0 = "a0"
Example 7:Array / Slice 格式化
- var _ = []int{
-	1, 2, 
-	3, 4, 5}
// 当代码是如上这种 3 行格式的时候(这 3 行内不能有注释),会格式化为下面这样。
// 上面第一行是 2 个元素,所以按照每行 2 个元素格式化对齐。

+	var _ = []int{
+	 1, 2,
+	 3, 4,
+	 5,
+	 }

2 安装/更新

export GO111MODULE=on
go env GOPROXY=https://goproxy.cn,direct

go install github.com/fsgo/go_fmt/cmd/gorgeous@latest

升级 Go 版本后,请用最新版本 go 重新安装/更新 gorgeous
最低 Go 版本:go1.22

3 使用

3.0 help

gorgeous -help

usage: gorgeous [flags] [path ...]
  -d	display diffs instead of rewriting files
  -df string
    	display diffs format, support: text, json (default "text")
  -e	enable extra rules (default true)
  -ig string
    	import groups sort rule,
    	stc: Go Standard package, Third Party package, Current package
    	sct: Go Standard package, Current package, Third Party package
    	 (default "stc")
  -local string
    	current package path, will put imports beginning with this string as 3rd-party packages.
    	by default, it will got from 'go.mod' file.
    	 (default "auto")
  -mi
    	merge imports into one section.
    	with env 'GORGEOUS_MI=false' to set default value as false (default true)
  -r value
    	rewrite rule (e.g., 'a[b:len(a)] -> a[b:]')
    	or a file path for rewrite rules (like -rr)

  -rr
    	rewrite with build in rules:
    	a[b:len(a)] -> a[b:]
    	interface{} -> any                    // go1.18
    	io/#ioutil.NopCloser -> io.NopCloser  // go1.16
    	io/#ioutil.ReadAll   -> io.ReadAll    // go1.16
    	io/#ioutil.ReadFile  -> os.ReadFile   // go1.16
    	io/#ioutil.TempFile  -> os.CreateTemp // go1.16
    	io/#ioutil.TempDir   -> os.MkdirTemp  // go1.16
    	io/#ioutil.WriteFile -> os.WriteFile  // go1.16
    	io/#ioutil.Discard   -> io.Discard    // go1.16

    	with env 'GORGEOUS_RR=false' to set default value as false
    	 (default true)
  -s	simplify code (default true)
  -slcr
    	multiline copyright to single-line
    	with env 'GORGEOUS_SLCR=true' to set default value as true (default true)
  -trace
    	show trace messages
  -w	write result to (source) file instead of stdout (default true)

3.1 格式化 git 项目里有修改的.go文件

$ gorgeous

3.2 对当前目录所有 .go 文件格式化

$ gorgeous ./...

3.3 对指定 .go 文件格式化

$ gorgeous abc.go

3.4 从 STDIN 读取代码并输出到 STDOUT

$ cat code.go|gorgeous stdin

4 git hooks

在执行 git 命令时自动格式化或者检查是否已经完成格式化。

4.1 使用 bin-auto-switcher 添加全局 Hooks

bin-auto-switcher 可以很方便的对任意命令添加前置和后置 Hooks。

  1. 安装 git 替换命令(安装后,执行 git 命令时,实际会执行此命令,并执行配置的 Hooks):
    go install github.com/fsgo/bin-auto-switcher/git@latest
  2. 编辑配置文件 ~/.config/bas/git.toml
[[Rules]]
Cmd = "/usr/local/bin/git" # 替换为实际 git 命令的地址

[[Rules.Pre]]
Match = "^add\\s"  # 在执行 git add 命令前执行
Trace = true       # 打印日志
#Cond  = ["in_dir /home/work/goapps"]
Cond  = ["go_module"]
Cmd   = "gorgeous"

# 在 go.mod 文件所在目录下执行 gorgeous 命令
#Cmd   = "inner:find-exec"
#Args  = ["-name","go.mod","-dir_not","testdata","gorgeous"]

4.2 使用 git hooks

编辑项目的 .git/hooks/pre-commit文件,将gorgeous命令加入。

# 检查是否格式化
echo -e '\n gorgeous -d \n' >> $(git rev-parse --git-dir)/hooks/pre-commit

chmod 777 $(git rev-parse --git-dir)/hooks/pre-commit

# 或者:自动格式化
echo -e '\n gorgeous \n git add . \n' >> $(git rev-parse --git-dir)/hooks/pre-commit

还可以配置到全局 Hooks:

该方式会导致项目自身的 hooks 失效。
若项目有自己的 hooks,请不要配置全局而要配置到单个项目。

mkdir -p ~/.git_config/hooks/
git config --global core.hooksPath ~/.git_config/hooks/

echo -e '\n gorgeous -d\n' >>  ~/.git_config/hooks/pre-commit
chmod 777 ~/.git_config/hooks/pre-commit

5 GitHub Actions

- name: Set up Go
  uses: actions/setup-go@v4
  with:
    go-version: 1.20

- name: gorgeous style check
  run: go install github.com/fsgo/go_fmt/cmd/gorgeous@latest && gorgeous -d ./...

6 Visual Studio Code

6.1 As goformat

  1. Install as goformat:
go install github.com/fsgo/go_fmt/cmd/goformat@latest
  1. 配置的 Go: Format Tool,设置为 "goformat":
  "go.formatTool": "goformat"

6.2 Run on Save

  1. 先安装插件 Run on Save

  2. 配置插件,在保存文件的时候执行格式化命令:

  "runOnSave.commands": [
    {
        "match": "\\.go$",
        "command": "cd ${fileDirname} && gorgeous -rr ${fileBasename}",
        "runIn":"terminal"
    }
 ]

3.配置的 Go: Format Tool,设置为 "default":

  "go.formatTool": "default"

go_fmt's People

Contributors

hidu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

go_fmt's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.