Skip to content

Commit 4809501

Browse files
authored
chore: improve internal release command (#2315)
1 parent d0708fc commit 4809501

File tree

15 files changed

+311
-284
lines changed

15 files changed

+311
-284
lines changed

.goreleaser.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ builds:
1414
- -s -w -X main.version={{.Version}}
1515

1616
goos:
17-
- windows
18-
- darwin
1917
- linux
18+
- darwin
19+
- windows
2020
- freebsd
2121
- openbsd
2222
- solaris

Makefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,16 @@ checks:
3939
.PHONY: patch minor major detach
4040

4141
patch:
42-
go run ./internal/useragent/ release -m patch
42+
go run ./internal/releaser/ release -m patch
4343

4444
minor:
45-
go run ./internal/useragent/ release -m minor
45+
go run ./internal/releaser/ release -m minor
4646

4747
major:
48-
go run ./internal/useragent/ release -m major
48+
go run ./internal/releaser/ release -m major
4949

5050
detach:
51-
go run ./internal/useragent/ detach
51+
go run ./internal/releaser/ detach
5252

5353
# Docs
5454
.PHONY: docs-build docs-serve docs-themes

acme/api/internal/sender/useragent.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/lego/main.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,14 @@ import (
1313
"github.com/urfave/cli/v2"
1414
)
1515

16-
var version = "dev"
17-
1816
func main() {
1917
app := cli.NewApp()
2018
app.Name = "lego"
2119
app.HelpName = "lego"
2220
app.Usage = "Let's Encrypt client written in Go"
2321
app.EnableBashCompletion = true
2422

25-
app.Version = version
23+
app.Version = getVersion()
2624
cli.VersionPrinter = func(c *cli.Context) {
2725
fmt.Printf("lego version %s %s/%s\n", c.App.Version, runtime.GOOS, runtime.GOARCH)
2826
}

cmd/lego/zz_gen_version.go

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ require (
3636
github.com/gophercloud/gophercloud v1.14.0
3737
github.com/gophercloud/utils v0.0.0-20231010081019-80377eca5d56
3838
github.com/hashicorp/go-retryablehttp v0.7.7
39+
github.com/hashicorp/go-version v1.7.0
3940
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.114
4041
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df
4142
github.com/infobloxopen/infoblox-go-client v1.1.1

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,8 @@ github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
454454
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
455455
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
456456
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
457+
github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY=
458+
github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
457459
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
458460
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
459461
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=

internal/releaser/generator.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"embed"
6+
"fmt"
7+
"go/format"
8+
"os"
9+
"path/filepath"
10+
"text/template"
11+
)
12+
13+
const (
14+
dnsTemplate = "templates/dns.go.tmpl"
15+
dnsTargetFile = "./providers/dns/internal/useragent/useragent.go"
16+
)
17+
18+
const (
19+
senderTemplate = "templates/sender.go.tmpl"
20+
senderTargetFile = "./acme/api/internal/sender/useragent.go"
21+
)
22+
23+
const (
24+
versionTemplate = "templates/version.go.tmpl"
25+
versionTargetFile = "./cmd/lego/zz_gen_version.go"
26+
)
27+
28+
//go:embed templates
29+
var templateFS embed.FS
30+
31+
type Generator struct {
32+
templatePath string
33+
targetFile string
34+
}
35+
36+
func NewGenerator(templatePath string, targetFile string) *Generator {
37+
return &Generator{templatePath: templatePath, targetFile: targetFile}
38+
}
39+
40+
func (g *Generator) Generate(version, comment string) error {
41+
tmpl, err := template.New(filepath.Base(g.templatePath)).ParseFS(templateFS, g.templatePath)
42+
if err != nil {
43+
return fmt.Errorf("parsing template (%s): %w", g.templatePath, err)
44+
}
45+
46+
b := &bytes.Buffer{}
47+
48+
err = tmpl.Execute(b, map[string]string{
49+
"version": version,
50+
"comment": comment,
51+
})
52+
if err != nil {
53+
return fmt.Errorf("execute template (%s): %w", g.templatePath, err)
54+
}
55+
56+
source, err := format.Source(b.Bytes())
57+
if err != nil {
58+
return fmt.Errorf("format generated content (%s): %w", g.targetFile, err)
59+
}
60+
61+
err = os.WriteFile(g.targetFile, source, 0o644)
62+
if err != nil {
63+
return fmt.Errorf("write file (%s): %w", g.targetFile, err)
64+
}
65+
66+
return nil
67+
}
68+
69+
func generate(targetVersion, comment string) error {
70+
generators := []*Generator{
71+
NewGenerator(dnsTemplate, dnsTargetFile),
72+
NewGenerator(senderTemplate, senderTargetFile),
73+
NewGenerator(versionTemplate, versionTargetFile),
74+
}
75+
76+
for _, generator := range generators {
77+
err := generator.Generate(targetVersion, comment)
78+
if err != nil {
79+
return fmt.Errorf("generate file(s): %w", err)
80+
}
81+
}
82+
83+
return nil
84+
}

internal/releaser/releaser.go

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"go/ast"
6+
"go/parser"
7+
"go/token"
8+
"log"
9+
"os"
10+
"strconv"
11+
12+
hcversion "github.com/hashicorp/go-version"
13+
"github.com/urfave/cli/v2"
14+
)
15+
16+
const flgMode = "mode"
17+
18+
const (
19+
modePatch = "patch"
20+
modeMinor = "minor"
21+
modeMajor = "major"
22+
)
23+
24+
const versionSourceFile = "./cmd/lego/zz_gen_version.go"
25+
26+
const (
27+
commentRelease = "release"
28+
commentDetach = "detach"
29+
)
30+
31+
func main() {
32+
app := cli.NewApp()
33+
app.Name = "lego-releaser"
34+
app.Usage = "Lego releaser"
35+
app.HelpName = "releaser"
36+
app.Commands = []*cli.Command{
37+
{
38+
Name: "release",
39+
Usage: "Update file for a release",
40+
Action: release,
41+
Before: func(ctx *cli.Context) error {
42+
mode := ctx.String("mode")
43+
switch mode {
44+
case modePatch, modeMinor, modeMajor:
45+
return nil
46+
default:
47+
return fmt.Errorf("invalid mode: %s", mode)
48+
}
49+
},
50+
Flags: []cli.Flag{
51+
&cli.StringFlag{
52+
Name: flgMode,
53+
Aliases: []string{"m"},
54+
Value: modePatch,
55+
Usage: fmt.Sprintf("The release mode: %s|%s|%s", modePatch, modeMinor, modeMajor),
56+
},
57+
},
58+
},
59+
{
60+
Name: "detach",
61+
Usage: "Update file post release",
62+
Action: detach,
63+
},
64+
}
65+
66+
err := app.Run(os.Args)
67+
if err != nil {
68+
log.Fatal(err)
69+
}
70+
}
71+
72+
func release(ctx *cli.Context) error {
73+
mode := ctx.String(flgMode)
74+
75+
currentVersion, err := readCurrentVersion(versionSourceFile)
76+
if err != nil {
77+
return fmt.Errorf("read current version: %w", err)
78+
}
79+
80+
nextVersion, err := bumpVersion(mode, currentVersion)
81+
if err != nil {
82+
return fmt.Errorf("bump version: %w", err)
83+
}
84+
85+
err = generate(nextVersion, commentRelease)
86+
if err != nil {
87+
return err
88+
}
89+
90+
return nil
91+
}
92+
93+
func detach(_ *cli.Context) error {
94+
currentVersion, err := readCurrentVersion(versionSourceFile)
95+
if err != nil {
96+
return fmt.Errorf("read current version: %w", err)
97+
}
98+
99+
v := currentVersion.Core().String()
100+
101+
err = generate(v, commentDetach)
102+
if err != nil {
103+
return err
104+
}
105+
106+
return nil
107+
}
108+
109+
func readCurrentVersion(filename string) (*hcversion.Version, error) {
110+
fset := token.NewFileSet()
111+
file, err := parser.ParseFile(fset, filename, nil, parser.AllErrors)
112+
if err != nil {
113+
return nil, err
114+
}
115+
116+
v := visitor{data: make(map[string]string)}
117+
ast.Walk(v, file)
118+
119+
current, err := hcversion.NewSemver(v.data["defaultVersion"])
120+
if err != nil {
121+
return nil, err
122+
}
123+
124+
return current, nil
125+
}
126+
127+
type visitor struct {
128+
data map[string]string
129+
}
130+
131+
func (v visitor) Visit(n ast.Node) ast.Visitor {
132+
if n == nil {
133+
return nil
134+
}
135+
136+
switch d := n.(type) {
137+
case *ast.GenDecl:
138+
if d.Tok == token.CONST {
139+
for _, spec := range d.Specs {
140+
valueSpec, ok := spec.(*ast.ValueSpec)
141+
if !ok {
142+
continue
143+
}
144+
if len(valueSpec.Names) != 1 || len(valueSpec.Values) != 1 {
145+
continue
146+
}
147+
148+
va, ok := valueSpec.Values[0].(*ast.BasicLit)
149+
if !ok {
150+
continue
151+
}
152+
if va.Kind != token.STRING {
153+
continue
154+
}
155+
156+
s, err := strconv.Unquote(va.Value)
157+
if err != nil {
158+
continue
159+
}
160+
161+
v.data[valueSpec.Names[0].String()] = s
162+
}
163+
}
164+
default:
165+
// noop
166+
}
167+
return v
168+
}
169+
170+
func bumpVersion(mode string, v *hcversion.Version) (string, error) {
171+
segments := v.Segments()
172+
173+
switch mode {
174+
case modePatch:
175+
return fmt.Sprintf("%d.%d.%d", segments[0], segments[1], segments[2]+1), nil
176+
case modeMinor:
177+
return fmt.Sprintf("%d.%d.0", segments[0], segments[1]+1), nil
178+
case modeMajor:
179+
return fmt.Sprintf("%d.0.0", segments[0]+1), nil
180+
default:
181+
return "", fmt.Errorf("invalid mode: %s", mode)
182+
}
183+
}

internal/useragent/templates/dns.go.tmpl renamed to internal/releaser/templates/dns.go.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Code generated by 'internal/useragent'; DO NOT EDIT.
1+
// Code generated by 'internal/releaser'; DO NOT EDIT.
22

33
package useragent
44

0 commit comments

Comments
 (0)