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

add basic linter workflow#41

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
juruen merged 1 commit intomainfromjuruen/lint
Mar 26, 2025
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
58 changes: 58 additions & 0 deletions.github/workflows/lint.yaml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -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
28 changes: 28 additions & 0 deletions.golangci.yml
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -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
12 changes: 6 additions & 6 deletionscmd/github-mcp-server/main.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -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")
Expand All@@ -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)
Expand Down
14 changes: 7 additions & 7 deletionscmd/mcpcurl/main.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,6 @@ import (
"bytes"
"encoding/json"
"fmt"
"golang.org/x/exp/rand"
"io"
"os"
"os/exec"
Expand All@@ -13,6 +12,7 @@ import (

"github.com/spf13/cobra"
"github.com/spf13/viper"
"golang.org/x/exp/rand"
)

type (
Expand DownExpand Up@@ -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
Expand All@@ -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")
Expand DownExpand Up@@ -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 {
Expand DownExpand Up@@ -257,15 +257,15 @@ 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 {
case "string":
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)
Expand DownExpand Up@@ -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()
Expand Down
4 changes: 2 additions & 2 deletionspkg/github/code_scanning_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -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"}`))
}),
Expand DownExpand Up@@ -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"}`))
}),
Expand Down
6 changes: 3 additions & 3 deletionspkg/github/helper_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -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 andmarshalled body.
// that returns a specified status code andmarshaled 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)
Expand Down
16 changes: 8 additions & 8 deletionspkg/github/issues_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -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"}`))
}),
Expand DownExpand Up@@ -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"}`))
}),
Expand DownExpand Up@@ -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"}`))
}),
Expand DownExpand Up@@ -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"}`))
}),
Expand DownExpand Up@@ -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"}`))
}),
Expand All@@ -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"}`))
}),
Expand DownExpand Up@@ -881,15 +881,15 @@ func Test_UpdateIssue(t *testing.T) {
}

// Check assignees if expected
iftc.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)
}
}

// Check labels if expected
iftc.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)
Expand Down
22 changes: 11 additions & 11 deletionspkg/github/pullrequests_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -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"}`))
}),
Expand DownExpand Up@@ -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"}`))
}),
Expand DownExpand Up@@ -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"}`))
}),
Expand DownExpand Up@@ -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"}`))
}),
Expand DownExpand Up@@ -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"}`))
}),
Expand All@@ -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"}`))
}),
Expand DownExpand Up@@ -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"}`))
}),
Expand DownExpand Up@@ -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"}`))
}),
Expand DownExpand Up@@ -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"}`))
}),
Expand DownExpand Up@@ -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"}`))
}),
Expand All@@ -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"}`))
}),
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp