在Go中创建包含命令的包,可以通过main包和cmd子目录结构来实现。以下是具体实现步骤和示例代码:
1. 项目结构
your-package/
├── cmd/
│ └── your-package/
│ └── main.go
├── internal/
│ └── config/
│ └── generator.go
├── go.mod
└── README.md
2. 主命令实现
cmd/your-package/main.go:
package main
import (
"fmt"
"os"
"path/filepath"
"your-package/internal/config"
)
func main() {
if len(os.Args) < 3 {
printUsage()
os.Exit(1)
}
command := os.Args[1]
subcommand := os.Args[2]
if command == "init" && subcommand == "config" {
generateConfig()
} else {
printUsage()
os.Exit(1)
}
}
func generateConfig() {
cwd, err := os.Getwd()
if err != nil {
fmt.Printf("获取当前目录失败: %v\n", err)
os.Exit(1)
}
configPath := filepath.Join(cwd, "config.yaml")
err = config.Generate(configPath)
if err != nil {
fmt.Printf("生成配置文件失败: %v\n", err)
os.Exit(1)
}
fmt.Printf("配置文件已生成: %s\n", configPath)
}
func printUsage() {
fmt.Println("用法: your-package init config")
fmt.Println("在当前目录生成配置文件")
}
3. 配置文件生成逻辑
internal/config/generator.go:
package config
import (
"fmt"
"os"
)
func Generate(filepath string) error {
configContent := `# 应用配置
app:
name: "my-application"
port: 8080
debug: true
database:
host: "localhost"
port: 5432
name: "appdb"
user: "admin"
logging:
level: "info"
file: "app.log"
`
return os.WriteFile(filepath, []byte(configContent), 0644)
}
4. go.mod 文件
module your-package
go 1.21
5. 安装和使用
用户安装:
go install your-package/cmd/your-package@latest
用户使用:
# 在用户项目中
your-package init config
6. 高级实现(使用cobra库)
如果需要更复杂的命令行功能,可以使用cobra库:
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/spf13/cobra"
"your-package/internal/config"
)
var rootCmd = &cobra.Command{
Use: "your-package",
Short: "Your package CLI tool",
}
var initCmd = &cobra.Command{
Use: "init",
Short: "初始化命令",
}
var configCmd = &cobra.Command{
Use: "config",
Short: "生成配置文件",
Run: func(cmd *cobra.Command, args []string) {
cwd, _ := os.Getwd()
configPath := filepath.Join(cwd, "config.yaml")
if err := config.Generate(configPath); err != nil {
fmt.Printf("错误: %v\n", err)
os.Exit(1)
}
fmt.Printf("配置文件已生成: %s\n", configPath)
},
}
func main() {
initCmd.AddCommand(configCmd)
rootCmd.AddCommand(initCmd)
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
7. 发布包
发布到GitHub后,用户可以通过以下方式使用:
go install github.com/yourusername/your-package/cmd/your-package@latest
这个实现允许用户通过your-package init config命令在当前工作目录生成配置文件。配置文件内容可以根据实际需求在config.Generate()函数中自定义。