第一个golang项目
- 开发环境
- 安装golang
- Visual Studio Code安装golang语言插件
- 初始化项目
- 创建目录
- 初始化golang配置
- 开始开发
- 安装所需依赖
- 创建main.go
- 创建配置文件
- 创建命令
- 版本命令
- 查看指定目录指定后缀文件并将指定内容替换为新内容
- 打包并运行
- 前因后果:因为工作需要使用一些工具将指定文件的特定内容替换成新的内容,然而网上找了一圈要不是收费要不是linux平台的shell脚本,使用都太麻烦。so…就想自己写一个小工具来完成自己的需求,所以就有了这个项目。
- 目的是记录一下整个过程。
- 基于本人有一定开发基础的前提下进行。
开发环境
- 操作系统:Window 10
- CPU:Intel® Core™ i5-7500 CPU @ 3.40GHz 3.40 GHz
- 内存:16.0 GB
- 硬盘:1TB
- 开发工具:Visual Studio Code(需要安装golang语言插件)
安装golang
- 安装golang,下载绿色版go1.23.0.windows-amd64
- 配置环境PATH变量,增加golang安装路径
- 配置环境变量,CGO_ENABLED=1
- 配置环境变量,GO111MODULE=on
- 配置环境变量,GOPROXY=https://goproxy.cn,国内代理加速
- 安装mingw-w64
- 配置环境PATH变量,增加mingw-w64安装路径
- 验证go安装版本,执行
go version
Visual Studio Code安装golang语言插件
初始化项目
创建目录
- 打开Visual Studio Code
- 创建一个本地目录dev-tools
初始化golang配置
-
打开终端
-
执行
go mod init gitee/eddy-org/dev-tools
开始开发
安装所需依赖
# toml配置文件依赖
go get -u github.com/spf13/viper
go install github.com/spf13/viper
此时项目的基本结构已经完成,会出现go.mod、go.sum两个文件
创建main.go
- 创建main.go
- 这是程序入口,其中包含main函数
package main
import (
"flag"
"gitee/eddy-org/dev-tools/commands"
"log"
"os"
)
func main() {
if len(os.Args) >= 2 {
if os.Args[1] == "version" {
commands.Version()
} else if os.Args[1] == "replace" {
var dir string
flagSet := flag.NewFlagSet("devtools command: ", flag.ExitOnError)
flagSet.StringVar(&dir, "dir", "", "Which dir to replace")
if err := flagSet.Parse(os.Args[2:]); err != nil {
log.Printf("解析参数失败: %v", err)
os.Exit(1)
}
commands.Replace(dir)
}
}
}
创建配置文件
- 创建配置文件config.toml
- 里面配置了版本号、以及我们内容替换的一些参数
version = "0.0.1"
[standard]
root-path = "E:\\release\\release-v3\\standard\\"
suffix = ".setting"
current-version = "v3.5.9"
new-version = "v3.6.0"
[standard-fix]
root-path = "E:\\release\\release-v3\\standard-fix\\"
current-version = "v3.5.9"
suffix = ".setting"
new-version = "v3.6.0"
[saas]
root-path = "E:\\release\\release-v3\\saas\\"
suffix = ".setting"
current-version = "v3.5.9"
new-version = "v3.6.0"
[saas-fix]
root-path = "E:\\release\\release-v3\\saas-fix\\"
suffix = ".setting"
current-version = "v3.5.9"
new-version = "v3.6.0"
创建命令
- 先创建commands目录
- 创建version.go,用于查看当前工具版本
package commands
import (
"bufio"
"log"
"os"
"github.com/spf13/viper"
)
func Version() {
viper.SetConfigName("config") // 配置文件名(不包含扩展名)
viper.SetConfigType("toml") // 配置文件格式
viper.AddConfigPath(".") // 查找配置文件的路径
if err := viper.ReadInConfig(); err != nil {
log.Fatalf("Error reading config file, %s", err)
}
version := viper.Get("version").(string)
log.Printf("current version is %s", version)
log.Printf("程序执行完毕,请按Enter键退出...")
reader := bufio.NewReader(os.Stdin)
reader.ReadByte() // 读取一个字节,这将阻塞直到用户输入
}
- 创建replace.go,用于实现我的内容替换需求
package commands
import (
"bufio"
"log"
"os"
"path/filepath"
"strings"
"github.com/spf13/viper"
)
func walkDir(dir, suffix string) []string {
var files []string
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() && strings.HasSuffix(info.Name(), suffix) {
files = append(files, path)
}
return nil
})
if err != nil {
log.Printf("walkDir: %v", err)
}
return files
}
func replaceContentInFile(filePath, oldStr, newStr string) error {
// 读取文件内容
content, err := os.ReadFile(filePath)
if err != nil {
return err
}
// 替换内容
newContent := strings.ReplaceAll(string(content), oldStr, newStr)
// 写入新内容到文件
return os.WriteFile(filePath, []byte(newContent), 0644)
}
func Replace(dir string) {
viper.SetConfigName("config") // 配置文件名(不包含扩展名)
viper.SetConfigType("toml") // 配置文件格式
viper.AddConfigPath(".") // 查找配置文件的路径
if err := viper.ReadInConfig(); err != nil {
log.Fatalf("Error reading config file, %s", err)
}
// 使用参数
log.Printf("Replace dir is %s", dir)
pathKey := dir + ".root-path"
suffixKey := dir + ".suffix"
currentKey := dir + ".current-version"
newKey := dir + ".new-version"
rootPath := viper.Get(pathKey).(string)
suffix := viper.Get(suffixKey).(string)
oldStr := viper.Get(currentKey).(string)
newStr := viper.Get(newKey).(string)
log.Printf("rootPath is %s", rootPath)
log.Printf("suffix is %s", suffix)
log.Printf("oldStr is %s", oldStr)
log.Printf("newStr is %s", newStr)
files := walkDir(rootPath, suffix)
log.Printf("Find files %d", len(files))
for _, file := range files {
err := replaceContentInFile(file, oldStr, newStr)
if err != nil {
panic(err)
}
}
log.Printf("程序执行完毕,请按Enter键退出...")
reader := bufio.NewReader(os.Stdin)
reader.ReadByte() // 读取一个字节,这将阻塞直到用户输入
}
版本命令
go run main.go version
查看指定目录指定后缀文件并将指定内容替换为新内容
go run main.go replace -dir standard-fix
打包并运行
go build -v -ldflags "-linkmode external -extldflags '-static' -w" -o devtools.exe main.go
devtools.exe version
devtools.exe replace -dir standard-fix
https://gitee.com/xqxyxchy/dev-tools
尽情享用吧