fixes to test plugins by os.Exec()

This commit is contained in:
Jeff Carr 2025-08-16 16:23:08 -05:00
parent de6b45ced2
commit edb3e23311
12 changed files with 208 additions and 33 deletions

View File

@ -3,14 +3,16 @@ GUIVERSION = $(shell git describe --tags)
BUILDTIME = $(shell date +%Y.%m.%d)
all: verbose
./fixup drives
-fixup --gui-check-plugin ../../../toolkits/gocui/gocui.so
fixup --gui gocui --gui-verbose --gui-file ../../toolkits/gocui/gocui.so drives
go-build: goimports
GO111MODULE=off go build \
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
verbose: goimports
GO111MODULE=off go build -v -x \
-cp -a ../../../toolkits/gocui/gocui.so resources/
GO111MODULE=off go install -v -x \
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
install: goimports

View File

@ -59,5 +59,5 @@ func init() {
}
func (args) Version() string {
return "wit-test " + VERSION + " Built on " + BUILDTIME
return ARGNAME + " " + VERSION + " Built on " + BUILDTIME
}

View File

@ -13,9 +13,6 @@ import (
handles shell autocomplete
*/
// used for shell auto completion
var ARGNAME string = "wit-test" // todo: get this from $0 ?
func (args) doBashAuto() {
argv.doBashHelp()
switch argv.BashAuto[0] {
@ -68,6 +65,8 @@ func (args) doBash() {
fmt.Println("")
fmt.Println("# todo: add this to go-arg as a 'hidden' go-arg option --bash")
fmt.Println("#")
fmt.Println("# Put the below in the file: ~/.local/share/bash-completion/completions/" + ARGNAME)
fmt.Println("#")
fmt.Println("# todo: make this output work/parse with:")
fmt.Println("# complete -C " + ARGNAME + " --bash go")
fmt.Println("")

View File

@ -2,7 +2,6 @@ package main
import (
"bufio"
"fmt"
"io/fs"
"os"
"path/filepath"
@ -18,7 +17,7 @@ func doDrives() {
}
for _, p := range parts {
fmt.Printf("Device: /dev/%s\tSize: %d KiB\n", p.Name, p.Blocks)
log.Printf("Device: /dev/%s\tSize: %d KiB\n", p.Name, p.Blocks)
}
blockDir := "/sys/block"
@ -33,7 +32,7 @@ func doDrives() {
if d.IsDir() && filepath.Dir(path) == blockDir {
dev := d.Name()
devPath := "/dev/" + dev
fmt.Printf("Drive: %s\n", devPath)
log.Printf("Drive: %s\n", devPath)
// Look for partitions
partitions, err := filepath.Glob(filepath.Join(blockDir, dev, dev+"*"))
@ -51,18 +50,18 @@ func doDrives() {
hasPartition = true
partDev := "/dev/" + partName
isMounted := mounts[partDev]
fmt.Printf(" Partition: %s [%v]\n", partDev, isMounted)
log.Printf(" Partition: %s [%v]\n", partDev, isMounted)
if isMounted {
used = true
}
}
if !hasPartition {
fmt.Println(" No partitions found.")
log.Println(" No partitions found.")
}
if !used {
fmt.Println(" → Drive appears to be unused.")
log.Println(" → Drive appears to be unused.")
}
}
return nil
@ -127,9 +126,9 @@ func parseProcPartitions() ([]Partition, error) {
}
var p Partition
_, err := fmt.Sscanf(line, "%d %d %d %s", &p.Major, &p.Minor, &p.Blocks, &p.Name)
_, err := log.Sscanf(line, "%d %d %d %s", &p.Major, &p.Minor, &p.Blocks, &p.Name)
if err != nil {
return nil, fmt.Errorf("error parsing line: %q: %w", line, err)
return nil, log.Errorf("error parsing line: %q: %w", line, err)
}
partitions = append(partitions, p)
}

71
doGui.go Normal file
View File

@ -0,0 +1,71 @@
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
// Use of this source code is governed by the GPL 3.0
package main
// An app to submit patches for the 30 GO GUI repos
import (
"os"
"time"
"go.wit.com/gui"
"go.wit.com/lib/gadgets"
"go.wit.com/log"
)
func debug() {
for {
time.Sleep(3 * time.Second)
log.Info("TODO: use this?")
}
}
func doGui() {
me.myGui = gui.New()
me.myGui.InitEmbed(resources)
me.myGui.Default()
mainWindow := gadgets.NewGenericWindow("RiscV Imager", "Show Drives")
mainWindow.Custom = func() {
log.Warn("Main window close")
os.Exit(0)
}
drawWindow(mainWindow)
// sits here forever
debug()
}
func drawWindow(win *gadgets.GenericWindow) {
grid := win.Group.RawGrid()
grid.NewLabel("Drives:")
me.dd = grid.NewDropdown()
me.dd.AddText("/dev/blah")
me.dd.Custom = func() {
log.Info("todo: changed drive")
}
grid.NextRow()
grid.NewButton("doDrives()", func() {
doDrives()
})
grid.NewButton("doDrives2()", func() {
doDrives2()
})
grid.NewButton("partition drives", func() {
log.Info("something")
})
grid.NextRow()
grid.NewButton("ConfigSave()", func() {
log.Info("todo: make code for this")
})
}

View File

@ -1,10 +1,11 @@
package main
import (
"fmt"
"os"
"path/filepath"
"strings"
"go.wit.com/log"
)
type DevInfo struct {
@ -17,7 +18,7 @@ type DevInfo struct {
func doDrives2() {
parts, err := parseProcPartitions()
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading /proc/partitions: %v\n", err)
log.Printf("Error reading /proc/partitions: %v\n", err)
os.Exit(1)
}
@ -42,12 +43,14 @@ func doDrives2() {
for _, info := range devs {
devPath := "/dev/" + info.Name
if info.IsRaw {
fmt.Printf("%-12s -> %-8s (raw)\n", devPath, info.Type)
s := log.Sprintf("%-12s -> %-8s (raw)", devPath, info.Type)
log.Info(s)
me.dd.AddText(s)
} else {
if info.Parent != "" {
fmt.Printf("%-12s -> partition of /dev/%s\n", devPath, info.Parent)
log.Printf("%-12s -> partition of /dev/%s\n", devPath, info.Parent)
} else {
fmt.Printf("%-12s -> unknown (no parent found)\n", devPath)
log.Printf("%-12s -> unknown (no parent found)\n", devPath)
}
}
}

73
main.go
View File

@ -5,12 +5,16 @@ package main
import (
"debug/buildinfo"
"embed"
"fmt"
"os"
"os/exec"
"path/filepath"
"plugin"
"unicode"
"go.wit.com/dev/alexflint/arg"
"go.wit.com/gui"
"go.wit.com/log"
)
@ -18,9 +22,16 @@ import (
var VERSION string
var BUILDTIME string
// used for shell auto completion
var ARGNAME string = "fixup" // todo: get this from $0 ?
//go:embed resources/*
var resources embed.FS
func main() {
me = new(autoType)
me.argpp = arg.MustParse(&argv)
gui.InitArg()
me.pp = arg.MustParse(&argv)
if argv.Bash {
argv.doBash()
@ -31,12 +42,21 @@ func main() {
os.Exit(0)
}
if argv.Drives != nil {
doDrives()
doDrives2()
}
// checkPlug("../../../toolkits/gocui/gocui.so")
// checkPlug("/usr/lib/go-gui-toolkits/gocui.v0.22.46.so")
listenForBlockEvents()
/*
if argv.Drives != nil {
doDrives()
doDrives2()
}
*/
// doDrives()
// okExit("everything compiled")
go listenForBlockEvents()
doGui()
okExit("everything compiled")
}
@ -71,26 +91,57 @@ func dumpDebug() {
// Get absolute path of the currently running binary
exePath, err := os.Executable()
if err != nil {
fmt.Println("Error getting executable path:", err)
log.Println("Error getting executable path:", err)
return
}
// Resolve symlinks if necessary
exePath, err = filepath.EvalSymlinks(exePath)
if err != nil {
fmt.Println("Error resolving symlink:", err)
log.Println("Error resolving symlink:", err)
return
}
// Read build info
bi, err := buildinfo.ReadFile(exePath)
if err != nil {
fmt.Println("Error reading build info:", err)
log.Println("Error reading build info:", err)
return
}
fmt.Println("Go Version:", bi.GoVersion)
log.Println("Go Version:", bi.GoVersion)
for _, dep := range bi.Deps {
fmt.Printf("Dependency: %s %s\n", dep.Path, dep.Version)
log.Printf("Dependency: %s %s\n", dep.Path, dep.Version)
}
}
func checkPlug(pluginPath string) *plugin.Plugin {
if err := checkPluginViaSubprocess(pluginPath); err != nil {
fmt.Printf("Plugin check failed: %v\n", err)
return nil
}
p, err := plugin.Open(pluginPath)
if err != nil {
log.Fatalf("plugin.Open failed: %v", err)
}
log.Println("Plugin loaded successfully.")
return p
}
func checkPluginViaSubprocess(path string) error {
exe, err := os.Executable()
if err != nil {
return fmt.Errorf("failed to get executable path: %w", err)
}
resolved, err := filepath.EvalSymlinks(exe)
if err != nil {
return fmt.Errorf("failed to resolve executable symlink: %w", err)
}
cmd := exec.Command(resolved, "--gui-check-plugin", path)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}

47
plugincheck/check.go Normal file
View File

@ -0,0 +1,47 @@
package plugincheck
import (
"debug/buildinfo"
"errors"
"fmt"
"runtime/debug"
)
// CheckPluginCompatibility verifies that the plugin .so file was built
// with the same Go version and dependency versions as the host binary.
func CheckPluginCompatibility(pluginPath string) error {
pluginInfo, err := buildinfo.ReadFile(pluginPath)
if err != nil {
return fmt.Errorf("failed to read plugin build info: %w", err)
}
mainInfo, ok := debug.ReadBuildInfo()
if !ok {
return errors.New("failed to read main binary build info")
}
if pluginInfo.GoVersion != mainInfo.GoVersion {
return fmt.Errorf("Go version mismatch: plugin=%s, host=%s",
pluginInfo.GoVersion, mainInfo.GoVersion)
}
// Create a map of main binary dependencies for quick lookup
hostDeps := make(map[string]string)
for _, dep := range mainInfo.Deps {
hostDeps[dep.Path] = dep.Version
}
// Compare plugin dependencies
for _, dep := range pluginInfo.Deps {
hostVer, ok := hostDeps[dep.Path]
if !ok {
return fmt.Errorf("dependency %s not found in host binary", dep.Path)
}
if dep.Version != hostVer {
return fmt.Errorf("dependency version mismatch for %s: plugin=%s, host=%s",
dep.Path, dep.Version, hostVer)
}
}
return nil
}

1
resources/README Normal file
View File

@ -0,0 +1 @@
put the GO GUI plugin .so files here

BIN
resources/gocui.so Normal file

Binary file not shown.

View File

@ -5,11 +5,14 @@ package main
import (
"go.wit.com/dev/alexflint/arg"
"go.wit.com/gui"
)
var me *autoType
// this app's variables
type autoType struct {
argpp *arg.Parser // go-arg preprocessor
pp *arg.Parser // go-arg preprocessor
myGui *gui.Node // the gui toolkit handle
dd *gui.Node // the drives dropdown list
}

View File

@ -1,7 +1,6 @@
package main
import (
"fmt"
"log"
"syscall"
)
@ -43,7 +42,7 @@ func listenForBlockEvents() {
msg := parseUevent(buf[:n])
if msg["SUBSYSTEM"] == "block" && msg["ACTION"] == "add" {
fmt.Printf("New block device added: %s\n", msg["DEVNAME"])
log.Printf("New block device added: %s\n", msg["DEVNAME"])
}
}
}