walkTree enumerates files by fetching each tree level individually, avoiding the truncation limit of the recursive tree API. Recursion depth is bounded by maxTreeDepth to prevent unbounded API calls.
(client *api.Client, host, owner, repo, sha, prefix string, depth int)
| 838 | // avoiding the truncation limit of the recursive tree API. Recursion |
| 839 | // depth is bounded by maxTreeDepth to prevent unbounded API calls. |
| 840 | func walkTree(client *api.Client, host, owner, repo, sha, prefix string, depth int) ([]SkillFile, error) { |
| 841 | if depth > maxTreeDepth { |
| 842 | return nil, fmt.Errorf("tree depth exceeds %d levels at %s", maxTreeDepth, prefix) |
| 843 | } |
| 844 | apiPath := fmt.Sprintf("repos/%s/%s/git/trees/%s", url.PathEscape(owner), url.PathEscape(repo), url.PathEscape(sha)) |
| 845 | var tree treeResponse |
| 846 | if err := client.REST(host, "GET", apiPath, nil, &tree); err != nil { |
| 847 | return nil, fmt.Errorf("could not fetch tree %s: %w", prefix, err) |
| 848 | } |
| 849 | |
| 850 | var files []SkillFile |
| 851 | for _, entry := range tree.Tree { |
| 852 | entryPath := entry.Path |
| 853 | if prefix != "" { |
| 854 | entryPath = prefix + "/" + entry.Path |
| 855 | } |
| 856 | switch entry.Type { |
| 857 | case "blob": |
| 858 | files = append(files, SkillFile{Path: entryPath, SHA: entry.SHA, Size: entry.Size}) |
| 859 | case "tree": |
| 860 | sub, err := walkTree(client, host, owner, repo, entry.SHA, entryPath, depth+1) |
| 861 | if err != nil { |
| 862 | return nil, err |
| 863 | } |
| 864 | files = append(files, sub...) |
| 865 | } |
| 866 | } |
| 867 | return files, nil |
| 868 | } |
| 869 | |
| 870 | // FetchBlob retrieves the content of a blob by SHA. |
| 871 | func FetchBlob(client *api.Client, host, owner, repo, sha string) (string, error) { |
no test coverage detected