diff --git a/README.md b/README.md index a7e100a8..3f6e17f0 100644 --- a/README.md +++ b/README.md @@ -343,7 +343,7 @@ Below you'll find a list of open positions that require at least **experience wi | -----------|--------|-------------| | Kudo, an Indonesian startup technology company | Application Programming Interface Developer | Navigate to: https://glints.id/opportunities/jobs/5553 | -Employers that are looking for briliant Software Engineers with good experience on Go Programming Language and Iris can put their startup's or company's name here or, if privacy is the key, [contact with us](mailto:kataras2006@hotmail.com?subject=Employer%20That%20Hires%20Smart%20Devs) to suggest some good and well-tested freelancers that suits your needs. +Employers that are looking for brilliant Software Engineers with good experience on Go Programming Language and Iris can put their startup's or company's name here or, if privacy is the key, [contact with us](mailto:kataras2006@hotmail.com?subject=Employer%20That%20Hires%20Smart%20Devs) to suggest some good and well-tested freelancers that suits your needs. ### 🥇 People diff --git a/VERSION b/VERSION new file mode 100644 index 00000000..ce44b5bd --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +8.2.1:https://github.com/kataras/iris/blob/master/HISTORY.md#tu-08-august-2017--v821 \ No newline at end of file diff --git a/configuration.go b/configuration.go index a697b9f3..980ec9e9 100644 --- a/configuration.go +++ b/configuration.go @@ -136,6 +136,11 @@ var WithoutInterruptHandler = func(app *Application) { app.config.DisableInterruptHandler = true } +// WithoutVersionCheck will disable the version checker and updater. +var WithoutVersionCheck = func(app *Application) { + app.config.DisableVersionCheck = true +} + // WithoutPathCorrection disables the PathCorrection setting. // // See `Configuration`. @@ -276,6 +281,11 @@ type Configuration struct { // Defaults to false. DisableInterruptHandler bool `yaml:"DisableInterruptHandler" toml:"DisableInterruptHandler"` + // DisableVersionCheck if true then process will be not be notified for any available updates. + // + // Defaults to false. + DisableVersionCheck bool `yaml:"DisableVersionCheck" toml:"DisableVersionCheck"` + // DisablePathCorrection corrects and redirects the requested path to the registered path // for example, if /home/ path is requested but no handler for this Route found, // then the Router checks if /home handler exists, if yes, @@ -597,6 +607,7 @@ func DefaultConfiguration() Configuration { return Configuration{ DisableStartupLog: false, DisableInterruptHandler: false, + DisableVersionCheck: false, DisablePathCorrection: false, EnablePathEscape: false, FireMethodNotAllowed: false, diff --git a/iris.go b/iris.go index ac48696d..0e67db39 100644 --- a/iris.go +++ b/iris.go @@ -647,6 +647,11 @@ func (app *Application) Run(serve Runner, withOrWithout ...Configurator) error { app.Configure(withOrWithout...) app.logger.Debugf("Application: running using %d host(s)", len(app.Hosts)+1) + + if !app.config.DisableVersionCheck && app.logger.Printer.IsTerminal { + go CheckVersion() + } + // this will block until an error(unless supervisor's DeferFlow called from a Task). err := serve(app) if err != nil { diff --git a/sessions/sessiondb/boltdb/database.go b/sessions/sessiondb/boltdb/database.go index 64c36151..8c146a1a 100644 --- a/sessions/sessiondb/boltdb/database.go +++ b/sessions/sessiondb/boltdb/database.go @@ -191,7 +191,7 @@ func (db *Database) destroy(bsid []byte) error { // we store the whole data to the key-value pair of the root bucket // so we don't need a separate bucket for each session // this method could be faster if we had large data to store -// but with sessions we recommend small ammount of data, so the method finally choosen +// but with sessions we recommend small amount of data, so the method finally chosen // is faster (decode/encode the whole store + lifetime and return it as it's) // // func (db *Database) getSessBucket(tx *bolt.Tx, sid string) (*bolt.Bucket, error) { diff --git a/version.go b/version.go new file mode 100644 index 00000000..970c4edb --- /dev/null +++ b/version.go @@ -0,0 +1,151 @@ +package iris + +import ( + "bufio" + "io/ioutil" + "net" + "net/http" + "os" + "os/exec" + "strings" + "sync" + "time" + + "github.com/hashicorp/go-version" + "github.com/kataras/golog" +) + +const ( + versionURL = "https://raw.githubusercontent.com/kataras/iris/master/VERSION" + updateCmd = "go get -u -f -v github.com/kataras/iris" +) + +var checkVersionOnce = sync.Once{} + +// CheckVersion checks for any available updates. +func CheckVersion() { + checkVersionOnce.Do(func() { + checkVersion() + }) +} + +func checkVersion() { + + // open connection and read/write timeouts + timeout := time.Duration(10 * time.Second) + + transport := http.Transport{ + Dial: func(network string, addr string) (net.Conn, error) { + conn, err := net.DialTimeout(network, addr, timeout) + if err != nil { + golog.Debugf("%v", err) + return nil, err + } + conn.SetDeadline(time.Now().Add(timeout)) // skip error + return conn, nil + }, + } + + client := http.Client{ + Transport: &transport, + } + + r, err := client.Get(versionURL) + if err != nil { + golog.Debugf("%v", err) + return + } + defer r.Body.Close() + + if r.StatusCode >= 400 { + return + } + + b, err := ioutil.ReadAll(r.Body) + + if len(b) == 0 || err != nil { + golog.Debugf("%v", err) + return + } + + var ( + fetchedVersion = string(b) + changelogURL string + ) + + // 8.2.1:https://github.com/kataras/iris/blob/master/HISTORY.md#tu-08-august-2017--v821 + if idx := strings.IndexByte(fetchedVersion, ':'); idx > 0 { + changelogURL = fetchedVersion[idx+1:] + fetchedVersion = fetchedVersion[0:idx] + } + + latestVersion, err := version.NewVersion(fetchedVersion) + if err != nil { + golog.Debugf("while parsing latest version: %v", err) + return + } + + currentVersion, err := version.NewVersion(Version) + if err != nil { + golog.Debugf("while parsing current version: %v", err) + return + } + + if currentVersion.GreaterThan(latestVersion) { + golog.Debugf("current version is greater than latest version, report as bug") + return + } + + if currentVersion.Equal(latestVersion) { + return + } + + // currentVersion.LessThan(latestVersion) + + var updaterYesInput = [...]string{"y", "yes"} + + text := "A more recent version has been found[%s > %s].\n" + + if changelogURL != "" { + text += "Release notes: %s\n" + } + + text += "Update now?[%s]: " + + golog.Warnf(text, + latestVersion.String(), currentVersion.String(), + changelogURL, + updaterYesInput[0]+"/n") + + silent := false + + sc := bufio.NewScanner(os.Stdin) + + shouldUpdate := silent + + if !silent { + if sc.Scan() { + inputText := sc.Text() + for _, s := range updaterYesInput { + if inputText == s { + shouldUpdate = true + } + } + } + } + + if shouldUpdate { + goget := strings.Split(updateCmd, " ") + // go get -u github.com/:owner/:repo + cmd := exec.Command(goget[0], goget[1:]...) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stdout + + if err := cmd.Run(); err != nil { + golog.Warnf("unexpected message while trying to go get: %v", err) + return + } + + golog.Infof("Update process finished, current version: %s.\nManual restart is required to apply the changes.\n", latestVersion.String()) + } +}