Build & Run

This commit is contained in:
Liang Ding 2014-08-22 11:57:05 +08:00
parent efe527c1fd
commit a5b2ecb5a5
5 changed files with 139 additions and 29 deletions

View File

@ -40,6 +40,7 @@ func main() {
http.HandleFunc("/", indexHandler)
http.HandleFunc("/build", output.BuildHandler)
http.HandleFunc("/run", output.RunHandler)
http.HandleFunc("/output/ws", output.WSHandler)

View File

@ -10,6 +10,8 @@ import (
"net/http"
"os"
"os/exec"
"runtime"
"strings"
)
var outputWS = map[string]*websocket.Conn{}
@ -41,31 +43,11 @@ func RunHandler(w http.ResponseWriter, r *http.Request) {
return
}
filePath := args["file"].(string)
filePath := args["executable"].(string)
curDir := filePath[:strings.LastIndex(filePath, string(os.PathSeparator))]
fout, err := os.Create(filePath)
if nil != err {
glog.Error(err)
http.Error(w, err.Error(), 500)
return
}
code := args["code"].(string)
fout.WriteString(code)
if err := fout.Close(); nil != err {
glog.Error(err)
http.Error(w, err.Error(), 500)
return
}
argv := []string{"run", filePath}
cmd := exec.Command("go", argv...)
cmd := exec.Command(filePath)
cmd.Dir = curDir
stdout, err := cmd.StdoutPipe()
if nil != err {
@ -119,3 +101,104 @@ func RunHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write(ret)
}
func BuildHandler(w http.ResponseWriter, r *http.Request) {
session, _ := session.Store.Get(r, "wide-session")
sid := session.Values["id"].(string)
decoder := json.NewDecoder(r.Body)
var args map[string]interface{}
if err := decoder.Decode(&args); err != nil {
glog.Error(err)
http.Error(w, err.Error(), 500)
return
}
filePath := args["file"].(string)
curDir := filePath[:strings.LastIndex(filePath, string(os.PathSeparator))]
fout, err := os.Create(filePath)
if nil != err {
glog.Error(err)
http.Error(w, err.Error(), 500)
return
}
code := args["code"].(string)
fout.WriteString(code)
if err := fout.Close(); nil != err {
glog.Error(err)
http.Error(w, err.Error(), 500)
return
}
suffix := ""
if "windows" == runtime.GOOS {
suffix = ".exe"
}
executable := "main" + suffix
argv := []string{"build", "-o", executable, filePath}
cmd := exec.Command("go", argv...)
cmd.Dir = curDir
glog.Info("go build ", filePath)
stdout, err := cmd.StdoutPipe()
if nil != err {
glog.Error(err)
http.Error(w, err.Error(), 500)
return
}
stderr, err := cmd.StderrPipe()
if nil != err {
glog.Error(err)
http.Error(w, err.Error(), 500)
return
}
reader := io.MultiReader(stdout, stderr)
cmd.Start()
go func(runningId int) {
glog.Infof("Session [%s] is building [id=%d, file=%s]", sid, runningId, filePath)
// 一次性读取
buf := make([]byte, 1024*8)
count, _ := reader.Read(buf)
channelRet := map[string]interface{}{}
channelRet["output"] = string(buf[:count])
channelRet["cmd"] = "build"
channelRet["nextCmd"] = "run"
channelRet["executable"] = curDir + string(os.PathSeparator) + executable
if nil != outputWS[sid] {
glog.Infof("Session [%s] 's build [id=%d, file=%s] has done", sid, runningId, filePath)
err := outputWS[sid].WriteJSON(&channelRet)
if nil != err {
glog.Error(err)
}
}
}(rand.Int())
ret, _ := json.Marshal(map[string]interface{}{"succ": true})
w.Header().Set("Content-Type", "application/json")
w.Write(ret)
}

View File

@ -74,5 +74,5 @@ ul {
}
.shellOutput {
height: 125px;
height: 80px;
}

View File

@ -5,9 +5,30 @@ outputWS.onopen = function() {
outputWS.onmessage = function(e) {
console.log('[output onmessage]' + e.data);
var data = JSON.parse(e.data);
if ('init-output' !== data.cmd) {
$('#output').val($('#output').val() + data.output);
}
if ('build' == data.cmd) {
if ('run' === data.nextCmd) {
var request = {
"executable": data.executable
};
$.ajax({
type: 'POST',
url: '/run',
data: JSON.stringify(request),
dataType: "json",
beforeSend: function(data) {
$('#output').val('');
},
success: function(data) {
}
});
}
}
};
outputWS.onclose = function(e) {
console.log('[output onclose] disconnected (' + e.code + ')');
@ -80,16 +101,21 @@ var wide = {
"file": wide.curNode.path,
"code": wide.curEditor.getValue()
};
$.ajax({
type: 'POST',
url: '/run',
url: '/build',
data: JSON.stringify(request),
dataType: "json",
beforeSend: function(data) {
$('#output').val('');
},
success: function(data) {
console.log(data);
executable = data.executable;
if (data.succ) {
}
}
});
},

View File

@ -40,7 +40,7 @@
<div>
<button id="saveBtn" onclick="wide.save()">Save</button>
<button id="fmtBtn" onclick="wide.fmt()">Format</button>
<button id="runBtn" onclick="wide.run()">Run</button>
<button id="runBtn" onclick="wide.run()">Build & Run</button>
</div>
<div>