go 项目布局与管理

文章简明扼要的总结了 golang 项目在文件和文件夹布局上是怎么样的,有什么特别注意的点,另外常见的 go 项目管理是怎么做的。

go 项目布局

为了弄清楚 go 项目的布局(layout),我打算从 repo --> namespace --> module --> package --> file 的层次来说明,如下所示。

>> tree github.com
github.com
`-- user
    |-- module1
    |   |-- LICENSE
    |   |-- go.mod
    |   |-- module1.go
    |   |-- package1
    |   |   |-- fun1.go
    |   |   `-- fun2.go
    |   `-- package2
    |       |-- fun1.go
    |       |-- fun2.go
    |       `-- fun3.go
    `-- module2
        |-- LICENSE
        |-- cmd1
        |   `-- main.go
        |-- cmd2
        |   `-- main.go
        |-- go.mod
        |-- main.go
        `-- package1
            |-- sub-package1
            |   |-- sub-func1.go
            |   `-- sub-func2.go
            `-- fun1.go

github.com 代码仓库为例(这里可以同等替换为任意的代码仓库或代码管理平台,如gitlab.com):

  1. go 项目存储在代码仓库的 namespace 下面,GitHub 的 namespace 是 username 或者 organization 等即 github.com/user
  2. namespace 下可以有多个 go 项目,这些项目在 go 中被称为 module(模块)即 github.com/user/module1
  3. module 下可以有多个 package,例如github.com/user/module1下名为 package1 的包,package1 是一个功能相对独立的组件,需要注意的是func1.gofun2.gopackage ${package_name} 中的 package_name 需要跟该组件最后一层目录一致
  4. module 下还可以有多个 command,例如github.com/user/module2github.com/user/module2/cmd1下名的 main.go
  5. package 下面还可以嵌套 package,例如github.com/user/module2/package1/sub-package1

go 项目管理

1. go.mod

通过 go mod 命令行初始化项目:

go mod init ${module_name}

其中 module_name 从包管理和导入角度考虑一般是 repo/namespace/module-name,例如 "github.com/spf13/viper"

2. 依赖管理

通过 go mod 命令行管理项目的依赖:

go mod tidy

其它跟依赖管理相关还有 go mod edit, go mod download, go mod vendor 等,可以参考命令对应的文档。

3. 包升级

通过 go get -u 命令对依赖包进行升级:

go get -u github.com/xxx/xxx@v1.6.2
go get github.com/xxxx/xxx@q2516faf3

References

  1. Organizing a Go module - The Go Programming Language