MCPcopy Create free account
hub / github.com/cli/cli / fetchFile

Function fetchFile

pkg/cmd/repo/read-file/http.go:128–172  ·  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

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