Add nixpkgs support to doctor command. (#1551)

* Dependancy => Dependency typo fix.

* Add Nixpkgs support to doctor command.

* Add mention of nixpkgs to linux distro support doc.
This commit is contained in:
Ian M. Jones
2022-07-13 07:29:41 +10:00
committed by GitHub
parent 51a7630cd7
commit 82cc5498f1
9 changed files with 193 additions and 30 deletions
@@ -68,7 +68,7 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
// Output Dependencies Status
var dependenciesMissing = []string{}
var externalPackages = []*packagemanager.Dependancy{}
var externalPackages = []*packagemanager.Dependency{}
var dependenciesAvailableRequired = 0
var dependenciesAvailableOptional = 0
fmt.Fprintf(w, "\n")
@@ -0,0 +1,159 @@
//go:build linux
// +build linux
package packagemanager
import (
"encoding/json"
"github.com/wailsapp/wails/v2/internal/shell"
)
// Nixpkgs represents the Nixpkgs manager
type Nixpkgs struct {
name string
osid string
}
type NixPackageDetail struct {
Name string
Pname string
Version string
}
var available map[string]NixPackageDetail
// NewNixpkgs creates a new Nixpkgs instance
func NewNixpkgs(osid string) *Nixpkgs {
available = map[string]NixPackageDetail{}
return &Nixpkgs{
name: "nixpkgs",
osid: osid,
}
}
// Packages returns the libraries that we need for Wails to compile
// They will potentially differ on different distributions or versions
func (n *Nixpkgs) Packages() packagemap {
// Currently, only support checking the default channel.
channel := "nixpkgs"
if n.osid == "nixos" {
channel = "nixos"
}
return packagemap{
"libgtk-3": []*Package{
{Name: channel + ".gtk3", SystemPackage: true, Library: true},
},
"libwebkit": []*Package{
{Name: channel + ".webkitgtk", SystemPackage: true, Library: true},
},
"gcc": []*Package{
{Name: channel + ".gcc", SystemPackage: true},
},
"pkg-config": []*Package{
{Name: channel + ".pkg-config", SystemPackage: true},
},
"npm": []*Package{
{Name: channel + ".nodejs", SystemPackage: true},
},
"upx": []*Package{
{Name: channel + ".upx", SystemPackage: true, Optional: true},
},
"docker": []*Package{
{Name: channel + ".docker", SystemPackage: true, Optional: true},
},
"nsis": []*Package{
{Name: channel + ".nsis", SystemPackage: true, Optional: true},
},
}
}
// Name returns the name of the package manager
func (n *Nixpkgs) Name() string {
return n.name
}
// PackageInstalled tests if the given package name is installed
func (n *Nixpkgs) PackageInstalled(pkg *Package) (bool, error) {
if pkg.SystemPackage == false {
return false, nil
}
stdout, _, err := shell.RunCommand(".", "nix-env", "--json", "-qA", pkg.Name)
if err != nil {
return false, nil
}
var attributes map[string]NixPackageDetail
err = json.Unmarshal([]byte(stdout), &attributes)
if err != nil {
return false, err
}
// Did we get one?
installed := false
for attribute, detail := range attributes {
if attribute == pkg.Name {
installed = true
pkg.Version = detail.Version
}
break
}
// If on NixOS, package may be installed via system config, so check the nix store.
detail, ok := available[pkg.Name]
if !installed && n.osid == "nixos" && ok {
cmd := "nix-store --query --requisites /run/current-system | cut -d- -f2- | sort | uniq | grep '^" + detail.Pname + "'"
if pkg.Library {
cmd += " | grep 'dev$'"
}
stdout, _, err = shell.RunCommand(".", "sh", "-c", cmd)
if err != nil {
return false, nil
}
if len(stdout) > 0 {
installed = true
}
}
return installed, nil
}
// PackageAvailable tests if the given package is available for installation
func (n *Nixpkgs) PackageAvailable(pkg *Package) (bool, error) {
if pkg.SystemPackage == false {
return false, nil
}
stdout, _, err := shell.RunCommand(".", "nix-env", "--json", "-qaA", pkg.Name)
if err != nil {
return false, nil
}
var attributes map[string]NixPackageDetail
err = json.Unmarshal([]byte(stdout), &attributes)
if err != nil {
return false, err
}
// Grab first version.
for attribute, detail := range attributes {
pkg.Version = detail.Version
available[attribute] = detail
break
}
return len(pkg.Version) > 0, nil
}
// InstallCommand returns the package manager specific command to install a package
func (n *Nixpkgs) InstallCommand(pkg *Package) string {
if pkg.SystemPackage == false {
return pkg.InstallCommand[n.osid]
}
return "nix-env -iA " + pkg.Name
}
@@ -18,6 +18,7 @@ var pmcommands = []string{
"pacman",
"emerge",
"zypper",
"nix-env",
}
// Find will attempt to find the system package manager
@@ -46,19 +47,21 @@ func newPackageManager(pmname string, osid string) PackageManager {
return NewEmerge(osid)
case "zypper":
return NewZypper(osid)
case "nix-env":
return NewNixpkgs(osid)
}
return nil
}
// Dependancies scans the system for required dependancies
// Returns a list of dependancies search for, whether they were found
// Dependencies scans the system for required dependencies
// Returns a list of dependencies search for, whether they were found
// and whether they were installed
func Dependancies(p PackageManager) (DependencyList, error) {
func Dependencies(p PackageManager) (DependencyList, error) {
var dependencies DependencyList
for name, packages := range p.Packages() {
dependency := &Dependancy{Name: name}
dependency := &Dependency{Name: name}
for _, pkg := range packages {
dependency.Optional = pkg.Optional
dependency.External = !pkg.SystemPackage
+3 -3
View File
@@ -21,8 +21,8 @@ type PackageManager interface {
InstallCommand(*Package) string
}
// Dependancy represents a system package that we require
type Dependancy struct {
// Dependency represents a system package that we require
type Dependency struct {
Name string
PackageName string
Installed bool
@@ -33,7 +33,7 @@ type Dependancy struct {
}
// DependencyList is a list of Dependency instances
type DependencyList []*Dependancy
type DependencyList []*Dependency
// InstallAllRequiredCommand returns the command you need to use to install all required dependencies
func (d DependencyList) InstallAllRequiredCommand() string {
+11 -11
View File
@@ -32,7 +32,7 @@ func GetInfo() (*Info, error) {
return &result, nil
}
func checkNPM() *packagemanager.Dependancy {
func checkNPM() *packagemanager.Dependency {
// Check for npm
output, err := exec.Command("npm", "-version").Output()
@@ -43,7 +43,7 @@ func checkNPM() *packagemanager.Dependancy {
} else {
version = strings.TrimSpace(strings.Split(string(output), "\n")[0])
}
return &packagemanager.Dependancy{
return &packagemanager.Dependency{
Name: "npm ",
PackageName: "N/A",
Installed: installed,
@@ -54,7 +54,7 @@ func checkNPM() *packagemanager.Dependancy {
}
}
func checkUPX() *packagemanager.Dependancy {
func checkUPX() *packagemanager.Dependency {
// Check for npm
output, err := exec.Command("upx", "-V").Output()
@@ -65,7 +65,7 @@ func checkUPX() *packagemanager.Dependancy {
} else {
version = strings.TrimSpace(strings.Split(string(output), "\n")[0])
}
return &packagemanager.Dependancy{
return &packagemanager.Dependency{
Name: "upx ",
PackageName: "N/A",
Installed: installed,
@@ -76,7 +76,7 @@ func checkUPX() *packagemanager.Dependancy {
}
}
func checkNSIS() *packagemanager.Dependancy {
func checkNSIS() *packagemanager.Dependency {
// Check for nsis installer
output, err := exec.Command("makensis", "-VERSION").Output()
@@ -87,7 +87,7 @@ func checkNSIS() *packagemanager.Dependancy {
} else {
version = strings.TrimSpace(strings.Split(string(output), "\n")[0])
}
return &packagemanager.Dependancy{
return &packagemanager.Dependency{
Name: "nsis ",
PackageName: "N/A",
Installed: installed,
@@ -98,12 +98,12 @@ func checkNSIS() *packagemanager.Dependancy {
}
}
func checkLibrary(name string) func() *packagemanager.Dependancy {
return func() *packagemanager.Dependancy {
func checkLibrary(name string) func() *packagemanager.Dependency {
return func() *packagemanager.Dependency {
output, _, _ := shell.RunCommand(".", "pkg-config", "--cflags", name)
installed := len(strings.TrimSpace(output)) > 0
return &packagemanager.Dependancy{
return &packagemanager.Dependency{
Name: "lib" + name + " ",
PackageName: "N/A",
Installed: installed,
@@ -115,7 +115,7 @@ func checkLibrary(name string) func() *packagemanager.Dependancy {
}
}
func checkDocker() *packagemanager.Dependancy {
func checkDocker() *packagemanager.Dependency {
// Check for npm
output, err := exec.Command("docker", "version").Output()
@@ -139,7 +139,7 @@ func checkDocker() *packagemanager.Dependancy {
}
}
}
return &packagemanager.Dependancy{
return &packagemanager.Dependency{
Name: "docker ",
PackageName: "N/A",
Installed: installed,
+1 -1
View File
@@ -42,7 +42,7 @@ func (i *Info) discover() error {
version = strings.TrimSpace(version)
version = strings.TrimSuffix(version, ".")
}
xcodeDep := &packagemanager.Dependancy{
xcodeDep := &packagemanager.Dependency{
Name: "xcode command line tools ",
PackageName: "N/A",
Installed: installed,
+7 -7
View File
@@ -8,11 +8,11 @@ import (
"github.com/wailsapp/wails/v2/internal/system/packagemanager"
)
func checkGCC() *packagemanager.Dependancy {
func checkGCC() *packagemanager.Dependency {
version := packagemanager.AppVersion("gcc")
return &packagemanager.Dependancy{
return &packagemanager.Dependency{
Name: "gcc ",
PackageName: "N/A",
Installed: version != "",
@@ -23,11 +23,11 @@ func checkGCC() *packagemanager.Dependancy {
}
}
func checkPkgConfig() *packagemanager.Dependancy {
func checkPkgConfig() *packagemanager.Dependency {
version := packagemanager.AppVersion("pkg-config")
return &packagemanager.Dependancy{
return &packagemanager.Dependency{
Name: "pkg-config ",
PackageName: "N/A",
Installed: version != "",
@@ -38,7 +38,7 @@ func checkPkgConfig() *packagemanager.Dependancy {
}
}
func checkLocallyInstalled(checker func() *packagemanager.Dependancy, dependency *packagemanager.Dependancy) {
func checkLocallyInstalled(checker func() *packagemanager.Dependency, dependency *packagemanager.Dependency) {
if !dependency.Installed {
locallyInstalled := checker()
if locallyInstalled.Installed {
@@ -48,7 +48,7 @@ func checkLocallyInstalled(checker func() *packagemanager.Dependancy, dependency
}
}
var checkerFunctions = map[string]func() *packagemanager.Dependancy{
var checkerFunctions = map[string]func() *packagemanager.Dependency{
"npm": checkNPM,
"docker": checkDocker,
"upx": checkUPX,
@@ -69,7 +69,7 @@ func (i *Info) discover() error {
i.PM = packagemanager.Find(osinfo.ID)
if i.PM != nil {
dependencies, err := packagemanager.Dependancies(i.PM)
dependencies, err := packagemanager.Dependencies(i.PM)
if err != nil {
return err
}
+3 -3
View File
@@ -22,16 +22,16 @@ func (i *Info) discover() error {
i.Dependencies = append(i.Dependencies, checkNPM())
i.Dependencies = append(i.Dependencies, checkUPX())
i.Dependencies = append(i.Dependencies, checkNSIS())
//i.Dependencies = append(i.Dependencies, checkDocker())
// i.Dependencies = append(i.Dependencies, checkDocker())
return nil
}
func checkWebView2() *packagemanager.Dependancy {
func checkWebView2() *packagemanager.Dependency {
version, _ := webviewloader.GetWebviewVersion("")
installed := version != ""
return &packagemanager.Dependancy{
return &packagemanager.Dependency{
Name: "WebView2 ",
PackageName: "N/A",
Installed: installed,
@@ -11,6 +11,7 @@ manager. Currently, we support the following package managers:
- dnf
- emerge
- eopkg
- nixpkgs
- pacman
- zypper