Merge remote-tracking branch 'refs/remotes/origin/1.5.3-dev'

This commit is contained in:
Liang Ding 2017-03-15 23:27:06 +08:00
commit 4a4788be85
9 changed files with 183 additions and 120 deletions

View File

@ -59,6 +59,7 @@ type User struct {
Workspace string // the GOPATH of this user (maybe contain several paths splitted by os.PathListSeparator) Workspace string // the GOPATH of this user (maybe contain several paths splitted by os.PathListSeparator)
Locale string Locale string
GoFormat string GoFormat string
GoBuildArgs string
FontFamily string FontFamily string
FontSize string FontSize string
Theme string Theme string
@ -91,7 +92,7 @@ func NewUser(username, password, email, workspace string) *User {
now := time.Now().UnixNano() now := time.Now().UnixNano()
return &User{Name: username, Password: password, Salt: salt, Email: email, Gravatar: gravatar, Workspace: workspace, return &User{Name: username, Password: password, Salt: salt, Email: email, Gravatar: gravatar, Workspace: workspace,
Locale: Wide.Locale, GoFormat: "gofmt", FontFamily: "Helvetica", FontSize: "13px", Theme: "default", Locale: Wide.Locale, GoFormat: "gofmt", GoBuildArgs: "-i", FontFamily: "Helvetica", FontSize: "13px", Theme: "default",
Keymap: "wide", Keymap: "wide",
Created: now, Updated: now, Lived: now, Created: now, Updated: now, Lived: now,
Editor: &editor{FontFamily: "Consolas, 'Courier New', monospace", FontSize: "inherit", LineHeight: "17px", Editor: &editor{FontFamily: "Consolas, 'Courier New', monospace", FontSize: "inherit", LineHeight: "17px",

View File

@ -7,6 +7,7 @@
"Workspace": "${GOPATH}", "Workspace": "${GOPATH}",
"Locale": "en_US", "Locale": "en_US",
"GoFormat": "gofmt", "GoFormat": "gofmt",
"GoBuildArgs": "-i",
"FontFamily": "Helvetica", "FontFamily": "Helvetica",
"FontSize": "13px", "FontSize": "13px",
"Theme": "default", "Theme": "default",
@ -18,20 +19,15 @@
"FontFamily": "Consolas, 'Courier New', monospace", "FontFamily": "Consolas, 'Courier New', monospace",
"FontSize": "13px", "FontSize": "13px",
"LineHeight": "17px", "LineHeight": "17px",
"Theme": "lesser-dark", "Theme": "wide",
"TabSize": "4" "TabSize": "4"
}, },
"LatestSessionContent": { "LatestSessionContent": {
"fileTree": [ "fileTree": [
"/Users/Vanessa/Work/GoGoGo/src",
"/Users/Vanessa/Work/GoGoGo/src/github.com",
"/Users/Vanessa/Work/GoGoGo/src/github.com/b3log",
"/Users/Vanessa/Work/GoGoGo/src/github.com/b3log/wide"
], ],
"files": [ "files": [
"/Users/Vanessa/Work/GoGoGo/src/github.com/b3log/wide/.gitignore"
], ],
"currentFile": "/Users/Vanessa/Work/GoGoGo/src/github.com/b3log/wide/.gitignore", "currentFile": "",
"layout": { "layout": {
"side": { "side": {
"state": "normal", "state": "normal",

View File

@ -137,6 +137,11 @@ func initUsers() {
user.Keymap = "wide" user.Keymap = "wide"
} }
// Compatibility upgrade (1.5.3): https://github.com/b3log/wide/issues/308
if "" == user.GoBuildArgs {
user.GoBuildArgs = "-i"
}
Users = append(Users, user) Users = append(Users, user)
} }

View File

@ -18,8 +18,6 @@ import (
"bufio" "bufio"
"encoding/json" "encoding/json"
"io" "io"
"io/ioutil"
"math/rand"
"net/http" "net/http"
"os" "os"
"os/exec" "os/exec"
@ -45,7 +43,8 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
username := httpSession.Values["username"].(string) username := httpSession.Values["username"].(string)
locale := conf.GetUser(username).Locale user := conf.GetUser(username)
locale := user.Locale
var args map[string]interface{} var args map[string]interface{}
@ -93,7 +92,11 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
suffix = ".exe" suffix = ".exe"
} }
cmd := exec.Command("go", "build") goBuildArgs := []string{}
goBuildArgs = append(goBuildArgs, "build")
goBuildArgs = append(goBuildArgs, strings.Split(user.GoBuildArgs, " ")...)
cmd := exec.Command("go", goBuildArgs...)
cmd.Dir = curDir cmd.Dir = curDir
setCmdEnv(cmd, username) setCmdEnv(cmd, username)
@ -126,7 +129,10 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
if nil != session.OutputWS[sid] { if nil != session.OutputWS[sid] {
// display "START [go build]" in front-end browser // display "START [go build]" in front-end browser
channelRet["output"] = "<span class='start-build'>" + i18n.Get(locale, "start-build").(string) + "</span>\n" msg := i18n.Get(locale, "start-build").(string)
msg = strings.Replace(msg, "build]", "build "+user.GoBuildArgs+"]", 1)
channelRet["output"] = "<span class='start-build'>" + msg + "</span>\n"
channelRet["cmd"] = "start-build" channelRet["cmd"] = "start-build"
wsChannel := session.OutputWS[sid] wsChannel := session.OutputWS[sid]
@ -140,8 +146,6 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
wsChannel.Refresh() wsChannel.Refresh()
} }
reader := bufio.NewReader(io.MultiReader(stdout, stderr))
if err := cmd.Start(); nil != err { if err := cmd.Start(); nil != err {
logger.Error(err) logger.Error(err)
result.Succ = false result.Succ = false
@ -149,20 +153,81 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
return return
} }
go func(runningId int) {
defer util.Recover()
defer cmd.Wait()
// logger.Debugf("User [%s, %s] is building [id=%d, dir=%s]", username, sid, runningId, curDir) // logger.Debugf("User [%s, %s] is building [id=%d, dir=%s]", username, sid, runningId, curDir)
// read all
buf, _ := ioutil.ReadAll(reader)
channelRet := map[string]interface{}{}
channelRet["cmd"] = "build" channelRet["cmd"] = "build"
channelRet["executable"] = executable channelRet["executable"] = executable
if 0 == len(buf) { // build success outReader := bufio.NewReader(stdout)
/////////
go func() {
defer util.Recover()
for {
wsChannel := session.OutputWS[sid]
if nil == wsChannel {
break
}
line, err := outReader.ReadString('\n')
if io.EOF == err {
break
}
if nil != err {
logger.Warn(err)
break
}
channelRet["output"] = line
err = wsChannel.WriteJSON(&channelRet)
if nil != err {
logger.Warn(err)
break
}
wsChannel.Refresh()
}
}()
errReader := bufio.NewReader(stderr)
lines := []string{}
for {
wsChannel := session.OutputWS[sid]
if nil == wsChannel {
break
}
line, err := errReader.ReadString('\n')
if io.EOF == err {
break
}
lines = append(lines, line)
if nil != err {
logger.Warn(err)
break
}
// path process
errOutWithPath := parsePath(curDir, line)
channelRet["output"] = "<span class='stderr'>" + errOutWithPath + "</span>"
err = wsChannel.WriteJSON(&channelRet)
if nil != err {
logger.Warn(err)
break
}
wsChannel.Refresh()
}
if nil == cmd.Wait() {
channelRet["nextCmd"] = args["nextCmd"] channelRet["nextCmd"] = args["nextCmd"]
channelRet["output"] = "<span class='build-succ'>" + i18n.Get(locale, "build-succ").(string) + "</span>\n" channelRet["output"] = "<span class='build-succ'>" + i18n.Get(locale, "build-succ").(string) + "</span>\n"
@ -179,23 +244,11 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
logger.Warn(string(out)) logger.Warn(string(out))
} }
}() }()
} else { // build error } else {
// build gutter lint channelRet["output"] = "<span class='build-error'>" + i18n.Get(locale, "build-error").(string) + "</span>\n"
errOut := string(buf)
lines := strings.Split(errOut, "\n")
// path process
var errOutWithPath string
for _, line := range lines {
errOutWithPath += parsePath(curDir, line) + "\n"
}
channelRet["output"] = "<span class='build-error'>" + i18n.Get(locale, "build-error").(string) + "</span>\n" +
"<span class='stderr'>" + errOutWithPath + "</span>"
logger.Info(lines)
// lint process // lint process
if lines[0][0] == '#' { if lines[0][0] == '#' {
lines = lines[1:] // skip the first line lines = lines[1:] // skip the first line
} }
@ -203,7 +256,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
lints := []*Lint{} lints := []*Lint{}
for _, line := range lines { for _, line := range lines {
if len(line) < 1 { if len(line) < 1 || !strings.Contains(line, ":") {
continue continue
} }
@ -234,7 +287,7 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
} }
lint := &Lint{ lint := &Lint{
File: filepath.Join(curDir, file), File: filepath.ToSlash(filepath.Join(curDir, file)),
LineNo: lineNo - 1, LineNo: lineNo - 1,
Severity: lintSeverityError, Severity: lintSeverityError,
Msg: msg, Msg: msg,
@ -246,17 +299,14 @@ func BuildHandler(w http.ResponseWriter, r *http.Request) {
channelRet["lints"] = lints channelRet["lints"] = lints
} }
if nil != session.OutputWS[sid] {
// logger.Debugf("User [%s, %s] 's build [id=%d, dir=%s] has done", username, sid, runningId, curDir)
wsChannel := session.OutputWS[sid] wsChannel := session.OutputWS[sid]
err := wsChannel.WriteJSON(&channelRet) if nil == wsChannel {
return
}
err = wsChannel.WriteJSON(&channelRet)
if nil != err { if nil != err {
logger.Warn(err) logger.Warn(err)
} }
wsChannel.Refresh() wsChannel.Refresh()
} }
}(rand.Int())
}

View File

@ -93,7 +93,7 @@ func parsePath(curDir, outputLine string) string {
column = parts[2] column = parts[2]
} }
tagStart := `<span class="path" data-path="` + filepath.Join(curDir, file) + `" data-line="` + line + tagStart := `<span class="path" data-path="` + filepath.ToSlash(filepath.Join(curDir, file)) + `" data-line="` + line +
`" data-column="` + column + `">` `" data-column="` + column + `">`
text := file + ":" + line text := file + ":" + line
if hasColumn { if hasColumn {

View File

@ -95,6 +95,7 @@ func PreferenceHandler(w http.ResponseWriter, r *http.Request) {
FontFamily string FontFamily string
FontSize string FontSize string
GoFmt string GoFmt string
GoBuildArgs string
Keymap string Keymap string
Workspace string Workspace string
Username string Username string
@ -119,6 +120,7 @@ func PreferenceHandler(w http.ResponseWriter, r *http.Request) {
user.FontFamily = args.FontFamily user.FontFamily = args.FontFamily
user.FontSize = args.FontSize user.FontSize = args.FontSize
user.GoFormat = args.GoFmt user.GoFormat = args.GoFmt
user.GoBuildArgs = args.GoBuildArgs
user.Keymap = args.Keymap user.Keymap = args.Keymap
// XXX: disallow change workspace at present // XXX: disallow change workspace at present
// user.Workspace = args.Workspace // user.Workspace = args.Workspace

View File

@ -19,7 +19,7 @@
* *
* @author <a href="http://vanessa.b3log.org">Liyuan Li</a> * @author <a href="http://vanessa.b3log.org">Liyuan Li</a>
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.0.1, Dec 8, 2015 * @version 1.1.1.1, Mar 15, 2017
*/ */
var bottomGroup = { var bottomGroup = {
tabs: undefined, tabs: undefined,
@ -82,6 +82,7 @@ var bottomGroup = {
fillOutput: function (data) { fillOutput: function (data) {
var $output = $('.bottom-window-group .output'); var $output = $('.bottom-window-group .output');
data = data.replace(/\r/g, '');
data = data.replace(/\n/g, '<br/>'); data = data.replace(/\n/g, '<br/>');
if (-1 !== data.indexOf("<br/>")) { if (-1 !== data.indexOf("<br/>")) {

View File

@ -19,7 +19,7 @@
* *
* @author <a href="http://vanessa.b3log.org">Liyuan Li</a> * @author <a href="http://vanessa.b3log.org">Liyuan Li</a>
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.1, Dec 8, 2015 * @version 1.0.1.1, Mar 15, 2017
*/ */
var menu = { var menu = {
init: function () { init: function () {
@ -313,10 +313,11 @@ var menu = {
dataType: "json", dataType: "json",
beforeSend: function () { beforeSend: function () {
bottomGroup.resetOutput(); bottomGroup.resetOutput();
},
success: function (result) {
$("#buildRun").addClass("ico-stop") $("#buildRun").addClass("ico-stop")
.removeClass("ico-buildrun").attr("title", config.label.stop); .removeClass("ico-buildrun").attr("title", config.label.stop);
},
success: function (result) {
} }
}); });
}, },
@ -424,6 +425,7 @@ var menu = {
$fontFamily = $dialogPreference.find("input[name=fontFamily]"), $fontFamily = $dialogPreference.find("input[name=fontFamily]"),
$fontSize = $dialogPreference.find("input[name=fontSize]"), $fontSize = $dialogPreference.find("input[name=fontSize]"),
$goFmt = $dialogPreference.find("select[name=goFmt]"), $goFmt = $dialogPreference.find("select[name=goFmt]"),
$goBuildArgs = $dialogPreference.find("input[name=goBuildArgs]"),
$workspace = $dialogPreference.find("input[name=workspace]"), $workspace = $dialogPreference.find("input[name=workspace]"),
$password = $dialogPreference.find("input[name=password]"), $password = $dialogPreference.find("input[name=password]"),
$email = $dialogPreference.find("input[name=email]"), $email = $dialogPreference.find("input[name=email]"),
@ -440,6 +442,7 @@ var menu = {
"fontFamily": $fontFamily.val(), "fontFamily": $fontFamily.val(),
"fontSize": $fontSize.val(), "fontSize": $fontSize.val(),
"goFmt": $goFmt.val(), "goFmt": $goFmt.val(),
"goBuildArgs": $goBuildArgs.val(),
"workspace": $workspace.val(), "workspace": $workspace.val(),
"password": $password.val(), "password": $password.val(),
"email": $email.val(), "email": $email.val(),
@ -469,6 +472,7 @@ var menu = {
$fontFamily.data("value", $fontFamily.val()); $fontFamily.data("value", $fontFamily.val());
$fontSize.data("value", $fontSize.val()); $fontSize.data("value", $fontSize.val());
$goFmt.data("value", $goFmt.val()); $goFmt.data("value", $goFmt.val());
$goBuildArgs.data("value", $goBuildArgs.val());
$workspace.data("value", $workspace.val()); $workspace.data("value", $workspace.val());
$password.data("value", $password.val()); $password.data("value", $password.val());
$email.data("value", $email.val()); $email.data("value", $email.val());

View File

@ -70,6 +70,10 @@
{{end}} {{end}}
</select> </select>
</label> </label>
<label>
Go Build Args{{.i18n.colon}}
<input data-value="{{.user.GoBuildArgs}}" value="{{.user.GoBuildArgs}}" name="goBuildArgs"/>
</label>
</div> </div>
<div class="fn-none" data-index="keymap"> <div class="fn-none" data-index="keymap">
<label> <label>