func (ws *GoWorkspace) search(def filesystem.WorkspaceFS, cwd, pt string) (filesystem.WorkspaceFS, string, error) { if strings.HasPrefix(pt, "../src") { return def, pt[2:], nil } if strings.HasPrefix(pt, def.Base()) { return def, pt[len(def.Base()):], nil } abspath := filepath.Clean(filepath.Join(cwd, pt)) for _, wfs := range ws.filesystems { if strings.HasPrefix(abspath, wfs.Base()) { return wfs, abspath[len(wfs.Base()):], nil } } return nil, "", fmt.Errorf("cannot find %s/%s in filesystems", cwd, pt) }
func appendTokenPosition(fs filesystem.WorkspaceFS, ar []TokenPosition, pos token.Position, name, target string, tt TokenType) []TokenPosition { pt := pos.Filename var fsname string if fs != nil { fsname = fs.Name() if pat, err := filepath.Rel(fs.Base(), pos.Filename); err == nil { pt = pat } else { buildLogger.Errorf("Path is not relative to Filesystem: %s", err) } } tp := TokenPosition{Type: tt, Source: "/" + pt, Name: name, Target: target, Line: pos.Line, Offset: pos.Offset, Column: pos.Column, Filesystem: fsname, Filename: filepath.Base(pos.Filename), Package: "/" + filepath.Dir(pt)} return append(ar, tp) }
func (ws *GoWorkspace) parseBuildTypedOutput(base filesystem.WorkspaceFS, output string, etype BuildResultType) []BuildResult { var res []BuildResult resultset := make(map[BuildResult]bool) lines := strings.Split(output, "\n") for _, l := range lines { if strings.HasPrefix(l, "#") { continue } l = strings.TrimSpace(l) b := []byte(l) if strings.HasPrefix(l, goerr_cantloadpackage) { b = []byte(l[len(goerr_cantloadpackage):]) } m := build_line.FindSubmatch(b) if m != nil { var br BuildResult br.Original = l br.Source = string(m[1]) br.Type = etype fs, pt, err := ws.search(base, ws.Workdir, br.Source) if err != nil { buildLogger.Errorf("cannot parse buildresult : %s", err) br.File = br.Source } else { br.File = pt br.Filesystem = fs.Name() } // we always work in a subdirectory named ".carpowork", so strip the ".." from the filepath br.Directory = filepath.Dir(br.File) pt, err = ws.findPackageFromDirectory(filepath.Join(base.Base(), br.Directory)) if err != nil { buildLogger.Errorf("cannot find package for directory '%s': %s", br.Directory, err) } else { br.PackageImportPath = pt } br.Message = string(m[len(m)-1]) sourceline := strings.Split(string(m[2]), ":")[0] ln, err := strconv.ParseInt(sourceline, 10, 0) if err != nil { buildLogger.Errorf("Compiler output line cannot be parsed as INT: Output=%s, Message=%s\n", l, err) } else { br.Line = int(ln) } if _, ok := resultset[br]; !ok { // do not append the same message twice. this can happen, because wie build packages AND their tests res = append(res, br) } } else { if len(res) > 0 { l = strings.TrimSpace(l) if len(l) > 0 { last := &res[len(res)-1] last.Original = last.Original + " " + l last.Message = last.Message + " " + l } } } } // now parse output return res }