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)
| 879 | // avoiding the truncation limit of the recursive tree API. Recursion |
| 880 | // depth is bounded by maxTreeDepth to prevent unbounded API calls. |
| 881 | func walkTree(client *api.Client, host, owner, repo, sha, prefix string, depth int) ([]SkillFile, error) { |
| 882 | if depth > maxTreeDepth { |
| 883 | return nil, fmt.Errorf("tree depth exceeds %d levels at %s", maxTreeDepth, prefix) |
| 884 | } |
| 885 | apiPath, err := safeurl.JoinPath("repos", owner, repo, "git", "trees", sha) |
| 886 | if err != nil { |
| 887 | return nil, err |
| 888 | } |
| 889 | var tree treeResponse |
| 890 | if err := client.REST(host, "GET", apiPath.String(), nil, &tree); err != nil { |
| 891 | return nil, fmt.Errorf("could not fetch tree %s: %w", prefix, err) |
| 892 | } |
| 893 | |
| 894 | var files []SkillFile |
| 895 | for _, entry := range tree.Tree { |
| 896 | entryPath := entry.Path |
| 897 | if prefix != "" { |
| 898 | entryPath = prefix + "/" + entry.Path |
| 899 | } |
| 900 | switch entry.Type { |
| 901 | case "blob": |
| 902 | files = append(files, SkillFile{Path: entryPath, SHA: entry.SHA, Size: entry.Size}) |
| 903 | case "tree": |
| 904 | sub, err := walkTree(client, host, owner, repo, entry.SHA, entryPath, depth+1) |
| 905 | if err != nil { |
| 906 | return nil, err |
| 907 | } |
| 908 | files = append(files, sub...) |
| 909 | } |
| 910 | } |
| 911 | return files, nil |
| 912 | } |
| 913 | |
| 914 | // FetchBlob retrieves the content of a blob by SHA. The blob is base64-encoded |
| 915 | // inside the JSON response and decoded here, so it is returned as |
no test coverage detected