remove hampack app
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 4.6 KiB |
@@ -1,8 +0,0 @@
|
||||
module hampack
|
||||
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/diamondburned/gotk4-adwaita/pkg v0.0.0-20250703085708-8e7f01e2c815
|
||||
github.com/diamondburned/gotk4/pkg v0.3.2-0.20250703063411-16654385f59a
|
||||
)
|
||||
@@ -1,637 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/diamondburned/gotk4-adwaita/pkg/adw"
|
||||
"github.com/diamondburned/gotk4/pkg/gdk/v4"
|
||||
"github.com/diamondburned/gotk4/pkg/glib/v2"
|
||||
"github.com/diamondburned/gotk4/pkg/gtk/v4"
|
||||
)
|
||||
|
||||
// ── Helpers ────────────────────────────────────────────────────────────────────
|
||||
|
||||
func homeDir() string {
|
||||
d, _ := os.UserHomeDir()
|
||||
return d
|
||||
}
|
||||
|
||||
func hampackDir() string {
|
||||
if d := os.Getenv("HAMPACK_DIR"); d != "" {
|
||||
return d
|
||||
}
|
||||
return filepath.Join(homeDir(), ".local/share/HamPack")
|
||||
}
|
||||
|
||||
func stateFilePath() string {
|
||||
return filepath.Join(homeDir(), ".local/state/HamPack/selections.json")
|
||||
}
|
||||
|
||||
func expand(v string) string {
|
||||
return strings.ReplaceAll(v, "$HOME", homeDir())
|
||||
}
|
||||
|
||||
var windowsItems = [][2]string{
|
||||
{"VARA HF", filepath.Join(homeDir(), ".wine/drive_c/VARA")},
|
||||
{"VARA FM", filepath.Join(homeDir(), ".wine/drive_c/VARA FM")},
|
||||
{"VARA Terminal", filepath.Join(homeDir(), ".wine/drive_c/VARA Terminal")},
|
||||
{"Winlink Express", filepath.Join(homeDir(), ".wine/drive_c/RMS Express")},
|
||||
}
|
||||
|
||||
// ── Config parsing ─────────────────────────────────────────────────────────────
|
||||
|
||||
func parseINI(path string) map[string]map[string]string {
|
||||
entries := make(map[string]map[string]string)
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return entries
|
||||
}
|
||||
var cur string
|
||||
for _, line := range strings.Split(string(data), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
if len(line) > 2 && line[0] == '[' && line[len(line)-1] == ']' {
|
||||
cur = line[1 : len(line)-1]
|
||||
entries[cur] = make(map[string]string)
|
||||
continue
|
||||
}
|
||||
if cur == "" {
|
||||
continue
|
||||
}
|
||||
if k, v, ok := strings.Cut(line, "="); ok {
|
||||
entries[cur][strings.TrimSpace(k)] = strings.TrimSpace(v)
|
||||
}
|
||||
}
|
||||
return entries
|
||||
}
|
||||
|
||||
func parsePackages() (utils, apps []string) {
|
||||
path := filepath.Join(hampackDir(), "packages.conf")
|
||||
cmd := exec.Command("bash", "-c", fmt.Sprintf(
|
||||
`source '%s' && printf '%%s\n' ${UTILITIES[@]} && echo '---' && printf '%%s\n' ${APPLICATIONS[@]}`,
|
||||
path))
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
inApps := false
|
||||
for _, line := range strings.Split(string(out), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "---" {
|
||||
inApps = true
|
||||
} else if line != "" {
|
||||
if inApps {
|
||||
apps = append(apps, line)
|
||||
} else {
|
||||
utils = append(utils, line)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func parseFlatpaks() []string {
|
||||
path := filepath.Join(hampackDir(), "install-flatpaks.sh")
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
re := regexp.MustCompile(`^[a-zA-Z][a-zA-Z0-9_-]*(\.[a-zA-Z][a-zA-Z0-9_-]*){2,}$`)
|
||||
var ids []string
|
||||
for _, line := range strings.Split(string(data), "\n") {
|
||||
s := strings.Trim(strings.TrimSpace(line), `"'`)
|
||||
if re.MatchString(s) {
|
||||
ids = append(ids, s)
|
||||
}
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// ── State ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
// installedPacmanPackages returns a set of all installed pacman package names.
|
||||
func installedPacmanPackages() map[string]bool {
|
||||
out, err := exec.Command("pacman", "-Q").Output()
|
||||
if err != nil {
|
||||
return map[string]bool{}
|
||||
}
|
||||
installed := make(map[string]bool)
|
||||
for _, line := range strings.Split(string(out), "\n") {
|
||||
if fields := strings.Fields(line); len(fields) > 0 {
|
||||
installed[fields[0]] = true
|
||||
}
|
||||
}
|
||||
return installed
|
||||
}
|
||||
|
||||
// installedFlatpaks returns a set of all installed Flatpak application IDs.
|
||||
func installedFlatpaks() map[string]bool {
|
||||
out, err := exec.Command("flatpak", "list", "--app", "--columns=application").Output()
|
||||
if err != nil {
|
||||
return map[string]bool{}
|
||||
}
|
||||
installed := make(map[string]bool)
|
||||
for _, line := range strings.Split(string(out), "\n") {
|
||||
if s := strings.TrimSpace(line); s != "" {
|
||||
installed[s] = true
|
||||
}
|
||||
}
|
||||
return installed
|
||||
}
|
||||
|
||||
// detectInitialState checks actual installation status for every item.
|
||||
func detectInitialState(
|
||||
utils, apps, flatpaks []string,
|
||||
compiled, binaries map[string]map[string]string,
|
||||
) map[string]bool {
|
||||
pacman := installedPacmanPackages()
|
||||
flatpak := installedFlatpaks()
|
||||
state := make(map[string]bool)
|
||||
|
||||
for _, name := range utils {
|
||||
state["utility:"+name] = pacman[name]
|
||||
}
|
||||
for _, name := range apps {
|
||||
state["application:"+name] = pacman[name]
|
||||
}
|
||||
for _, id := range flatpaks {
|
||||
state["flatpak:"+id] = flatpak[id]
|
||||
}
|
||||
for name, fields := range compiled {
|
||||
path := expand(fields["install"])
|
||||
_, err := os.Stat(path)
|
||||
state["compiled:"+name] = err == nil
|
||||
}
|
||||
for name, fields := range binaries {
|
||||
path := expand(fields["install"])
|
||||
_, err := os.Stat(path)
|
||||
state["binary:"+name] = err == nil
|
||||
}
|
||||
for _, item := range windowsItems {
|
||||
_, err := os.Stat(item[1])
|
||||
state["windows:"+item[0]] = err == nil
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
func saveState(state map[string]bool) {
|
||||
os.MkdirAll(filepath.Dir(stateFilePath()), 0755)
|
||||
data, _ := json.MarshalIndent(state, "", " ")
|
||||
os.WriteFile(stateFilePath(), data, 0644)
|
||||
}
|
||||
|
||||
|
||||
// ── Operations ────────────────────────────────────────────────────────────────
|
||||
|
||||
type Op struct {
|
||||
Label string
|
||||
Cmds [][]string
|
||||
Env []string // nil means inherit os.Environ()
|
||||
Tmp string // temp file to clean up after the op
|
||||
}
|
||||
|
||||
func writeTempINI(name string, fields map[string]string) string {
|
||||
f, err := os.CreateTemp("", "hampack-*.conf")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
defer f.Close()
|
||||
fmt.Fprintf(f, "[%s]\n", name)
|
||||
for k, v := range fields {
|
||||
fmt.Fprintf(f, "%s=%s\n", k, v)
|
||||
}
|
||||
return f.Name()
|
||||
}
|
||||
|
||||
func sortedKeys(m map[string]map[string]string) []string {
|
||||
keys := make([]string, 0, len(m))
|
||||
for k := range m {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return keys
|
||||
}
|
||||
|
||||
func computeOps(
|
||||
oldState, newState map[string]bool,
|
||||
compiled, binaries map[string]map[string]string,
|
||||
) []Op {
|
||||
allKeys := make(map[string]bool)
|
||||
for k := range oldState {
|
||||
allKeys[k] = true
|
||||
}
|
||||
for k := range newState {
|
||||
allKeys[k] = true
|
||||
}
|
||||
keys := make([]string, 0, len(allKeys))
|
||||
for k := range allKeys {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
var ops []Op
|
||||
windowsInstallAdded := false
|
||||
|
||||
for _, key := range keys {
|
||||
was := oldState[key]
|
||||
now := newState[key]
|
||||
if was == now {
|
||||
continue
|
||||
}
|
||||
parts := strings.SplitN(key, ":", 2)
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
cat, name := parts[0], parts[1]
|
||||
|
||||
if now { // ── install ──────────────────────────────────────────────────
|
||||
switch cat {
|
||||
case "utility", "application":
|
||||
ops = append(ops, Op{
|
||||
Label: "Install " + name,
|
||||
Cmds: [][]string{{"yay", "-S", "--noconfirm", name}},
|
||||
})
|
||||
case "flatpak":
|
||||
ops = append(ops, Op{
|
||||
Label: "Install " + name,
|
||||
Cmds: [][]string{{"flatpak", "install", "--noninteractive", "flathub", name}},
|
||||
})
|
||||
case "compiled":
|
||||
if fields, ok := compiled[name]; ok {
|
||||
tmp := writeTempINI(name, fields)
|
||||
ops = append(ops, Op{
|
||||
Label: "Build " + name,
|
||||
Cmds: [][]string{{"bash", filepath.Join(hampackDir(), "install-compiled.sh")}},
|
||||
Env: append(os.Environ(), "HAMPACK_COMPILE_CONF="+tmp),
|
||||
Tmp: tmp,
|
||||
})
|
||||
}
|
||||
case "binary":
|
||||
if fields, ok := binaries[name]; ok {
|
||||
tmp := writeTempINI(name, fields)
|
||||
ops = append(ops, Op{
|
||||
Label: "Install " + name,
|
||||
Cmds: [][]string{{"bash", filepath.Join(hampackDir(), "install-binaries.sh")}},
|
||||
Env: append(os.Environ(), "HAMPACK_BINARIES_CONF="+tmp),
|
||||
Tmp: tmp,
|
||||
})
|
||||
}
|
||||
case "windows":
|
||||
if !windowsInstallAdded {
|
||||
ops = append(ops, Op{
|
||||
Label: "Install Windows Apps (Wine)",
|
||||
Cmds: [][]string{{"bash", filepath.Join(hampackDir(), "install-windows-apps.sh")}},
|
||||
})
|
||||
windowsInstallAdded = true
|
||||
}
|
||||
}
|
||||
} else { // ── uninstall ────────────────────────────────────────────────
|
||||
switch cat {
|
||||
case "utility", "application":
|
||||
ops = append(ops, Op{
|
||||
Label: "Remove " + name,
|
||||
Cmds: [][]string{{"sudo", "pacman", "-Rns", "--noconfirm", name}},
|
||||
})
|
||||
case "flatpak":
|
||||
ops = append(ops, Op{
|
||||
Label: "Remove " + name,
|
||||
Cmds: [][]string{{"flatpak", "uninstall", "--noninteractive", name}},
|
||||
})
|
||||
case "compiled":
|
||||
if fields, ok := compiled[name]; ok {
|
||||
installPath := expand(fields["install"])
|
||||
desktopSrc := expand(fields["desktop"])
|
||||
cmds := [][]string{{"rm", "-f", installPath}}
|
||||
if desktopSrc != "" {
|
||||
cmds = append(cmds, []string{"rm", "-f", desktopSrc})
|
||||
}
|
||||
cmds = append(cmds, []string{"rm", "-f",
|
||||
filepath.Join(homeDir(), ".local/share/applications", name+".desktop")})
|
||||
ops = append(ops, Op{Label: "Remove " + name, Cmds: cmds})
|
||||
}
|
||||
case "binary":
|
||||
if fields, ok := binaries[name]; ok {
|
||||
installPath := expand(fields["install"])
|
||||
ops = append(ops, Op{
|
||||
Label: "Remove " + name,
|
||||
Cmds: [][]string{
|
||||
{"rm", "-f", installPath},
|
||||
{"rm", "-f", filepath.Join(homeDir(), ".local/share/applications", name+".desktop")},
|
||||
},
|
||||
})
|
||||
}
|
||||
case "windows":
|
||||
for _, item := range windowsItems {
|
||||
if item[0] == name {
|
||||
ops = append(ops, Op{
|
||||
Label: "Remove " + name,
|
||||
Cmds: [][]string{{"rm", "-rf", item[1]}},
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ops
|
||||
}
|
||||
|
||||
// ── Output window ─────────────────────────────────────────────────────────────
|
||||
|
||||
type outputWin struct {
|
||||
*gtk.Window
|
||||
buf *gtk.TextBuffer
|
||||
tv *gtk.TextView
|
||||
endMark *gtk.TextMark
|
||||
closeBtn *gtk.Button
|
||||
}
|
||||
|
||||
func newOutputWin(ops []Op, onDone func()) *outputWin {
|
||||
w := &outputWin{Window: gtk.NewWindow()}
|
||||
w.SetTitle("Applying Changes")
|
||||
w.SetDefaultSize(680, 500)
|
||||
|
||||
toolbar := adw.NewToolbarView()
|
||||
w.SetChild(toolbar)
|
||||
|
||||
header := adw.NewHeaderBar()
|
||||
header.SetShowEndTitleButtons(false)
|
||||
toolbar.AddTopBar(header)
|
||||
|
||||
w.closeBtn = gtk.NewButtonWithLabel("Close")
|
||||
w.closeBtn.SetSensitive(false)
|
||||
w.closeBtn.ConnectClicked(func() { w.Close() })
|
||||
header.PackEnd(w.closeBtn)
|
||||
|
||||
scroll := gtk.NewScrolledWindow()
|
||||
scroll.SetPolicy(gtk.PolicyAutomatic, gtk.PolicyAlways)
|
||||
scroll.SetVExpand(true)
|
||||
scroll.SetHExpand(true)
|
||||
|
||||
w.buf = gtk.NewTextBuffer(nil)
|
||||
endIter := w.buf.EndIter()
|
||||
w.endMark = w.buf.CreateMark("end", endIter, false)
|
||||
|
||||
w.tv = gtk.NewTextView()
|
||||
w.tv.SetBuffer(w.buf)
|
||||
w.tv.SetEditable(false)
|
||||
w.tv.SetCursorVisible(false)
|
||||
w.tv.SetMonospace(true)
|
||||
w.tv.SetLeftMargin(12)
|
||||
w.tv.SetRightMargin(12)
|
||||
w.tv.SetTopMargin(8)
|
||||
w.tv.SetBottomMargin(8)
|
||||
w.tv.SetWrapMode(gtk.WrapWordChar)
|
||||
scroll.SetChild(w.tv)
|
||||
toolbar.SetContent(scroll)
|
||||
|
||||
go w.run(ops, onDone)
|
||||
return w
|
||||
}
|
||||
|
||||
func (w *outputWin) append(text string) {
|
||||
glib.IdleAdd(func() bool {
|
||||
iter := w.buf.EndIter()
|
||||
w.buf.Insert(iter, text)
|
||||
w.tv.ScrollToMark(w.endMark, 0, false, 0, 1)
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
func (w *outputWin) runCmd(cmd, env []string) bool {
|
||||
w.append(fmt.Sprintf("$ %s\n", strings.Join(cmd, " ")))
|
||||
|
||||
c := exec.Command(cmd[0], cmd[1:]...)
|
||||
c.Dir = hampackDir()
|
||||
if env != nil {
|
||||
c.Env = env
|
||||
}
|
||||
|
||||
pr, pw := io.Pipe()
|
||||
c.Stdout = pw
|
||||
c.Stderr = pw
|
||||
|
||||
scanDone := make(chan struct{})
|
||||
go func() {
|
||||
defer close(scanDone)
|
||||
scanner := bufio.NewScanner(pr)
|
||||
for scanner.Scan() {
|
||||
w.append(scanner.Text() + "\n")
|
||||
}
|
||||
}()
|
||||
|
||||
if err := c.Start(); err != nil {
|
||||
pw.Close()
|
||||
<-scanDone
|
||||
pr.Close()
|
||||
w.append(fmt.Sprintf("Error: %v\n", err))
|
||||
return false
|
||||
}
|
||||
|
||||
err := c.Wait()
|
||||
pw.Close()
|
||||
<-scanDone
|
||||
pr.Close()
|
||||
|
||||
if err != nil {
|
||||
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||
w.append(fmt.Sprintf("[exit %d]\n", exitErr.ExitCode()))
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (w *outputWin) run(ops []Op, onDone func()) {
|
||||
success := true
|
||||
for _, op := range ops {
|
||||
w.append(fmt.Sprintf("\n── %s ──\n", op.Label))
|
||||
for _, cmd := range op.Cmds {
|
||||
if !w.runCmd(cmd, op.Env) {
|
||||
success = false
|
||||
}
|
||||
}
|
||||
if op.Tmp != "" {
|
||||
os.Remove(op.Tmp)
|
||||
}
|
||||
}
|
||||
if success {
|
||||
w.append("\n── Done ──\n")
|
||||
} else {
|
||||
w.append("\n── Completed with errors ──\n")
|
||||
}
|
||||
glib.IdleAdd(func() bool {
|
||||
w.closeBtn.SetSensitive(true)
|
||||
onDone()
|
||||
return false
|
||||
})
|
||||
}
|
||||
|
||||
// ── Main window ───────────────────────────────────────────────────────────────
|
||||
|
||||
type mainWin struct {
|
||||
*adw.ApplicationWindow
|
||||
compiled map[string]map[string]string
|
||||
binaries map[string]map[string]string
|
||||
state map[string]bool
|
||||
rows map[string]*gtk.Switch
|
||||
applyBtn *gtk.Button
|
||||
updateBtn *gtk.Button
|
||||
}
|
||||
|
||||
func newMainWin(app *adw.Application) *mainWin {
|
||||
compiled := parseINI(filepath.Join(hampackDir(), "compile.conf"))
|
||||
binaries := parseINI(filepath.Join(hampackDir(), "binaries.conf"))
|
||||
utils, apps := parsePackages()
|
||||
flatpaks := parseFlatpaks()
|
||||
|
||||
w := &mainWin{
|
||||
ApplicationWindow: adw.NewApplicationWindow(&app.Application),
|
||||
compiled: compiled,
|
||||
binaries: binaries,
|
||||
state: detectInitialState(utils, apps, flatpaks, compiled, binaries),
|
||||
rows: make(map[string]*gtk.Switch),
|
||||
}
|
||||
w.SetTitle("HamPack Manager")
|
||||
w.SetDefaultSize(600, 720)
|
||||
|
||||
toolbar := adw.NewToolbarView()
|
||||
w.SetContent(toolbar)
|
||||
|
||||
header := adw.NewHeaderBar()
|
||||
toolbar.AddTopBar(header)
|
||||
|
||||
w.applyBtn = gtk.NewButtonWithLabel("Apply Changes")
|
||||
w.applyBtn.AddCSSClass("suggested-action")
|
||||
w.applyBtn.ConnectClicked(func() { w.onApply() })
|
||||
header.PackEnd(w.applyBtn)
|
||||
|
||||
w.updateBtn = gtk.NewButtonWithLabel("Run Update")
|
||||
w.updateBtn.ConnectClicked(func() { w.onUpdate() })
|
||||
header.PackStart(w.updateBtn)
|
||||
|
||||
page := adw.NewPreferencesPage()
|
||||
toolbar.SetContent(page)
|
||||
|
||||
windows := make([]string, len(windowsItems))
|
||||
for i, item := range windowsItems {
|
||||
windows[i] = item[0]
|
||||
}
|
||||
|
||||
w.makeGroup(page, "System Utilities", "utility", utils)
|
||||
w.makeGroup(page, "AUR Applications", "application", apps)
|
||||
w.makeGroup(page, "Flatpaks", "flatpak", flatpaks)
|
||||
w.makeGroup(page, "Compiled from Source", "compiled", sortedKeys(w.compiled))
|
||||
w.makeGroup(page, "Pre-built Binaries", "binary", sortedKeys(w.binaries))
|
||||
w.makeGroup(page, "Windows Apps (Wine)", "windows", windows)
|
||||
|
||||
return w
|
||||
}
|
||||
|
||||
func (w *mainWin) makeGroup(page *adw.PreferencesPage, title, cat string, names []string) {
|
||||
if len(names) == 0 {
|
||||
return
|
||||
}
|
||||
group := adw.NewPreferencesGroup()
|
||||
group.SetTitle(title)
|
||||
page.Add(group)
|
||||
|
||||
var actionRows []*adw.ActionRow
|
||||
for _, name := range names {
|
||||
key := cat + ":" + name
|
||||
row := adw.NewActionRow()
|
||||
row.SetTitle(name)
|
||||
sw := gtk.NewSwitch()
|
||||
sw.SetVAlign(gtk.AlignCenter)
|
||||
sw.SetActive(w.state[key])
|
||||
row.AddSuffix(sw)
|
||||
row.SetActivatableWidget(sw)
|
||||
group.Add(row)
|
||||
w.rows[key] = sw
|
||||
actionRows = append(actionRows, row)
|
||||
}
|
||||
|
||||
expanded := true
|
||||
chevron := gtk.NewImageFromIconName("pan-down-symbolic")
|
||||
toggleBtn := gtk.NewButton()
|
||||
toggleBtn.SetChild(chevron)
|
||||
toggleBtn.AddCSSClass("flat")
|
||||
toggleBtn.ConnectClicked(func() {
|
||||
expanded = !expanded
|
||||
for _, row := range actionRows {
|
||||
row.SetVisible(expanded)
|
||||
}
|
||||
if expanded {
|
||||
chevron.SetFromIconName("pan-down-symbolic")
|
||||
} else {
|
||||
chevron.SetFromIconName("pan-end-symbolic")
|
||||
}
|
||||
})
|
||||
group.SetHeaderSuffix(toggleBtn)
|
||||
}
|
||||
|
||||
func (w *mainWin) onApply() {
|
||||
newState := make(map[string]bool, len(w.rows))
|
||||
for k, sw := range w.rows {
|
||||
newState[k] = sw.Active()
|
||||
}
|
||||
|
||||
ops := computeOps(w.state, newState, w.compiled, w.binaries)
|
||||
|
||||
if len(ops) == 0 {
|
||||
dlg := adw.NewAlertDialog("No changes", "Nothing to install or remove.")
|
||||
dlg.AddResponse("ok", "OK")
|
||||
dlg.Present(w)
|
||||
return
|
||||
}
|
||||
|
||||
w.applyBtn.SetSensitive(false)
|
||||
|
||||
out := newOutputWin(ops, func() {
|
||||
w.state = newState
|
||||
saveState(w.state)
|
||||
w.applyBtn.SetSensitive(true)
|
||||
})
|
||||
out.Present()
|
||||
}
|
||||
|
||||
func (w *mainWin) onUpdate() {
|
||||
w.updateBtn.SetSensitive(false)
|
||||
w.applyBtn.SetSensitive(false)
|
||||
|
||||
ops := []Op{{
|
||||
Label: "Run Update",
|
||||
Cmds: [][]string{{"bash", "-c", "wget -qO- https://gitea.young.computer/david/hampack/raw/branch/main/install.sh | bash"}},
|
||||
Env: append(os.Environ(), "TERM=xterm"),
|
||||
}}
|
||||
|
||||
newOutputWin(ops, func() {
|
||||
w.updateBtn.SetSensitive(true)
|
||||
w.applyBtn.SetSensitive(true)
|
||||
}).Present()
|
||||
}
|
||||
|
||||
// ── Main ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
func main() {
|
||||
app := adw.NewApplication("computer.young.HamPack", 0)
|
||||
app.ConnectActivate(func() {
|
||||
iconTheme := gtk.IconThemeGetForDisplay(gdk.DisplayGetDefault())
|
||||
iconTheme.AddSearchPath(filepath.Join(hampackDir(), "desktop", "icons"))
|
||||
gtk.WindowSetDefaultIconName("computer.young.HamPack")
|
||||
newMainWin(app).Present()
|
||||
})
|
||||
os.Exit(app.Run(os.Args))
|
||||
}
|
||||
@@ -64,7 +64,6 @@ echo "Removing HamPack scripts and binaries..."
|
||||
rm -f ~/.local/bin/hampackrefresh
|
||||
rm -f ~/.local/bin/hampackupdate
|
||||
rm -f ~/.local/bin/hampackcheck
|
||||
rm -f ~/.local/bin/hampack
|
||||
rm -f ~/.local/bin/dx.py
|
||||
|
||||
# Uninstall not1mm
|
||||
@@ -160,7 +159,6 @@ rm -rf "$HOME/.wine/drive_c/RMS Express"
|
||||
|
||||
# Remove desktop files
|
||||
echo "Removing desktop files..."
|
||||
rm -f ~/.local/share/applications/hampack.desktop
|
||||
rm -f ~/.local/share/applications/js8call.desktop
|
||||
rm -f ~/.local/share/applications/yaac.desktop
|
||||
rm -f ~/.local/share/applications/potacat.desktop
|
||||
|
||||
+1
-23
@@ -86,30 +86,8 @@ echo "Installing dx.py..."
|
||||
wget -q https://raw.githubusercontent.com/HB9VQQ/dx.py/main/dx.py -O "$HOME/.local/bin/dx.py"
|
||||
chmod +x "$HOME/.local/bin/dx.py"
|
||||
|
||||
echo "Building HamPack..."
|
||||
cd ~/.local/share/HamPack/hampack-src
|
||||
go get github.com/diamondburned/gotk4-adwaita/pkg/adw@latest
|
||||
go get github.com/diamondburned/gotk4/pkg/gtk/v4@latest
|
||||
go mod tidy
|
||||
go build -o ~/.local/bin/hampack .
|
||||
cd ~/.local/share/HamPack
|
||||
|
||||
echo "Installing HamPack desktop file..."
|
||||
mkdir -p ~/.local/share/applications
|
||||
mkdir -p ~/.local/share/HamPack/desktop/icons/hicolor/256x256/apps
|
||||
cp ~/.local/share/HamPack/desktop/icons/ham.png \
|
||||
~/.local/share/HamPack/desktop/icons/hicolor/256x256/apps/computer.young.HamPack.png
|
||||
cat > ~/.local/share/applications/hampack.desktop << EOF
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=HamPack
|
||||
Exec=$HOME/.local/bin/hampack
|
||||
Icon=$HOME/.local/share/HamPack/desktop/icons/ham.png
|
||||
Comment=Manage HamPack amateur radio software
|
||||
Categories=HamRadio;
|
||||
EOF
|
||||
|
||||
echo "Installing JS8Call desktop file..."
|
||||
mkdir -p ~/.local/share/applications
|
||||
sed "s|\$HOME|$HOME|g" ~/.local/share/HamPack/desktop/js8call.desktop \
|
||||
> ~/.local/share/applications/js8call.desktop
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# /etc/coredesktop/updaters.d/170-hampack-build
|
||||
|
||||
HAMPACK_DIR="$HOME/.local/share/HamPack"
|
||||
|
||||
is_installed() {
|
||||
[[ -d "$HAMPACK_DIR/hampack-src" ]] && command -v go &>/dev/null
|
||||
}
|
||||
|
||||
run_update() {
|
||||
echo "→ Rebuilding HamPack..."
|
||||
cd "$HAMPACK_DIR/hampack-src"
|
||||
go get github.com/diamondburned/gotk4-adwaita/pkg/adw@latest
|
||||
go get github.com/diamondburned/gotk4/pkg/gtk/v4@latest
|
||||
go mod tidy
|
||||
go build -o "$HOME/.local/bin/hampack" .
|
||||
cd "$HAMPACK_DIR"
|
||||
|
||||
echo "→ Updating desktop files..."
|
||||
mkdir -p "$HOME/.local/share/applications"
|
||||
cat > "$HOME/.local/share/applications/hampack.desktop" << EOF
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=HamPack
|
||||
Exec=$HOME/.local/bin/hampack
|
||||
Icon=$HOME/.local/share/HamPack/desktop/icons/ham.png
|
||||
Comment=Manage HamPack amateur radio software
|
||||
Categories=HamRadio;
|
||||
EOF
|
||||
sed "s|\$HOME|$HOME|g" "$HAMPACK_DIR/desktop/js8call.desktop" \
|
||||
> "$HOME/.local/share/applications/js8call.desktop"
|
||||
update-desktop-database "$HOME/.local/share/applications/"
|
||||
|
||||
echo "✓ HamPack built and desktop files updated."
|
||||
}
|
||||
Reference in New Issue
Block a user