diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 000000000..553514a96 --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,58 @@ +name: Lint +on: + push: + paths: + - "**.go" + - go.mod + - go.sum + pull_request: + paths: + - "**.go" + - go.mod + - go.sum + +permissions: + contents: read + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version-file: 'go.mod' + + - name: Verify dependencies + run: | + go mod verify + go mod download + + LINT_VERSION=1.64.8 + curl -fsSL https://github.com/golangci/golangci-lint/releases/download/v${LINT_VERSION}/golangci-lint-${LINT_VERSION}-linux-amd64.tar.gz | \ + tar xz --strip-components 1 --wildcards \*/golangci-lint + mkdir -p bin && mv golangci-lint bin/ + + - name: Run checks + run: | + STATUS=0 + assert-nothing-changed() { + local diff + "$@" >/dev/null || return 1 + if ! diff="$(git diff -U1 --color --exit-code)"; then + printf '\e[31mError: running `\e[1m%s\e[22m` results in modifications that you must check into version control:\e[0m\n%s\n\n' "$*" "$diff" >&2 + git checkout -- . + STATUS=1 + fi + } + + assert-nothing-changed go fmt ./... + assert-nothing-changed go mod tidy + + bin/golangci-lint run --out-format=colored-line-number --timeout=3m || STATUS=$? + + exit $STATUS diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 000000000..43e3d62dc --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,28 @@ +run: + timeout: 5m + tests: true + concurrency: 4 + +linters: + enable: + - govet + - errcheck + - staticcheck + - gofmt + - goimports + - revive + - ineffassign + - typecheck + - unused + - gosimple + - misspell + - nakedret + - bodyclose + - gocritic + - makezero + - gosec + +output: + formats: colored-line-number + print-issued-lines: true + print-linter-name: true diff --git a/cmd/github-mcp-server/main.go b/cmd/github-mcp-server/main.go index 5e8c520e4..f523c1fda 100644 --- a/cmd/github-mcp-server/main.go +++ b/cmd/github-mcp-server/main.go @@ -30,7 +30,7 @@ var ( Use: "stdio", Short: "Start stdio server", Long: `Start a server that communicates via standard input/output streams using JSON-RPC messages.`, - Run: func(cmd *cobra.Command, args []string) { + Run: func(_ *cobra.Command, _ []string) { logFile := viper.GetString("log-file") readOnly := viper.GetBool("read-only") exportTranslations := viper.GetBool("export-translations") @@ -57,11 +57,11 @@ func init() { rootCmd.PersistentFlags().String("gh-host", "", "Specify the GitHub hostname (for GitHub Enterprise etc.)") // Bind flag to viper - viper.BindPFlag("read-only", rootCmd.PersistentFlags().Lookup("read-only")) - viper.BindPFlag("log-file", rootCmd.PersistentFlags().Lookup("log-file")) - viper.BindPFlag("enable-command-logging", rootCmd.PersistentFlags().Lookup("enable-command-logging")) - viper.BindPFlag("export-translations", rootCmd.PersistentFlags().Lookup("export-translations")) - viper.BindPFlag("gh-host", rootCmd.PersistentFlags().Lookup("gh-host")) + _ = viper.BindPFlag("read-only", rootCmd.PersistentFlags().Lookup("read-only")) + _ = viper.BindPFlag("log-file", rootCmd.PersistentFlags().Lookup("log-file")) + _ = viper.BindPFlag("enable-command-logging", rootCmd.PersistentFlags().Lookup("enable-command-logging")) + _ = viper.BindPFlag("export-translations", rootCmd.PersistentFlags().Lookup("export-translations")) + _ = viper.BindPFlag("gh-host", rootCmd.PersistentFlags().Lookup("gh-host")) // Add subcommands rootCmd.AddCommand(stdioCmd) diff --git a/cmd/mcpcurl/main.go b/cmd/mcpcurl/main.go index 77dfd4f04..bcc46e00f 100644 --- a/cmd/mcpcurl/main.go +++ b/cmd/mcpcurl/main.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/json" "fmt" - "golang.org/x/exp/rand" "io" "os" "os/exec" @@ -13,6 +12,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" + "golang.org/x/exp/rand" ) type ( @@ -99,7 +99,7 @@ var ( Use: "mcpcurl", Short: "CLI tool with dynamically generated commands", Long: "A CLI tool for interacting with MCP API based on dynamically loaded schemas", - PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + PersistentPreRunE: func(cmd *cobra.Command, _ []string) error { // Skip validation for help and completion commands if cmd.Name() == "help" || cmd.Name() == "completion" { return nil @@ -119,7 +119,7 @@ var ( Use: "schema", Short: "Fetch schema from MCP server", Long: "Fetches the tools schema from the MCP server specified by --stdio-server-cmd", - RunE: func(cmd *cobra.Command, args []string) error { + RunE: func(cmd *cobra.Command, _ []string) error { serverCmd, _ := cmd.Flags().GetString("stdio-server-cmd") if serverCmd == "" { return fmt.Errorf("--stdio-server-cmd is required") @@ -206,7 +206,7 @@ func addCommandFromTool(toolsCmd *cobra.Command, tool *Tool, prettyPrint bool) { cmd := &cobra.Command{ Use: tool.Name, Short: tool.Description, - Run: func(cmd *cobra.Command, args []string) { + Run: func(cmd *cobra.Command, _ []string) { // Build a map of arguments from flags arguments, err := buildArgumentsMap(cmd, tool) if err != nil { @@ -257,7 +257,7 @@ func addCommandFromTool(toolsCmd *cobra.Command, tool *Tool, prettyPrint bool) { // Enhance description to indicate if parameter is optional description := prop.Description if !isRequired { - description = description + " (optional)" + description += " (optional)" } switch prop.Type { @@ -265,7 +265,7 @@ func addCommandFromTool(toolsCmd *cobra.Command, tool *Tool, prettyPrint bool) { cmd.Flags().String(name, "", description) if len(prop.Enum) > 0 { // Add validation in PreRun for enum values - cmd.PreRunE = func(cmd *cobra.Command, args []string) error { + cmd.PreRunE = func(cmd *cobra.Command, _ []string) error { for flagName, property := range tool.InputSchema.Properties { if len(property.Enum) > 0 { value, _ := cmd.Flags().GetString(flagName) @@ -373,7 +373,7 @@ func executeServerCommand(cmdStr, jsonRequest string) (string, error) { return "", fmt.Errorf("empty command") } - cmd := exec.Command(cmdParts[0], cmdParts[1:]...) + cmd := exec.Command(cmdParts[0], cmdParts[1:]...) //nolint:gosec //mcpcurl is a test command that needs to execute arbitrary shell commands // Setup stdin pipe stdin, err := cmd.StdinPipe() diff --git a/pkg/github/code_scanning_test.go b/pkg/github/code_scanning_test.go index 890123344..6263a7f0f 100644 --- a/pkg/github/code_scanning_test.go +++ b/pkg/github/code_scanning_test.go @@ -62,7 +62,7 @@ func Test_GetCodeScanningAlert(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetReposCodeScanningAlertsByOwnerByRepoByAlertNumber, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) }), @@ -176,7 +176,7 @@ func Test_ListCodeScanningAlerts(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetReposCodeScanningAlertsByOwnerByRepo, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusUnauthorized) _, _ = w.Write([]byte(`{"message": "Unauthorized access"}`)) }), diff --git a/pkg/github/helper_test.go b/pkg/github/helper_test.go index 5e71f4187..72241623e 100644 --- a/pkg/github/helper_test.go +++ b/pkg/github/helper_test.go @@ -2,19 +2,19 @@ package github import ( "encoding/json" - "github.com/stretchr/testify/assert" "net/http" "testing" "github.com/mark3labs/mcp-go/mcp" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // mockResponse is a helper function to create a mock HTTP response handler -// that returns a specified status code and marshalled body. +// that returns a specified status code and marshaled body. func mockResponse(t *testing.T, code int, body interface{}) http.HandlerFunc { t.Helper() - return func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(code) b, err := json.Marshal(body) require.NoError(t, err) diff --git a/pkg/github/issues_test.go b/pkg/github/issues_test.go index c2de65797..edc531ae4 100644 --- a/pkg/github/issues_test.go +++ b/pkg/github/issues_test.go @@ -164,7 +164,7 @@ func Test_AddIssueComment(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.PostReposIssuesCommentsByOwnerByRepoByIssueNumber, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusUnprocessableEntity) _, _ = w.Write([]byte(`{"message": "Invalid request"}`)) }), @@ -323,7 +323,7 @@ func Test_SearchIssues(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetSearchIssues, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusBadRequest) _, _ = w.Write([]byte(`{"message": "Validation Failed"}`)) }), @@ -463,7 +463,7 @@ func Test_CreateIssue(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.PostReposIssuesByOwnerByRepo, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusUnprocessableEntity) _, _ = w.Write([]byte(`{"message": "Validation failed"}`)) }), @@ -646,7 +646,7 @@ func Test_ListIssues(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetReposIssuesByOwnerByRepo, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Repository not found"}`)) }), @@ -799,7 +799,7 @@ func Test_UpdateIssue(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.PatchReposIssuesByOwnerByRepoByIssueNumber, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Issue not found"}`)) }), @@ -819,7 +819,7 @@ func Test_UpdateIssue(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.PatchReposIssuesByOwnerByRepoByIssueNumber, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusUnprocessableEntity) _, _ = w.Write([]byte(`{"message": "Invalid state value"}`)) }), @@ -881,7 +881,7 @@ func Test_UpdateIssue(t *testing.T) { } // Check assignees if expected - if tc.expectedIssue.Assignees != nil && len(tc.expectedIssue.Assignees) > 0 { + if len(tc.expectedIssue.Assignees) > 0 { assert.Len(t, returnedIssue.Assignees, len(tc.expectedIssue.Assignees)) for i, assignee := range returnedIssue.Assignees { assert.Equal(t, *tc.expectedIssue.Assignees[i].Login, *assignee.Login) @@ -889,7 +889,7 @@ func Test_UpdateIssue(t *testing.T) { } // Check labels if expected - if tc.expectedIssue.Labels != nil && len(tc.expectedIssue.Labels) > 0 { + if len(tc.expectedIssue.Labels) > 0 { assert.Len(t, returnedIssue.Labels, len(tc.expectedIssue.Labels)) for i, label := range returnedIssue.Labels { assert.Equal(t, *tc.expectedIssue.Labels[i].Name, *label.Name) diff --git a/pkg/github/pullrequests_test.go b/pkg/github/pullrequests_test.go index 15c5e0702..6432c5710 100644 --- a/pkg/github/pullrequests_test.go +++ b/pkg/github/pullrequests_test.go @@ -74,7 +74,7 @@ func Test_GetPullRequest(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetReposPullsByOwnerByRepoByPullNumber, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) }), @@ -193,7 +193,7 @@ func Test_ListPullRequests(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetReposPullsByOwnerByRepo, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusBadRequest) _, _ = w.Write([]byte(`{"message": "Invalid request"}`)) }), @@ -302,7 +302,7 @@ func Test_MergePullRequest(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.PutReposPullsMergeByOwnerByRepoByPullNumber, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusMethodNotAllowed) _, _ = w.Write([]byte(`{"message": "Pull request cannot be merged"}`)) }), @@ -414,7 +414,7 @@ func Test_GetPullRequestFiles(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetReposPullsFilesByOwnerByRepoByPullNumber, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) }), @@ -551,7 +551,7 @@ func Test_GetPullRequestStatus(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetReposPullsByOwnerByRepoByPullNumber, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) }), @@ -574,7 +574,7 @@ func Test_GetPullRequestStatus(t *testing.T) { ), mock.WithRequestMatchHandler( mock.GetReposCommitsStatusesByOwnerByRepoByRef, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) }), @@ -695,7 +695,7 @@ func Test_UpdatePullRequestBranch(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.PutReposPullsUpdateBranchByOwnerByRepoByPullNumber, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusConflict) _, _ = w.Write([]byte(`{"message": "Merge conflict"}`)) }), @@ -811,7 +811,7 @@ func Test_GetPullRequestComments(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetReposPullsCommentsByOwnerByRepoByPullNumber, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) }), @@ -934,7 +934,7 @@ func Test_GetPullRequestReviews(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetReposPullsReviewsByOwnerByRepoByPullNumber, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) }), @@ -1099,7 +1099,7 @@ func Test_CreatePullRequestReview(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.PostReposPullsReviewsByOwnerByRepoByPullNumber, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusUnprocessableEntity) _, _ = w.Write([]byte(`{"message": "Invalid comment format"}`)) }), @@ -1126,7 +1126,7 @@ func Test_CreatePullRequestReview(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.PostReposPullsReviewsByOwnerByRepoByPullNumber, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusUnprocessableEntity) _, _ = w.Write([]byte(`{"message": "Invalid comment format"}`)) }), diff --git a/pkg/github/repositories_test.go b/pkg/github/repositories_test.go index 34e8850a6..1b416d8c9 100644 --- a/pkg/github/repositories_test.go +++ b/pkg/github/repositories_test.go @@ -105,7 +105,7 @@ func Test_GetFileContents(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetReposContentsByOwnerByRepoByPath, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) }), @@ -234,7 +234,7 @@ func Test_ForkRepository(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.PostReposForksByOwnerByRepo, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusForbidden) _, _ = w.Write([]byte(`{"message": "Forbidden"}`)) }), @@ -370,7 +370,7 @@ func Test_CreateBranch(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetReposByOwnerByRepo, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Repository not found"}`)) }), @@ -389,7 +389,7 @@ func Test_CreateBranch(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetReposGitRefByOwnerByRepoByRef, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Reference not found"}`)) }), @@ -413,7 +413,7 @@ func Test_CreateBranch(t *testing.T) { ), mock.WithRequestMatchHandler( mock.PostReposGitRefsByOwnerByRepo, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusUnprocessableEntity) _, _ = w.Write([]byte(`{"message": "Reference already exists"}`)) }), @@ -573,7 +573,7 @@ func Test_ListCommits(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetReposCommitsByOwnerByRepo, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusNotFound) _, _ = w.Write([]byte(`{"message": "Not Found"}`)) }), @@ -717,7 +717,7 @@ func Test_CreateOrUpdateFile(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.PutReposContentsByOwnerByRepoByPath, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusUnprocessableEntity) _, _ = w.Write([]byte(`{"message": "Invalid request"}`)) }), @@ -856,7 +856,7 @@ func Test_CreateRepository(t *testing.T) { Pattern: "/user/repos", Method: "POST", }, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusUnprocessableEntity) _, _ = w.Write([]byte(`{"message": "Repository creation failed"}`)) }), diff --git a/pkg/github/search_test.go b/pkg/github/search_test.go index bee2d8d90..69fa7ca4e 100644 --- a/pkg/github/search_test.go +++ b/pkg/github/search_test.go @@ -92,7 +92,7 @@ func Test_SearchRepositories(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetSearchRepositories, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusBadRequest) _, _ = w.Write([]byte(`{"message": "Invalid query"}`)) }), @@ -229,7 +229,7 @@ func Test_SearchCode(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetSearchCode, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusBadRequest) _, _ = w.Write([]byte(`{"message": "Validation Failed"}`)) }), @@ -370,7 +370,7 @@ func Test_SearchUsers(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetSearchUsers, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusBadRequest) _, _ = w.Write([]byte(`{"message": "Validation Failed"}`)) }), diff --git a/pkg/github/server.go b/pkg/github/server.go index d8b3714c9..c01e0918f 100644 --- a/pkg/github/server.go +++ b/pkg/github/server.go @@ -90,7 +90,7 @@ func getMe(client *github.Client, t translations.TranslationHelperFunc) (tool mc mcp.Description("Optional: reason the session was created"), ), ), - func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + func(ctx context.Context, _ mcp.CallToolRequest) (*mcp.CallToolResult, error) { user, resp, err := client.Users.Get(ctx, "") if err != nil { return nil, fmt.Errorf("failed to get user: %w", err) diff --git a/pkg/github/server_test.go b/pkg/github/server_test.go index 5e7ac9d4d..a4d819f7b 100644 --- a/pkg/github/server_test.go +++ b/pkg/github/server_test.go @@ -80,7 +80,7 @@ func Test_GetMe(t *testing.T) { mockedClient: mock.NewMockedHTTPClient( mock.WithRequestMatchHandler( mock.GetUser, - http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusUnauthorized) _, _ = w.Write([]byte(`{"message": "Unauthorized"}`)) }), diff --git a/pkg/translations/translations.go b/pkg/translations/translations.go index dd23323eb..8f19f1585 100644 --- a/pkg/translations/translations.go +++ b/pkg/translations/translations.go @@ -2,6 +2,7 @@ package translations import ( "encoding/json" + "fmt" "log" "os" "strings" @@ -11,7 +12,7 @@ import ( type TranslationHelperFunc func(key string, defaultValue string) string -func NullTranslationHelper(key string, defaultValue string) string { +func NullTranslationHelper(_ string, defaultValue string) string { return defaultValue } @@ -52,26 +53,30 @@ func TranslationHelper() (TranslationHelperFunc, func()) { return translationKeyMap[key] }, func() { // dump the translationKeyMap to a json file - DumpTranslationKeyMap(translationKeyMap) + if err := DumpTranslationKeyMap(translationKeyMap); err != nil { + log.Fatalf("Could not dump translation key map: %v", err) + } } } // dump translationKeyMap to a json file called github-mcp-server.json -func DumpTranslationKeyMap(translationKeyMap map[string]string) { +func DumpTranslationKeyMap(translationKeyMap map[string]string) error { file, err := os.Create("github-mcp-server.json") if err != nil { - log.Fatalf("Error creating file: %v", err) + return fmt.Errorf("error creating file: %v", err) } - defer file.Close() + defer func() { _ = file.Close() }() // marshal the map to json jsonData, err := json.MarshalIndent(translationKeyMap, "", " ") if err != nil { - log.Fatalf("Error marshaling map to JSON: %v", err) + return fmt.Errorf("error marshaling map to JSON: %v", err) } // write the json data to the file if _, err := file.Write(jsonData); err != nil { - log.Fatalf("Error writing to file: %v", err) + return fmt.Errorf("error writing to file: %v", err) } + + return nil }
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: