Skip to content

Commit 3b9f711

Browse files
authored
Merge pull request #3 from Jackenmen/add_app_manifest_icon_and_version
Add app manifest, icon, and version number to exe
2 parents 19ccb4c + 1850bfa commit 3b9f711

15 files changed

Lines changed: 256 additions & 0 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ dist/
44
/.venv
55
/redbot-update
66
*.exe
7+
**/resources/generated/
8+
resources_windows.syso

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ build-all: build-go build-python
1111

1212
.PHONY: build-go
1313
build-go:
14+
CGO_ENABLED=1 go generate ./...
1415
CGO_ENABLED=1 go build ./...
1516
CGO_ENABLED=1 go build ./go/cmd/redbot-update
1617

@@ -38,6 +39,7 @@ fmt format reformat: fmt-go fmt-python
3839
.PHONY: fmt-go format-go reformat-go
3940
fmt-go format-go reformat-go:
4041
go fmt ./...
42+
cd ./go/build_tools && go fmt ./...
4143

4244
.PHONY: fmt-python format-python reformat-python
4345
fmt-python format-python reformat-python:

go.mod

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,10 @@ module github.com/cog-creators/redbot-update-wrapper
33
go 1.26
44

55
toolchain go1.26.3
6+
7+
tool github.com/josephspurrier/goversioninfo/cmd/goversioninfo
8+
9+
require (
10+
github.com/akavel/rsrc v0.10.2 // indirect
11+
github.com/josephspurrier/goversioninfo v1.7.0 // indirect
12+
)

go.sum

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
github.com/akavel/rsrc v0.10.2 h1:Zxm8V5eI1hW4gGaYsJQUhxpjkENuG91ki8B4zCrvEsw=
2+
github.com/akavel/rsrc v0.10.2/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
3+
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
4+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5+
github.com/josephspurrier/goversioninfo v1.7.0 h1:LQzXOlVm/CtbwJ9/UHl5a2HT0BjcLAwid5gqGd7ZUJ8=
6+
github.com/josephspurrier/goversioninfo v1.7.0/go.mod h1:z9y0r2G6g5jwSJaFE0cxW9to0aeIibK7UYeLx53aQRU=
7+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
8+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
9+
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
10+
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
11+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
12+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

go.work

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
go 1.26.3
2+
3+
use (
4+
.
5+
./go/build_tools
6+
)
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"os"
6+
"path/filepath"
7+
"text/template"
8+
9+
"github.com/BurntSushi/toml"
10+
)
11+
12+
const (
13+
resourcesDir = "resources"
14+
baseResourcesDir = resourcesDir + string(filepath.Separator) + "base"
15+
generatedResourcesDir = resourcesDir + string(filepath.Separator) + "generated"
16+
)
17+
18+
type Project struct {
19+
Version string `toml:"version"`
20+
}
21+
22+
type PyProject struct {
23+
Project Project `toml:"project"`
24+
}
25+
26+
func main() {
27+
projectDir := os.Args[1]
28+
projectFile := filepath.Join(projectDir, "pyproject.toml")
29+
30+
var pyproject PyProject
31+
if _, err := toml.DecodeFile(projectFile, &pyproject); err != nil {
32+
panic(err)
33+
}
34+
rawVersion := pyproject.Project.Version
35+
v := parsePythonProjectVersion(rawVersion)
36+
37+
if err := os.MkdirAll(generatedResourcesDir, 0700); err != nil {
38+
panic(err)
39+
}
40+
generateAppManifestFile(v)
41+
generateVersionInfoFile(v)
42+
}
43+
44+
// generate app manifest
45+
func generateAppManifestFile(v PythonProjectVersion) {
46+
t, err := template.ParseFiles(filepath.Join(baseResourcesDir, "app.manifest.tmpl"))
47+
if err != nil {
48+
panic(err)
49+
}
50+
f, err := os.Create(filepath.Join(generatedResourcesDir, "app.manifest"))
51+
if err != nil {
52+
panic(err)
53+
}
54+
defer f.Close()
55+
t.Execute(f, struct{ ProductVersion string }{v.FileVersion().String()})
56+
if err := f.Close(); err != nil {
57+
panic(err)
58+
}
59+
}
60+
61+
// generate versioninfo.json
62+
func generateVersionInfoFile(v PythonProjectVersion) {
63+
data, err := os.ReadFile(filepath.Join(baseResourcesDir, "versioninfo.json"))
64+
if err != nil {
65+
panic(err)
66+
}
67+
versioninfo := map[string]any{}
68+
json.Unmarshal(data, &versioninfo)
69+
70+
fixedFileInfo := versioninfo["FixedFileInfo"].(map[string]any)
71+
fixedFileInfo["FileVersion"] = v.FileVersion()
72+
fixedFileInfo["ProductVersion"] = v.FileVersion()
73+
stringFileInfo := versioninfo["StringFileInfo"].(map[string]any)
74+
stringFileInfo["FileVersion"] = v.String()
75+
stringFileInfo["ProductVersion"] = v.String()
76+
77+
data, err = json.Marshal(versioninfo)
78+
if err != nil {
79+
panic(err)
80+
}
81+
err = os.WriteFile(filepath.Join(generatedResourcesDir, "versioninfo.json"), data, 0600)
82+
if err != nil {
83+
panic(err)
84+
}
85+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package main
2+
3+
import "strconv"
4+
5+
type Int interface {
6+
~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
7+
}
8+
9+
func ParseInt[T Int](s string) T {
10+
i, err := strconv.Atoi(s)
11+
if err != nil {
12+
panic(err)
13+
}
14+
return T(i)
15+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"regexp"
6+
)
7+
8+
type ReleaseLevel string
9+
10+
var (
11+
ReleaseLevelAlpha ReleaseLevel = "a"
12+
ReleaseLevelBeta ReleaseLevel = "b"
13+
ReleaseLevelReleaseCandidate ReleaseLevel = "rc"
14+
ReleaseLevelFinal ReleaseLevel = ""
15+
16+
pythonProjectVersionRegexp = regexp.MustCompile(
17+
`(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:(a|b|rc)(0|[1-9]\d*))?`,
18+
)
19+
pythonSerialToFileVersionMap = map[ReleaseLevel]uint16{
20+
ReleaseLevelAlpha: 0x2000,
21+
ReleaseLevelBeta: 0x4000,
22+
ReleaseLevelReleaseCandidate: 0x6000,
23+
ReleaseLevelFinal: 0x8000,
24+
}
25+
)
26+
27+
type FileVersion struct {
28+
Major uint16
29+
Minor uint16
30+
Patch uint16
31+
Build uint16
32+
}
33+
34+
func (fv FileVersion) String() string {
35+
return fmt.Sprintf("%v.%v.%v.%v", fv.Major, fv.Minor, fv.Patch, fv.Build)
36+
}
37+
38+
type PythonProjectVersion struct {
39+
Major uint16
40+
Minor uint16
41+
Micro uint16
42+
ReleaseLevel ReleaseLevel
43+
Serial uint8
44+
}
45+
46+
func parsePythonProjectVersion(v string) PythonProjectVersion {
47+
matches := pythonProjectVersionRegexp.FindStringSubmatch(v)
48+
if matches == nil {
49+
panic("could not parse Python project version")
50+
}
51+
ppv := PythonProjectVersion{}
52+
ppv.Major = ParseInt[uint16](matches[1])
53+
ppv.Minor = ParseInt[uint16](matches[2])
54+
ppv.Micro = ParseInt[uint16](matches[3])
55+
ppv.ReleaseLevel = ReleaseLevel(matches[4])
56+
if matches[5] != "" {
57+
ppv.Serial = ParseInt[uint8](matches[5])
58+
}
59+
return ppv
60+
}
61+
62+
func (ppv PythonProjectVersion) String() string {
63+
baseVersion := fmt.Sprintf("%v.%v.%v", ppv.Major, ppv.Minor, ppv.Micro)
64+
if ppv.ReleaseLevel == ReleaseLevelFinal {
65+
return baseVersion
66+
}
67+
return fmt.Sprintf("%v%v%v", baseVersion, ppv.ReleaseLevel, ppv.Serial)
68+
}
69+
70+
func (ppv PythonProjectVersion) FileVersion() FileVersion {
71+
return FileVersion{
72+
Major: ppv.Major,
73+
Minor: ppv.Minor,
74+
Patch: ppv.Micro,
75+
Build: pythonSerialToFileVersionMap[ppv.ReleaseLevel] | uint16(ppv.Serial),
76+
}
77+
}

go/build_tools/go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module github.com/cog-creators/redbot-update-wrapper/go/build_tools
2+
3+
go 1.26.3
4+
5+
require github.com/BurntSushi/toml v1.6.0

go/build_tools/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
2+
github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=

0 commit comments

Comments
 (0)