build(deps): bump github.com/gookit/config/v2 from 2.2.5 to 2.2.6

Bumps [github.com/gookit/config/v2](https://github.com/gookit/config) from 2.2.5 to 2.2.6.
- [Release notes](https://github.com/gookit/config/releases)
- [Commits](https://github.com/gookit/config/compare/v2.2.5...v2.2.6)

---
updated-dependencies:
- dependency-name: github.com/gookit/config/v2
  dependency-version: 2.2.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
dependabot[bot]
2025-04-29 14:15:29 +00:00
committed by GitHub
parent a97f5e4c2e
commit 452d40dad7
61 changed files with 1037 additions and 365 deletions
+9 -6
View File
@@ -394,12 +394,17 @@ func (c *Cmd) Output() (string, error) {
return "DRY-RUN: ok", nil
}
output, err := c.Cmd.Output()
bs, err := c.Cmd.Output()
if c.AfterRun != nil {
c.AfterRun(c, err)
}
return string(output), err
return string(bs), err
}
// AllOutput run and return output, will combine stderr and stdout output
func (c *Cmd) AllOutput() (string, error) {
return c.CombinedOutput()
}
// CombinedOutput run and return output, will combine stderr and stdout output
@@ -412,12 +417,11 @@ func (c *Cmd) CombinedOutput() (string, error) {
return "DRY-RUN: ok", nil
}
output, err := c.Cmd.CombinedOutput()
bs, err := c.Cmd.CombinedOutput()
if c.AfterRun != nil {
c.AfterRun(c, err)
}
return string(output), err
return string(bs), err
}
// MustRun a command. will panic on error
@@ -444,7 +448,6 @@ func (c *Cmd) Run() error {
// do running
err := c.Cmd.Run()
if c.AfterRun != nil {
c.AfterRun(c, err)
}
+29 -14
View File
@@ -1,10 +1,10 @@
package sysutil
import (
"bytes"
"os/exec"
"github.com/gookit/goutil/cliutil/cmdline"
"github.com/gookit/goutil/internal/checkfn"
"github.com/gookit/goutil/sysutil/cmdr"
)
@@ -13,17 +13,19 @@ func NewCmd(bin string, args ...string) *cmdr.Cmd {
return cmdr.NewCmd(bin, args...)
}
// FlushExec instance
// FlushExec command, will flush output to stdout,stderr
func FlushExec(bin string, args ...string) error {
return cmdr.NewCmd(bin, args...).FlushRun()
}
// QuickExec quick exec an simple command line
// QuickExec quick exec a simple command line, return combined output.
func QuickExec(cmdLine string, workDir ...string) (string, error) {
return ExecLine(cmdLine, workDir...)
}
// ExecLine quick exec an command line string
// ExecLine quick exec a command line string, return combined output.
//
// NOTE: not support | or ; in cmdLine
func ExecLine(cmdLine string, workDir ...string) (string, error) {
p := cmdline.NewParser(cmdLine)
@@ -33,11 +35,11 @@ func ExecLine(cmdLine string, workDir ...string) (string, error) {
cmd.Dir = workDir[0]
}
bs, err := cmd.Output()
bs, err := cmd.CombinedOutput()
return string(bs), err
}
// ExecCmd a command and return output.
// ExecCmd a command and return combined output.
//
// Usage:
//
@@ -49,11 +51,15 @@ func ExecCmd(binName string, args []string, workDir ...string) (string, error) {
cmd.Dir = workDir[0]
}
bs, err := cmd.Output()
bs, err := cmd.CombinedOutput()
return string(bs), err
}
// ShellExec exec command by shell cmdLine. eg: "ls -al"
// ShellExec exec command by shell cmdLine, return combined output.
//
// shells e.g. "/bin/sh", "bash", "cmd", "cmd.exe", "powershell", "powershell.exe", "pwsh", "pwsh.exe"
//
// eg: ShellExec("ls -al")
func ShellExec(cmdLine string, shells ...string) (string, error) {
// shell := "/bin/sh"
shell := "sh"
@@ -61,12 +67,21 @@ func ShellExec(cmdLine string, shells ...string) (string, error) {
shell = shells[0]
}
var out bytes.Buffer
cmd := exec.Command(shell, "-c", cmdLine)
cmd.Stdout = &out
// "-c" for bash,sh,zsh shell
mark := "-c"
if err := cmd.Run(); err != nil {
return "", err
// special for Windows shell
if IsWindows() {
// use cmd.exe, mark is "/c"
if checkfn.StringsContains([]string{"cmd", "cmd.exe"}, shell) {
mark = "/c"
} else if checkfn.StringsContains([]string{"powershell", "powershell.exe", "pwsh", "pwsh.exe"}, shell) {
// "-Command" for powershell
mark = "-Command"
}
}
return out.String(), nil
cmd := exec.Command(shell, mark, cmdLine)
bs, err := cmd.CombinedOutput()
return string(bs), err
}
+143
View File
@@ -0,0 +1,143 @@
package sysutil
import (
"fmt"
"strings"
"github.com/gookit/goutil/errorx"
"github.com/gookit/goutil/strutil"
)
// OSVersionInfo 结构体用于存储操作系统版本信息
//
// NOTE: Windows 10 和 Windows 11 在主版本号和次版本号上是相同的,因此需要通过构建号(win11: DwBuildNumber>=22000)来进一步区分
type OSVersionInfo struct {
// 主版本号
MajorVersion uint16
// 次版本号
MinorVersion uint16
// 构建号
BuildNumber uint32
// 修订号
RevisionNumber uint32
}
// FetchOsVersion Get Windows system version information
//
// 还可用使用dll获取:
//
// 通过 GetVersion, GetVersionEx 函数获取的信息不准确. win11获取到 6.2.9200, 实际是 10.0.22631
func FetchOsVersion() (*OSVersionInfo, error) {
// Windows cmd 执行 ver 命令
out, err := ShellExec("ver", "cmd")
if err != nil {
return nil, err
}
return parseOsVersionString(out)
}
// IsLtWindows7 判断是否小于 Windows 7
func (ov *OSVersionInfo) IsLtWindows7() bool {
return ov.MajorVersion < 6 || (ov.MajorVersion == 6 && ov.MinorVersion < 1)
}
// IsWindows7 判断是否为 Windows 7
func (ov *OSVersionInfo) IsWindows7() bool {
return ov.MajorVersion == 6 && ov.MinorVersion == 1
}
// IsWindows8 判断是否为 Windows 8
func (ov *OSVersionInfo) IsWindows8() bool {
return ov.MajorVersion == 6 && ov.MinorVersion == 2
}
// IsWindows10 判断是否为 Windows 10
func (ov *OSVersionInfo) IsWindows10() bool {
return ov.MajorVersion == 10 && ov.MinorVersion == 0 && ov.BuildNumber < 22000
}
// IsWindows11 判断是否为 Windows 11
func (ov *OSVersionInfo) IsWindows11() bool {
return ov.MajorVersion == 10 && ov.MinorVersion == 0 && ov.BuildNumber >= 22000
}
// Name 获取 Windows 通用的版本名称. eg: xp, win7, win8, win10, win11, unknown
func (ov *OSVersionInfo) Name() string {
switch ov.MajorVersion {
case 10:
if ov.BuildNumber < 22000 {
return "win10"
} else {
return "win11"
}
case 6:
switch ov.MinorVersion {
case 0:
return "vista"
case 1:
return "win7"
case 2:
return "win8"
case 3:
return "win8.1"
}
case 5:
switch ov.MinorVersion {
case 1:
return "xp"
case 2:
return "ws2003" // win server 2003
}
}
return "unknown"
}
// String format
func (ov *OSVersionInfo) String() string {
return fmt.Sprintf("%d.%d.%d", ov.MajorVersion, ov.MinorVersion, ov.BuildNumber)
}
func parseOsVersionString(out string) (*OSVersionInfo, error) {
// out eg: Microsoft Windows [Version 10.0.22631.4391] => 10.0.22631.4391
// 部分系统会输出中文 eg: Microsoft Windows [版本 10.0.22631.4391]
out = strings.TrimSpace(out)
ns := strings.SplitN(out, "[", 2)
if len(ns) < 2 {
return nil, errorx.Rawf("cannot parse version info: %s", out)
}
ns = strutil.SplitByWhitespace(strings.Trim(ns[1], "]"))
if len(ns) < 2 {
return nil, errorx.Rawf("cannot parse version info2: %s", out)
}
var err error
var ovi OSVersionInfo
// get like: 10.0.22631.4391 or 10.0.22631
verStr := ns[1]
if strings.Count(verStr, ".") >= 3 {
_, err = fmt.Sscanf(verStr, "%d.%d.%d.%d", &ovi.MajorVersion, &ovi.MinorVersion, &ovi.BuildNumber, &ovi.RevisionNumber)
} else {
_, err = fmt.Sscanf(verStr, "%d.%d.%d", &ovi.MajorVersion, &ovi.MinorVersion, &ovi.BuildNumber)
}
if err != nil {
return nil, errorx.Rawf("parse version info %q error: %v", verStr, err)
}
return &ovi, nil
}
// 全局变量
var stdOv, stdErr = FetchOsVersion()
// OsVersion Get operating system version information
func OsVersion() *OSVersionInfo {
return stdOv
}
// OvParseError error on parse os version info
func OvParseError() error {
return stdErr
}
+23 -2
View File
@@ -8,6 +8,7 @@ import (
"strings"
"syscall"
"github.com/gookit/goutil/internal/checkfn"
"github.com/gookit/goutil/internal/comfunc"
"golang.org/x/term"
)
@@ -144,6 +145,12 @@ func EnvPaths() []string {
return filepath.SplitList(os.Getenv("PATH"))
}
// SearchPathOption settings for SearchPath
type SearchPathOption struct {
// 限制的扩展名
LimitExt []string
}
// SearchPath search executable files in the system $PATH
//
// Usage:
@@ -154,6 +161,9 @@ func SearchPath(keywords string, limit int) []string {
ptn := "*" + keywords + "*"
list := make([]string, 0)
// if windows, will limit with .exe, .bat, .cmd
isWindows := IsWindows()
winExts := []string{".exe", ".bat", ".cmd"}
checked := make(map[string]bool)
for _, dir := range filepath.SplitList(path) {
// Unix shell semantics: path element "" means "."
@@ -169,10 +179,21 @@ func SearchPath(keywords string, limit int) []string {
checked[dir] = true
matches, err := filepath.Glob(filepath.Join(dir, ptn))
if err == nil && len(matches) > 0 {
list = append(list, matches...)
size := len(list)
if isWindows {
// if windows, will limit with .exe, .bat, .cmd
for _, fPath := range matches {
fExt := filepath.Ext(fPath)
if checkfn.StringsContains(winExts, fExt) {
continue
}
list = append(list, fPath)
}
} else {
list = append(list, matches...)
}
// limit result size
size := len(list)
if limit > 0 && size >= limit {
list = list[:limit]
break
+19 -26
View File
@@ -7,7 +7,7 @@ import (
"github.com/gookit/goutil/internal/comfunc"
)
// MustFindUser must find an system user by name
// MustFindUser must find a system user by name
func MustFindUser(uname string) *user.User {
u, err := user.Lookup(uname)
if err != nil {
@@ -16,14 +16,13 @@ func MustFindUser(uname string) *user.User {
return u
}
// LoginUser must get current user
// LoginUser must get current user, will panic if error
func LoginUser() *user.User {
return CurrentUser()
}
// CurrentUser must get current user
// CurrentUser must get current user, will panic if error
func CurrentUser() *user.User {
// check $HOME/.terminfo
u, err := user.Current()
if err != nil {
panic(err)
@@ -31,9 +30,8 @@ func CurrentUser() *user.User {
return u
}
// UHomeDir get user home dir path.
// UHomeDir get user home dir path, ignore error. (by user.Current)
func UHomeDir() string {
// check $HOME/.terminfo
u, err := user.Current()
if err != nil {
return ""
@@ -42,37 +40,32 @@ func UHomeDir() string {
}
// homeDir cache
var homeDir string
var _homeDir string
// UserHomeDir is alias of os.UserHomeDir, but ignore error
// UserHomeDir is alias of os.UserHomeDir, but ignore error.(by os.UserHomeDir)
func UserHomeDir() string {
if homeDir == "" {
homeDir, _ = os.UserHomeDir()
if _homeDir == "" {
_homeDir, _ = os.UserHomeDir()
}
return homeDir
return _homeDir
}
// HomeDir get user home dir path.
func HomeDir() string {
return UserHomeDir()
func HomeDir() string { return UserHomeDir() }
// UserDir will prepend user home dir to subPaths
func UserDir(subPaths ...string) string {
return comfunc.JoinPaths2(UserHomeDir(), subPaths)
}
// UserDir will prepend user home dir to subPath
func UserDir(subPath string) string {
dir := UserHomeDir()
return dir + "/" + subPath
}
// UserCacheDir will prepend user `$HOME/.cache` to subPath
func UserCacheDir(subPath string) string {
dir := UserHomeDir()
return dir + "/.cache/" + subPath
// UserCacheDir will prepend user `$HOME/.cache` to subPaths
func UserCacheDir(subPaths ...string) string {
return comfunc.JoinPaths3(UserHomeDir(), ".cache", subPaths)
}
// UserConfigDir will prepend user `$HOME/.config` to subPath
func UserConfigDir(subPath string) string {
dir := UserHomeDir()
return dir + "/.config/" + subPath
func UserConfigDir(subPaths ...string) string {
return comfunc.JoinPaths3(UserHomeDir(), ".config", subPaths)
}
// ExpandPath will parse `~` as user home dir path.
+6
View File
@@ -3,11 +3,17 @@
package sysutil
import (
"os"
"syscall"
"github.com/gookit/goutil/strutil"
)
// IsAdmin Determine whether the current user is an administrator(root)
func IsAdmin() bool {
return os.Getuid() == 0
}
// ChangeUserByName change work user by new username.
func ChangeUserByName(newUname string) error {
u := MustFindUser(newUname)
+7
View File
@@ -19,3 +19,10 @@ func ChangeUserUidGid(newUid int, newGid int) (err error) {
func ChangeUserUIDGid(newUid int, newGid int) (err error) {
return nil
}
// IsAdmin Determine whether the current user is an administrator
func IsAdmin() bool {
// 执行 net session 判断
_, err := ExecCmd("net", []string{"session"})
return err == nil
}