xcaddy/internal/utils/resource.go
WeidiDeng 33a5925979
embed icon and version information to windows builds (#184)
* embed icon and version information to windows builds

* fix lint
2024-05-29 14:45:07 -06:00

87 lines
2.4 KiB
Go

package utils
import (
"embed"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/Masterminds/semver/v3"
"github.com/josephspurrier/goversioninfo"
)
//go:embed resources/*
var embedFS embed.FS
// WindowsResource create a Windows resource system object
// for embedding into the Caddy binary.
// reference: https://github.com/rclone/rclone/blob/v1.66.0/bin/resource_windows.go
func WindowsResource(version, outputFile, tempDir string) error {
vi := &goversioninfo.VersionInfo{}
// FixedFileInfo
vi.FixedFileInfo.FileOS = "040004" // VOS_NT_WINDOWS32
vi.FixedFileInfo.FileType = "01" // VFT_APP
semanticVersion, err := semver.NewVersion(version)
if err != nil {
return err
}
basename := filepath.Base(outputFile)
ext := filepath.Ext(basename)
// FixedFileInfo.FileVersion
vi.FixedFileInfo.FileVersion.Major = int(semanticVersion.Major())
vi.FixedFileInfo.FileVersion.Minor = int(semanticVersion.Minor())
vi.FixedFileInfo.FileVersion.Patch = int(semanticVersion.Patch())
vi.FixedFileInfo.FileVersion.Build = 0
// FixedFileInfo.ProductVersion
vi.FixedFileInfo.ProductVersion.Major = int(semanticVersion.Major())
vi.FixedFileInfo.ProductVersion.Minor = int(semanticVersion.Minor())
vi.FixedFileInfo.ProductVersion.Patch = int(semanticVersion.Patch())
vi.FixedFileInfo.ProductVersion.Build = 0
// StringFileInfo
vi.StringFileInfo.CompanyName = "https://caddyserver.com/"
vi.StringFileInfo.ProductName = "Caddy"
vi.StringFileInfo.FileDescription = "Caddy"
vi.StringFileInfo.InternalName = strings.TrimSuffix(basename, ext)
vi.StringFileInfo.OriginalFilename = basename
vi.StringFileInfo.LegalCopyright = "The Caddy Authors"
vi.StringFileInfo.FileVersion = semanticVersion.String()
vi.StringFileInfo.ProductVersion = semanticVersion.String()
// extract ico file from embed to an actual file
ico, err := embedFS.ReadFile("resources/ico/caddy.ico")
if err != nil {
return err
}
icoCopy, err := os.Create(filepath.Join(tempDir, "caddy.ico"))
if err != nil {
return err
}
// set ico path
vi.IconPath = icoCopy.Name()
_, err = icoCopy.Write(ico)
if err != nil {
return err
}
err = icoCopy.Close()
if err != nil {
return err
}
// Build native structures from the configuration data
vi.Build()
// Write the native structures as binary data to a buffer
vi.Walk()
arch := GetGOARCH()
// Write the binary data buffer to file
return vi.WriteSyso(filepath.Join(tempDir, fmt.Sprintf("resource_windows_%s.syso", arch)), arch)
}