golang使用占位符创建文本模板并集成Git仓库元数据的插件库tbd
Golang 使用占位符创建文本模板并集成 Git 仓库元数据的插件库 tbd
简介
tbd
(to be defined) 是一个简单易用的文本模板工具,支持通过占位符创建动态文本模板,并自动集成 Git 仓库元数据。
内置变量
当在 Git 仓库中执行时,tbd
会自动导出一些与 Git 仓库相关的变量:
ARCH
- 系统架构OS
- 操作系统REPO_COMMIT
- 仓库提交哈希REPO_HOST
- 仓库主机REPO_NAME
- 仓库名称REPO_ROOT
- 仓库根目录REPO_TAG
- 仓库标签REPO_TAG_CLEAN
- 清理后的仓库标签REPO_URL
- 仓库 URLTIMESTAMP
- 时间戳
查看当前变量:
$ tbd vars
+----------------+------------------------------------------+
| ARCH | amd64 |
| OS | linux |
| REPO_COMMIT | a3193274112d3a6f5c2a0277e2ca07ec238d622f |
| REPO_HOST | github.com |
| REPO_NAME | tbd |
| REPO_ROOT | lucasepe |
| REPO_TAG | v0.1.1 |
| REPO_TAG_CLEAN | 0.1.1 |
| REPO_URL | https://github.com/lucasepe/tbd |
| TIMESTAMP | 2021-07-26T14:22:36Z |
+----------------+------------------------------------------+
模板示例
模板是包含占位符的文本文档,占位符由 {{
和 }}
包围。
YAML 模板示例
apiVersion: v1
kind: Pod
metadata:
name: {{ metadata.name }}
labels:
app: {{ metadata.labels.app }}
spec:
containers:
- name: {{ container.1.name }}
image: {{ container.1.image }}
ports:
- containerPort: {{ container.1.port }}
- name: {{ container.2.name }}
image: {{ container.2.image }}
ports:
- containerPort: {{ container.2.port }}
文本模板示例
{{ greeting }}
I will be out of the office from {{ start.date }} until {{ return.date }}.
If you need immediate assistance while I'm away, please email {{ contact.email }}.
Best,
{{ name }}
定义占位符值
创建变量文件定义占位符值:
# metadata values
metadata.name = rss-site
metadata.labels.app = web
# containers values
container.1.name = front-end
container.1.image = nginx
container.1.port = 80
container.2.name = rss-reader
container.2.image: nickchase/rss-php-nginx:v1
container.2.port: 88
或:
greeting: Greetings
start.date: August, 9
return.date: August 23
contact.email: pinco.pallo@gmail.com
name: Pinco Pallo
填充模板
使用 merge
命令填充模板:
$ tbd merge /path/to/your/template /path/to/your/envfile
示例:
$ tbd merge testdata/sample.tbd testdata/sample.vars
输出:
Greetings
I will be out of the office from August, 9 until August 23.
If you need immediate assistance while I'm away, please email pinco.pallo@gmail.com.
Best,
Pinco Pallo
列出模板占位符
使用 marks
命令:
$ tbd marks /path/to/your/template
示例:
$ tbd marks testdata/sample.tbd
greeting
start.date
return.date
contact.email
name
列出所有变量
使用 vars
命令:
$ tbd vars /path/to/your/envfile
示例:
$ tbd vars testdata/sample.vars
+----------------+------------------------------------------+
| Label | Value |
+----------------+------------------------------------------+
| ARCH | amd64 |
| OS | linux |
| REPO_COMMIT | a3193274112d3a6f5c2a0277e2ca07ec238d622f |
| REPO_HOST | github.com |
| REPO_NAME | tbd |
| REPO_ROOT | lucasepe |
| REPO_TAG | v0.1.1 |
| REPO_TAG_CLEAN | 0.1.1 |
| REPO_URL | https://github.com/lucasepe/tbd |
| TIMESTAMP | 2021-07-26T14:17:49Z |
| contact.email | pinco.pallo@gmail.com |
| greeting | Greetings |
| name | Pinco Pallo |
| return.date | August 23 |
| start.date | August, 9 |
+----------------+------------------------------------------+
安装
使用 Go 安装:
$ go install github.com/lucasepe/tbd@latest
或下载预编译版本:
- MacOS
- Linux
- Windows
完整示例
- 创建模板文件
template.txt
:
Hello {{ user.name }},
Welcome to {{ project.name }} (version: {{ project.version }}).
This project was last updated on {{ timestamp }}.
Repository: {{ repo.url }}
Commit: {{ repo.commit }}
- 创建变量文件
vars.env
:
user.name = John Doe
project.name = Awesome Project
project.version = 1.0.0
# Git repo info will be auto-populated
- 填充模板:
$ tbd merge template.txt vars.env
输出:
Hello John Doe,
Welcome to Awesome Project (version: 1.0.0).
This project was last updated on 2023-05-15T10:30:00Z.
Repository: https://github.com/yourusername/yourrepo
Commit: a1b2c3d4e5f6g7h8i9j0
注意事项
- 这是一个简单工具,不支持复杂语法
- 对于高级模板需求,推荐使用 gotemplate、pongo2 或 quicktemplate
更多关于golang使用占位符创建文本模板并集成Git仓库元数据的插件库tbd的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang使用占位符创建文本模板并集成Git仓库元数据的插件库tbd的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用Golang创建文本模板并集成Git元数据的方案
在Golang中,我们可以使用标准库的text/template
包创建带有占位符的文本模板,并结合Git仓库元数据来填充这些模板。下面我将介绍一个完整的解决方案。
核心实现方案
1. 基本文本模板功能
首先,我们使用text/template
包创建模板:
package main
import (
"os"
"text/template"
)
func main() {
// 定义模板
const tmpl = `项目信息:
项目名称: {{.ProjectName}}
版本: {{.Version}}
描述: {{.Description}}
Git提交: {{.GitCommit}}
分支: {{.GitBranch}}
`
// 准备数据
data := struct {
ProjectName string
Version string
Description string
GitCommit string
GitBranch string
}{
ProjectName: "MyProject",
Version: "1.0.0",
Description: "这是一个示例项目",
GitCommit: "a1b2c3d",
GitBranch: "main",
}
// 解析并执行模板
t := template.Must(template.New("project").Parse(tmpl))
err := t.Execute(os.Stdout, data)
if err != nil {
panic(err)
}
}
2. 集成Git元数据
我们可以使用go-git
库来获取Git仓库信息:
package gitmeta
import (
"fmt"
"os"
"path/filepath"
"github.com/go-git/go-git/v5"
)
type GitMetadata struct {
CommitHash string
Branch string
Tag string
RemoteURL string
}
func GetGitMetadata(repoPath string) (*GitMetadata, error) {
// 自动发现.git目录
if repoPath == "" {
var err error
repoPath, err = findGitDir(".")
if err != nil {
return nil, fmt.Errorf("无法找到.git目录: %v", err)
}
}
repo, err := git.PlainOpen(repoPath)
if err != nil {
return nil, fmt.Errorf("无法打开Git仓库: %v", err)
}
ref, err := repo.Head()
if err != nil {
return nil, fmt.Errorf("无法获取HEAD引用: %v", err)
}
// 获取提交哈希
commitHash := ref.Hash().String()
// 获取分支名称
branch := ref.Name().Short()
// 获取标签
tags, err := repo.Tags()
if err != nil {
return nil, fmt.Errorf("无法获取标签: %v", err)
}
var tag string
err = tags.ForEach(func(t *plumbing.Reference) error {
if t.Hash() == ref.Hash() {
tag = t.Name().Short()
}
return nil
})
// 获取远程URL
remotes, err := repo.Remotes()
var remoteURL string
if err == nil && len(remotes) > 0 {
remoteURL = remotes[0].Config().URLs[0]
}
return &GitMetadata{
CommitHash: commitHash,
Branch: branch,
Tag: tag,
RemoteURL: remoteURL,
}, nil
}
func findGitDir(startDir string) (string, error) {
dir, err := filepath.Abs(startDir)
if err != nil {
return "", err
}
for {
gitDir := filepath.Join(dir, ".git")
if _, err := os.Stat(gitDir); err == nil {
return dir, nil
}
parent := filepath.Dir(dir)
if parent == dir {
return "", fmt.Errorf("未找到.git目录")
}
dir = parent
}
}
3. 完整插件库设计
下面是一个完整的模板处理器设计:
package tbd
import (
"bytes"
"text/template"
"github.com/yourusername/tbd/gitmeta"
)
type TemplateData struct {
Project ProjectInfo
Git gitmeta.GitMetadata
Custom map[string]interface{}
}
type ProjectInfo struct {
Name string
Version string
Description string
Author string
}
type TemplateProcessor struct {
funcMap template.FuncMap
}
func NewTemplateProcessor() *TemplateProcessor {
return &TemplateProcessor{
funcMap: template.FuncMap{
"upper": strings.ToUpper,
"lower": strings.ToLower,
// 可以添加更多自定义函数
},
}
}
func (tp *TemplateProcessor) Render(templateStr string, project ProjectInfo, customData map[string]interface{}, repoPath string) (string, error) {
// 获取Git元数据
gitMeta, err := gitmeta.GetGitMetadata(repoPath)
if err != nil {
return "", err
}
// 准备模板数据
data := TemplateData{
Project: project,
Git: *gitMeta,
Custom: customData,
}
// 创建并解析模板
tmpl, err := template.New("tbd-template").
Funcs(tp.funcMap).
Parse(templateStr)
if err != nil {
return "", err
}
// 执行模板
var buf bytes.Buffer
err = tmpl.Execute(&buf, data)
if err != nil {
return "", err
}
return buf.String(), nil
}
使用示例
package main
import (
"fmt"
"log"
"github.com/yourusername/tbd"
)
func main() {
processor := tbd.NewTemplateProcessor()
project := tbd.ProjectInfo{
Name: "Awesome Project",
Version: "1.2.3",
Description: "This is an awesome project",
Author: "John Doe",
}
customData := map[string]interface{}{
"Environment": "production",
"Region": "us-west-1",
}
templateStr := `# {{.Project.Name}} (v{{.Project.Version}})
## 项目信息
- 描述: {{.Project.Description}}
- 作者: {{.Project.Author}}
## Git信息
- 分支: {{.Git.Branch}}
- 提交: {{.Git.CommitHash}}
- 仓库: {{.Git.RemoteURL}}
## 环境
- 环境: {{.Custom.Environment}}
- 区域: {{.Custom.Region | upper}}
`
result, err := processor.Render(templateStr, project, customData, "")
if err != nil {
log.Fatal(err)
}
fmt.Println(result)
}
高级功能扩展
- 模板文件支持:可以从文件加载模板而不仅是字符串
- 模板缓存:缓存已解析的模板以提高性能
- 更多Git元数据:添加更多Git相关信息如提交消息、作者等
- 模板继承:支持基础模板和子模板的继承关系
- 自定义函数:添加更多有用的模板函数
这个方案提供了灵活且强大的文本模板处理能力,同时集成了Git仓库元数据,可以满足大多数项目的需求。