Added custom UTF-8 converter for settings file.

This commit is contained in:
Corey Butler
2023-02-24 12:31:57 -06:00
parent 1216b37643
commit 16afa15d7d
4 changed files with 145 additions and 45 deletions

64
src/encoding/encoding.go Normal file
View File

@@ -0,0 +1,64 @@
package encoding
import (
"errors"
"strings"
"unicode/utf8"
"github.com/mushroomsir/iconv"
"github.com/saintfish/chardet"
)
func DetectCharset(content []byte) (string, error) {
detector := chardet.NewTextDetector()
result, err := detector.DetectBest(content)
if err != nil {
return "", err
}
return strings.ToUpper(result.Charset), nil
}
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)
}

View File

@@ -7,9 +7,15 @@ go 1.18
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/olekukonko/tablewriter v0.0.5
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a
golang.org/x/text v0.3.2
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
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
)

View File

@@ -2,10 +2,28 @@ github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdn
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/coreybutler/go-fsutil v1.2.0 h1:kbm62NSofawglUppEOhpHC3NDf/J7ZpguBirBnsgUwU=
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/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=
@@ -15,8 +33,9 @@ golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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=
@@ -24,3 +43,7 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm
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=

View File

@@ -18,19 +18,21 @@ import (
"time"
"nvm/arch"
"nvm/encoding"
"nvm/file"
"nvm/node"
"nvm/web"
"github.com/blang/semver"
// "github.com/fatih/color"
"github.com/coreybutler/go-where"
"github.com/olekukonko/tablewriter"
"golang.org/x/sys/windows"
"golang.org/x/sys/windows/registry"
"golang.org/x/text/encoding"
)
const (
NvmVersion = "1.1.10"
NvmVersion = "1.1.11"
)
type Environment struct {
@@ -157,7 +159,7 @@ func main() {
setNodeMirror(detail)
case "npm_mirror":
setNpmMirror(detail)
case "check":
case "debug":
checkLocalEnvironment()
default:
help()
@@ -896,7 +898,11 @@ func checkLocalEnvironment() {
if value > 0 {
devmode = "ON"
}
} else {
devmode = "UNKNOWN"
}
} else {
devmode = "UNKNOWN (user cannot read registry)"
}
defer k.Close()
@@ -906,15 +912,15 @@ func checkLocalEnvironment() {
if !admin && !elevated {
user, _ := user.Current()
username := strings.Split(user.Username, "\\")
fmt.Printf("\"%v\" does not have admin or elevated rights", username[len(username)-1])
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 enabled.\nMost commands will still work unless %v lacks rights to modify %v.\n", username[len(username)-1], current)
} else {
fmt.Println(".")
}
} else {
if admin {
fmt.Println("Running NVM for Windows as an admin user.")
fmt.Println("Running NVM for Windows with administrator privileges.")
} else if elevated {
fmt.Println("Running NVM for Windows with elevated permissions.")
}
@@ -925,10 +931,24 @@ func checkLocalEnvironment() {
// Display developer mode status
if !admin {
fmt.Printf("\nWindows Developer Mode: %v\n", devmode)
// if devmode == "ON" {
// devmode = color.GreenString(devmode)
// } else if devmode == "OFF" {
// devmode = color.YellowString(devmode)
// } else {
// devmode = color.YellowString(devmode)
// }
fmt.Printf("\n%v %v\n", "Windows Developer Mode:", devmode)
}
fmt.Printf("\nInformation\n-----------\nPath: %v\nVersion: %v\nNVM_HOME: %v\nNVM_SYMLINK: %v\n", os.Args[0], NvmVersion, home, symlink)
executable := os.Args[0]
path, err := where.Find(executable)
if err != nil {
path = "UNKNOWN: " + err.Error()
}
fmt.Printf("\nPath: %v\nVersion: %v\nNVM_HOME: %v\nNVM_SYMLINK: %v\n", path, NvmVersion, home, symlink)
if !nvmsymlinkfound {
problems = append(problems, "The NVM4W symlink ("+env.symlink+") was not found in the PATH environment variable.")
@@ -956,16 +976,15 @@ func checkLocalEnvironment() {
}
if len(problems) == 0 {
fmt.Println("\nNo problems detected.")
return
fmt.Println("\n" + "No problems detected.")
} else {
fmt.Println("\n" + "Problems Detected:")
for _, p := range problems {
fmt.Println(" - " + p)
}
}
fmt.Println("\nProblems Detected:")
for _, p := range problems {
fmt.Println(" - " + p)
}
fmt.Println("\nFind help at https://github.com/coreybutler/nvm-windows/wiki/Common-Issues")
fmt.Println("\n" + "Find help at https://github.com/coreybutler/nvm-windows/wiki/Common-Issues")
}
func help() {
@@ -973,8 +992,8 @@ func help() {
fmt.Println("\nUsage:")
fmt.Println(" ")
fmt.Println(" nvm arch : Show if node is running in 32 or 64 bit mode.")
fmt.Println(" nvm check : Check the NVM4W process for known problems (experimental troubleshooter).")
fmt.Println(" nvm current : Display active version.")
fmt.Println(" nvm debug : Check the NVM4W process for known problems (experimental 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.")
@@ -1151,15 +1170,9 @@ func runElevated(command string, forceUAC ...bool) (bool, error) {
}
func saveSettings() {
content := "root: " + strings.Trim(env.root, " \n\r") + "\r\narch: " + strings.Trim(env.arch, " \n\r") + "\r\nproxy: " + strings.Trim(env.proxy, " \n\r") + "\r\noriginalpath: " + strings.Trim(env.originalpath, " \n\r") + "\r\noriginalversion: " + strings.Trim(env.originalversion, " \n\r")
content = content + "\r\nnode_mirror: " + strings.Trim(env.node_mirror, " \n\r") + "\r\nnpm_mirror: " + strings.Trim(env.npm_mirror, " \n\r")
decoder := encoding.Decoder{}
decoded, err := decoder.String(content)
if err != nil {
fmt.Printf("Error attempting to save settings:\n%v\n", err.Error())
return
}
ioutil.WriteFile(env.settings, []byte(decoded), 0644)
content := "root: " + strings.Trim(encode(env.root), " \n\r") + "\r\narch: " + strings.Trim(encode(env.arch), " \n\r") + "\r\nproxy: " + strings.Trim(encode(env.proxy), " \n\r") + "\r\noriginalpath: " + strings.Trim(encode(env.originalpath), " \n\r") + "\r\noriginalversion: " + strings.Trim(encode(env.originalversion), " \n\r")
content = content + "\r\nnode_mirror: " + strings.Trim(encode(env.node_mirror), " \n\r") + "\r\nnpm_mirror: " + strings.Trim(encode(env.npm_mirror), " \n\r")
ioutil.WriteFile(env.settings, []byte(content), 0644)
}
func getProcessPermissions() (admin bool, elevated bool, err error) {
@@ -1185,22 +1198,16 @@ func getProcessPermissions() (admin bool, elevated bool, err error) {
return
}
// NOT USED?
/*
func useArchitecture(a string) {
if strings.ContainsAny("32",os.Getenv("PROCESSOR_ARCHITECTURE")) {
fmt.Println("This computer only supports 32-bit processing.")
return
}
if a == "32" || a == "64" {
env.arch = a
saveSettings()
fmt.Println("Set to "+a+"-bit mode.")
} else {
fmt.Println("Cannot set architecture to "+a+". Must be 32 or 64 are acceptable values.")
}
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
}
return converted
}
*/
// ===============================================================
// END | Utility functions
// ===============================================================