第一个golang项目

第一个golang项目

  • 前因后果:因为工作需要使用一些工具将指定文件的特定内容替换成新的内容,然而网上找了一圈要不是收费要不是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

尽情享用吧

相关推荐
SHtop112 分钟前
模板语法
golang
Ajiang28247353041 小时前
贪吃蛇项目实现(C语言)——附源码
c语言·开发语言
guicai_guojia2 小时前
面试题篇: 跨域问题如何处理(Java和Nginx处理方式)
java·开发语言·nginx
鼠鼠龙年发大财2 小时前
fly专享
开发语言·php
hunandede2 小时前
直播相关02-录制麦克风声音,QT 信号与槽,自定义信号和槽
开发语言·qt
lzb_kkk3 小时前
【Redis】redis5种数据类型(哈希)
开发语言·redis·算法·缓存·哈希算法
Good_tea_h4 小时前
如何实现Java中的多态性
java·开发语言·python
格林威4 小时前
Baumer工业相机堡盟工业相机如何通过BGAPISDK使用短曝光功能(曝光可设置1微秒)(C语言)
c语言·开发语言·人工智能·数码相机·计算机视觉
老身聊发少年狂4 小时前
R语言xlsx,txt文件处理:以《书摘》00年-10年资源合集整理为例
开发语言·r语言
为为-180-3121-14554 小时前
R语言的Meta分析【全流程、不确定性分析】方法与Meta机器学习技术应用
开发语言·r语言