MCPcopy Index your code
hub / github.com/cli/cli / fetchFile

Function fetchFile

pkg/cmd/repo/read-file/http.go:125–169  ·  view source on GitHub ↗

fetchFile retrieves a single path's metadata and inline content via the REST Contents API. It returns a typed error when the path is a directory, symlink, or submodule. Content is populated only when the API returns it inline; larger files come back with empty content, and it is up to the caller to

(httpClient *http.Client, repo ghrepo.Interface, filePath, ref string)

Source from the content-addressed store, hash-verified

123// it is up to the caller to fetch the raw bytes via fetchRawFile when the content is actually
124// needed.
125func fetchFile(httpClient *http.Client, repo ghrepo.Interface, filePath, ref string) (*repoFile, error) {
126 content, err := fetchContent(httpClient, repo, filePath, ref)
127 if err != nil {
128 return nil, err
129 }
130
131 if content.Type != "file" {
132 // The path resolved to something other than a regular file. Use content.Path
133 // (the API-sanitized path) rather than the user input in these messages, so a
134 // crafted path cannot smuggle terminal escape sequences into our output.
135 switch content.Type {
136 case "dir":
137 return nil, fmt.Errorf("path %q is a directory; use `gh repo read-dir` instead", content.Path)
138 case "symlink":
139 return nil, fmt.Errorf("path %q is a symlink to %q which does not exist", content.Path, content.Target)
140 case "submodule":
141 return nil, fmt.Errorf("path %q is a submodule (%s at %s)", content.Path, content.SubmoduleGitURL, content.SHA)
142 default:
143 return nil, fmt.Errorf("path %q is not a regular file (type: %s)", content.Path, content.Type)
144 }
145 }
146
147 file := &repoFile{
148 Name: content.Name,
149 Path: content.Path,
150 SHA: content.SHA,
151 Size: content.Size,
152 URL: content.URL,
153 HTMLURL: content.HTMLURL,
154 GitURL: content.GitURL,
155 DownloadURL: content.DownloadURL,
156 Type: content.Type,
157 Encoding: content.Encoding,
158 }
159
160 if content.Encoding == "base64" && content.Content != "" {
161 decoded, err := base64.StdEncoding.DecodeString(content.Content)
162 if err != nil {
163 return nil, fmt.Errorf("failed to decode base64 file content: %w", err)
164 }
165 file.Content = decoded
166 }
167
168 return file, nil
169}
170
171// fetchRawFile retrieves the raw bytes of a file, used for files larger than the
172// 1 MB inline content limit of the Contents API.

Callers 1

readFileRunFunction · 0.85

Calls 2

fetchContentFunction · 0.85
ErrorfMethod · 0.65

Tested by

no test coverage detected