From 4af4fce76a43bb94e552322f81dbc334df016f6d Mon Sep 17 00:00:00 2001 From: sewn Date: Wed, 18 Oct 2023 20:14:24 +0300 Subject: [PATCH] initial sysinfo support --- cmd/vinegar/vinegar.go | 40 +++++++++++++++++++++++++---- sysinfo/distro.go | 57 ++++++++++++++++++++++++++++++++++++++++++ sysinfo/sysinfo.go | 18 +++++++------ wine/exec.go | 7 ++++-- wine/prefix.go | 2 -- 5 files changed, 108 insertions(+), 16 deletions(-) create mode 100644 sysinfo/distro.go diff --git a/cmd/vinegar/vinegar.go b/cmd/vinegar/vinegar.go index ae96bbcb..a78c9223 100644 --- a/cmd/vinegar/vinegar.go +++ b/cmd/vinegar/vinegar.go @@ -8,6 +8,7 @@ import ( "os" "os/signal" "path/filepath" + "slices" "syscall" "github.com/vinegarhq/vinegar/internal/config" @@ -15,6 +16,7 @@ import ( "github.com/vinegarhq/vinegar/internal/config/state" "github.com/vinegarhq/vinegar/internal/dirs" "github.com/vinegarhq/vinegar/internal/logs" + "github.com/vinegarhq/vinegar/sysinfo" "github.com/vinegarhq/vinegar/roblox" "github.com/vinegarhq/vinegar/wine" ) @@ -24,7 +26,7 @@ var BinPrefix string func usage() { fmt.Fprintln(os.Stderr, "usage: vinegar [-config filepath] player|studio [args...]") fmt.Fprintln(os.Stderr, "usage: vinegar [-config filepath] exec prog [args...]") - fmt.Fprintln(os.Stderr, " vinegar [-config filepath] edit|kill|uninstall|delete|install-webview2|winetricks|reportinfo") + fmt.Fprintln(os.Stderr, " vinegar [-config filepath] edit|kill|uninstall|delete|install-webview2|winetricks|sysinfo") os.Exit(1) } @@ -49,7 +51,7 @@ func main() { } // These commands (except player & studio) don't require a configuration, // but they require a wineprefix, hence wineroot of configuration is required. - case "player", "studio", "exec", "kill", "install-webview2", "winetricks": + case "sysinfo", "player", "studio", "exec", "kill", "install-webview2", "winetricks": pfxKilled := false cfg, err := config.Load(*configPath) if err != nil { @@ -77,14 +79,17 @@ func main() { }() switch cmd { - case "reportinfo": - // TODO: implement this function + case "sysinfo": + Sysinfo(&pfx) case "exec": if len(args) < 2 { usage() } - if err := pfx.Wine(args[1], args[2:]...).Run(); err != nil { + cmd := pfx.Wine(args[1], args[2:]...) + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + if err := cmd.Run(); err != nil { log.Fatal(err) } case "kill": @@ -198,3 +203,28 @@ func Delete() { log.Fatal(err) } } + +func Sysinfo(pfx *wine.Prefix) { + cpu := sysinfo.GetCPU() + avx := slices.Contains(cpu.Flags, "avx") + k := sysinfo.GetKernel() + d, err := sysinfo.GetDistro() + if err != nil { + log.Fatal(err) + } + + ver, err := pfx.Wine("--version").Output() + if err != nil { + log.Fatal(err) + } + + info := `## System information +* Distro: %s +* Processor: %s + * Supports AVX: %t +* Kernel: %s +* Wine: %s +` + + fmt.Printf(info, d, cpu.Model, avx, k, ver) +} diff --git a/sysinfo/distro.go b/sysinfo/distro.go new file mode 100644 index 00000000..85cf5ec3 --- /dev/null +++ b/sysinfo/distro.go @@ -0,0 +1,57 @@ +package sysinfo + +import ( + "os" + "bufio" + "strings" +) + +type Distro struct { + Name string + Version string +} + +func GetDistro() (Distro, error) { + var d Distro + + f, err := os.Open("/etc/os-release") + if err != nil { + return Distro{}, err + } + defer f.Close() + + s := bufio.NewScanner(f) + + for s.Scan() { + m := strings.SplitN(s.Text(), "=", 2) + if len(m) != 2 { + continue + } + + val := strings.Trim(m[1], "\"") + + switch m[0] { + case "PRETTY_NAME": + d.Name = val + case "VERSION_ID": + d.Version = val + } + } + if err := s.Err(); err != nil { + return Distro{}, err + } + + return d, nil +} + +func (d Distro) String() string { + if d.Name == "" { + d.Name = "Linux" + } + + if d.Version == "" { + d.Version = "Linux" + } + + return d.Name + " " + d.Version +} diff --git a/sysinfo/sysinfo.go b/sysinfo/sysinfo.go index 95996736..ea10f9b3 100644 --- a/sysinfo/sysinfo.go +++ b/sysinfo/sysinfo.go @@ -9,7 +9,6 @@ import ( "syscall" "strings" "path/filepath" - "slices" ) type Kernel struct { @@ -20,7 +19,6 @@ type Kernel struct { type CPU struct { Model string Flags []string - AVX bool } type GPU struct { @@ -32,7 +30,7 @@ type GPU struct { type GPUs []GPU -func NewKernel() Kernel { +func GetKernel() Kernel { var un syscall.Utsname _ = syscall.Uname(&un) @@ -53,7 +51,11 @@ func NewKernel() Kernel { } } -func NewCPU() (cpu CPU) { +func (k Kernel) String() string { + return k.Release + " " + k.Version +} + +func GetCPU() (cpu CPU) { column := regexp.MustCompile("\t+: ") f, _ := os.Open("/proc/cpuinfo") @@ -80,8 +82,6 @@ func NewCPU() (cpu CPU) { } } - cpu.AVX = slices.Contains(cpu.Flags, "avx") - if s.Err() != nil { return } @@ -89,7 +89,11 @@ func NewCPU() (cpu CPU) { return } -func NewGPUs() (gpus GPUs) { +func (cpu *CPU) String() string { + return cpu.Model +} + +func GetGPUs() (gpus GPUs) { card := regexp.MustCompile(`card([0-9]+)(?:-eDP-\d+)?$`) filepath.Walk("/sys/class/drm", func(p string, i fs.FileInfo, err error) error { diff --git a/wine/exec.go b/wine/exec.go index 459e7446..de9f51a2 100644 --- a/wine/exec.go +++ b/wine/exec.go @@ -11,8 +11,11 @@ type Cmd struct { func (p *Prefix) Command(name string, arg ...string) *Cmd { cmd := exec.Command(name, arg...) - cmd.Stderr = p.Output - cmd.Stdout = p.Output + if p.Output != nil { + cmd.Stderr = p.Output + cmd.Stdout = p.Output + } + cmd.Env = append(cmd.Environ(), "WINEPREFIX="+p.Dir, ) diff --git a/wine/prefix.go b/wine/prefix.go index c4d4e2dc..5d37f2e5 100644 --- a/wine/prefix.go +++ b/wine/prefix.go @@ -3,7 +3,6 @@ package wine import ( "io" "log" - "os" ) type Prefix struct { @@ -14,7 +13,6 @@ type Prefix struct { func New(dir string) Prefix { return Prefix{ Dir: dir, - Output: os.Stderr, } }