Skip to content

feat: add golangci && resolve current lint errors #104

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
27 changes: 27 additions & 0 deletions .github/workflows/golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: golangci-lint
on:
push:
branches:
- main
pull_request:

permissions:
contents: read

jobs:
golangci:
strategy:
matrix:
go: [stable]
os: [ubuntu-latest, macos-latest, windows-latest]
name: lint
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go }}
- name: golangci-lint
uses: golangci/golangci-lint-action@v7
with:
version: v2.0
5 changes: 2 additions & 3 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

tea "github.com/charmbracelet/bubbletea"
zone "github.com/lrstanley/bubblezone"
"github.com/opencode-ai/opencode/internal/app"
"github.com/opencode-ai/opencode/internal/config"
"github.com/opencode-ai/opencode/internal/db"
Expand All @@ -16,7 +17,6 @@ import (
"github.com/opencode-ai/opencode/internal/pubsub"
"github.com/opencode-ai/opencode/internal/tui"
"github.com/opencode-ai/opencode/internal/version"
zone "github.com/lrstanley/bubblezone"
"github.com/spf13/cobra"
)

Expand All @@ -29,8 +29,7 @@ to assist developers in writing, debugging, and understanding code directly from
RunE: func(cmd *cobra.Command, args []string) error {
// If the help flag is set, show the help message
if cmd.Flag("help").Changed {
cmd.Help()
return nil
return cmd.Help()
}
if cmd.Flag("version").Changed {
fmt.Println(version.Version)
Expand Down
14 changes: 8 additions & 6 deletions internal/app/lsp.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func (app *App) initLSPClients(ctx context.Context) {
func (app *App) createAndStartLSPClient(ctx context.Context, name string, command string, args ...string) {
// Create a specific context for initialization with a timeout
logging.Info("Creating LSP client", "name", name, "command", command, "args", args)

// Create the LSP client
lspClient, err := lsp.NewClient(ctx, command, args...)
if err != nil {
Expand All @@ -36,13 +36,13 @@ func (app *App) createAndStartLSPClient(ctx context.Context, name string, comman
// Create a longer timeout for initialization (some servers take time to start)
initCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()

// Initialize with the initialization context
_, err = lspClient.InitializeLSPClient(initCtx, config.WorkingDirectory())
if err != nil {
logging.Error("Initialize failed", "name", name, "error", err)
// Clean up the client to prevent resource leaks
lspClient.Close()
lspClient.Close() //nolint:errcheck
return
}

Expand All @@ -57,13 +57,15 @@ func (app *App) createAndStartLSPClient(ctx context.Context, name string, comman
}

logging.Info("LSP client initialized", "name", name)

// Create a child context that can be canceled when the app is shutting down
watchCtx, cancelFunc := context.WithCancel(ctx)

// Create a context with the server name for better identification
//nolint:staticcheck
//lint:ignore SA1029 will be resolved in the future
watchCtx = context.WithValue(watchCtx, "serverName", name)

// Create the workspace watcher
workspaceWatcher := watcher.NewWorkspaceWatcher(lspClient)

Expand Down
9 changes: 6 additions & 3 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,9 @@ func Load(workingDir string, debug bool) (*Config, error) {
}

// Load and merge local config
mergeLocalConfig(workingDir)
if err := mergeLocalConfig(workingDir); err != nil {
return cfg, err
}

// Apply configuration to the struct
if err := viper.Unmarshal(cfg); err != nil {
Expand Down Expand Up @@ -315,16 +317,17 @@ func readConfig(err error) error {
}

// mergeLocalConfig loads and merges configuration from the local directory.
func mergeLocalConfig(workingDir string) {
func mergeLocalConfig(workingDir string) error {
local := viper.New()
local.SetConfigName(fmt.Sprintf(".%s", appName))
local.SetConfigType("json")
local.AddConfigPath(workingDir)

// Merge local config if it exists
if err := local.ReadInConfig(); err == nil {
viper.MergeConfigMap(local.AllSettings())
return viper.MergeConfigMap(local.AllSettings())
}
return nil
}

// applyDefaultValues sets default values for configuration fields that need processing.
Expand Down
3 changes: 1 addition & 2 deletions internal/config/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ func MarkProjectInitialized() error {
if err != nil {
return fmt.Errorf("failed to create init flag file: %w", err)
}
defer file.Close()
defer file.Close() //nolint:errcheck

return nil
}

2 changes: 1 addition & 1 deletion internal/db/connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func Connect() (*sql.DB, error) {

// Verify connection
if err = db.Ping(); err != nil {
db.Close()
db.Close() //nolint:errcheck
return nil, fmt.Errorf("failed to connect to database: %w", err)
}

Expand Down
2 changes: 1 addition & 1 deletion internal/history/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func (s *service) createWithVersion(ctx context.Context, sessionID, path, conten
})
if txErr != nil {
// Rollback the transaction
tx.Rollback()
tx.Rollback() //nolint:errcheck

// Check if this is a uniqueness constraint violation
if strings.Contains(txErr.Error(), "UNIQUE constraint failed") {
Expand Down
2 changes: 1 addition & 1 deletion internal/llm/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ func (a *agent) processGeneration(ctx context.Context, sessionID, content string
if err != nil {
if errors.Is(err, context.Canceled) {
agentMessage.AddFinish(message.FinishReasonCanceled)
a.messages.Update(context.Background(), agentMessage)
a.messages.Update(context.Background(), agentMessage) //nolint:errcheck
return a.err(ErrRequestCancelled)
}
return a.err(fmt.Errorf("failed to process events: %w", err))
Expand Down
4 changes: 2 additions & 2 deletions internal/llm/agent/mcp-tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (b *mcpTool) Info() tools.ToolInfo {
}

func runTool(ctx context.Context, c MCPClient, toolName string, input string) (tools.ToolResponse, error) {
defer c.Close()
defer c.Close() //nolint:errcheck
initRequest := mcp.InitializeRequest{}
initRequest.Params.ProtocolVersion = mcp.LATEST_PROTOCOL_VERSION
initRequest.Params.ClientInfo = mcp.Implementation{
Expand Down Expand Up @@ -158,7 +158,7 @@ func getTools(ctx context.Context, name string, m config.MCPServer, permissions
for _, t := range tools.Tools {
stdioTools = append(stdioTools, NewMcpTool(name, t, permissions, m))
}
defer c.Close()
defer c.Close() //nolint:errcheck
return stdioTools
}

Expand Down
2 changes: 1 addition & 1 deletion internal/llm/prompt/prompt.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func processContextPaths(workDir string, paths []string) string {
defer wg.Done()

if strings.HasSuffix(p, "/") {
filepath.WalkDir(filepath.Join(workDir, p), func(path string, d os.DirEntry, err error) error {
filepath.WalkDir(filepath.Join(workDir, p), func(path string, d os.DirEntry, err error) error { //nolint:errcheck
if err != nil {
return err
}
Expand Down
16 changes: 3 additions & 13 deletions internal/llm/provider/anthropic.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/anthropics/anthropic-sdk-go"
"github.com/anthropics/anthropic-sdk-go/bedrock"
"github.com/anthropics/anthropic-sdk-go/option"
"github.com/opencode-ai/opencode/internal/config"
"github.com/opencode-ai/opencode/internal/llm/tools"
"github.com/opencode-ai/opencode/internal/logging"
"github.com/opencode-ai/opencode/internal/message"
Expand Down Expand Up @@ -194,11 +193,6 @@ func (a *anthropicClient) preparedMessages(messages []anthropic.MessageParam, to

func (a *anthropicClient) send(ctx context.Context, messages []message.Message, tools []tools.BaseTool) (resposne *ProviderResponse, err error) {
preparedMessages := a.preparedMessages(a.convertMessages(messages), a.convertTools(tools))
cfg := config.Get()
if cfg.Debug {
// jsonData, _ := json.Marshal(preparedMessages)
// logging.Debug("Prepared messages", "messages", string(jsonData))
}
attempts := 0
for {
attempts++
Expand Down Expand Up @@ -241,11 +235,6 @@ func (a *anthropicClient) send(ctx context.Context, messages []message.Message,

func (a *anthropicClient) stream(ctx context.Context, messages []message.Message, tools []tools.BaseTool) <-chan ProviderEvent {
preparedMessages := a.preparedMessages(a.convertMessages(messages), a.convertTools(tools))
cfg := config.Get()
if cfg.Debug {
// jsonData, _ := json.Marshal(preparedMessages)
// logging.Debug("Prepared messages", "messages", string(jsonData))
}
attempts := 0
eventChan := make(chan ProviderEvent)
go func() {
Expand All @@ -268,9 +257,10 @@ func (a *anthropicClient) stream(ctx context.Context, messages []message.Message

switch event := event.AsAny().(type) {
case anthropic.ContentBlockStartEvent:
if event.ContentBlock.Type == "text" {
switch event.ContentBlock.Type {
case "text":
eventChan <- ProviderEvent{Type: EventContentStart}
} else if event.ContentBlock.Type == "tool_use" {
case "tool_use":
currentToolCallID = event.ContentBlock.ID
eventChan <- ProviderEvent{
Type: EventToolUseStart,
Expand Down
8 changes: 4 additions & 4 deletions internal/llm/provider/bedrock.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func newBedrockClient(opts providerClientOptions) BedrockClient {
if strings.Contains(string(opts.model.APIModel), "anthropic") {
// Create Anthropic client with Bedrock configuration
anthropicOpts := opts
anthropicOpts.anthropicOptions = append(anthropicOpts.anthropicOptions,
anthropicOpts.anthropicOptions = append(anthropicOpts.anthropicOptions,
WithAnthropicBedrock(true),
WithAnthropicDisableCache(),
)
Expand Down Expand Up @@ -84,7 +84,7 @@ func (b *bedrockClient) send(ctx context.Context, messages []message.Message, to

func (b *bedrockClient) stream(ctx context.Context, messages []message.Message, tools []tools.BaseTool) <-chan ProviderEvent {
eventChan := make(chan ProviderEvent)

if b.childProvider == nil {
go func() {
eventChan <- ProviderEvent{
Expand All @@ -95,6 +95,6 @@ func (b *bedrockClient) stream(ctx context.Context, messages []message.Message,
}()
return eventChan
}

return b.childProvider.stream(ctx, messages, tools)
}
}
9 changes: 5 additions & 4 deletions internal/llm/provider/gemini.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,10 @@ func (g *geminiClient) convertTools(tools []tools.BaseTool) []*genai.Tool {
}

func (g *geminiClient) finishReason(reason genai.FinishReason) message.FinishReason {
switch {
case reason == genai.FinishReasonStop:
switch reason {
case genai.FinishReasonStop:
return message.FinishReasonEndTurn
case reason == genai.FinishReasonMaxTokens:
case genai.FinishReasonMaxTokens:
return message.FinishReasonMaxTokens
default:
return message.FinishReasonUnknown
Expand Down Expand Up @@ -392,7 +392,7 @@ func (g *geminiClient) shouldRetry(attempts int, err error) (bool, int64, error)
}

errMsg := err.Error()
isRateLimit := false
var isRateLimit bool

// Check for common rate limit error messages
if contains(errMsg, "rate limit", "quota exceeded", "too many requests") {
Expand All @@ -411,6 +411,7 @@ func (g *geminiClient) shouldRetry(attempts int, err error) (bool, int64, error)
return true, int64(retryMs), nil
}

//lint:ignore U1000 will be used in the future
func (g *geminiClient) toolCalls(resp *genai.GenerateContentResponse) []message.ToolCall {
var toolCalls []message.ToolCall

Expand Down
2 changes: 1 addition & 1 deletion internal/llm/provider/openai.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func (o *openaiClient) preparedParams(messages []openai.ChatCompletionMessagePar
Tools: tools,
}

if o.providerOptions.model.CanReason == true {
if o.providerOptions.model.CanReason {
params.MaxCompletionTokens = openai.Int(o.providerOptions.maxTokens)
switch o.options.reasoningEffort {
case "low":
Expand Down
2 changes: 1 addition & 1 deletion internal/llm/tools/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ func (t *fetchTool) Run(ctx context.Context, call ToolCall) (ToolResponse, error
if err != nil {
return ToolResponse{}, fmt.Errorf("failed to fetch URL: %w", err)
}
defer resp.Body.Close()
defer resp.Body.Close() //nolint:errcheck

if resp.StatusCode != http.StatusOK {
return NewTextErrorResponse(fmt.Sprintf("Request failed with status code: %d", resp.StatusCode)), nil
Expand Down
2 changes: 1 addition & 1 deletion internal/llm/tools/grep.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ func fileContainsPattern(filePath string, pattern *regexp.Regexp) (bool, int, st
if err != nil {
return false, 0, "", err
}
defer file.Close()
defer file.Close() //nolint:errcheck

scanner := bufio.NewScanner(file)
lineNum := 0
Expand Down
Loading