func (serv *workspace) saveConfig(request *restful.Request, response *restful.Response) { f, err := os.Create(filepath.Join(serv.Path, ".carpo.json")) if err != nil { sendError(response, http.StatusBadRequest, fmt.Errorf("Error create config: %s", err)) return } defer f.Close() defer request.Request.Body.Close() var conf interface{} err = json.NewDecoder(request.Request.Body).Decode(&conf) if err != nil { sendError(response, http.StatusBadRequest, fmt.Errorf("Error parsing config: %s", err)) return } oldgo := serv.gobinpath() serv.config = conf.(map[string]interface{}) newgo := serv.gobinpath() if bytes.Compare([]byte(*oldgo), []byte(*newgo)) != 0 { gws := builder.NewGoWorkspace(*newgo, serv.Path, serv.gocode, *serv.golint, serv.filesystems) serv.goworkspace.Shutdown() serv.goworkspace = gws } b, err := json.MarshalIndent(conf, "", " ") if err != nil { sendError(response, http.StatusBadRequest, fmt.Errorf("Error writing config: %s", err)) return } f.Write(b) //json.NewEncoder(f).Encode(conf) }
func NewWorkspace(path string, version string) error { if !filepath.IsAbs(path) { workdir, err := os.Getwd() if err != nil { return fmt.Errorf("cannot get current workingdir: %s", err) } path = filepath.Join(workdir, path) } os.Mkdir(filepath.Join(path, "src"), 0755) os.Mkdir(filepath.Join(path, "pkg"), 0755) os.Mkdir(filepath.Join(path, "bin"), 0755) plugindir := filepath.Join(path, ".carpoplugins") err := os.Mkdir(plugindir, 0755) if err != nil && !os.IsExist(err) { workspaceLogger.Criticalf("cannot create subdirectory '.carpoplugins': %s", err) } else { os.Mkdir(filepath.Join(plugindir, "src"), 0755) os.Mkdir(filepath.Join(plugindir, "pkg"), 0755) os.Mkdir(filepath.Join(plugindir, "bin"), 0755) } w := workspace{ Version: version, Path: path, plugindir: plugindir, gotool: nil, goapptool: nil, gocode: nil, goimports: nil, goworkspace: nil, config: nil, processes: make(map[int]*os.Process), debugSession: make(map[int]*gdbmi.GDB), proclock: new(sync.Mutex), filesystems: make(map[string]filesystem.WorkspaceFS), } w.loadConfiguration() //w.processes = make(map[int]*os.Process) //w.debugSession = make(map[int]*gdbmi.GDB) gopath, err := exec.LookPath("go") if err != nil { workspaceLogger.Infof("no go tool found in path: %s", err) } else { w.gotool = &gopath workspaceLogger.Infof("go: %s", *w.gotool) } goapppath, err := exec.LookPath("goapp") if err != nil { workspaceLogger.Infof("no goapp tool found in path: %s", err) } else { w.goapptool = &goapppath workspaceLogger.Infof("goapp: %s", *w.goapptool) } gobinpath := w.gobinpath() if gobinpath != nil { workspaceLogger.Infof("Workspace uses %s as go", *gobinpath) } else { if gopath != "" { gobinpath = &gopath } else { return errors.New("Workspace uses nothing as go, no 'goapp' or 'go' als failover found") } } gws := builder.NewGoWorkspace(*gobinpath, path, w.gocode, plugindir, w.filesystems) w.goworkspace = gws tools := []tool{ {"github.com/nsf/gocode", "gocode", &w.gocode}, {"github.com/golang/lint/golint", "golint", &w.golint}, } var wg sync.WaitGroup for _, at := range tools { wg.Add(1) go func(t tool) { workspaceLogger.Infof("update/install %s in pluginpath", t.cmd) gt, err := gws.InstallPlugin(plugindir, t.pack, t.cmd) if err == nil { *t.targ = gt } else { workspaceLogger.Infof("%s cannot be installed: %s", t.pack, err) } wg.Done() }(at) } wg.Add(1) go func() { // install these tools sequential because the use the same repo and // a parallel installation will invoke parallel 'git' commands in the // same local repo toolsGolang := []tool{ {"golang.org/x/tools/cmd/goimports", "goimports", &w.goimports}, {"golang.org/x/tools/cmd/oracle", "oracle", &w.gooracle}, } for _, t := range toolsGolang { workspaceLogger.Infof("update/install %s in pluginpath", t.cmd) gt, err := gws.InstallPlugin(plugindir, t.pack, t.cmd) if err == nil { *t.targ = gt } else { workspaceLogger.Infof("%s cannot be installed: %s", t.pack, err) } } wg.Done() }() wg.Wait() workspaceLogger.Infof("Workspace initialized") wsContainer := restful.NewContainer() w.register(wsContainer) http.Handle("/workspace/", logged(wsContainer)) http.Handle("/launch/", logged(websocket.Handler(launchProcessHandler(&w)))) http.Handle("/debugconsole/", logged(websocket.Handler(debugConsoleHandler(&w)))) http.Handle("/debug/", logged(websocket.Handler(debugProcessHandler(&w)))) //http.Handle("/wsworkspace", logged(websocket.Handler(workspaceHandler(&w)))) return nil }