Files

344 lines
9.5 KiB
Go
Raw Permalink Normal View History

2018-12-16 20:16:40 +11:00
package cmd
2018-12-19 12:49:04 -08:00
import (
2018-12-22 18:40:36 -08:00
"fmt"
2019-06-24 09:11:06 +10:00
"net/url"
"os"
2019-06-25 08:13:20 +10:00
"runtime"
2018-12-19 12:49:04 -08:00
"strings"
2019-06-24 09:11:06 +10:00
"github.com/pkg/browser"
2018-12-19 12:49:04 -08:00
)
2018-12-16 20:16:40 +11:00
// LinuxDistribution is of type int
type LinuxDistribution int
const (
2018-12-22 18:40:36 -08:00
// Unknown is the catch-all distro
2019-05-02 13:35:34 +10:00
Unknown LinuxDistribution = iota
2019-10-08 06:12:08 +11:00
// Debian distribution
Debian
2018-12-23 15:37:51 +11:00
// Ubuntu distribution
2019-05-02 13:35:34 +10:00
Ubuntu
// Arch linux distribution
Arch
2019-10-08 06:12:08 +11:00
// CentOS linux distribution
CentOS
// Fedora linux distribution
Fedora
// Gentoo distribution
Gentoo
// Zorin distribution
Zorin
// Parrot distribution
Parrot
// Linuxmint distribution
Linuxmint
// VoidLinux distribution
VoidLinux
// Elementary distribution
Elementary
// Kali distribution
Kali
// Neon distribution
Neon
// ArcoLinux distribution
ArcoLinux
2019-10-08 06:12:08 +11:00
// Manjaro distribution
Manjaro
2020-01-08 23:38:05 +02:00
// ManjaroARM distribution
ManjaroARM
// Deepin distribution
Deepin
// Raspbian distribution
Raspbian
2020-05-17 20:17:00 +10:00
// Tumbleweed (OpenSUSE) distribution
2020-04-19 12:20:27 +02:00
Tumbleweed
2020-05-17 20:17:00 +10:00
// Leap (OpenSUSE) distribution
2020-04-19 12:20:27 +02:00
Leap
2020-05-17 20:17:00 +10:00
// ArchLabs distribution
ArchLabs
2020-05-27 06:54:32 +10:00
// PopOS distribution
PopOS
2020-05-27 10:16:44 +10:00
// Solus distribution
Solus
2020-09-03 14:42:03 +05:00
// Ctlos Linux distribution
Ctlos
2020-11-26 20:44:42 +11:00
// EndeavourOS linux distribution
EndeavourOS
2021-03-27 21:06:02 +11:00
// Crux linux distribution
Crux
2021-04-03 16:15:32 +11:00
// RHEL distribution
RHEL
2021-08-30 19:15:10 +01:00
// NixOS distribution
NixOS
2021-10-11 17:16:24 +02:00
// Artix linux distribution
ArtixLinux
2022-01-05 11:13:34 +08:00
//Uos distribution
Uos
2018-12-16 20:16:40 +11:00
)
// DistroInfo contains all the information relating to a linux distribution
type DistroInfo struct {
2019-10-08 06:12:08 +11:00
Distribution LinuxDistribution
Name string
ID string
Description string
Release string
2018-12-16 20:16:40 +11:00
}
2018-12-22 18:40:36 -08:00
// GetLinuxDistroInfo returns information about the running linux distribution
2018-12-19 12:49:04 -08:00
func GetLinuxDistroInfo() *DistroInfo {
2019-10-08 06:12:08 +11:00
result := &DistroInfo{
Distribution: Unknown,
ID: "unknown",
Name: "Unknown",
}
_, err := os.Stat("/etc/os-release")
if !os.IsNotExist(err) {
osRelease, _ := os.ReadFile("/etc/os-release")
2019-10-08 06:12:08 +11:00
result = parseOsRelease(string(osRelease))
2018-12-16 20:16:40 +11:00
}
return result
}
2018-12-22 18:40:36 -08:00
2019-10-08 06:12:08 +11:00
// parseOsRelease parses the given os-release data and returns
// a DistroInfo struct with the details
func parseOsRelease(osRelease string) *DistroInfo {
result := &DistroInfo{Distribution: Unknown}
// Default value
osID := "unknown"
osNAME := "Unknown"
version := ""
// Split into lines
lines := strings.Split(osRelease, "\n")
// Iterate lines
for _, line := range lines {
// Split each line by the equals char
splitLine := strings.SplitN(line, "=", 2)
// Check we have
if len(splitLine) != 2 {
continue
}
switch splitLine[0] {
case "ID":
2020-05-27 12:48:28 +10:00
osID = strings.ToLower(strings.Trim(splitLine[1], "\""))
2019-10-08 06:12:08 +11:00
case "NAME":
osNAME = strings.Trim(splitLine[1], "\"")
case "VERSION_ID":
version = strings.Trim(splitLine[1], "\"")
}
}
2019-10-08 06:12:08 +11:00
// Check distro name against list of distros
2020-05-27 12:48:28 +10:00
switch osID {
2019-10-08 06:12:08 +11:00
case "fedora":
result.Distribution = Fedora
case "centos":
result.Distribution = CentOS
2021-04-03 16:15:32 +11:00
case "rhel":
result.Distribution = RHEL
2019-10-08 06:12:08 +11:00
case "arch":
result.Distribution = Arch
2020-05-17 20:17:00 +10:00
case "archlabs":
result.Distribution = ArchLabs
2020-09-03 14:42:03 +05:00
case "ctlos":
2020-11-26 20:44:42 +11:00
result.Distribution = Ctlos
2019-10-08 06:12:08 +11:00
case "debian":
result.Distribution = Debian
case "ubuntu":
result.Distribution = Ubuntu
case "gentoo":
result.Distribution = Gentoo
case "zorin":
result.Distribution = Zorin
case "parrot":
result.Distribution = Parrot
case "linuxmint":
result.Distribution = Linuxmint
case "void":
result.Distribution = VoidLinux
case "elementary":
result.Distribution = Elementary
case "kali":
result.Distribution = Kali
case "neon":
result.Distribution = Neon
case "arcolinux":
result.Distribution = ArcoLinux
2019-10-08 06:12:08 +11:00
case "manjaro":
result.Distribution = Manjaro
2020-01-08 23:38:05 +02:00
case "manjaro-arm":
result.Distribution = ManjaroARM
case "deepin":
result.Distribution = Deepin
case "raspbian":
result.Distribution = Raspbian
2020-04-19 12:20:27 +02:00
case "opensuse-tumbleweed":
result.Distribution = Tumbleweed
case "opensuse-leap":
result.Distribution = Leap
2020-05-27 06:54:32 +10:00
case "pop":
result.Distribution = PopOS
2020-05-27 10:16:44 +10:00
case "solus":
result.Distribution = Solus
2020-11-26 20:44:42 +11:00
case "endeavouros":
result.Distribution = EndeavourOS
2021-03-27 21:06:02 +11:00
case "crux":
result.Distribution = Crux
2021-08-30 19:15:10 +01:00
case "nixos":
result.Distribution = NixOS
2021-10-11 17:16:24 +02:00
case "artix":
result.Distribution = ArtixLinux
2022-01-05 11:13:34 +08:00
case "uos":
result.Distribution = Uos
2019-10-08 06:12:08 +11:00
default:
result.Distribution = Unknown
}
result.Name = osNAME
result.ID = osID
result.Release = version
return result
}
// CheckPkgInstalled is all functions that use local programs to see if a package is installed
type CheckPkgInstalled func(string) (bool, error)
// EqueryInstalled uses equery to see if a package is installed
func EqueryInstalled(packageName string) (bool, error) {
program := NewProgramHelper()
equery := program.FindProgram("equery")
if equery == nil {
return false, fmt.Errorf("cannont check dependencies: equery not found")
}
_, _, exitCode, _ := equery.Run("l", packageName)
return exitCode == 0, nil
}
2018-12-22 18:40:36 -08:00
// DpkgInstalled uses dpkg to see if a package is installed
func DpkgInstalled(packageName string) (bool, error) {
program := NewProgramHelper()
dpkg := program.FindProgram("dpkg")
if dpkg == nil {
return false, fmt.Errorf("cannot check dependencies: dpkg not found")
}
2018-12-23 15:37:51 +11:00
_, _, exitCode, _ := dpkg.Run("-L", packageName)
2019-04-10 08:38:46 +10:00
return exitCode == 0, nil
2018-12-22 18:40:36 -08:00
}
2019-05-02 13:35:34 +10:00
2020-05-27 10:16:44 +10:00
// EOpkgInstalled uses dpkg to see if a package is installed
func EOpkgInstalled(packageName string) (bool, error) {
program := NewProgramHelper()
eopkg := program.FindProgram("eopkg")
if eopkg == nil {
return false, fmt.Errorf("cannot check dependencies: eopkg not found")
}
2020-05-27 10:33:00 +10:00
stdout, _, _, _ := eopkg.Run("info", packageName)
return strings.HasPrefix(stdout, "Installed"), nil
2020-05-27 10:16:44 +10:00
}
2019-05-02 13:35:34 +10:00
// PacmanInstalled uses pacman to see if a package is installed.
func PacmanInstalled(packageName string) (bool, error) {
program := NewProgramHelper()
pacman := program.FindProgram("pacman")
if pacman == nil {
return false, fmt.Errorf("cannot check dependencies: pacman not found")
}
_, _, exitCode, _ := pacman.Run("-Qs", packageName)
return exitCode == 0, nil
}
2019-10-08 06:12:08 +11:00
// XbpsInstalled uses pacman to see if a package is installed.
func XbpsInstalled(packageName string) (bool, error) {
program := NewProgramHelper()
xbpsQuery := program.FindProgram("xbps-query")
if xbpsQuery == nil {
return false, fmt.Errorf("cannot check dependencies: xbps-query not found")
}
_, _, exitCode, _ := xbpsQuery.Run("-S", packageName)
return exitCode == 0, nil
}
// RpmInstalled uses rpm to see if a package is installed
func RpmInstalled(packageName string) (bool, error) {
program := NewProgramHelper()
rpm := program.FindProgram("rpm")
if rpm == nil {
return false, fmt.Errorf("cannot check dependencies: rpm not found")
}
_, _, exitCode, _ := rpm.Run("--query", packageName)
return exitCode == 0, nil
}
2019-06-24 09:11:06 +10:00
2021-03-27 21:06:02 +11:00
// PrtGetInstalled uses prt-get to see if a package is installed
func PrtGetInstalled(packageName string) (bool, error) {
program := NewProgramHelper()
prtget := program.FindProgram("prt-get")
if prtget == nil {
return false, fmt.Errorf("cannot check dependencies: prt-get not found")
}
_, _, exitCode, _ := prtget.Run("isinst", packageName)
return exitCode == 0, nil
}
2021-08-30 19:15:10 +01:00
// NixEnvInstalled uses nix-env to see if a package is installed
func NixEnvInstalled(packageName string) (bool, error) {
program := NewProgramHelper()
nixEnv := program.FindProgram("nix-env")
if nixEnv == nil {
return false, fmt.Errorf("cannot check dependencies: nix-env not found")
}
packageName = strings.ReplaceAll(packageName, "+", `\+`)
_, _, exitCode, _ := nixEnv.Run("-q", packageName)
return exitCode == 0, nil
}
2019-06-24 09:11:06 +10:00
// RequestSupportForDistribution promts the user to submit a request to support their
// currently unsupported distribution
2019-10-08 06:12:08 +11:00
func RequestSupportForDistribution(distroInfo *DistroInfo) error {
2019-06-24 09:11:06 +10:00
var logger = NewLogger()
2019-10-08 06:12:08 +11:00
defaultError := fmt.Errorf("unable to check libraries on distribution '%s'", distroInfo.Name)
2019-06-24 09:11:06 +10:00
2019-10-08 06:12:08 +11:00
logger.Yellow("Distribution '%s' is not currently supported, but we would love to!", distroInfo.Name)
q := fmt.Sprintf("Would you like to submit a request to support distribution '%s'?", distroInfo.Name)
2019-06-24 09:11:06 +10:00
result := Prompt(q, "yes")
if strings.ToLower(result) != "yes" {
return defaultError
}
2019-10-08 06:12:08 +11:00
title := fmt.Sprintf("Support Distribution '%s'", distroInfo.Name)
2019-06-24 09:11:06 +10:00
2019-06-25 08:13:20 +10:00
var str strings.Builder
gomodule, exists := os.LookupEnv("GO111MODULE")
if !exists {
gomodule = "(Not Set)"
}
str.WriteString("\n| Name | Value |\n| ----- | ----- |\n")
str.WriteString(fmt.Sprintf("| Wails Version | %s |\n", Version))
str.WriteString(fmt.Sprintf("| Go Version | %s |\n", runtime.Version()))
str.WriteString(fmt.Sprintf("| Platform | %s |\n", runtime.GOOS))
str.WriteString(fmt.Sprintf("| Arch | %s |\n", runtime.GOARCH))
str.WriteString(fmt.Sprintf("| GO111MODULE | %s |\n", gomodule))
2019-10-08 06:12:08 +11:00
str.WriteString(fmt.Sprintf("| Distribution ID | %s |\n", distroInfo.ID))
str.WriteString(fmt.Sprintf("| Distribution Name | %s |\n", distroInfo.Name))
2019-06-25 08:13:20 +10:00
str.WriteString(fmt.Sprintf("| Distribution Version | %s |\n", distroInfo.Release))
2019-10-08 06:12:08 +11:00
body := fmt.Sprintf("**Description**\nDistribution '%s' is currently unsupported.\n\n**Further Information**\n\n%s\n\n*Please add any extra information here, EG: libraries that are needed to make the distribution work, or commands to install them*", distroInfo.ID, str.String())
2019-06-24 09:11:06 +10:00
fullURL := "https://github.com/wailsapp/wails/issues/new?"
params := "title=" + title + "&body=" + body
fmt.Println("Opening browser to file request.")
browser.OpenURL(fullURL + url.PathEscape(params))
2020-05-27 06:54:32 +10:00
result = Prompt("We have a guide for adding support for your distribution. Would you like to view it?", "yes")
if strings.ToLower(result) == "yes" {
browser.OpenURL("https://wails.app/guides/distro/")
}
2019-06-24 09:11:06 +10:00
return nil
}