diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 22e6a5c..7f8c928 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: strategy: matrix: - go: [ '1.19.x', '1.20.x' ] + go: [ '1.20.x', '1.21.x' ] steps: - name: Checkout diff --git a/README.md b/README.md index fefc37a..3200a2f 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@

- Usage demoInstallationUsageBuild StatusContributingLicense + Usage demoInstallationUsageCI StatusContributingLicense

`rbinstall` is a utility for installing prebuilt Ruby to [rbenv](https://github.com/rbenv/rbenv). @@ -21,10 +21,10 @@ ### Installation -#### From [ESSENTIAL KAOS Public Repository](https://yum.kaos.st) +#### From [ESSENTIAL KAOS Public Repository](https://pkgs.kaos.st) ```bash -sudo yum install -y https://yum.kaos.st/kaos-repo-latest.el$(grep 'CPE_NAME' /etc/os-release | tr -d '"' | cut -d':' -f5).noarch.rpm +sudo yum install -y https://pkgs.kaos.st/kaos-repo-latest.el$(grep 'CPE_NAME' /etc/os-release | tr -d '"' | cut -d':' -f5).noarch.rpm sudo yum install rbinstall ``` @@ -34,18 +34,19 @@ Usage: rbinstall {options} version Options - --reinstall, -R Reinstall already installed version (if allowed in config) - --uninstall, -U Uninstall already installed version (if allowed in config) - --gems-update, -G Update gems for some version (if allowed in config) - --rehash, -H Rehash rbenv shims - --gems-insecure, -s Use HTTP instead of HTTPS for installing gems - --ruby-version, -r Install version defined in version file - --info, -i Print detailed info about version - --all, -a Print all available versions - --no-progress, -np Disable progress bar and spinner - --no-color, -nc Disable colors in output - --help, -h Show this help message - --version, -v Show version + --reinstall, -R Reinstall already installed version (if allowed in configuration file) + --uninstall, -U Uninstall already installed version (if allowed in configuration file) + --reinstall-updated, -X Reinstall all updated (rebuilt) versions (if allowed in configuration file) + --gems-update, -G Update gems for some version (if allowed in configuration file) + --rehash, -H Rehash rbenv shims + --gems-insecure, -s Use HTTP instead of HTTPS for installing gems + --ruby-version, -r Install version defined in version file + --info, -i Print detailed info about version + --all, -a Print all available versions + --no-progress, -np Disable progress bar and spinner + --no-color, -nc Disable colors in output + --help, -h Show this help message + --version, -v Show version Examples @@ -71,7 +72,7 @@ Examples Install version defined in .ruby-version file ``` -### Build Status +### CI Status | Branch | Status | |--------|--------| diff --git a/cli/cli.go b/cli/cli.go index 5cad600..0a992d9 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -12,7 +12,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "net/http" "net/url" "os" @@ -66,26 +65,27 @@ import ( // App info const ( APP = "RBInstall" - VER = "3.0.5" - DESC = "Utility for installing prebuilt Ruby versions to RBEnv" + VER = "3.1.0" + DESC = "Utility for installing prebuilt Ruby versions to rbenv" ) // ////////////////////////////////////////////////////////////////////////////////// // // List of supported command-line arguments const ( - OPT_REINSTALL = "R:reinstall" - OPT_UNINSTALL = "U:uninstall" - OPT_GEMS_UPDATE = "G:gems-update" - OPT_REHASH = "H:rehash" - OPT_GEMS_INSECURE = "s:gems-insecure" - OPT_RUBY_VERSION = "r:ruby-version" - OPT_INFO = "i:info" - OPT_ALL = "a:all" - OPT_NO_COLOR = "nc:no-color" - OPT_NO_PROGRESS = "np:no-progress" - OPT_HELP = "h:help" - OPT_VER = "v:version" + OPT_REINSTALL = "R:reinstall" + OPT_UNINSTALL = "U:uninstall" + OPT_REINSTALL_UPDATED = "X:reinstall-updated" + OPT_GEMS_UPDATE = "G:gems-update" + OPT_REHASH = "H:rehash" + OPT_GEMS_INSECURE = "s:gems-insecure" + OPT_RUBY_VERSION = "r:ruby-version" + OPT_INFO = "i:info" + OPT_ALL = "a:all" + OPT_NO_COLOR = "nc:no-color" + OPT_NO_PROGRESS = "np:no-progress" + OPT_HELP = "h:help" + OPT_VER = "v:version" OPT_VERB_VER = "vv:verbose-version" OPT_COMPLETION = "completion" @@ -141,18 +141,19 @@ const ( // ////////////////////////////////////////////////////////////////////////////////// // var optMap = options.Map{ - OPT_REINSTALL: {Type: options.BOOL, Conflicts: OPT_UNINSTALL}, - OPT_UNINSTALL: {Type: options.BOOL, Conflicts: OPT_REINSTALL}, - OPT_GEMS_UPDATE: {Type: options.BOOL}, - OPT_GEMS_INSECURE: {Type: options.BOOL}, - OPT_RUBY_VERSION: {Type: options.BOOL}, - OPT_REHASH: {Type: options.BOOL}, - OPT_ALL: {Type: options.BOOL}, - OPT_INFO: {Type: options.BOOL}, - OPT_NO_COLOR: {Type: options.BOOL}, - OPT_NO_PROGRESS: {Type: options.BOOL}, - OPT_HELP: {Type: options.BOOL}, - OPT_VER: {Type: options.MIXED}, + OPT_REINSTALL: {Type: options.BOOL, Conflicts: OPT_UNINSTALL}, + OPT_UNINSTALL: {Type: options.BOOL, Conflicts: OPT_REINSTALL}, + OPT_REINSTALL_UPDATED: {Type: options.BOOL, Conflicts: OPT_UNINSTALL}, + OPT_GEMS_UPDATE: {Type: options.BOOL}, + OPT_GEMS_INSECURE: {Type: options.BOOL}, + OPT_RUBY_VERSION: {Type: options.BOOL}, + OPT_REHASH: {Type: options.BOOL}, + OPT_ALL: {Type: options.BOOL}, + OPT_INFO: {Type: options.BOOL}, + OPT_NO_COLOR: {Type: options.BOOL}, + OPT_NO_PROGRESS: {Type: options.BOOL}, + OPT_HELP: {Type: options.BOOL}, + OPT_VER: {Type: options.MIXED}, OPT_VERB_VER: {Type: options.BOOL}, OPT_COMPLETION: {}, @@ -194,7 +195,7 @@ func Run(gitRev string, gomod []byte) { args, errs := options.Parse(optMap) if len(errs) != 0 { - terminal.PrintErrorMessage(errs[0].Error()) + terminal.Error(errs[0].Error()) os.Exit(1) } @@ -260,6 +261,10 @@ func preConfigureUI() { // configureUI configure user interface func configureUI() { + if options.GetB(OPT_NO_COLOR) { + fmtc.DisableColors = true + } + switch { case fmtc.IsTrueColorSupported(): colorTagApp, colorTagVer = "{#CC1E2C}", "{#CC1E2C}" @@ -388,10 +393,10 @@ func validateConfig() { }) if len(errs) != 0 { - terminal.PrintErrorMessage("Error while config validation:") + terminal.Error("Error while config validation:") for _, err := range errs { - terminal.PrintErrorMessage(" %v", err) + terminal.Error(" %v", err) } exit(1) @@ -418,7 +423,7 @@ func fetchIndex() { err = resp.JSON(repoIndex) if err != nil { - printErrorAndExit("Can't decode repository index json: %v", err) + printErrorAndExit("Can't decode repository index JSON: %v", err) } repoIndex.Sort() @@ -454,13 +459,20 @@ func process(args options.Arguments) { switch { case options.GetB(OPT_GEMS_UPDATE): updateGems(rubyVersion) + case options.GetB(OPT_REINSTALL): + reinstallVersion(rubyVersion) case options.GetB(OPT_UNINSTALL): - uninstallCommand(rubyVersion) + uninstallVersion(rubyVersion) default: - installCommand(rubyVersion) + installVersion(rubyVersion, false) } } else { - listCommand() + switch { + case options.GetB(OPT_REINSTALL_UPDATED): + reinstallUpdatedVersions() + default: + listCommand() + } } } @@ -525,7 +537,7 @@ func listCommand() { } if !repoIndex.HasData(dist, arch) { - terminal.PrintWarnMessage( + terminal.Warn( "Prebuilt binaries not found for this system (%s/%s)", dist, arch, ) @@ -639,8 +651,13 @@ func printRawListing(dist, arch string) { fmt.Print(strings.Join(result, "\n")) } -// installCommand install some version of ruby -func installCommand(rubyVersion string) { +// installVersion install given version of ruby +func installVersion(rubyVersion string, reinstall bool) { + if isVersionInstalled(rubyVersion) && !reinstall { + terminal.Warn("Version %s already installed", rubyVersion) + exit(0) + } + info, category, err := getVersionInfo(rubyVersion) if err != nil { @@ -650,15 +667,6 @@ func installCommand(rubyVersion string) { checkRBEnv() checkDependencies(info, category) - if isVersionInstalled(info.Name) { - if knf.GetB(RBENV_ALLOW_OVERWRITE) && options.GetB(OPT_REINSTALL) { - fmtc.Printf("{y}Reinstalling %s…{!}\n\n", info.Name) - } else { - terminal.PrintWarnMessage("Version %s already installed", info.Name) - exit(0) - } - } - if !fsutil.IsExist(getUnpackDirPath()) { err = os.Mkdir(getUnpackDirPath(), 0770) @@ -730,12 +738,10 @@ func installCommand(rubyVersion string) { // //////////////////////////////////////////////////////////////////////////////// // if isVersionInstalled(info.Name) { - if knf.GetB(RBENV_ALLOW_OVERWRITE) && options.GetB(OPT_REINSTALL) { - err = os.RemoveAll(getVersionPath(info.Name)) + err = os.RemoveAll(getVersionPath(info.Name)) - if err != nil { - printErrorAndExit("Can't remove %s: %v", info.Name, err) - } + if err != nil { + printErrorAndExit("Can't remove %s: %v", info.Name, err) } } @@ -755,7 +761,7 @@ func installCommand(rubyVersion string) { spinner.Done(err == nil) if err != nil { - terminal.PrintWarnMessage(err.Error()) + terminal.Warn(err.Error()) } } @@ -777,7 +783,7 @@ func installCommand(rubyVersion string) { spinner.Done(err == nil) if err != nil { - terminal.PrintWarnMessage(err.Error()) + terminal.Warn(err.Error()) } } } @@ -795,7 +801,7 @@ func installCommand(rubyVersion string) { if err != nil { fmtc.Println("{r}✖ {!}Creating alias") - terminal.PrintWarnMessage(err.Error()) + terminal.Warn(err.Error()) } else { fmtc.Println("{g}✔ {!}Creating alias") aliasCreated = true @@ -818,8 +824,8 @@ func installCommand(rubyVersion string) { } } -// uninstallCommand unistall some version of ruby -func uninstallCommand(rubyVersion string) { +// uninstallVersion unistall given version of ruby +func uninstallVersion(rubyVersion string) { if !knf.GetB(RBENV_ALLOW_UNINSTALL, false) { printErrorAndExit("Uninstalling is not allowed") } @@ -855,6 +861,71 @@ func uninstallCommand(rubyVersion string) { fmtc.Printf("{g}Version {*}%s{!*} successfully uninstalled{!}\n", rubyVersion) } +// reinstallVersion reinstalls given version of ruby +func reinstallVersion(rubyVersion string) { + if !isVersionInstalled(rubyVersion) { + printErrorAndExit("Version %s in not installed", rubyVersion) + } + + if !knf.GetB(RBENV_ALLOW_OVERWRITE, false) { + printErrorAndExit("Reinstalling is not allowed") + } + + terminal.Warn("Reinstalling %s…\n", rubyVersion) + + installVersion(rubyVersion, true) +} + +// reinstallUpdatedVersions reinstalls all rebuilt versions +func reinstallUpdatedVersions() { + installed := getInstalledVersionsMap() + + if len(installed) == 0 { + terminal.Warn("There is no installed versions") + return + } + + checkPerms() + setupLogger() + setupTemp() + + var hasUpdates bool + + for rubyVersion := range installed { + info, _, err := getVersionInfo(rubyVersion) + + if err != nil { + continue + } + + installDate, err := fsutil.GetMTime(getVersionPath(rubyVersion)) + + if err != nil { + fmtc.NewLine() + terminal.Error("Can't check install date of version %s: %v", rubyVersion, err) + continue + } + + if installDate.Unix() >= info.Added { + continue + } + + if hasUpdates { + fmtc.NewLine() + } + + terminal.Warn("Reinstalling %s…\n", rubyVersion) + + installVersion(rubyVersion, true) + + hasUpdates = true + } + + if !hasUpdates { + fmtc.Println("{g}All versions are up-to-date{!}") + } +} + // rehashShims run 'rbenv rehash' command func rehashShims() { spinner.Show("Rehashing") @@ -987,7 +1058,7 @@ func updateGems(rubyVersion string) { spinner.Done(err == nil) if err != nil { - terminal.PrintWarnMessage(err.Error()) + terminal.Warn(err.Error()) } installed = true @@ -1025,7 +1096,7 @@ func updateGems(rubyVersion string) { ) } } else { - terminal.PrintWarnMessage(err.Error()) + terminal.Warn(err.Error()) } } @@ -1421,7 +1492,7 @@ func getVersionFromFile() (string, error) { return "", fmtc.Errorf("Can't find proper version file") } - versionData, err := ioutil.ReadFile(versionFile) + versionData, err := os.ReadFile(versionFile) if err != nil { return "", fmtc.Errorf("Can't read version file: %v", err) @@ -1466,7 +1537,7 @@ func getVersionInfo(rubyVersion string) (*index.VersionInfo, string, error) { return info, category, nil } -// getInstalledVersionsMap return map with names of installed versions +// getInstalledVersionsMap returns map with names of installed versions func getInstalledVersionsMap() map[string]bool { result := make(map[string]bool) versions := fsutil.List( @@ -1485,7 +1556,7 @@ func getInstalledVersionsMap() map[string]bool { return result } -// getVersionGemPath return path to directory with installed gems +// getVersionGemPath returns path to directory with installed gems func getVersionGemDirPath(rubyVersion string) string { gemsPath := getVersionPath(rubyVersion) + "/lib/ruby/gems" @@ -1535,7 +1606,7 @@ func getGemSourceURL(rubyVersion string) string { return "http://" + knf.GetS(GEMS_SOURCE) } -// checkRBEnv check RBEnv directory and state +// checkRBEnv check rbenv directory and state func checkRBEnv() { versionsDir := getRBEnvVersionsPath() @@ -1677,7 +1748,7 @@ func parseGemInfo(data string) (string, string) { // to this log file func logFailedAction(message string) (string, error) { if len(message) == 0 { - return "", errors.New("Output data is empty") + return "", errors.New("Output is empty") } logSuffix := passwd.GenPassword(8, passwd.STRENGTH_WEAK) @@ -1688,7 +1759,7 @@ func logFailedAction(message string) (string, error) { } data := append([]byte(message), []byte("\n\n")...) - err := ioutil.WriteFile(tmpName, data, 0666) + err := os.WriteFile(tmpName, data, 0666) if err != nil { return "", err @@ -1707,7 +1778,7 @@ func intSignalHandler() { // printErrorAndExit print error message and exit with non-zero exit code func printErrorAndExit(f string, a ...interface{}) { - terminal.PrintErrorMessage(f, a...) + terminal.Error(f, a...) exit(1) } @@ -1757,9 +1828,10 @@ func genUsage() *usage.Info { info.AppNameColorTag = "{*}" + colorTagApp - info.AddOption(OPT_REINSTALL, "Reinstall already installed version {s-}(if allowed in config){!}") - info.AddOption(OPT_UNINSTALL, "Uninstall already installed version {s-}(if allowed in config){!}") - info.AddOption(OPT_GEMS_UPDATE, "Update gems for some version {s-}(if allowed in config){!}") + info.AddOption(OPT_REINSTALL, "Reinstall already installed version {s-}(if allowed in configuration file){!}") + info.AddOption(OPT_UNINSTALL, "Uninstall already installed version {s-}(if allowed in configuration file){!}") + info.AddOption(OPT_REINSTALL_UPDATED, "Reinstall all updated (rebuilt) versions {s-}(if allowed in configuration file){!}") + info.AddOption(OPT_GEMS_UPDATE, "Update gems for some version {s-}(if allowed in configuration file){!}") info.AddOption(OPT_REHASH, "Rehash rbenv shims") info.AddOption(OPT_GEMS_INSECURE, "Use HTTP instead of HTTPS for installing gems") info.AddOption(OPT_RUBY_VERSION, "Install version defined in version file") diff --git a/clone/clone.go b/clone/clone.go index 39b46bc..8ce8e83 100644 --- a/clone/clone.go +++ b/clone/clone.go @@ -43,7 +43,7 @@ import ( // App info const ( APP = "RBInstall Clone" - VER = "3.0.2" + VER = "3.0.3" DESC = "Utility for cloning RBInstall repository" ) diff --git a/common/eol.json b/common/eol.json index f93a184..9871f22 100644 --- a/common/eol.json +++ b/common/eol.json @@ -11,5 +11,6 @@ "jruby-1.6": true, "jruby-1.7": true, "jruby-9.0": true, - "jruby-9.1": true + "jruby-9.1": true, + "jruby-9.2": true } diff --git a/common/rbinstall.spec b/common/rbinstall.spec index 755006d..27f2abc 100644 --- a/common/rbinstall.spec +++ b/common/rbinstall.spec @@ -10,7 +10,7 @@ Summary: Utility for installing prebuilt Ruby to rbenv Name: rbinstall -Version: 3.0.5 +Version: 3.1.0 Release: 0%{?dist} Group: Applications/System License: Apache License, Version 2.0 @@ -38,7 +38,7 @@ Utility for installing different prebuilt versions of Ruby to rbenv. %package gen Summary: Utility for generating RBInstall index -Version: 3.0.2 +Version: 3.0.3 Release: 0%{?dist} Group: Development/Tools @@ -50,7 +50,7 @@ Utility for generating RBInstall index. %package clone Summary: Utility for cloning RBInstall repository -Version: 3.0.2 +Version: 3.0.3 Release: 0%{?dist} Group: Development/Tools @@ -118,6 +118,12 @@ rm -rf %{buildroot} ################################################################################ %changelog +* Fri Sep 01 2023 Anton Novojilov - 3.1.0-0 +- [cli] Added option -X/--reinstall-updated for updating rebuilt versions +- [cli] Fixed color disabling using -nc/--no-color option +- [cli|gen|clone] Code refactoring +- Dependencies update + * Tue Jul 04 2023 Anton Novojilov - 3.0.5-0 - Dependencies update diff --git a/gen/gen.go b/gen/gen.go index 0975367..b3e4b72 100644 --- a/gen/gen.go +++ b/gen/gen.go @@ -9,7 +9,6 @@ package gen import ( "fmt" - "io/ioutil" "os" "runtime" "sort" @@ -41,7 +40,7 @@ import ( // App info const ( APP = "RBInstall Gen" - VER = "3.0.2" + VER = "3.0.3" DESC = "Utility for generating RBInstall index" ) @@ -433,7 +432,7 @@ func saveIndex(outputFile string, i *index.Index) { fsutil.MoveFile(outputFile, outputFile+".bkp", 0600) } - err = ioutil.WriteFile(outputFile, indexData, 0644) + err = os.WriteFile(outputFile, indexData, 0644) if err != nil { printErrorAndExit(err.Error()) diff --git a/go.mod b/go.mod index b125f38..2b2750c 100644 --- a/go.mod +++ b/go.mod @@ -4,13 +4,13 @@ go 1.18 require ( github.com/essentialkaos/depsy v1.1.0 - github.com/essentialkaos/ek/v12 v12.69.0 - github.com/essentialkaos/npck v1.5.1 + github.com/essentialkaos/ek/v12 v12.75.1 + github.com/essentialkaos/npck v1.6.0 ) require ( github.com/essentialkaos/go-linenoise/v3 v3.4.0 // indirect github.com/klauspost/compress v1.16.7 // indirect - golang.org/x/crypto v0.11.0 // indirect - golang.org/x/sys v0.10.0 // indirect + golang.org/x/crypto v0.12.0 // indirect + golang.org/x/sys v0.11.0 // indirect ) diff --git a/go.sum b/go.sum index 113b3c5..418791b 100644 --- a/go.sum +++ b/go.sum @@ -1,18 +1,18 @@ github.com/essentialkaos/check v1.4.0 h1:kWdFxu9odCxUqo1NNFNJmguGrDHgwi3A8daXX1nkuKk= github.com/essentialkaos/depsy v1.1.0 h1:U6dp687UkQwXlZU17Hg2KMxbp3nfZAoZ8duaeUFYvJI= github.com/essentialkaos/depsy v1.1.0/go.mod h1:kpiTAV17dyByVnrbNaMcZt2jRwvuXClUYOzpyJQwtG8= -github.com/essentialkaos/ek/v12 v12.69.0 h1:UxDZdFLgA15BVelpR3IpkY3RPc/EdY7sXJHbT4T7J90= -github.com/essentialkaos/ek/v12 v12.69.0/go.mod h1:juDcZWOWaj1QmYShZkT9RzdqJ3n0tmeP/iq4sw5fQF0= +github.com/essentialkaos/ek/v12 v12.75.1 h1:HE8/uWED+QgyT6HIcRULqjMYWKhqQ1rkfa/ozcva1eQ= +github.com/essentialkaos/ek/v12 v12.75.1/go.mod h1:juDcZWOWaj1QmYShZkT9RzdqJ3n0tmeP/iq4sw5fQF0= github.com/essentialkaos/go-linenoise/v3 v3.4.0 h1:g72w8x+/HIwOMBVvNaPYp+wMWVHrYZwzFAF7OfZR5Ts= github.com/essentialkaos/go-linenoise/v3 v3.4.0/go.mod h1:t1kNLY2bSMQCy1JXOefD2BDLs/TTPMtTv3DFNV5uDSI= -github.com/essentialkaos/npck v1.5.1 h1:YVlRWXNUCM8qsHPtcolJnjCPCqdL6cre9IZXs94UqV0= -github.com/essentialkaos/npck v1.5.1/go.mod h1:qUndlyW1srbtP7RvBdW92/VO/El3btprLISMD7Kpqak= +github.com/essentialkaos/npck v1.6.0 h1:8uI0WlkU6lTOm/AJqw+/8jT74xOljhKd3uOnfOapnGc= +github.com/essentialkaos/npck v1.6.0/go.mod h1:CBGBGZlr1cqyhDFzv8i74Ok3lHGDcjbqIFeFfbkHe/w= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=