github.com/AlpineAIO/wails/v2@v2.0.0-beta.32.0.20240505041856-1047a8fa5fef/internal/system/packagemanager/nixpkgs.go (about)

     1  //go:build linux
     2  // +build linux
     3  
     4  package packagemanager
     5  
     6  import (
     7  	"encoding/json"
     8  	"github.com/AlpineAIO/wails/v2/internal/shell"
     9  )
    10  
    11  // Nixpkgs represents the Nixpkgs manager
    12  type Nixpkgs struct {
    13  	name string
    14  	osid string
    15  }
    16  
    17  type NixPackageDetail struct {
    18  	Name    string
    19  	Pname   string
    20  	Version string
    21  }
    22  
    23  var available map[string]NixPackageDetail
    24  
    25  // NewNixpkgs creates a new Nixpkgs instance
    26  func NewNixpkgs(osid string) *Nixpkgs {
    27  	available = map[string]NixPackageDetail{}
    28  
    29  	return &Nixpkgs{
    30  		name: "nixpkgs",
    31  		osid: osid,
    32  	}
    33  }
    34  
    35  // Packages returns the libraries that we need for Wails to compile
    36  // They will potentially differ on different distributions or versions
    37  func (n *Nixpkgs) Packages() packagemap {
    38  	// Currently, only support checking the default channel.
    39  	channel := "nixpkgs"
    40  	if n.osid == "nixos" {
    41  		channel = "nixos"
    42  	}
    43  
    44  	return packagemap{
    45  		"libgtk-3": []*Package{
    46  			{Name: channel + ".gtk3", SystemPackage: true, Library: true},
    47  		},
    48  		"libwebkit": []*Package{
    49  			{Name: channel + ".webkitgtk", SystemPackage: true, Library: true},
    50  		},
    51  		"gcc": []*Package{
    52  			{Name: channel + ".gcc", SystemPackage: true},
    53  		},
    54  		"pkg-config": []*Package{
    55  			{Name: channel + ".pkg-config", SystemPackage: true},
    56  		},
    57  		"npm": []*Package{
    58  			{Name: channel + ".nodejs", SystemPackage: true},
    59  		},
    60  		"upx": []*Package{
    61  			{Name: channel + ".upx", SystemPackage: true, Optional: true},
    62  		},
    63  		"docker": []*Package{
    64  			{Name: channel + ".docker", SystemPackage: true, Optional: true},
    65  		},
    66  		"nsis": []*Package{
    67  			{Name: channel + ".nsis", SystemPackage: true, Optional: true},
    68  		},
    69  	}
    70  }
    71  
    72  // Name returns the name of the package manager
    73  func (n *Nixpkgs) Name() string {
    74  	return n.name
    75  }
    76  
    77  // PackageInstalled tests if the given package name is installed
    78  func (n *Nixpkgs) PackageInstalled(pkg *Package) (bool, error) {
    79  	if pkg.SystemPackage == false {
    80  		return false, nil
    81  	}
    82  
    83  	stdout, _, err := shell.RunCommand(".", "nix-env", "--json", "-qA", pkg.Name)
    84  	if err != nil {
    85  		return false, nil
    86  	}
    87  
    88  	var attributes map[string]NixPackageDetail
    89  	err = json.Unmarshal([]byte(stdout), &attributes)
    90  	if err != nil {
    91  		return false, err
    92  	}
    93  
    94  	// Did we get one?
    95  	installed := false
    96  	for attribute, detail := range attributes {
    97  		if attribute == pkg.Name {
    98  			installed = true
    99  			pkg.Version = detail.Version
   100  		}
   101  		break
   102  	}
   103  
   104  	// If on NixOS, package may be installed via system config, so check the nix store.
   105  	detail, ok := available[pkg.Name]
   106  	if !installed && n.osid == "nixos" && ok {
   107  		cmd := "nix-store --query --requisites /run/current-system | cut -d- -f2- | sort | uniq | grep '^" + detail.Pname + "'"
   108  
   109  		if pkg.Library {
   110  			cmd += " | grep 'dev$'"
   111  		}
   112  
   113  		stdout, _, err = shell.RunCommand(".", "sh", "-c", cmd)
   114  		if err != nil {
   115  			return false, nil
   116  		}
   117  
   118  		if len(stdout) > 0 {
   119  			installed = true
   120  		}
   121  	}
   122  
   123  	return installed, nil
   124  }
   125  
   126  // PackageAvailable tests if the given package is available for installation
   127  func (n *Nixpkgs) PackageAvailable(pkg *Package) (bool, error) {
   128  	if pkg.SystemPackage == false {
   129  		return false, nil
   130  	}
   131  
   132  	stdout, _, err := shell.RunCommand(".", "nix-env", "--json", "-qaA", pkg.Name)
   133  	if err != nil {
   134  		return false, nil
   135  	}
   136  
   137  	var attributes map[string]NixPackageDetail
   138  	err = json.Unmarshal([]byte(stdout), &attributes)
   139  	if err != nil {
   140  		return false, err
   141  	}
   142  
   143  	// Grab first version.
   144  	for attribute, detail := range attributes {
   145  		pkg.Version = detail.Version
   146  		available[attribute] = detail
   147  		break
   148  	}
   149  
   150  	return len(pkg.Version) > 0, nil
   151  }
   152  
   153  // InstallCommand returns the package manager specific command to install a package
   154  func (n *Nixpkgs) InstallCommand(pkg *Package) string {
   155  	if pkg.SystemPackage == false {
   156  		return pkg.InstallCommand[n.osid]
   157  	}
   158  	return "nix-env -iA " + pkg.Name
   159  }