Skip to content

Commit

Permalink
feat: enable all golangci-lint linters (#229)
Browse files Browse the repository at this point in the history
  • Loading branch information
nobe4 authored Jan 2, 2025
1 parent 2817e50 commit dc40a12
Show file tree
Hide file tree
Showing 16 changed files with 81 additions and 63 deletions.
77 changes: 47 additions & 30 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,17 +1,47 @@
---
# Ref: https://golangci-lint.run/usage/configuration/
# Inspired by https://github.com/ccoVeille/golangci-lint-config-examples/
linters:
enable:
enable-all: true

disable:
# TODO: remove the line and fix the issues
- bodyclose
- cyclop
- depguard
- err113
- errorlint
- forbidigo
- gochecknoglobals
- gochecknoinits
- gomnd
- inamedparam
- ireturn
- lll
- musttag
- nestif
- paralleltest
- predeclared
- recvcheck
- revive
- gci
- thelper
- mirror
- usestdlibvars
- misspell
- dupword
- loggercheck
- fatcontext
- whitespace
- wrapcheck
- wsl

- nlreturn # keeps the code concise
- godox # I like leaving TODOs in the code
- varnamelen # short variable names are okay
- testpackage # keep the tests close to the code
- exhaustruct # it's ok not to specify all the fields in a struct definition

# deprecated
- mnd
- exportloopref

issues:
exclude-rules:
- path: _test.go
linters:
- funlen

linters-settings:
gci:
Expand All @@ -21,30 +51,17 @@ linters-settings:
- localmodule

revive:
enable-all-rules: true
rules:
- name: blank-imports
- name: context-as-argument
arguments:
- allowTypesBefore: "*testing.T"
- name: context-keys-type
- name: dot-imports
- name: empty-block
- name: error-naming
- name: error-return
- name: error-strings
- name: errorf
- name: increment-decrement
- name: indent-error-flow
- name: range
- name: receiver-naming
- name: redefines-builtin-id
- name: superfluous-else
- name: time-naming
- name: unexported-return
- name: unreachable-code
- name: unused-parameter
- name: var-declaration
- name: var-naming

tagliatelle:
case:
rules:
json: snake

misspell:
locale: US
mode: default
5 changes: 2 additions & 3 deletions internal/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ func NewFileCache(path string) *FileCache {

func (c *FileCache) Read(out any) error {
content, err := os.ReadFile(c.path)

if err != nil {
if errors.Is(err, os.ErrNotExist) {
slog.Debug("cache doesn't exist", "path", c.path)
Expand Down Expand Up @@ -94,9 +93,9 @@ func (c *FileCache) Write(in any) error {
return err
}

if err := os.MkdirAll(filepath.Dir(c.path), 0755); err != nil {
if err := os.MkdirAll(filepath.Dir(c.path), 0o755); err != nil {
return err
}

return os.WriteFile(c.path, marshaled, 0644)
return os.WriteFile(c.path, marshaled, 0o600)
}
12 changes: 5 additions & 7 deletions internal/cmd/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ import (
//go:embed actions-help.txt
var longHelp string

var (
actionsCmd = &cobra.Command{
Use: "actions",
Short: "Show information about the actions",
Long: "'gh-not' has multiple actions that perform different actions:\n\n" + longHelp,
}
)
var actionsCmd = &cobra.Command{
Use: "actions",
Short: "Show information about the actions",
Long: "'gh-not' has multiple actions that perform different actions:\n\n" + longHelp,
}

func init() {
rootCmd.AddCommand(actionsCmd)
Expand Down
3 changes: 2 additions & 1 deletion internal/cmd/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"errors"
"fmt"
"log/slog"
"os"
Expand Down Expand Up @@ -75,7 +76,7 @@ func editConfig() error {

editor := os.Getenv("EDITOR")
if editor == "" {
return fmt.Errorf("EDITOR environment variable not set")
return errors.New("EDITOR environment variable not set")
}

cmd := exec.Command(editor, config.Path)
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func filter(notifications notifications.Notifications) (notifications.Notificati

if !found {
slog.Error("Rule not found", "rule", ruleFlag)
return nil, fmt.Errorf("Rule '%s' not found", ruleFlag)
return nil, fmt.Errorf("rule '%s' not found", ruleFlag)
}
}

Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ See synchronization logic at https://pkg.go.dev/github.com/nobe4/gh-not/internal
func init() {
rootCmd.AddCommand(syncCmd)

syncCmd.Flags().VarP(&forceStrategy, "force-strategy", "f", fmt.Sprintf("Force strategy: %s", forceStrategy.Allowed()))
syncCmd.Flags().VarP(&refreshStrategy, "refresh-strategy", "r", fmt.Sprintf("Refresh strategy: %s", refreshStrategy.Allowed()))
syncCmd.Flags().VarP(&forceStrategy, "force-strategy", "f", "Force strategy: "+forceStrategy.Allowed())
syncCmd.Flags().VarP(&refreshStrategy, "refresh-strategy", "r", "Refresh strategy: "+refreshStrategy.Allowed())

syncCmd.Flags().StringVarP(&notificationDumpPath, "from-file", "", "", "Path to notification dump in JSON (generate with 'gh api /notifications')")
}
Expand Down
6 changes: 4 additions & 2 deletions internal/config/keymap.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import (
"github.com/charmbracelet/bubbles/key"
)

type Keymap map[string]KeyBindings
type KeyBindings map[string]KeyBinding
type (
Keymap map[string]KeyBindings
KeyBindings map[string]KeyBinding
)

type KeyBinding []string

Expand Down
4 changes: 2 additions & 2 deletions internal/gh/gh.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ package gh
import (
"encoding/json"
"errors"
"fmt"
"io"
"log/slog"
"net/http"
"net/url"
"regexp"
"strconv"

ghapi "github.com/cli/go-gh/v2/pkg/api"

Expand Down Expand Up @@ -45,7 +45,7 @@ func NewClient(api api.Requestor, cache cache.RefreshReadWriter, config config.E
query.Set("all", "true")
}
if config.PerPage > 0 && config.PerPage != 100 {
query.Set("per_page", fmt.Sprintf("%d", config.PerPage))
query.Set("per_page", strconv.Itoa(config.PerPage))
}
url.RawQuery = query.Encode()

Expand Down
1 change: 0 additions & 1 deletion internal/gh/gh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,6 @@ func TestEnrich(t *testing.T) {
notification *notifications.Notification
assertError func(*testing.T, error)
}{

{
name: "no notification",
},
Expand Down
3 changes: 2 additions & 1 deletion internal/manager/manager.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package manager

import (
"errors"
"fmt"
"log/slog"
"os"
Expand Down Expand Up @@ -63,7 +64,7 @@ func (m *Manager) Refresh() error {

func (m *Manager) refreshNotifications() error {
if m.client == nil {
return fmt.Errorf("manager has no client, cannot refresh notifications")
return errors.New("manager has no client, cannot refresh notifications")
}

fmt.Printf("Refreshing notifications...\n")
Expand Down
2 changes: 2 additions & 0 deletions internal/manager/strategies.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ func (r RefreshStrategy) ShouldRefresh(expired bool) bool {
slog.Info("preventing a refresh")
return false

case AutoRefresh:
fallthrough
default:
slog.Debug("refresh based on cache expiration", "expired", expired)
return expired
Expand Down
10 changes: 6 additions & 4 deletions internal/notifications/notifications.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import (
"time"
)

type Notifications []*Notification
type NotificationMap map[string]*Notification
type (
Notifications []*Notification
NotificationMap map[string]*Notification
)

type Notification struct {
// Standard API fields
Expand Down Expand Up @@ -167,7 +169,7 @@ func (n Notifications) IDList() []string {
return ids
}

// TODO: in-place update
// TODO: in-place update.
func (n Notifications) Compact() Notifications {
return slices.DeleteFunc(n, func(n *Notification) bool {
return n == nil
Expand All @@ -185,7 +187,7 @@ func (n Notifications) Sort() {
})
}

// TODO: in-place update
// TODO: in-place update.
func (n Notifications) Uniq() Notifications {
seenIDs := map[string]bool{}
return slices.DeleteFunc(n, func(n *Notification) bool {
Expand Down
2 changes: 1 addition & 1 deletion internal/notifications/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ It applies the following rules:
Notes on (2) Update: Updating the notification will also reset the `Meta.Done`
state if the remote notification is newer than the local one.
TODO: refactor this to `func (n Notifications) Sync(remote Notifications) {}`
TODO: refactor this to `func (n Notifications) Sync(remote Notifications) {}`.
*/
func Sync(local, remote Notifications) Notifications {
// TODO: do we need to have the whole map?
Expand Down
4 changes: 2 additions & 2 deletions internal/repl/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func (msg ApplyCommandMsg) apply(m model) (tea.Model, tea.Cmd) {

runner, ok := m.actions[msg.Command]
if !ok {
return m, m.renderResult(fmt.Errorf("Invalid command %s", msg.Command))
return m, m.renderResult(fmt.Errorf("invalid command %s", msg.Command))
}

m.resultStrings = []string{}
Expand Down Expand Up @@ -123,7 +123,7 @@ func (m model) applyNext() tea.Cmd {

slog.Debug("apply next", "notification", current.notification.String())

message := ""
var message string
out := &strings.Builder{}
if err := m.currentRun.Runner.Run(current.notification, m.currentRun.Args, out); err != nil {
message = fmt.Sprintf("Error for '%s': %s", current.notification.Subject.Title, err.Error())
Expand Down
1 change: 0 additions & 1 deletion internal/repl/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ func (m *model) handleCommand(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
}

func (m *model) handleResult(msg tea.KeyMsg) (tea.Model, tea.Cmd) {

switch {

case key.Matches(msg, m.list.KeyMap.ShowFullHelp):
Expand Down
8 changes: 3 additions & 5 deletions internal/repl/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import (
"github.com/charmbracelet/lipgloss"
)

var (
noStyle = lipgloss.NewStyle()
)
var noStyle = lipgloss.NewStyle()

func (m *model) initView() {
m.list.SetShowStatusBar(false)
Expand Down Expand Up @@ -112,8 +110,8 @@ func (m model) View() string {
return m.viewFullHelp()
}

content := ""
statusLine := ""
var content string
var statusLine string

if m.showResult {
content = m.result.View()
Expand Down

0 comments on commit dc40a12

Please sign in to comment.