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

     1  //go:build linux
     2  // +build linux
     3  
     4  package packagemanager
     5  
     6  import (
     7  	"os/exec"
     8  	"regexp"
     9  	"strings"
    10  
    11  	"github.com/AlpineAIO/wails/v2/internal/shell"
    12  )
    13  
    14  // Zypper represents the Zypper package manager
    15  type Zypper struct {
    16  	name string
    17  	osid string
    18  }
    19  
    20  // NewZypper creates a new Zypper instance
    21  func NewZypper(osid string) *Zypper {
    22  	return &Zypper{
    23  		name: "zypper",
    24  		osid: osid,
    25  	}
    26  }
    27  
    28  // Packages returns the libraries that we need for Wails to compile
    29  // They will potentially differ on different distributions or versions
    30  func (z *Zypper) Packages() packagemap {
    31  	return packagemap{
    32  		"libgtk-3": []*Package{
    33  			{Name: "gtk3-devel", SystemPackage: true, Library: true},
    34  		},
    35  		"libwebkit": []*Package{
    36  			{Name: "webkit2gtk3-soup2-devel", SystemPackage: true, Library: true},
    37  			{Name: "webkit2gtk3-devel", SystemPackage: true, Library: true},
    38  		},
    39  		"gcc": []*Package{
    40  			{Name: "gcc-c++", SystemPackage: true},
    41  		},
    42  		"pkg-config": []*Package{
    43  			{Name: "pkg-config", SystemPackage: true},
    44  			{Name: "pkgconf-pkg-config", SystemPackage: true},
    45  		},
    46  		"npm": []*Package{
    47  			{Name: "npm10", SystemPackage: true},
    48  			{Name: "npm20", SystemPackage: true},
    49  		},
    50  		"docker": []*Package{
    51  			{Name: "docker", SystemPackage: true, Optional: true},
    52  		},
    53  	}
    54  }
    55  
    56  // Name returns the name of the package manager
    57  func (z *Zypper) Name() string {
    58  	return z.name
    59  }
    60  
    61  // PackageInstalled tests if the given package name is installed
    62  func (z *Zypper) PackageInstalled(pkg *Package) (bool, error) {
    63  	if pkg.SystemPackage == false {
    64  		return false, nil
    65  	}
    66  	var env []string
    67  	env = shell.SetEnv(env, "LANGUAGE", "en_US.utf-8")
    68  	stdout, _, err := shell.RunCommandWithEnv(env, ".", "zypper", "info", pkg.Name)
    69  	if err != nil {
    70  		_, ok := err.(*exec.ExitError)
    71  		if ok {
    72  			return false, nil
    73  		}
    74  		return false, err
    75  	}
    76  	reg := regexp.MustCompile(`.*Installed\s*:\s*(Yes)\s*`)
    77  	matches := reg.FindStringSubmatch(stdout)
    78  	pkg.Version = ""
    79  	noOfMatches := len(matches)
    80  	if noOfMatches > 1 {
    81  		z.getPackageVersion(pkg, stdout)
    82  	}
    83  	return noOfMatches > 1, err
    84  }
    85  
    86  // PackageAvailable tests if the given package is available for installation
    87  func (z *Zypper) PackageAvailable(pkg *Package) (bool, error) {
    88  	if pkg.SystemPackage == false {
    89  		return false, nil
    90  	}
    91  	var env []string
    92  	env = shell.SetEnv(env, "LANGUAGE", "en_US.utf-8")
    93  	stdout, _, err := shell.RunCommandWithEnv(env, ".", "zypper", "info", pkg.Name)
    94  	// We add a space to ensure we get a full match, not partial match
    95  	if err != nil {
    96  		_, ok := err.(*exec.ExitError)
    97  		if ok {
    98  			return false, nil
    99  		}
   100  		return false, err
   101  	}
   102  
   103  	available := strings.Contains(stdout, "Information for package")
   104  	if available {
   105  		z.getPackageVersion(pkg, stdout)
   106  	}
   107  
   108  	return available, nil
   109  }
   110  
   111  // InstallCommand returns the package manager specific command to install a package
   112  func (z *Zypper) InstallCommand(pkg *Package) string {
   113  	if pkg.SystemPackage == false {
   114  		return pkg.InstallCommand[z.osid]
   115  	}
   116  	return "sudo zypper in " + pkg.Name
   117  }
   118  
   119  func (z *Zypper) getPackageVersion(pkg *Package, output string) {
   120  
   121  	reg := regexp.MustCompile(`.*Version.*:(.*)`)
   122  	matches := reg.FindStringSubmatch(output)
   123  	pkg.Version = ""
   124  	noOfMatches := len(matches)
   125  	if noOfMatches > 1 {
   126  		pkg.Version = strings.TrimSpace(matches[1])
   127  	}
   128  }