func getGolangDoc(importPath, etag string) (*Package, error) { match := map[string]string{ "cred": setting.GitHubCredentials, } // Check revision. commit, err := getGithubRevision("github.com/golang/go") if err != nil { return nil, fmt.Errorf("get revision: %v", err) } if commit == etag { return nil, ErrPackageNotModified } // Get files. var tree struct { Tree []struct { Url string Path string Type string } Url string } if err := com.HttpGetJSON(Client, com.Expand("https://api.github.com/repos/golang/go/git/trees/master?recursive=1&{cred}", match), &tree); err != nil { return nil, fmt.Errorf("get tree: %v", err) } dirPrefix := "src/" + importPath + "/" dirLevel := len(strings.Split(dirPrefix, "/")) dirLength := len(dirPrefix) dirMap := make(map[string]bool) files := make([]com.RawFile, 0, 10) for _, node := range tree.Tree { // Skip directories and files in irrelevant directories. if node.Type != "blob" || !strings.HasPrefix(node.Path, dirPrefix) { continue } // Get files and check if directories have acceptable files. if d, f := path.Split(node.Path); IsDocFile(f) { // Check if file is in the directory that is corresponding to import path. if d == dirPrefix { files = append(files, &Source{ SrcName: f, BrowseUrl: com.Expand("github.com/golang/go/blob/master/{0}", nil, node.Path), RawSrcUrl: com.Expand("https://raw.github.com/golang/go/master/{0}?{1}", nil, node.Path, setting.GitHubCredentials), }) continue } // Otherwise, check if it's a direct sub-directory of import path. if len(strings.Split(d, "/"))-dirLevel == 1 { dirMap[d[dirLength:len(d)-1]] = true continue } } } dirs := base.MapToSortedStrings(dirMap) if len(files) == 0 && len(dirs) == 0 { return nil, ErrPackageNoGoFile } else if err := com.FetchFiles(Client, files, githubRawHeader); err != nil { return nil, fmt.Errorf("fetch files: %v", err) } // Start generating data. w := &Walker{ LineFmt: "#L%d", Pdoc: &Package{ PkgInfo: &models.PkgInfo{ ImportPath: importPath, ProjectPath: "github.com/golang/go", ViewDirPath: "github.com/golang/go/tree/master/src/" + importPath, Etag: commit, IsGoRepo: true, Subdirs: strings.Join(dirs, "|"), }, }, } srcs := make([]*Source, 0, len(files)) srcMap := make(map[string]*Source) for _, f := range files { s := f.(*Source) srcs = append(srcs, s) if !strings.HasSuffix(f.Name(), "_test.go") { srcMap[f.Name()] = s } } pdoc, err := w.Build(&WalkRes{ WalkDepth: WD_All, WalkType: WT_Memory, WalkMode: WM_All, Srcs: srcs, }) if err != nil { return nil, fmt.Errorf("walk package: %v", err) } return pdoc, nil }
func getGithubDoc(match map[string]string, etag string) (*Package, error) { match["cred"] = setting.GitHubCredentials // Check revision. commit, err := getGithubRevision(com.Expand("github.com/{owner}/{repo}", match)) if err != nil { return nil, fmt.Errorf("get revision: %v", err) } if commit == etag { return nil, ErrPackageNotModified } // Get files. var tree struct { Tree []struct { Url string Path string Type string } Url string } if err := com.HttpGetJSON(Client, com.Expand("https://api.github.com/repos/{owner}/{repo}/git/trees/master?recursive=1&{cred}", match), &tree); err != nil { return nil, fmt.Errorf("get tree: %v", err) } // Because Github API URLs are case-insensitive, we need to check that the // userRepo returned from Github matches the one that we are requesting. if !strings.HasPrefix(tree.Url, com.Expand("https://api.github.com/repos/{owner}/{repo}/", match)) { return nil, errors.New("GitHub import path has incorrect case") } // Get source file data and subdirectories. dirPrefix := match["dir"] if dirPrefix != "" { dirPrefix = dirPrefix[1:] + "/" } dirLevel := len(strings.Split(dirPrefix, "/")) dirLength := len(dirPrefix) dirMap := make(map[string]bool) files := make([]com.RawFile, 0, 10) for _, node := range tree.Tree { // Skip directories and files in wrong directories, get them later. if node.Type != "blob" || !strings.HasPrefix(node.Path, dirPrefix) { continue } // Get files and check if directories have acceptable files. if d, f := path.Split(node.Path); IsDocFile(f) { // Check if file is in the directory that is corresponding to import path. if d == dirPrefix { files = append(files, &Source{ SrcName: f, BrowseUrl: com.Expand("github.com/{owner}/{repo}/blob/master/{0}", match, node.Path), RawSrcUrl: com.Expand("https://raw.github.com/{owner}/{repo}/master/{0}?{1}", match, node.Path, setting.GitHubCredentials), }) continue } // Otherwise, check if it's a direct sub-directory of import path. if len(strings.Split(d, "/"))-dirLevel == 1 { dirMap[d[dirLength:len(d)-1]] = true continue } } } dirs := base.MapToSortedStrings(dirMap) if len(files) == 0 && len(dirs) == 0 { return nil, ErrPackageNoGoFile } else if err := com.FetchFiles(Client, files, githubRawHeader); err != nil { return nil, fmt.Errorf("fetch files: %v", err) } // Start generating data. w := &Walker{ LineFmt: "#L%d", Pdoc: &Package{ PkgInfo: &models.PkgInfo{ ImportPath: match["importPath"], ProjectPath: com.Expand("github.com/{owner}/{repo}", match), ViewDirPath: com.Expand("github.com/{owner}/{repo}/tree/master/{importPath}", match), Etag: commit, Subdirs: strings.Join(dirs, "|"), }, }, } srcs := make([]*Source, 0, len(files)) srcMap := make(map[string]*Source) for _, f := range files { s, _ := f.(*Source) srcs = append(srcs, s) if !strings.HasSuffix(f.Name(), "_test.go") { srcMap[f.Name()] = s } } pdoc, err := w.Build(&WalkRes{ WalkDepth: WD_All, WalkType: WT_Memory, WalkMode: WM_All, Srcs: srcs, }) if err != nil { return nil, fmt.Errorf("error walking package: %v", err) } return pdoc, nil }