go-deb/buildPackage.go

263 lines
7.2 KiB
Go
Raw Normal View History

2024-02-23 13:15:51 -06:00
// This window, when it's hidden, still exists to the application
// so it can be treated as if it really exists
package main
import (
2024-03-01 07:44:02 -06:00
"errors"
2024-02-23 13:15:51 -06:00
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"go.wit.com/lib/gui/shell"
"go.wit.com/log"
)
2024-03-02 15:58:56 -06:00
func (c *controlBox) buildPackage() (bool, error) {
2024-02-23 13:15:51 -06:00
// TODO: if dirty, set GO111MODULE
// also, if last tag != version
/*
go install -ldflags " \
-X main.GITCOMMIT=${GITCOMMIT} \
-X main.GOVERSION='${GOVERSION}' \
-X main.BUILDTIME='${BUILDTIME}' \
-X main.VERSION=${VERSION}"
*/
// ldflags := "main.GOTAG=" + repo.LastTag()
2024-03-01 07:44:02 -06:00
filename := c.Package.String()
if filename == "" {
2024-03-02 15:58:56 -06:00
return false, errors.New("filename is blank")
2024-03-01 07:44:02 -06:00
}
homeDir, err := os.UserHomeDir()
if err != nil {
2024-03-02 15:58:56 -06:00
return false, err
2024-03-01 07:44:02 -06:00
}
arch := c.Architecture.String()
2024-03-02 17:51:34 -06:00
version := c.Version.String()
log.Info("version is:", version)
2024-03-01 07:44:02 -06:00
debname := filename + "_" + version + "_" + arch + ".deb"
2024-03-02 15:58:56 -06:00
fulldebname := filepath.Join(homeDir, "incoming", debname)
if shell.Exists(fulldebname) {
return true, errors.New("debian package already built: " + fulldebname)
}
2024-03-01 07:44:02 -06:00
var fullfilename string
if argv.Release {
2024-03-01 07:44:02 -06:00
fullfilename = filepath.Join(homeDir, "go/bin", filename)
} else {
fullfilename = filename
}
shell.Run([]string{"rm", "-f", fullfilename})
if shell.Exists(fullfilename) {
// something wrong
2024-03-02 15:58:56 -06:00
return false, errors.New("binary existed before build")
2024-03-01 07:44:02 -06:00
}
if argv.Release {
2024-02-23 13:15:51 -06:00
os.Unsetenv("GO111MODULE")
path := c.pathL.String() + "@latest"
cmd := []string{"go", "install", "-v", "-x", path}
if shell.Run(cmd) {
2024-03-01 07:44:02 -06:00
log.Warn("go install worked")
2024-02-23 13:15:51 -06:00
} else {
2024-03-02 15:58:56 -06:00
return false, errors.New("go install")
2024-02-23 13:15:51 -06:00
}
} else {
2024-03-01 07:44:02 -06:00
// set the GO111 build var to true. pass the versions to the compiler manually
2024-02-23 13:15:51 -06:00
os.Setenv("GO111MODULE", "off")
cmd := []string{"go", "build", "-v", "-x"}
// add some standard golang flags
2024-03-01 07:44:02 -06:00
vldflag := "-X main.VERSION=" + version
gldflag := "-X main.GUIVERSION=" + version // todo: git this from the filesystem
cmd = append(cmd, "-ldflags", vldflag)
cmd = append(cmd, "-ldflags", gldflag)
// add any flags from the command line
for _, flag := range argv.Ldflags {
cmd = append(cmd, "-ldflags", "-X "+flag)
}
if shell.Run(cmd) {
2024-03-01 07:44:02 -06:00
log.Warn("go build worked")
2024-02-23 13:15:51 -06:00
} else {
2024-03-02 15:58:56 -06:00
return false, errors.New("go build")
2024-02-23 13:15:51 -06:00
}
}
2024-03-01 07:44:02 -06:00
if !shell.Exists(fullfilename) {
log.Warn("build failed. filename does not exist", fullfilename)
2024-03-02 15:58:56 -06:00
return false, errors.New("missing" + fullfilename)
2024-02-23 13:15:51 -06:00
}
if shell.Exists("files") {
if shell.Run([]string{"rm", "-rf", "files"}) {
2024-02-23 13:15:51 -06:00
log.Warn("rm failed")
2024-03-02 15:58:56 -06:00
return false, errors.New("rm files/")
2024-02-23 13:15:51 -06:00
}
}
shell.Run([]string{"sync"}) // for some reason the next check fails sometimes?
2024-02-23 13:15:51 -06:00
if shell.Exists("files") {
// probably the 'shell' package id being stupid and not waiting for the process to actually exit
log.Warn("rm failed. files/ still exists. is golang doing these in parallel?")
2024-03-02 15:58:56 -06:00
return false, errors.New("rm files/")
2024-02-23 13:15:51 -06:00
}
if !shell.Mkdir("files/DEBIAN") {
2024-03-02 15:58:56 -06:00
return false, errors.New("mkdir files/DEBIAN")
2024-02-23 13:15:51 -06:00
}
if !shell.Mkdir("files/usr/bin") {
log.Warn("mkdir failed")
2024-03-02 15:58:56 -06:00
return false, errors.New("mkdir files/usr/bin")
2024-02-23 13:15:51 -06:00
}
2024-03-01 07:44:02 -06:00
if !shell.Run([]string{"cp", fullfilename, "files/usr/bin"}) {
2024-02-23 13:15:51 -06:00
log.Warn("cp failed")
2024-03-02 15:58:56 -06:00
return false, errors.New("cp " + fullfilename)
2024-02-23 13:15:51 -06:00
}
if !shell.Run([]string{"strip", "files/usr/bin/" + filename}) {
log.Warn("strip failed")
2024-03-02 15:58:56 -06:00
return false, errors.New("strip " + filename)
2024-02-23 13:15:51 -06:00
}
// put the README in there (if missing, generate it?)
var readme string = ""
if shell.Exists("README.md") {
readme = "README.md"
}
if shell.Exists("README") {
readme = "README"
}
if readme != "" {
path := filepath.Join("files/usr/lib/" + filename)
if !shell.Mkdir(path) {
2024-03-02 15:58:56 -06:00
return false, errors.New("no files/usr/lib")
2024-02-23 13:15:51 -06:00
}
if !shell.Run([]string{"cp", readme, path}) {
2024-03-02 15:58:56 -06:00
return false, errors.New("cp readme")
2024-02-23 13:15:51 -06:00
}
}
if !c.writeDebianControlFile() {
2024-03-02 15:58:56 -06:00
return false, errors.New("write control file")
2024-02-23 13:15:51 -06:00
}
if shell.Exists("postinst") {
shell.Run([]string{"cp", "postinst", "files/DEBIAN/"})
}
2024-02-23 13:15:51 -06:00
// experiment for the toolkit package
2024-03-02 15:58:56 -06:00
// if the git repo has a "./build" script run it before packaging
// this way the user can put custom files in the .deb package
2024-02-23 13:15:51 -06:00
if c.status.Exists("build") {
if argv.Release {
2024-02-23 13:15:51 -06:00
os.Unsetenv("GO111MODULE")
} else {
os.Setenv("GO111MODULE", "off")
}
shell.Run([]string{"./build"})
}
shell.Run([]string{"dpkg-deb", "--build", "files", fulldebname})
if shell.Exists(fulldebname) {
} else {
log.Warn("build failed")
2024-03-02 15:58:56 -06:00
return false, errors.New("dpkg-deb --build failed")
2024-02-23 13:15:51 -06:00
}
shell.Run([]string{"dpkg-deb", "-I", fulldebname})
shell.Run([]string{"dpkg-deb", "-c", fulldebname})
2024-03-02 15:58:56 -06:00
// cleanup files
if shell.Exists("files") {
if argv.KeepFiles {
log.Info("keeping the build files/")
} else {
if shell.Run([]string{"rm", "-rf", "files"}) {
log.Warn("rm failed")
return false, errors.New("rm files/")
}
2024-03-02 15:58:56 -06:00
}
}
return true, nil
2024-02-23 13:15:51 -06:00
}
func (c *controlBox) writeDebianControlFile() bool {
2024-02-23 13:15:51 -06:00
cf, err := os.OpenFile("files/DEBIAN/control", os.O_RDWR|os.O_CREATE, 0644)
if err != nil {
log.Info("open control file failed", err)
return false
}
fmt.Fprintln(cf, "Package:", c.Package.String())
fmt.Fprintln(cf, "Source:", c.Source.String())
fmt.Fprintln(cf, "Version:", c.Version.String())
fmt.Fprintln(cf, "Architecture:", c.Architecture.String())
fmt.Fprintln(cf, "Depends:", c.Depends.String())
fmt.Fprintln(cf, "Build-Depends:", c.BuildDepends.String())
stamp := time.Now().UTC().Format("2006/01/02 15:04:05 UTC")
// update to now now despite what the GUI is showing
fmt.Fprintln(cf, "Package-Build-Date:", stamp)
fmt.Fprintln(cf, "Git-Tag-Date:", c.tagDate.String())
fmt.Fprintln(cf, "Maintainer:", c.Maintainer.String())
desc := c.Description.String()
parts := strings.Split(desc, "\n")
fmt.Fprintln(cf, "Description:", strings.Join(parts, "\n "))
return true
}
// try to guess or figure out the config file values
// if there is not a control file
func (c *controlBox) computeControlValues() bool {
if c.Package.String() == "" {
// get the package name from the repo name
path := c.pathL.String()
parts := strings.Split(path, "/")
name := parts[len(parts)-1]
c.Package.SetText(name)
}
if c.Source.String() == "" {
c.Source.SetText(c.Package.String())
}
if c.BuildDepends.String() == "" {
c.BuildDepends.SetText("golang")
}
if c.Recommends.String() == "" {
c.Recommends.SetText("go-gui-toolkits")
}
// TODO: get this from the git log
if c.Maintainer.String() == "" {
c.Maintainer.SetText("Jeff Carr <jcarr@wit.com>")
}
// TODO: get this from gitea (or gitlab or github, etc)
// or from the README.md ?
if c.Description.String() == "" {
path := c.pathL.String()
c.Description.SetText("GO binary of " + path)
}
return true
}
// stamp := time.Now().UTC().Format("2006/01/02 15:04:05 UTC")
func (c *controlBox) getDateStamp(tag string) string {
_, out := c.status.RunCmd([]string{"git", "log", "-1", "--format=%at", tag})
out = strings.TrimSpace(out)
// Convert the string to an integer
gitTagTimestampInt, err := strconv.ParseInt(out, 10, 64)
if err != nil {
fmt.Println("Error converting timestamp:", err)
return "git tag " + tag + " unknown"
}
// Parse the Unix timestamp into a time.Time object
gitTagDate := time.Unix(gitTagTimestampInt, 0)
return gitTagDate.UTC().Format("2006/01/02 15:04:05 UTC")
}