//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 }