This commit is contained in:
parent
28ca0b2f94
commit
172f7f3b4f
25
conf/wide.go
25
conf/wide.go
|
@ -7,6 +7,7 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
_ "github.com/b3log/wide/i18n"
|
||||
|
@ -37,7 +38,7 @@ var Wide conf
|
|||
var rawWide conf
|
||||
|
||||
// 获取 username 指定的用户的工作空间路径.
|
||||
func (this *conf) GetUserWorkspace(username string) string {
|
||||
func (*conf) GetUserWorkspace(username string) string {
|
||||
for _, user := range Wide.Users {
|
||||
if user.Name == username {
|
||||
ret := strings.Replace(user.Workspace, "{Pwd}", Wide.Pwd, 1)
|
||||
|
@ -48,6 +49,28 @@ func (this *conf) GetUserWorkspace(username string) string {
|
|||
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 {
|
||||
// 只有 Users 是可以通过界面修改的,其他属性只能手工维护 wide.json 配置文件
|
||||
rawWide.Users = Wide.Users
|
||||
|
|
|
@ -62,8 +62,7 @@ func WSHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// glog.Infof("offset: %d", offset)
|
||||
|
||||
gocode := os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
|
||||
os.Getenv("GOOS") + "_" + os.Getenv("GOARCH") + string(os.PathSeparator) + "gocode"
|
||||
gocode := conf.Wide.GetGocode()
|
||||
argv := []string{"-f=json", "autocomplete", strconv.Itoa(offset)}
|
||||
|
||||
var output bytes.Buffer
|
||||
|
@ -122,8 +121,7 @@ func AutocompleteHandler(w http.ResponseWriter, r *http.Request) {
|
|||
//glog.Infof("gocode set lib-path %s", libPath)
|
||||
|
||||
// FIXME: 使用 gocode set lib-path 在多工作空间环境下肯定是有问题的,需要考虑其他实现方式
|
||||
gocode := os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
|
||||
os.Getenv("GOOS") + "_" + os.Getenv("GOARCH") + string(os.PathSeparator) + "gocode"
|
||||
gocode := conf.Wide.GetGocode()
|
||||
argv := []string{"set", "lib-path", libPath}
|
||||
cmd := exec.Command(gocode, argv...)
|
||||
cmd.Start()
|
||||
|
@ -200,8 +198,7 @@ func FindDeclarationHandler(w http.ResponseWriter, r *http.Request) {
|
|||
// glog.Infof("offset [%d]", offset)
|
||||
|
||||
// TODO: 目前是调用 liteide_stub 工具来查找声明,后续需要重新实现
|
||||
ide_stub := os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
|
||||
os.Getenv("GOOS") + "_" + os.Getenv("GOARCH") + string(os.PathSeparator) + "ide_stub"
|
||||
ide_stub := conf.Wide.GetIDEStub()
|
||||
argv := []string{"type", "-cursor", filename + ":" + strconv.Itoa(offset), "-def", "."}
|
||||
cmd := exec.Command(ide_stub, argv...)
|
||||
cmd.Dir = curDir
|
||||
|
@ -282,8 +279,7 @@ func FindUsagesHandler(w http.ResponseWriter, r *http.Request) {
|
|||
offset := getCursorOffset(code, line, ch)
|
||||
|
||||
// TODO: 目前是调用 liteide_stub 工具来查找使用,后续需要重新实现
|
||||
ide_stub := os.Getenv("GOPATH") + string(os.PathSeparator) + "bin" + string(os.PathSeparator) +
|
||||
os.Getenv("GOOS") + "_" + os.Getenv("GOARCH") + string(os.PathSeparator) + "ide_stub"
|
||||
ide_stub := conf.Wide.GetIDEStub()
|
||||
argv := []string{"type", "-cursor", filename + ":" + strconv.Itoa(offset), "-use", "."}
|
||||
cmd := exec.Command(ide_stub, argv...)
|
||||
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