Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitede9f22

Browse files
chore: use raw repo resources (#70)
* use raw repo URIs for resources* fetch repository content from raw urls* ensure no error in test write* Update pkg/github/repository_resource.goCo-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>* use appropriate file name for text file test---------Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parentad58220 commitede9f22

File tree

2 files changed

+122
-24
lines changed

2 files changed

+122
-24
lines changed

‎pkg/github/repository_resource.go

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import (
44
"context"
55
"encoding/base64"
66
"errors"
7+
"fmt"
8+
"io"
79
"mime"
10+
"net/http"
811
"path/filepath"
912
"strings"
1013

@@ -113,7 +116,12 @@ func repositoryResourceContentsHandler(client *github.Client) func(ctx context.C
113116
for_,entry:=rangedirectoryContent {
114117
mimeType:="text/directory"
115118
ifentry.GetType()=="file" {
116-
mimeType=mime.TypeByExtension(filepath.Ext(entry.GetName()))
119+
// this is system dependent, and a best guess
120+
ext:=filepath.Ext(entry.GetName())
121+
mimeType=mime.TypeByExtension(ext)
122+
ifext==".md" {
123+
mimeType="text/markdown"
124+
}
117125
}
118126
resources=append(resources, mcp.TextResourceContents{
119127
URI:entry.GetHTMLURL(),
@@ -127,28 +135,62 @@ func repositoryResourceContentsHandler(client *github.Client) func(ctx context.C
127135
}
128136
iffileContent!=nil {
129137
iffileContent.Content!=nil {
130-
decodedContent,err:=fileContent.GetContent()
138+
// download the file content from fileContent.GetDownloadURL() and use the content-type header to determine the MIME type
139+
// and return the content as a blob unless it is a text file, where you can return the content as text
140+
req,err:=http.NewRequest("GET",fileContent.GetDownloadURL(),nil)
131141
iferr!=nil {
132-
returnnil,err
142+
returnnil,fmt.Errorf("failed to create request: %w",err)
133143
}
134144

135-
mimeType:=mime.TypeByExtension(filepath.Ext(fileContent.GetName()))
145+
resp,err:=client.Client().Do(req)
146+
iferr!=nil {
147+
returnnil,fmt.Errorf("failed to send request: %w",err)
148+
}
149+
deferfunc() {_=resp.Body.Close() }()
150+
151+
ifresp.StatusCode!=http.StatusOK {
152+
body,err:=io.ReadAll(resp.Body)
153+
iferr!=nil {
154+
returnnil,fmt.Errorf("failed to read response body: %w",err)
155+
}
156+
returnnil,fmt.Errorf("failed to fetch file content: %s",string(body))
157+
}
158+
159+
ext:=filepath.Ext(fileContent.GetName())
160+
mimeType:=resp.Header.Get("Content-Type")
161+
ifext==".md" {
162+
mimeType="text/markdown"
163+
}elseifmimeType=="" {
164+
// backstop to the file extension if the content type is not set
165+
mimeType=mime.TypeByExtension(filepath.Ext(fileContent.GetName()))
166+
}
136167

168+
// if the content is a string, return it as text
137169
ifstrings.HasPrefix(mimeType,"text") {
170+
content,err:=io.ReadAll(resp.Body)
171+
iferr!=nil {
172+
returnnil,fmt.Errorf("failed to parse the response body: %w",err)
173+
}
174+
138175
return []mcp.ResourceContents{
139176
mcp.TextResourceContents{
140177
URI:request.Params.URI,
141178
MIMEType:mimeType,
142-
Text:decodedContent,
179+
Text:string(content),
143180
},
144181
},nil
145182
}
183+
// otherwise, read the content and encode it as base64
184+
decodedContent,err:=io.ReadAll(resp.Body)
185+
iferr!=nil {
186+
returnnil,fmt.Errorf("failed to parse the response body: %w",err)
187+
}
146188

147189
return []mcp.ResourceContents{
148190
mcp.BlobResourceContents{
149191
URI:request.Params.URI,
150192
MIMEType:mimeType,
151-
Blob:base64.StdEncoding.EncodeToString([]byte(decodedContent)),// Encode content as Base64
193+
Blob:base64.StdEncoding.EncodeToString(decodedContent),// Encode content as Base64
152194
},
153195
},nil
154196
}

‎pkg/github/repository_resource_test.go

Lines changed: 74 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package github
22

33
import (
44
"context"
5-
"encoding/base64"
65
"net/http"
76
"testing"
87

@@ -13,28 +12,35 @@ import (
1312
"github.com/stretchr/testify/require"
1413
)
1514

15+
varGetRawReposContentsByOwnerByRepoByPath mock.EndpointPattern= mock.EndpointPattern{
16+
Pattern:"/{owner}/{repo}/main/{path:.+}",
17+
Method:"GET",
18+
}
19+
1620
funcTest_repositoryResourceContentsHandler(t*testing.T) {
1721
mockDirContent:= []*github.RepositoryContent{
1822
{
19-
Type:github.Ptr("file"),
20-
Name:github.Ptr("README.md"),
21-
Path:github.Ptr("README.md"),
22-
SHA:github.Ptr("abc123"),
23-
Size:github.Ptr(42),
24-
HTMLURL:github.Ptr("https://github.com/owner/repo/blob/main/README.md"),
23+
Type:github.Ptr("file"),
24+
Name:github.Ptr("README.md"),
25+
Path:github.Ptr("README.md"),
26+
SHA:github.Ptr("abc123"),
27+
Size:github.Ptr(42),
28+
HTMLURL:github.Ptr("https://github.com/owner/repo/blob/main/README.md"),
29+
DownloadURL:github.Ptr("https://raw.githubusercontent.com/owner/repo/main/README.md"),
2530
},
2631
{
27-
Type:github.Ptr("dir"),
28-
Name:github.Ptr("src"),
29-
Path:github.Ptr("src"),
30-
SHA:github.Ptr("def456"),
31-
HTMLURL:github.Ptr("https://github.com/owner/repo/tree/main/src"),
32+
Type:github.Ptr("dir"),
33+
Name:github.Ptr("src"),
34+
Path:github.Ptr("src"),
35+
SHA:github.Ptr("def456"),
36+
HTMLURL:github.Ptr("https://github.com/owner/repo/tree/main/src"),
37+
DownloadURL:github.Ptr("https://raw.githubusercontent.com/owner/repo/main/src"),
3238
},
3339
}
3440
expectedDirContent:= []mcp.TextResourceContents{
3541
{
3642
URI:"https://github.com/owner/repo/blob/main/README.md",
37-
MIMEType:"",
43+
MIMEType:"text/markdown",
3844
Text:"README.md",
3945
},
4046
{
@@ -44,20 +50,41 @@ func Test_repositoryResourceContentsHandler(t *testing.T) {
4450
},
4551
}
4652

47-
mockFileContent:=&github.RepositoryContent{
53+
mockTextContent:=&github.RepositoryContent{
4854
Type:github.Ptr("file"),
4955
Name:github.Ptr("README.md"),
5056
Path:github.Ptr("README.md"),
51-
Content:github.Ptr("IyBUZXN0IFJlcG9zaXRvcnkKClRoaXMgaXMgYSB0ZXN0IHJlcG9zaXRvcnku"),// Base64 encoded "# Test Repository\n\nThis is a test repository."
57+
Content:github.Ptr("# Test Repository\n\nThis is a test repository."),
5258
SHA:github.Ptr("abc123"),
5359
Size:github.Ptr(42),
5460
HTMLURL:github.Ptr("https://github.com/owner/repo/blob/main/README.md"),
5561
DownloadURL:github.Ptr("https://raw.githubusercontent.com/owner/repo/main/README.md"),
5662
}
5763

64+
mockFileContent:=&github.RepositoryContent{
65+
Type:github.Ptr("file"),
66+
Name:github.Ptr("data.png"),
67+
Path:github.Ptr("data.png"),
68+
Content:github.Ptr("IyBUZXN0IFJlcG9zaXRvcnkKClRoaXMgaXMgYSB0ZXN0IHJlcG9zaXRvcnku"),// Base64 encoded "# Test Repository\n\nThis is a test repository."
69+
SHA:github.Ptr("abc123"),
70+
Size:github.Ptr(42),
71+
HTMLURL:github.Ptr("https://github.com/owner/repo/blob/main/data.png"),
72+
DownloadURL:github.Ptr("https://raw.githubusercontent.com/owner/repo/main/data.png"),
73+
}
74+
5875
expectedFileContent:= []mcp.BlobResourceContents{
5976
{
60-
Blob:base64.StdEncoding.EncodeToString([]byte("IyBUZXN0IFJlcG9zaXRvcnkKClRoaXMgaXMgYSB0ZXN0IHJlcG9zaXRvcnku")),
77+
Blob:"IyBUZXN0IFJlcG9zaXRvcnkKClRoaXMgaXMgYSB0ZXN0IHJlcG9zaXRvcnku",
78+
MIMEType:"image/png",
79+
URI:"",
80+
},
81+
}
82+
83+
expectedTextContent:= []mcp.TextResourceContents{
84+
{
85+
Text:"# Test Repository\n\nThis is a test repository.",
86+
MIMEType:"text/markdown",
87+
URI:"",
6188
},
6289
}
6390

@@ -94,21 +121,50 @@ func Test_repositoryResourceContentsHandler(t *testing.T) {
94121
expectError:"repo is required",
95122
},
96123
{
97-
name:"successfulfile content fetch",
124+
name:"successfulblob content fetch",
98125
mockedClient:mock.NewMockedHTTPClient(
99126
mock.WithRequestMatch(
100127
mock.GetReposContentsByOwnerByRepoByPath,
101128
mockFileContent,
102129
),
130+
mock.WithRequestMatchHandler(
131+
GetRawReposContentsByOwnerByRepoByPath,
132+
http.HandlerFunc(func(w http.ResponseWriter,_*http.Request) {
133+
w.Header().Set("Content-Type","image/png")
134+
// as this is given as a png, it will return the content as a blob
135+
_,err:=w.Write([]byte("# Test Repository\n\nThis is a test repository."))
136+
require.NoError(t,err)
137+
}),
138+
),
103139
),
104140
requestArgs:map[string]any{
105141
"owner": []string{"owner"},
106142
"repo": []string{"repo"},
107-
"path": []string{"README.md"},
143+
"path": []string{"data.png"},
108144
"branch": []string{"main"},
109145
},
110146
expectedResult:expectedFileContent,
111147
},
148+
{
149+
name:"successful text content fetch",
150+
mockedClient:mock.NewMockedHTTPClient(
151+
mock.WithRequestMatch(
152+
mock.GetReposContentsByOwnerByRepoByPath,
153+
mockTextContent,
154+
),
155+
mock.WithRequestMatch(
156+
GetRawReposContentsByOwnerByRepoByPath,
157+
[]byte("# Test Repository\n\nThis is a test repository."),
158+
),
159+
),
160+
requestArgs:map[string]any{
161+
"owner": []string{"owner"},
162+
"repo": []string{"repo"},
163+
"path": []string{"README.md"},
164+
"branch": []string{"main"},
165+
},
166+
expectedResult:expectedTextContent,
167+
},
112168
{
113169
name:"successful directory content fetch",
114170
mockedClient:mock.NewMockedHTTPClient(

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp