From 64f10f4194f9b341267efcd1ba0cc187912868bf Mon Sep 17 00:00:00 2001 From: David Dias Date: Thu, 4 Oct 2018 12:05:40 -0300 Subject: [PATCH] better error handling and fix lack of string trim --- .travis.yml | 11 ++++++++++ go.mod | 9 ++++++++ go.sum | 11 ++++++++++ main.go | 61 +++++++++++++++++++++++++++++------------------------ 4 files changed, 64 insertions(+), 28 deletions(-) create mode 100644 .travis.yml create mode 100644 go.mod create mode 100644 go.sum diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..85122b7 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,11 @@ +language: go +go: + - 1.10.x + - master +sudo: false + +install: true + +script: + - env GO111MODULE=on go build + - env GO111MODULE=on go test diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..67852d6 --- /dev/null +++ b/go.mod @@ -0,0 +1,9 @@ +module github.com/dvdscripter/elvuiUpdater + +require ( + github.com/PuerkitoBio/goquery v1.4.1 + github.com/andybalholm/cascadia v1.0.0 // indirect + github.com/pkg/errors v0.8.0 + golang.org/x/net v0.0.0-20181003013248-f5e5bdd77824 // indirect + golang.org/x/sys v0.0.0-20181003145944-af653ce8b74f +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..65e9da3 --- /dev/null +++ b/go.sum @@ -0,0 +1,11 @@ +github.com/PuerkitoBio/goquery v1.4.1 h1:smcIRGdYm/w7JSbcdeLHEMzxmsBQvl8lhf0dSw2nzMI= +github.com/PuerkitoBio/goquery v1.4.1/go.mod h1:T9ezsOHcCrDCgA8aF1Cqr3sSYbO/xgdy8/R/XiIMAhA= +github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o= +github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= +github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181003013248-f5e5bdd77824 h1:MkjFNbaZJyH98M67Q3umtwZ+EdVdrNJLqSwZp5vcv60= +golang.org/x/net v0.0.0-20181003013248-f5e5bdd77824/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sys v0.0.0-20181003145944-af653ce8b74f h1:zAtpFwFDtnvBWPPelq8CSiqRN1wrIzMUk9dwzbpjpNM= +golang.org/x/sys v0.0.0-20181003145944-af653ce8b74f/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/main.go b/main.go index 8f2db87..264fa82 100644 --- a/main.go +++ b/main.go @@ -18,6 +18,7 @@ import ( "golang.org/x/sys/windows/registry" "github.com/PuerkitoBio/goquery" + "github.com/pkg/errors" ) type configuration struct { @@ -37,21 +38,21 @@ type elvui struct { func (e *elvui) init(configPath string) error { rawConfig, err := ioutil.ReadFile(configPath) if err != nil { - return err + return errors.Wrapf(err, "cannot read file %s", configPath) } if err = json.Unmarshal(rawConfig, e); err != nil { - return err + return errors.Wrap(err, "cannot unmarshal config") } k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Wow6432Node\Blizzard Entertainment\World of Warcraft`, registry.QUERY_VALUE) if err != nil { - return err + return errors.Wrap(err, "cannot find WoW install directory") } defer k.Close() s, _, err := k.GetStringValue("InstallPath") if err != nil { - return err + return errors.Wrap(err, "cannot find WoW install directory") } e.addon = filepath.Join(s, "Interface", "AddOns") @@ -61,17 +62,17 @@ func (e *elvui) init(configPath string) error { func (e *elvui) getRemoteVersion() error { doc, err := goquery.NewDocument(e.Page) if err != nil { - return err + return errors.Wrapf(err, "cannot parse url: %s", e.Page) } sel := doc.Find(e.Versionselector) if sel == nil { - return fmt.Errorf("Version not found at %s", e.Page) + return errors.Errorf("version not found at %s", e.Page) } - span := sel.Text() + span := strings.TrimSpace(sel.Text()) if e.remoteVersion, err = strconv.ParseFloat(span, 64); err != nil { - return err + return errors.Wrapf(err, "cannot parse version number %s", span) } return nil @@ -83,7 +84,7 @@ func (e *elvui) getLocalVersion() error { toc, err := os.Open(tocFile) if err != nil { - return err + return errors.Wrapf(err, "cannot open file %s", tocFile) } defer toc.Close() tocReader := bufio.NewReader(toc) @@ -93,18 +94,19 @@ func (e *elvui) getLocalVersion() error { if err == io.EOF { break } else if err != nil { - return err + return errors.Wrapf(err, "cannot read lines from %s", tocFile) } if strings.HasPrefix(line, prefix) { // retard windows need -1 - if e.localVersion, err = strconv.ParseFloat(line[len(prefix):len(line)-1], 64); err != nil { - return err + rawVer := strings.TrimSpace(line[len(prefix) : len(line)-1]) + if e.localVersion, err = strconv.ParseFloat(rawVer, 64); err != nil { + return errors.Wrapf(err, "cannot parse version number %s", rawVer) } return nil } } - return fmt.Errorf("Local version not found at %s", tocFile) + return errors.Errorf("local version not found at %s", tocFile) } func (e elvui) downloadAndExtract() error { @@ -113,48 +115,51 @@ func (e elvui) downloadAndExtract() error { response, err := http.Get(dlLink) if err != nil { - return err + return errors.Wrapf(err, "cannot download file url %s", dlLink) } defer response.Body.Close() // hope tukui don't overflow my memory respBytes, err := ioutil.ReadAll(response.Body) if err != nil { - return err + return errors.Wrap(err, "cannot read response") } readerBytes := bytes.NewReader(respBytes) // zip work zipReader, err := zip.NewReader(readerBytes, response.ContentLength) if err != nil { - return err + return errors.Wrap(err, "cannot create zip reader") } // remove older directories for _, dir := range e.Directories { - if err := os.RemoveAll(filepath.Join(e.addon, dir)); err != nil { - return err + addonDir := filepath.Join(e.addon, dir) + if err := os.RemoveAll(addonDir); err != nil { + return errors.Wrapf(err, "cannot remove directory %s", addonDir) } } for _, f := range zipReader.File { if f.FileInfo().IsDir() { - if err := os.MkdirAll(filepath.Join(e.addon, f.Name), f.Mode()); err != nil { - return err + addonDir := filepath.Join(e.addon, f.Name) + if err := os.MkdirAll(addonDir, f.Mode()); err != nil { + return errors.Wrapf(err, "cannot create directory %s", addonDir) } } else { // open file inside zip for copy fileInZip, err := f.Open() if err != nil { - return err + return errors.Wrapf(err, "cannot open file %s inside zip", f.Name) } // create local file - fileLocal, err := os.Create(filepath.Join(e.addon, f.Name)) + localName := filepath.Join(e.addon, f.Name) + fileLocal, err := os.Create(localName) if err != nil { - return err + return errors.Wrapf(err, "cannot create file %s", localName) } // copy contents over _, err = io.Copy(fileLocal, fileInZip) if err != nil { - return err + return errors.Wrapf(err, "cannot extract content from %s to %s", f.Name, localName) } fileLocal.Close() @@ -168,19 +173,19 @@ func (e elvui) downloadAndExtract() error { func main() { conf := elvui{localName: "ElvUI"} if err := conf.init("config.json"); err != nil { - log.Fatal(err) + log.Fatalf("Fatal: %+v\n", err) } if err := conf.getLocalVersion(); err != nil { - log.Fatal(err) + log.Fatalf("Fatal: %+v\n", err) } if err := conf.getRemoteVersion(); err != nil { - log.Fatal(err) + log.Fatalf("Fatal: %+v\n", err) } if conf.remoteVersion > conf.localVersion { log.Printf("Upgrading %.2f->%.2f\n", conf.localVersion, conf.remoteVersion) if err := conf.downloadAndExtract(); err != nil { - log.Fatal(err) + log.Fatalf("Fatal: %+v\n", err) } log.Println("Success") } else {