// This window, when it's hidden, still exists to the application // so it can be treated as if it really exists package main import ( "errors" "fmt" "os" "path/filepath" "strconv" "strings" "time" "go.wit.com/lib/gui/repolist" "go.wit.com/lib/gui/shell" "go.wit.com/log" ) func (c *controlBox) buildPackage() (bool, error) { // 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() filename := c.Package.String() if filename == "" { return false, errors.New("filename is blank") } homeDir, err := os.UserHomeDir() if err != nil { return false, err } arch := c.Architecture.String() tmp := c.Version.String() version := repolist.ValidDebianPackageVersion(tmp) log.Info("version went from", tmp, "to", version) os.Exit(-1) debname := filename + "_" + version + "_" + arch + ".deb" fulldebname := filepath.Join(homeDir, "incoming", debname) if shell.Exists(fulldebname) { return true, errors.New("debian package already built: " + fulldebname) } var fullfilename string if args.Release { fullfilename = filepath.Join(homeDir, "go/bin", filename) } else { fullfilename = filename } shell.Run([]string{"rm", "-f", fullfilename}) if shell.Exists(fullfilename) { // something wrong return false, errors.New("binary existed before build") } if args.Release { os.Unsetenv("GO111MODULE") path := c.pathL.String() + "@latest" cmd := []string{"go", "install", "-v", "-x", path} if shell.Run(cmd) { log.Warn("go install worked") } else { return false, errors.New("go install") } } else { // set the GO111 build var to true. pass the versions to the compiler manually os.Setenv("GO111MODULE", "off") vldflag := "-X main.VERSION=" + version gldflag := "-X main.GUIVERSION=" + version // todo: git this from the filesystem if shell.Run([]string{"go", "build", "-v", "-x", "-ldflags", vldflag, "-ldflags", gldflag}) { log.Warn("go build worked") } else { return false, errors.New("go build") } } if !shell.Exists(fullfilename) { log.Warn("build failed. filename does not exist", fullfilename) return false, errors.New("missing" + fullfilename) } if shell.Exists("files") { if shell.Run([]string{"rm", "-rf", "files"}) { log.Warn("rm failed") return false, errors.New("rm files/") } } if shell.Exists("files") { log.Warn("rm failed") return false, errors.New("rm files/") } if !shell.Mkdir("files/DEBIAN") { return false, errors.New("mkdir files/DEBIAN") } if !shell.Mkdir("files/usr/bin") { log.Warn("mkdir failed") return false, errors.New("mkdir files/usr/bin") } if !shell.Run([]string{"cp", fullfilename, "files/usr/bin"}) { log.Warn("cp failed") return false, errors.New("cp " + fullfilename) } if !shell.Run([]string{"strip", "files/usr/bin/" + filename}) { log.Warn("strip failed") return false, errors.New("strip " + filename) } // 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) { return false, errors.New("no files/usr/lib") } if !shell.Run([]string{"cp", readme, path}) { return false, errors.New("cp readme") } } if !c.writeFiles() { return false, errors.New("write control file") } // experiment for the toolkit package // if the git repo has a "./build" script run it before packaging // this way the user can put custom files in the .deb package if c.status.Exists("build") { if args.Release { 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") return false, errors.New("dpkg-deb --build failed") } shell.Run([]string{"dpkg-deb", "-I", fulldebname}) shell.Run([]string{"dpkg-deb", "-c", fulldebname}) // cleanup files if shell.Exists("files") { if shell.Run([]string{"rm", "-rf", "files"}) { log.Warn("rm failed") return false, errors.New("rm files/") } } return true, nil } func (c *controlBox) writeFiles() bool { 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 ") } // 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") }