This commit is contained in:
parent
28ca0b2f94
commit
172f7f3b4f
25
conf/wide.go
25
conf/wide.go
|
@ -7,6 +7,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
_ "github.com/b3log/wide/i18n"
|
_ "github.com/b3log/wide/i18n"
|
||||||
|
@ -37,7 +38,7 @@ var Wide conf
|
||||||
var rawWide conf
|
var rawWide conf
|
||||||
|
|
||||||
// 获取 username 指定的用户的工作空间路径.
|
// 获取 username 指定的用户的工作空间路径.
|
||||||
func (this *conf) GetUserWorkspace(username string) string {
|
func (*conf) GetUserWorkspace(username string) string {
|
||||||
for _, user := range Wide.Users {
|
for _, user := range Wide.Users {
|
||||||
if user.Name == username {
|
if user.Name == username {
|
||||||
ret := strings.Replace(user.Workspace, "{Pwd}", Wide.Pwd, 1)
|
ret := strings.Replace(user.Workspace, "{Pwd}", Wide.Pwd, 1)
|
||||||
|
@ -48,6 +49,28 @@ func (this *conf) GetUserWorkspace(username string) string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取 gocode 路径.
|
||||||
|
func (*conf) GetGocode() string {
|
||||||
|
if "" != os.Getenv("GOARCH") {
|
||||||
|
return os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
|
||||||
|
runtime.GOOS + "_" + os.Getenv("GOARCH") + string(os.PathSeparator) + "gocode"
|
||||||
|
} else {
|
||||||
|
return os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
|
||||||
|
"gocode"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取 ide_stub 路径.
|
||||||
|
func (*conf) GetIDEStub() string {
|
||||||
|
if "" != os.Getenv("GOARCH") {
|
||||||
|
return os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
|
||||||
|
runtime.GOOS + "_" + os.Getenv("GOARCH") + string(os.PathSeparator) + "ide_stub"
|
||||||
|
} else {
|
||||||
|
return os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
|
||||||
|
"ide_stub"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func Save() bool {
|
func Save() bool {
|
||||||
// 只有 Users 是可以通过界面修改的,其他属性只能手工维护 wide.json 配置文件
|
// 只有 Users 是可以通过界面修改的,其他属性只能手工维护 wide.json 配置文件
|
||||||
rawWide.Users = Wide.Users
|
rawWide.Users = Wide.Users
|
||||||
|
|
|
@ -62,8 +62,7 @@ func WSHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// glog.Infof("offset: %d", offset)
|
// glog.Infof("offset: %d", offset)
|
||||||
|
|
||||||
gocode := os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
|
gocode := conf.Wide.GetGocode()
|
||||||
os.Getenv("GOOS") + "_" + os.Getenv("GOARCH") + string(os.PathSeparator) + "gocode"
|
|
||||||
argv := []string{"-f=json", "autocomplete", strconv.Itoa(offset)}
|
argv := []string{"-f=json", "autocomplete", strconv.Itoa(offset)}
|
||||||
|
|
||||||
var output bytes.Buffer
|
var output bytes.Buffer
|
||||||
|
@ -122,8 +121,7 @@ func AutocompleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
//glog.Infof("gocode set lib-path %s", libPath)
|
//glog.Infof("gocode set lib-path %s", libPath)
|
||||||
|
|
||||||
// FIXME: 使用 gocode set lib-path 在多工作空间环境下肯定是有问题的,需要考虑其他实现方式
|
// FIXME: 使用 gocode set lib-path 在多工作空间环境下肯定是有问题的,需要考虑其他实现方式
|
||||||
gocode := os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
|
gocode := conf.Wide.GetGocode()
|
||||||
os.Getenv("GOOS") + "_" + os.Getenv("GOARCH") + string(os.PathSeparator) + "gocode"
|
|
||||||
argv := []string{"set", "lib-path", libPath}
|
argv := []string{"set", "lib-path", libPath}
|
||||||
cmd := exec.Command(gocode, argv...)
|
cmd := exec.Command(gocode, argv...)
|
||||||
cmd.Start()
|
cmd.Start()
|
||||||
|
@ -200,8 +198,7 @@ func FindDeclarationHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
// glog.Infof("offset [%d]", offset)
|
// glog.Infof("offset [%d]", offset)
|
||||||
|
|
||||||
// TODO: 目前是调用 liteide_stub 工具来查找声明,后续需要重新实现
|
// TODO: 目前是调用 liteide_stub 工具来查找声明,后续需要重新实现
|
||||||
ide_stub := os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
|
ide_stub := conf.Wide.GetIDEStub()
|
||||||
os.Getenv("GOOS") + "_" + os.Getenv("GOARCH") + string(os.PathSeparator) + "ide_stub"
|
|
||||||
argv := []string{"type", "-cursor", filename + ":" + strconv.Itoa(offset), "-def", "."}
|
argv := []string{"type", "-cursor", filename + ":" + strconv.Itoa(offset), "-def", "."}
|
||||||
cmd := exec.Command(ide_stub, argv...)
|
cmd := exec.Command(ide_stub, argv...)
|
||||||
cmd.Dir = curDir
|
cmd.Dir = curDir
|
||||||
|
@ -282,8 +279,7 @@ func FindUsagesHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
offset := getCursorOffset(code, line, ch)
|
offset := getCursorOffset(code, line, ch)
|
||||||
|
|
||||||
// TODO: 目前是调用 liteide_stub 工具来查找使用,后续需要重新实现
|
// TODO: 目前是调用 liteide_stub 工具来查找使用,后续需要重新实现
|
||||||
ide_stub := os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
|
ide_stub := conf.Wide.GetIDEStub()
|
||||||
os.Getenv("GOOS") + "_" + os.Getenv("GOARCH") + string(os.PathSeparator) + "ide_stub"
|
|
||||||
argv := []string{"type", "-cursor", filename + ":" + strconv.Itoa(offset), "-use", "."}
|
argv := []string{"type", "-cursor", filename + ":" + strconv.Itoa(offset), "-use", "."}
|
||||||
cmd := exec.Command(ide_stub, argv...)
|
cmd := exec.Command(ide_stub, argv...)
|
||||||
cmd.Dir = curDir
|
cmd.Dir = curDir
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package notification
|
||||||
|
|
||||||
|
const (
|
||||||
|
EvtGOPATHNotFound = iota // 事件:找不到环境变量 $GOPATH
|
||||||
|
EvtGOROOTNotFound // 事件:找不到环境变量 $GOROOT
|
||||||
|
EvtGocodeNotFount // 事件:找不到 gocode
|
||||||
|
EvtIDEStubNotFound // 事件:找不到 IDE stub
|
||||||
|
)
|
|
@ -0,0 +1,123 @@
|
||||||
|
// 通知.
|
||||||
|
package notifications
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/b3log/wide/conf"
|
||||||
|
"github.com/b3log/wide/user"
|
||||||
|
"github.com/golang/glog"
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 通知结构.
|
||||||
|
type Notification struct {
|
||||||
|
Event int
|
||||||
|
Type string
|
||||||
|
Severity string // ERROR/WARN/INFO
|
||||||
|
Message string
|
||||||
|
}
|
||||||
|
|
||||||
|
var notificationWS = map[string]*websocket.Conn{}
|
||||||
|
|
||||||
|
func WSHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
session, _ := user.Session.Get(r, "wide-session")
|
||||||
|
username := session.Values["username"].(string)
|
||||||
|
sid := session.Values["id"].(string)
|
||||||
|
|
||||||
|
notificationWS[sid], _ = websocket.Upgrade(w, r, nil, 1024, 1024)
|
||||||
|
|
||||||
|
ret := map[string]interface{}{"output": "Notification initialized", "cmd": "init-notification"}
|
||||||
|
notificationWS[sid].WriteJSON(&ret)
|
||||||
|
|
||||||
|
glog.Infof("Open a new [Notification] with session [%s], %d", sid, len(notificationWS))
|
||||||
|
|
||||||
|
input := map[string]interface{}{}
|
||||||
|
|
||||||
|
for {
|
||||||
|
if err := notificationWS[sid].ReadJSON(&input); err != nil {
|
||||||
|
if err.Error() == "EOF" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err.Error() == "unexpected EOF" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
glog.Error("Shell WS ERROR: " + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
inputCmd := input["cmd"].(string)
|
||||||
|
|
||||||
|
cmds := strings.Split(inputCmd, "|")
|
||||||
|
commands := []*exec.Cmd{}
|
||||||
|
for _, cmdWithArgs := range cmds {
|
||||||
|
cmdWithArgs = strings.TrimSpace(cmdWithArgs)
|
||||||
|
cmdWithArgs := strings.Split(cmdWithArgs, " ")
|
||||||
|
args := []string{}
|
||||||
|
if len(cmdWithArgs) > 1 {
|
||||||
|
args = cmdWithArgs[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command(cmdWithArgs[0], args...)
|
||||||
|
commands = append(commands, cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
output := ""
|
||||||
|
if !strings.Contains(inputCmd, "clear") {
|
||||||
|
output = pipeCommands(username, commands...)
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = map[string]interface{}{"output": output, "cmd": "shell-output"}
|
||||||
|
|
||||||
|
if err := notificationWS[sid].WriteJSON(&ret); err != nil {
|
||||||
|
glog.Error("Shell WS ERROR: " + err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func pipeCommands(username string, commands ...*exec.Cmd) string {
|
||||||
|
for i, command := range commands[:len(commands)-1] {
|
||||||
|
setCmdEnv(command, username)
|
||||||
|
|
||||||
|
stdout, err := command.StdoutPipe()
|
||||||
|
if nil != err {
|
||||||
|
return err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
command.Start()
|
||||||
|
|
||||||
|
commands[i+1].Stdin = stdout
|
||||||
|
}
|
||||||
|
|
||||||
|
last := commands[len(commands)-1]
|
||||||
|
setCmdEnv(last, username)
|
||||||
|
|
||||||
|
out, err := last.CombinedOutput()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setCmdEnv(cmd *exec.Cmd, username string) {
|
||||||
|
userWorkspace := conf.Wide.GetUserWorkspace(username)
|
||||||
|
|
||||||
|
cmd.Env = append(cmd.Env,
|
||||||
|
"TERM="+os.Getenv("TERM"),
|
||||||
|
"GOPATH="+userWorkspace,
|
||||||
|
"GOOS="+runtime.GOOS,
|
||||||
|
"GOARCH="+runtime.GOARCH,
|
||||||
|
"GOROOT="+runtime.GOROOT(),
|
||||||
|
"PATH="+os.Getenv("PATH"))
|
||||||
|
|
||||||
|
cmd.Dir = userWorkspace
|
||||||
|
}
|
Loading…
Reference in New Issue