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

Use Raw repo resources#70

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 48 additions & 6 deletionspkg/github/repository_resource.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,10 @@ import (
"context"
"encoding/base64"
"errors"
"fmt"
"io"
"mime"
"net/http"
"path/filepath"
"strings"

Expand DownExpand Up@@ -113,7 +116,12 @@ func repositoryResourceContentsHandler(client *github.Client) func(ctx context.C
for _, entry := range directoryContent {
mimeType := "text/directory"
if entry.GetType() == "file" {
mimeType = mime.TypeByExtension(filepath.Ext(entry.GetName()))
// this is system dependent, and a best guess
ext := filepath.Ext(entry.GetName())
mimeType = mime.TypeByExtension(ext)
if ext == ".md" {
mimeType = "text/markdown"
}
}
resources = append(resources, mcp.TextResourceContents{
URI: entry.GetHTMLURL(),
Expand All@@ -127,28 +135,62 @@ func repositoryResourceContentsHandler(client *github.Client) func(ctx context.C
}
if fileContent != nil {
if fileContent.Content != nil {
decodedContent, err := fileContent.GetContent()
// download the file content from fileContent.GetDownloadURL() and use the content-type header to determine the MIME type
// and return the content as a blob unless it is a text file, where you can return the content as text
req, err := http.NewRequest("GET", fileContent.GetDownloadURL(), nil)
if err != nil {
return nil, err
return nil,fmt.Errorf("failed to create request: %w",err)
}

mimeType := mime.TypeByExtension(filepath.Ext(fileContent.GetName()))
resp, err := client.Client().Do(req)
if err != nil {
return nil, fmt.Errorf("failed to send request: %w", err)
}
defer func() { _ = resp.Body.Close() }()

if resp.StatusCode != http.StatusOK {
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response body: %w", err)
}
return nil, fmt.Errorf("failed to fetch file content: %s", string(body))
}

ext := filepath.Ext(fileContent.GetName())
mimeType := resp.Header.Get("Content-Type")
if ext == ".md" {
mimeType = "text/markdown"
} else if mimeType == "" {
// backstop to the file extension if the content type is not set
mimeType = mime.TypeByExtension(filepath.Ext(fileContent.GetName()))
}

// if the content is a string, return it as text
if strings.HasPrefix(mimeType, "text") {
content, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to parse the response body: %w", err)
}

return []mcp.ResourceContents{
mcp.TextResourceContents{
URI: request.Params.URI,
MIMEType: mimeType,
Text:decodedContent,
Text:string(content),
},
}, nil
}
// otherwise, read the content and encode it as base64
decodedContent, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to parse the response body: %w", err)
}

return []mcp.ResourceContents{
mcp.BlobResourceContents{
URI: request.Params.URI,
MIMEType: mimeType,
Blob: base64.StdEncoding.EncodeToString([]byte(decodedContent)), // Encode content as Base64
Blob: base64.StdEncoding.EncodeToString(decodedContent), // Encode content as Base64
},
}, nil
}
Expand Down
92 changes: 74 additions & 18 deletionspkg/github/repository_resource_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,6 @@ package github

import (
"context"
"encoding/base64"
"net/http"
"testing"

Expand All@@ -13,28 +12,35 @@ import (
"github.com/stretchr/testify/require"
)

var GetRawReposContentsByOwnerByRepoByPath mock.EndpointPattern = mock.EndpointPattern{
Pattern: "/{owner}/{repo}/main/{path:.+}",
Method: "GET",
}

func Test_repositoryResourceContentsHandler(t *testing.T) {
mockDirContent := []*github.RepositoryContent{
{
Type: github.Ptr("file"),
Name: github.Ptr("README.md"),
Path: github.Ptr("README.md"),
SHA: github.Ptr("abc123"),
Size: github.Ptr(42),
HTMLURL: github.Ptr("https://github.com/owner/repo/blob/main/README.md"),
Type: github.Ptr("file"),
Name: github.Ptr("README.md"),
Path: github.Ptr("README.md"),
SHA: github.Ptr("abc123"),
Size: github.Ptr(42),
HTMLURL: github.Ptr("https://github.com/owner/repo/blob/main/README.md"),
DownloadURL: github.Ptr("https://raw.githubusercontent.com/owner/repo/main/README.md"),
},
{
Type: github.Ptr("dir"),
Name: github.Ptr("src"),
Path: github.Ptr("src"),
SHA: github.Ptr("def456"),
HTMLURL: github.Ptr("https://github.com/owner/repo/tree/main/src"),
Type: github.Ptr("dir"),
Name: github.Ptr("src"),
Path: github.Ptr("src"),
SHA: github.Ptr("def456"),
HTMLURL: github.Ptr("https://github.com/owner/repo/tree/main/src"),
DownloadURL: github.Ptr("https://raw.githubusercontent.com/owner/repo/main/src"),
},
}
expectedDirContent := []mcp.TextResourceContents{
{
URI: "https://github.com/owner/repo/blob/main/README.md",
MIMEType: "",
MIMEType: "text/markdown",
Text: "README.md",
},
{
Expand All@@ -44,20 +50,41 @@ func Test_repositoryResourceContentsHandler(t *testing.T) {
},
}

mockFileContent := &github.RepositoryContent{
mockTextContent := &github.RepositoryContent{
Type: github.Ptr("file"),
Name: github.Ptr("README.md"),
Path: github.Ptr("README.md"),
Content: github.Ptr("IyBUZXN0IFJlcG9zaXRvcnkKClRoaXMgaXMgYSB0ZXN0IHJlcG9zaXRvcnku"), // Base64 encoded "# Test Repository\n\nThis is a test repository."
Content: github.Ptr("# Test Repository\n\nThis is a test repository."),
SHA: github.Ptr("abc123"),
Size: github.Ptr(42),
HTMLURL: github.Ptr("https://github.com/owner/repo/blob/main/README.md"),
DownloadURL: github.Ptr("https://raw.githubusercontent.com/owner/repo/main/README.md"),
}

mockFileContent := &github.RepositoryContent{
Type: github.Ptr("file"),
Name: github.Ptr("data.png"),
Path: github.Ptr("data.png"),
Content: github.Ptr("IyBUZXN0IFJlcG9zaXRvcnkKClRoaXMgaXMgYSB0ZXN0IHJlcG9zaXRvcnku"), // Base64 encoded "# Test Repository\n\nThis is a test repository."
SHA: github.Ptr("abc123"),
Size: github.Ptr(42),
HTMLURL: github.Ptr("https://github.com/owner/repo/blob/main/data.png"),
DownloadURL: github.Ptr("https://raw.githubusercontent.com/owner/repo/main/data.png"),
}

expectedFileContent := []mcp.BlobResourceContents{
{
Blob: base64.StdEncoding.EncodeToString([]byte("IyBUZXN0IFJlcG9zaXRvcnkKClRoaXMgaXMgYSB0ZXN0IHJlcG9zaXRvcnku")),
Blob: "IyBUZXN0IFJlcG9zaXRvcnkKClRoaXMgaXMgYSB0ZXN0IHJlcG9zaXRvcnku",
MIMEType: "image/png",
URI: "",
},
}

expectedTextContent := []mcp.TextResourceContents{
{
Text: "# Test Repository\n\nThis is a test repository.",
MIMEType: "text/markdown",
URI: "",
},
}

Expand DownExpand Up@@ -94,21 +121,50 @@ func Test_repositoryResourceContentsHandler(t *testing.T) {
expectError: "repo is required",
},
{
name: "successfulfile content fetch",
name: "successfulblob content fetch",
mockedClient: mock.NewMockedHTTPClient(
mock.WithRequestMatch(
mock.GetReposContentsByOwnerByRepoByPath,
mockFileContent,
),
mock.WithRequestMatchHandler(
GetRawReposContentsByOwnerByRepoByPath,
http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "image/png")
// as this is given as a png, it will return the content as a blob
_, err := w.Write([]byte("# Test Repository\n\nThis is a test repository."))
require.NoError(t, err)
}),
),
),
requestArgs: map[string]any{
"owner": []string{"owner"},
"repo": []string{"repo"},
"path": []string{"README.md"},
"path": []string{"data.png"},
Copy link
Preview

CopilotAIApr 2, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

In the 'successful text content fetch' test, the request argument 'path' is set to 'data.png' while the mockTextContent has a name of 'README.md' (implying a .md extension). This discrepancy could lead to inconsistent MIME type resolution; please ensure that the file name and path are consistent.

Copilot uses AI. Check for mistakes.

"branch": []string{"main"},
},
expectedResult: expectedFileContent,
},
{
name: "successful text content fetch",
mockedClient: mock.NewMockedHTTPClient(
mock.WithRequestMatch(
mock.GetReposContentsByOwnerByRepoByPath,
mockTextContent,
),
mock.WithRequestMatch(
GetRawReposContentsByOwnerByRepoByPath,
[]byte("# Test Repository\n\nThis is a test repository."),
),
),
requestArgs: map[string]any{
"owner": []string{"owner"},
"repo": []string{"repo"},
"path": []string{"README.md"},
"branch": []string{"main"},
},
expectedResult: expectedTextContent,
},
{
name: "successful directory content fetch",
mockedClient: mock.NewMockedHTTPClient(
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp