127 lines
2.6 KiB
Go
127 lines
2.6 KiB
Go
package windows
|
||
|
||
import (
|
||
"fmt"
|
||
"regexp"
|
||
"strconv"
|
||
"strings"
|
||
|
||
"github.com/beclab/Olares/cli/pkg/core/logger"
|
||
"github.com/beclab/Olares/cli/pkg/utils"
|
||
"github.com/pkg/errors"
|
||
)
|
||
|
||
type Wsl struct {
|
||
version string
|
||
}
|
||
|
||
func (w *Wsl) GetVersion() error {
|
||
var checkversion = &utils.DefaultCommandExecutor{
|
||
Commands: []string{"-v"},
|
||
}
|
||
versionOutput, err := checkversion.RunCmd("wsl", utils.DEFAULT)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
if version := w.tidyVersions(versionOutput); version != "" {
|
||
w.version = version
|
||
return nil
|
||
}
|
||
|
||
return fmt.Errorf("wsl version get invalid, output: %s", versionOutput)
|
||
}
|
||
|
||
func (w *Wsl) IsInstalled() bool {
|
||
return !strings.EqualFold(w.version, "")
|
||
}
|
||
|
||
func (w *Wsl) CompareTo(version2 string) int {
|
||
parts1 := strings.Split(w.version, ".")
|
||
parts2 := strings.Split(version2, ".")
|
||
|
||
maxLength := len(parts1)
|
||
if len(parts2) > maxLength {
|
||
maxLength = len(parts2)
|
||
}
|
||
|
||
for i := 0; i < maxLength; i++ {
|
||
var num1, num2 int
|
||
if i < len(parts1) {
|
||
num1, _ = strconv.Atoi(parts1[i])
|
||
}
|
||
if i < len(parts2) {
|
||
num2, _ = strconv.Atoi(parts2[i])
|
||
}
|
||
|
||
if num1 < num2 {
|
||
return -1
|
||
} else if num1 > num2 {
|
||
return 1
|
||
}
|
||
}
|
||
return 0
|
||
}
|
||
|
||
func (w *Wsl) PrintVersion() {
|
||
if w.IsInstalled() {
|
||
logger.Infof("WSL Version: %s", w.version)
|
||
return
|
||
}
|
||
logger.Info("WSL not found")
|
||
}
|
||
|
||
func (w *Wsl) Install(packagePath string) (string, error) {
|
||
var installCmd = &utils.DefaultCommandExecutor{
|
||
Commands: []string{"/i", packagePath, "/quiet", "/norestart"},
|
||
}
|
||
|
||
installoutput, err := installCmd.RunCmd("msiexec", utils.UTF8)
|
||
if err != nil {
|
||
return installoutput, errors.Wrap(errors.WithStack(err), fmt.Sprintf("Install WSL failed, message: %s", installoutput))
|
||
}
|
||
|
||
return installoutput, nil
|
||
}
|
||
|
||
func (w *Wsl) tidyVersions(content string) string {
|
||
var result = ""
|
||
content = strings.ReplaceAll(content, "\n", "\r")
|
||
lines := strings.Split(content, "\r")
|
||
for _, line := range lines {
|
||
line = strings.TrimSpace(line)
|
||
if line == "" {
|
||
continue
|
||
}
|
||
if !strings.Contains(line, "WSL") {
|
||
continue
|
||
}
|
||
if strings.Contains(line, "WSLg") {
|
||
continue
|
||
}
|
||
if strings.Contains(line, ":") || strings.Contains(line, ":") {
|
||
tmp := strings.ReplaceAll(line, ":", ":")
|
||
v := strings.Split(tmp, ":")
|
||
if v == nil || len(v) != 2 {
|
||
break
|
||
}
|
||
result = v[1]
|
||
result = strings.TrimSpace(result)
|
||
break
|
||
}
|
||
}
|
||
if result == "" || !w.isVersionValid(result) {
|
||
return ""
|
||
}
|
||
return result
|
||
}
|
||
|
||
func (w *Wsl) isVersionValid(version string) bool {
|
||
versionRegex := `^\d+(\.\d+)*$`
|
||
re := regexp.MustCompile(versionRegex)
|
||
if re.MatchString(version) {
|
||
return true
|
||
}
|
||
return false
|
||
}
|