mirror of
https://github.com/coreybutler/nvm-windows.git
synced 2026-01-19 07:06:31 +08:00
Move test command to 'debug'. Fixes #955 and #942. Addresses #945 with new encoding for settings (forcing UTF-8).
This commit is contained in:
@@ -1,11 +1,9 @@
|
||||
package encoding
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/mushroomsir/iconv"
|
||||
"github.com/saintfish/chardet"
|
||||
)
|
||||
|
||||
@@ -19,46 +17,56 @@ func DetectCharset(content []byte) (string, error) {
|
||||
return strings.ToUpper(result.Charset), nil
|
||||
}
|
||||
|
||||
func ToUTF8(content []byte, ignoreInvalidITF8Chars ...bool) (string, error) {
|
||||
ignore := false
|
||||
if len(ignoreInvalidITF8Chars) > 0 {
|
||||
ignore = ignoreInvalidITF8Chars[0]
|
||||
func ToUTF8(content string) []byte {
|
||||
b := make([]byte, len(content))
|
||||
i := 0
|
||||
for _, r := range content {
|
||||
i += utf8.EncodeRune(b[i:], r)
|
||||
}
|
||||
|
||||
cs, err := DetectCharset(content)
|
||||
if err != nil {
|
||||
if !ignore {
|
||||
return "", err
|
||||
}
|
||||
cs = "UTF-8"
|
||||
}
|
||||
|
||||
bs := string(content)
|
||||
if ignore {
|
||||
if !utf8.ValidString(bs) {
|
||||
v := make([]rune, 0, len(bs))
|
||||
for i, r := range bs {
|
||||
if r == utf8.RuneError {
|
||||
_, size := utf8.DecodeRuneInString(bs[i:])
|
||||
if size == 1 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
v = append(v, r)
|
||||
}
|
||||
bs = string(v)
|
||||
}
|
||||
}
|
||||
|
||||
if cs == "UTF-8" {
|
||||
return bs, nil
|
||||
}
|
||||
|
||||
converter, err := iconv.NewConverter(cs, "UTF-8")
|
||||
if err != nil {
|
||||
err = errors.New("Failed to convert " + cs + " to UTF-8: " + err.Error())
|
||||
return bs, err
|
||||
}
|
||||
|
||||
return converter.ConvertString(bs)
|
||||
return b[:i]
|
||||
}
|
||||
|
||||
// func ToUTF8(content []byte, ignoreInvalidITF8Chars ...bool) (string, error) {
|
||||
// ignore := false
|
||||
// if len(ignoreInvalidITF8Chars) > 0 {
|
||||
// ignore = ignoreInvalidITF8Chars[0]
|
||||
// }
|
||||
|
||||
// cs, err := DetectCharset(content)
|
||||
// if err != nil {
|
||||
// if !ignore {
|
||||
// return "", err
|
||||
// }
|
||||
// cs = "UTF-8"
|
||||
// }
|
||||
|
||||
// bs := string(content)
|
||||
// if ignore {
|
||||
// if !utf8.ValidString(bs) {
|
||||
// v := make([]rune, 0, len(bs))
|
||||
// for i, r := range bs {
|
||||
// if r == utf8.RuneError {
|
||||
// _, size := utf8.DecodeRuneInString(bs[i:])
|
||||
// if size == 1 {
|
||||
// continue
|
||||
// }
|
||||
// }
|
||||
// v = append(v, r)
|
||||
// }
|
||||
// bs = string(v)
|
||||
// }
|
||||
// }
|
||||
|
||||
// if cs == "UTF-8" {
|
||||
// return bs, nil
|
||||
// }
|
||||
|
||||
// converter, err := iconv.NewConverter(cs, "UTF-8")
|
||||
// if err != nil {
|
||||
// err = errors.New("Failed to convert " + cs + " to UTF-8: " + err.Error())
|
||||
// return bs, err
|
||||
// }
|
||||
|
||||
// return converter.ConvertString(bs)
|
||||
// }
|
||||
|
||||
@@ -8,14 +8,10 @@ require (
|
||||
github.com/blang/semver v3.5.1+incompatible
|
||||
github.com/coreybutler/go-fsutil v1.2.0
|
||||
github.com/coreybutler/go-where v1.0.1
|
||||
github.com/mushroomsir/iconv v0.0.0-20180525091039-6f95241e51c8
|
||||
github.com/djimenez/iconv-go v0.0.0-20160305225143-8960e66bd3da
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d
|
||||
golang.org/x/sys v0.3.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
github.com/stretchr/testify v1.8.1 // indirect
|
||||
golang.org/x/text v0.3.2 // indirect
|
||||
)
|
||||
require github.com/mattn/go-runewidth v0.0.9 // indirect
|
||||
|
||||
21
src/go.sum
21
src/go.sum
@@ -4,26 +4,14 @@ github.com/coreybutler/go-fsutil v1.2.0 h1:kbm62NSofawglUppEOhpHC3NDf/J7ZpguBirB
|
||||
github.com/coreybutler/go-fsutil v1.2.0/go.mod h1:B+6ufEkkRZgFwyR2sHEVG9dMzVBU3GbyGyYmCq7YkEk=
|
||||
github.com/coreybutler/go-where v1.0.1 h1:O88ndeqvrmuoq/2OfT+irLfzsjGrextvaNXE5pSEXUo=
|
||||
github.com/coreybutler/go-where v1.0.1/go.mod h1:IqV4saJiDXdNJURfTfVRywDHvY1IG5F+GXb2kmnmEe8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/djimenez/iconv-go v0.0.0-20160305225143-8960e66bd3da h1:0qwwqQCLOOXPl58ljnq3sTJR7yRuMolM02vjxDh4ZVE=
|
||||
github.com/djimenez/iconv-go v0.0.0-20160305225143-8960e66bd3da/go.mod h1:ns+zIWBBchgfRdxNgIJWn2x6U95LQchxeqiN5Cgdgts=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mushroomsir/iconv v0.0.0-20180525091039-6f95241e51c8 h1:qnum99kMXmcX8kwIvlHxMWeYCGx2h16gfIxyP1IhHjA=
|
||||
github.com/mushroomsir/iconv v0.0.0-20180525091039-6f95241e51c8/go.mod h1:a1NpVA8oEJfkxTRw/RgKXnQbW/oIDxdkW5FTlQ1tFrQ=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d h1:hrujxIzL1woJ7AwssoOcM/tq5JjjG2yYOc8odClEiXA=
|
||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/zmb3/gogetdoc v0.0.0-20190228002656-b37376c5da6a/go.mod h1:ofmGw6LrMypycsiWcyug6516EXpIxSbZ+uI9ppGypfY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
@@ -37,13 +25,8 @@ golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181207195948-8634b1ecd393/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190825031127-d72b05d2b1b6/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
84
src/nvm.go
84
src/nvm.go
@@ -16,6 +16,7 @@ import (
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
"nvm/arch"
|
||||
"nvm/encoding"
|
||||
@@ -217,6 +218,7 @@ func getVersion(version string, cpuarch string, localInstallsOnly ...bool) (stri
|
||||
// If user specifies "latest" version, find out what version is
|
||||
if version == "latest" || version == "node" {
|
||||
version = getLatest()
|
||||
fmt.Println(version)
|
||||
}
|
||||
|
||||
if version == "lts" {
|
||||
@@ -599,7 +601,7 @@ func findLatestSubVersion(version string, localOnly ...bool) string {
|
||||
url := web.GetFullNodeUrl("latest-v" + version + ".x" + "/SHASUMS256.txt")
|
||||
content := web.GetRemoteTextFile(url)
|
||||
re := regexp.MustCompile("node-v(.+)+msi")
|
||||
reg := regexp.MustCompile("node-v|-x.+")
|
||||
reg := regexp.MustCompile("node-v|-[xa].+")
|
||||
latest := reg.ReplaceAllString(re.FindString(content), "")
|
||||
return latest
|
||||
}
|
||||
@@ -914,7 +916,7 @@ func checkLocalEnvironment() {
|
||||
username := strings.Split(user.Username, "\\")
|
||||
fmt.Printf("%v is not using admin or elevated rights", username[len(username)-1])
|
||||
if devmode == "ON" {
|
||||
fmt.Printf(", but windows developer mode is enabled.\nMost commands will still work unless %v lacks rights to modify %v.\n", username[len(username)-1], current)
|
||||
fmt.Printf(", but windows developer mode is\nenabled. Most commands will still work unless %v lacks rights to\nmodify the %v symlink.\n", username[len(username)-1], current)
|
||||
} else {
|
||||
fmt.Println(".")
|
||||
}
|
||||
@@ -929,6 +931,36 @@ func checkLocalEnvironment() {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
kernel32 := syscall.NewLazyDLL("kernel32.dll")
|
||||
handle, _, err := kernel32.NewProc("GetStdHandle").Call(uintptr(0xfffffff5)) // get handle for console input
|
||||
if err != nil && err.Error() != "The operation completed successfully." {
|
||||
fmt.Printf("Error getting console handle: %v", err)
|
||||
} else {
|
||||
var mode uint32
|
||||
result, _, _ := kernel32.NewProc("GetConsoleMode").Call(handle, uintptr(unsafe.Pointer(&mode)))
|
||||
if result != 0 {
|
||||
var title [256]uint16
|
||||
_, _, err := kernel32.NewProc("GetConsoleTitleW").Call(uintptr(unsafe.Pointer(&title)), uintptr(len(title)))
|
||||
if err != nil && err.Error() != "The operation completed successfully." {
|
||||
fmt.Printf("Error getting console title: %v", err)
|
||||
} else {
|
||||
consoleTitle := syscall.UTF16ToString(title[:])
|
||||
|
||||
if !strings.Contains(strings.ToLower(consoleTitle), "command prompt") && !strings.Contains(strings.ToLower(consoleTitle), "powershell") {
|
||||
problems = append(problems, fmt.Sprintf("\"%v\" is not an officially supported shell. Some features may not work as expected.\n", consoleTitle))
|
||||
}
|
||||
|
||||
fmt.Printf("\n%v", consoleTitle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SHELL in Linux
|
||||
// TERM in Windows
|
||||
// COMSPEC in Windows provides the terminal path
|
||||
// shell := os.Getenv("ConEmuANSI")
|
||||
// fmt.Printf("Shell: %v\n", shell)
|
||||
|
||||
// Display developer mode status
|
||||
if !admin {
|
||||
// if devmode == "ON" {
|
||||
@@ -948,12 +980,22 @@ func checkLocalEnvironment() {
|
||||
path = "UNKNOWN: " + err.Error()
|
||||
}
|
||||
|
||||
fmt.Printf("\nPath: %v\nVersion: %v\nNVM_HOME: %v\nNVM_SYMLINK: %v\n", path, NvmVersion, home, symlink)
|
||||
out := "Unknown"
|
||||
output, err := exec.Command(os.Getenv("NVM_SYMLINK")+"\\node.exe", "-v").Output()
|
||||
if err == nil {
|
||||
out = string(output)
|
||||
}
|
||||
|
||||
fmt.Printf("\nPath: %v\nNVM4W Version: %v\nNVM_HOME: %v\nNVM_SYMLINK: %v\n\nActive Node.js Version: %v", path, NvmVersion, home, symlink, out)
|
||||
|
||||
if !nvmsymlinkfound {
|
||||
problems = append(problems, "The NVM4W symlink ("+env.symlink+") was not found in the PATH environment variable.")
|
||||
}
|
||||
|
||||
if home == symlink {
|
||||
problems = append(problems, "NVM_HOME and NVM_SYMLINK cannot be the same value ("+symlink+"). Change NVM_SYMLINK.")
|
||||
}
|
||||
|
||||
nodelist := web.Ping(web.GetFullNodeUrl("index.json"))
|
||||
if !nodelist {
|
||||
if len(env.node_mirror) > 0 && env.node_mirror != "none" {
|
||||
@@ -978,9 +1020,23 @@ func checkLocalEnvironment() {
|
||||
if len(problems) == 0 {
|
||||
fmt.Println("\n" + "No problems detected.")
|
||||
} else {
|
||||
fmt.Println("\n" + "Problems Detected:")
|
||||
// fmt.Println("")
|
||||
// table := tablewriter.NewWriter(os.Stdout)
|
||||
// table.SetHeader([]string{"#", "Problems Detected"})
|
||||
// table.SetColMinWidth(1, 40)
|
||||
// table.SetAutoWrapText(false)
|
||||
// // table.SetBorders(tablewriter.Border{Left: true, Top: false, Right: true, Bottom: false})
|
||||
// // table.SetAlignment(tablewriter.ALIGN_LEFT)
|
||||
// // table.SetCenterSeparator("|")
|
||||
// data := make([][]string, 0)
|
||||
// for i := 0; i < len(problems); i++ {
|
||||
// data = append(data, []string{fmt.Sprintf(" %v ", i+1), problems[i]})
|
||||
// }
|
||||
// table.AppendBulk(data) // Add Bulk Data
|
||||
// table.Render()
|
||||
fmt.Println("\nPROBLEMS DETECTED\n-----------------")
|
||||
for _, p := range problems {
|
||||
fmt.Println(" - " + p)
|
||||
fmt.Println(p + "\n")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -993,7 +1049,7 @@ func help() {
|
||||
fmt.Println(" ")
|
||||
fmt.Println(" nvm arch : Show if node is running in 32 or 64 bit mode.")
|
||||
fmt.Println(" nvm current : Display active version.")
|
||||
fmt.Println(" nvm debug : Check the NVM4W process for known problems (experimental troubleshooter).")
|
||||
fmt.Println(" nvm debug : Check the NVM4W process for known problems (troubleshooter).")
|
||||
fmt.Println(" nvm install <version> [arch] : The version can be a specific version, \"latest\" for the latest current version, or \"lts\" for the")
|
||||
fmt.Println(" most recent LTS version. Optionally specify whether to install the 32 or 64 bit version (defaults")
|
||||
fmt.Println(" to system arch). Set [arch] to \"all\" to install 32 AND 64 bit versions.")
|
||||
@@ -1028,7 +1084,7 @@ func checkVersionExceedsLatest(version string) bool {
|
||||
url := web.GetFullNodeUrl("latest/SHASUMS256.txt")
|
||||
content := web.GetRemoteTextFile(url)
|
||||
re := regexp.MustCompile("node-v(.+)+msi")
|
||||
reg := regexp.MustCompile("node-v|-x.+")
|
||||
reg := regexp.MustCompile("node-v|-[xa].+")
|
||||
latest := reg.ReplaceAllString(re.FindString(content), "")
|
||||
var vArr = strings.Split(version, ".")
|
||||
var lArr = strings.Split(latest, ".")
|
||||
@@ -1073,7 +1129,7 @@ func getLatest() string {
|
||||
url := web.GetFullNodeUrl("latest/SHASUMS256.txt")
|
||||
content := web.GetRemoteTextFile(url)
|
||||
re := regexp.MustCompile("node-v(.+)+msi")
|
||||
reg := regexp.MustCompile("node-v|-x.+")
|
||||
reg := regexp.MustCompile("node-v|-[xa].+")
|
||||
return reg.ReplaceAllString(re.FindString(content), "")
|
||||
}
|
||||
|
||||
@@ -1199,13 +1255,13 @@ func getProcessPermissions() (admin bool, elevated bool, err error) {
|
||||
}
|
||||
|
||||
func encode(val string) string {
|
||||
converted, err := encoding.ToUTF8([]byte(val))
|
||||
if err != nil {
|
||||
fmt.Printf("WARNING: [encoding error] - %v\n", err.Error())
|
||||
return val
|
||||
}
|
||||
converted := encoding.ToUTF8(val)
|
||||
// if err != nil {
|
||||
// fmt.Printf("WARNING: [encoding error] - %v\n", err.Error())
|
||||
// return val
|
||||
// }
|
||||
|
||||
return converted
|
||||
return string(converted)
|
||||
}
|
||||
|
||||
// ===============================================================
|
||||
|
||||
Reference in New Issue
Block a user