diff --git a/file/files.go b/file/files.go index f44c761..8e9a8a8 100644 --- a/file/files.go +++ b/file/files.go @@ -666,7 +666,7 @@ func find(dir, name string, results []*string) []*string { match, err := filepath.Match(strings.ToLower(pattern), strings.ToLower(path)) if nil != err { - logger.Errorf("Find match filename failed: [%s]", err.Error) + logger.Errorf("Find match filename failed: [%s]", err.Error()) continue } diff --git a/i18n/en_US.json b/i18n/en_US.json index aab4a63..1cd0513 100644 --- a/i18n/en_US.json +++ b/i18n/en_US.json @@ -162,5 +162,9 @@ "open": "Open", "pricing": "Pricing", "search_no_match": "No matching files were found.", - "outline": "Outline" + "outline": "Outline", + "govet": "go vet", + "start-vet": "START [go vet]", + "vet-succ": "[go vet] SUCCESS", + "vet-error": "[go vet] ERROR" } \ No newline at end of file diff --git a/i18n/ja_JP.json b/i18n/ja_JP.json index 7f711f2..db84830 100644 --- a/i18n/ja_JP.json +++ b/i18n/ja_JP.json @@ -162,5 +162,9 @@ "open": "オープン", "pricing": "价格", "search_no_match": "一致するファイルが見つかりませんでした。", - "outline": "アウトライン" + "outline": "アウトライン", + "govet": "go vet", + "start-vet": "START [go vet]", + "vet-succ": "[go vet] SUCCESS", + "vet-error": "[go vet] ERROR" } diff --git a/i18n/zh_CN.json b/i18n/zh_CN.json index 08c411b..8bf63c4 100644 --- a/i18n/zh_CN.json +++ b/i18n/zh_CN.json @@ -162,5 +162,9 @@ "open": "打开", "pricing": "价格", "search_no_match": "没有发现匹配的文件。", - "outline": "大纲" + "outline": "大纲", + "govet": "go vet", + "start-vet": "START [go vet]", + "vet-succ": "[go vet] SUCCESS", + "vet-error": "[go vet] ERROR" } \ No newline at end of file diff --git a/i18n/zh_TW.json b/i18n/zh_TW.json index 2fda18b..2e4b0d4 100644 --- a/i18n/zh_TW.json +++ b/i18n/zh_TW.json @@ -162,5 +162,9 @@ "open": "打開", "pricing": "價格", "search_no_match": "沒有發現匹配的文件。", - "outline": "大綱" + "outline": "大綱", + "govet": "go vet", + "start-vet": "START [go vet]", + "vet-succ": "[go vet] SUCCESS", + "vet-error": "[go vet] ERROR" } \ No newline at end of file diff --git a/main.go b/main.go index 84e8822..2c1ea11 100644 --- a/main.go +++ b/main.go @@ -118,6 +118,7 @@ func main() { http.HandleFunc(conf.Wide.Context+"/run", handlerWrapper(output.RunHandler)) http.HandleFunc(conf.Wide.Context+"/stop", handlerWrapper(output.StopHandler)) http.HandleFunc(conf.Wide.Context+"/go/test", handlerWrapper(output.GoTestHandler)) + http.HandleFunc(conf.Wide.Context+"/go/vet", handlerWrapper(output.GoVetHandler)) http.HandleFunc(conf.Wide.Context+"/go/get", handlerWrapper(output.GoGetHandler)) http.HandleFunc(conf.Wide.Context+"/go/install", handlerWrapper(output.GoInstallHandler)) http.HandleFunc(conf.Wide.Context+"/output/ws", handlerWrapper(output.WSHandler)) diff --git a/output/outputs.go b/output/outputs.go index 07eecaf..ecd32f4 100644 --- a/output/outputs.go +++ b/output/outputs.go @@ -615,6 +615,124 @@ func GoTestHandler(w http.ResponseWriter, r *http.Request) { }(rand.Int()) } +// GoVetHandler handles request of go vet. +func GoVetHandler(w http.ResponseWriter, r *http.Request) { + data := map[string]interface{}{"succ": true} + defer util.RetJSON(w, r, data) + + httpSession, _ := session.HTTPSession.Get(r, "wide-session") + if httpSession.IsNew { + http.Error(w, "Forbidden", http.StatusForbidden) + + return + } + username := httpSession.Values["username"].(string) + locale := conf.GetUser(username).Locale + + var args map[string]interface{} + + if err := json.NewDecoder(r.Body).Decode(&args); err != nil { + logger.Error(err) + data["succ"] = false + + return + } + + sid := args["sid"].(string) + + filePath := args["file"].(string) + curDir := filepath.Dir(filePath) + + cmd := exec.Command("go", "vet", ".") + cmd.Dir = curDir + + setCmdEnv(cmd, username) + + stdout, err := cmd.StdoutPipe() + if nil != err { + logger.Error(err) + data["succ"] = false + + return + } + + stderr, err := cmd.StderrPipe() + if nil != err { + logger.Error(err) + data["succ"] = false + + return + } + + if !data["succ"].(bool) { + return + } + + channelRet := map[string]interface{}{} + + if nil != session.OutputWS[sid] { + // display "START [go vet]" in front-end browser + + channelRet["output"] = "" + i18n.Get(locale, "start-vet").(string) + "\n" + channelRet["cmd"] = "start-vet" + + wsChannel := session.OutputWS[sid] + + err := wsChannel.WriteJSON(&channelRet) + if nil != err { + logger.Error(err) + return + } + + wsChannel.Refresh() + } + + reader := bufio.NewReader(io.MultiReader(stdout, stderr)) + + if err := cmd.Start(); nil != err { + logger.Error(err) + data["succ"] = false + + return + } + + go func(runningId int) { + defer util.Recover() + + logger.Debugf("User [%s, %s] is running [go vet] [runningId=%d]", username, sid, runningId) + + channelRet := map[string]interface{}{} + channelRet["cmd"] = "go vet" + + // read all + buf, _ := ioutil.ReadAll(reader) + + // waiting for go vet finished + cmd.Wait() + + if !cmd.ProcessState.Success() { + logger.Debugf("User [%s, %s] 's running [go vet] [runningId=%d] has done (with error)", username, sid, runningId) + + channelRet["output"] = "" + i18n.Get(locale, "vet-error").(string) + "\n" + string(buf) + } else { + logger.Debugf("User [%s, %s] 's running [go vet] [runningId=%d] has done", username, sid, runningId) + + channelRet["output"] = "" + i18n.Get(locale, "vet-succ").(string) + "\n" + string(buf) + } + + if nil != session.OutputWS[sid] { + wsChannel := session.OutputWS[sid] + + err := wsChannel.WriteJSON(&channelRet) + if nil != err { + logger.Error(err) + } + + wsChannel.Refresh() + } + }(rand.Int()) +} + // GoInstallHandler handles request of go install. func GoInstallHandler(w http.ResponseWriter, r *http.Request) { data := map[string]interface{}{"succ": true} diff --git a/output/processes.go b/output/processes.go index 8844e94..dca0bd0 100644 --- a/output/processes.go +++ b/output/processes.go @@ -86,7 +86,7 @@ func (procs *procs) kill(wSession *session.WideSession, pid int) { for i, p := range userProcesses { if p.Pid == pid { if err := p.Kill(); nil != err { - logger.Error("Kill a process [pid=%d] of user [%s, %s] failed [error=%v]", pid, wSession.Username, sid, err) + logger.Errorf("Kill a process [pid=%d] of user [%s, %s] failed [error=%v]", pid, wSession.Username, sid, err) } else { var newProcesses []*os.Process diff --git a/static/css/wide.css b/static/css/wide.css index e065cfe..57e64de 100644 --- a/static/css/wide.css +++ b/static/css/wide.css @@ -439,21 +439,21 @@ } .bottom-window-group .output .start-build, -.bottom-window-group .output .start-test, +.bottom-window-group .output .start-test, .start-vet, .bottom-window-group .output .start-install, .bottom-window-group .output .start-get { color: #999; } .bottom-window-group .output .build-succ, -.bottom-window-group .output .test-succ, +.bottom-window-group .output .test-succ, .vet-succ, .bottom-window-group .output .install-succ, .bottom-window-group .output .get-succ { color: rgb(0,153,0); } .bottom-window-group .output .build-error, -.bottom-window-group .output .test-error, +.bottom-window-group .output .test-error, .vet-error, .bottom-window-group .output .install-error, .bottom-window-group .output .get-error { color: #9d0000; diff --git a/static/js/editors.js b/static/js/editors.js index 1148766..b99b5e8 100644 --- a/static/js/editors.js +++ b/static/js/editors.js @@ -189,7 +189,7 @@ var editors = { } if (editors.data.length === 0) { // 起始页可能存在,所以用编辑器数据判断 - menu.disabled(['save-all', 'build', 'run', 'go-test', 'go-get', 'go-install', + menu.disabled(['save-all', 'build', 'run', 'go-test','go-vet', 'go-get', 'go-install', 'find', 'find-next', 'find-previous', 'replace', 'replace-all', 'format', 'autocomplete', 'jump-to-decl', 'expr-info', 'find-usages', 'toggle-comment', 'edit']); @@ -721,7 +721,7 @@ var editors = { content: '' }); - menu.undisabled(['save-all', 'close-all', 'build', 'run', 'go-test', 'go-get', 'go-install', + menu.undisabled(['save-all', 'close-all', 'build', 'run', 'go-test', 'go-vet', 'go-get', 'go-install', 'find', 'find-next', 'find-previous', 'replace', 'replace-all', 'format', 'autocomplete', 'jump-to-decl', 'expr-info', 'find-usages', 'toggle-comment', 'edit']); diff --git a/static/js/menu.js b/static/js/menu.js index 2ea6981..0afba74 100644 --- a/static/js/menu.js +++ b/static/js/menu.js @@ -227,7 +227,7 @@ var menu = { return false; } - if ($(".menu li.test").hasClass("disabled")) { + if ($(".menu li.go-test").hasClass("disabled")) { return false; } @@ -246,6 +246,34 @@ var menu = { } }); }, + // go vet. + govet: function () { + menu.saveAllFiles(); + + var currentPath = editors.getCurrentPath(); + if (!currentPath) { + return false; + } + + if ($(".menu li.go-vet").hasClass("disabled")) { + return false; + } + + var request = newWideRequest(); + request.file = currentPath; + + $.ajax({ + type: 'POST', + url: config.context + '/go/vet', + data: JSON.stringify(request), + dataType: "json", + beforeSend: function (data) { + bottomGroup.resetOutput(); + }, + success: function (data) { + } + }); + }, // Build & Run. run: function () { menu.saveAllFiles(); diff --git a/static/js/wide.js b/static/js/wide.js index 992e87d..4172811 100644 --- a/static/js/wide.js +++ b/static/js/wide.js @@ -367,12 +367,14 @@ var wide = { break; case 'start-build': case 'start-test': + case 'start-vet': case 'start-install': case 'start-get': bottomGroup.fillOutput(data.output); break; case 'go test': + case 'go vet': case 'go install': case 'go get': bottomGroup.fillOutput($('.bottom-window-group .output > div').html() + data.output); diff --git a/views/index.html b/views/index.html index 6f8b723..c605945 100644 --- a/views/index.html +++ b/views/index.html @@ -289,7 +289,12 @@
  • {{.i18n.goinstall}} -
  • + +
  • +
  • + + {{.i18n.govet}} +