Skip to content
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

Add golangci-lint configuration and appease some linters #13

Open
wants to merge 19 commits into
base: master
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
29 changes: 29 additions & 0 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: golangci-lint
on:
push:
branches:
- master
- main
pull_request:

permissions:
contents: read

jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.21'
cache: false
# Install libgit2-dev 1.5 for git2go
- run: sudo apt-get install -qqy wget
- run: wget http://archive.ubuntu.com/ubuntu/pool/universe/libg/libgit2/libgit2-{1.5,dev}_1.5.1+ds-1ubuntu1_amd64.deb
- run: sudo apt-get install -qqy ./*.deb
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: v1.54
121 changes: 121 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
---
linters:
enable-all: true
disable:
# Disabled to get codebase to pass the linter.
# We can enable these one at a time.
- cyclop
- forcetypeassert
- funlen
- gochecknoglobals
- gochecknoinits
- godox
- revive
- stylecheck
- wrapcheck
# Disabled permanently
- exhaustruct # structs may be uninitialized
- nlreturn # covered by wsl cuddle rules
- paralleltest # tests are acceptable in sequence
- goimports # conflicts with GCI
- depguard # manage using go.mod for now
- nonamedreturns # named returns are acceptable in short functions
# Deprecated
- exhaustivestruct
- scopelint
- interfacer
- maligned
- golint
- structcheck
- varcheck
- deadcode
- nosnakecase
- ifshort

severity:
default-severity: major

issues:
fast: false
max-issues-per-linter: 0
max-same-issues: 0
exclude-use-default: false
exclude-case-sensitive: true
exclude-rules:
- path: _test\.go
linters:
- gochecknoglobals
- errcheck
- wrapcheck
- gosec
- goerr113

linters-settings:
exhaustive:
default-signifies-exhaustive: true

errcheck:
exclude-functions:
- (*os.File).Close

gci:
sections:
- standard
- default
- prefix(github.com/getsolus/usysconf)

gomnd:
ignored-numbers: ['2', '4', '8', '16', '32', '64', '10']

gosec:
excludes: []

govet:
enable-all: true
disable:
- fieldalignment # misalignment is accepted

revive:
enable-all-rules: false
rules: # see https://github.com/mgechev/revive#recommended-configuration
- name: blank-imports
- name: context-as-argument
- name: context-keys-type
- name: dot-imports
- name: error-return
- name: error-strings
- name: error-naming
- name: exported
- name: if-return
- name: increment-decrement
- name: var-naming
- name: var-declaration
- name: package-comments
- name: range
- name: receiver-naming
- name: time-naming
- name: unexported-return
- name: indent-error-flow
- name: errorf
- name: empty-block
- name: superfluous-else
- name: unused-parameter
- name: unreachable-code
- name: redefines-builtin-id

stylecheck:
checks: [all]

tagalign:
order:
- zero
- short
- long
- desc
- cmd
- arg
- aliases
- help

varnamelen:
min-name-length: 1
11 changes: 1 addition & 10 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,7 @@ uninstall:
$(RMDIR_IF_EMPTY) $(BINDIR)

check:
$(GO) get -u golang.org/x/lint/golint
$(GO) get -u github.com/securego/gosec/cmd/gosec
$(GO) get -u honnef.co/go/tools/cmd/staticcheck
$(GO) get -u gitlab.com/opennota/check/cmd/aligncheck
$(GO) fmt -x ./...
$(GO) vet ./...
golint -set_exit_status `go list ./... | grep -v vendor`
gosec -exclude=G204 ./...
staticcheck ./...
aligncheck ./...
$(shell $(GO) env GOPATH)/bin/golangci-lint run
$(GO) test -cover ./...

vendor: check clean
Expand Down
13 changes: 7 additions & 6 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,23 @@ var Version string = "unknown"

// GlobalFlags contains the flags for all commands.
type GlobalFlags struct {
Debug bool `short:"d" long:"debug" help:"Run in debug mode."`
Chroot bool `short:"c" long:"chroot" help:"Specify that command is being run from a chrooted environment."`
Live bool `short:"l" long:"live" help:"Specify that command is being run from a live medium."`
Version kong.VersionFlag `short:"v" long:"version" help:"Print version and exit."`
Debug bool `short:"d" long:"debug" help:"Run in debug mode."`
Chroot bool `short:"c" long:"chroot" help:"Specify that command is being run from a chrooted environment."` //nolint:lll
Live bool `short:"l" long:"live" help:"Specify that command is being run from a live medium."`
Version kong.VersionFlag `short:"v" long:"version" help:"Print version and exit."`
}

type arguments struct {
GlobalFlags

Run run `cmd:"" aliases:"r" help:"Run specified trigger(s) to update the system configuration."`
Run run `cmd:"" aliases:"r" help:"Run specified trigger(s) to update the system configuration."`
List list `cmd:"" aliases:"ls" help:"List available triggers to run (user-specific)."`
Graph graph `cmd:"" aliases:"g" help:"Print the dependencies for all available triggers."`
Graph graph `cmd:"" aliases:"g" help:"Print the dependencies for all available triggers."`
}

func Parse() (*kong.Context, GlobalFlags) {
var args arguments
ctx := kong.Parse(&args, kong.Vars{"version": Version})

return ctx, args.GlobalFlags
}
4 changes: 3 additions & 1 deletion cli/graph.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ import (

type graph struct{}

// GraphDepsRun prints the usage for the requested command
// GraphDepsRun prints the usage for the requested command.
func (g graph) Run(flags GlobalFlags) error {
tm, err := config.LoadAll()
if err != nil {
return fmt.Errorf("failed to load triggers: %w", err)
}

tm.Graph(flags.Chroot, flags.Live).Print()

return nil
}
2 changes: 2 additions & 0 deletions cli/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ func (l list) Run(flags GlobalFlags) error {
if err != nil {
return fmt.Errorf("failed to load triggers: %w", err)
}

slog.Info("Available triggers:")
tm.Print(flags.Chroot, flags.Live)

return nil
}
9 changes: 7 additions & 2 deletions cli/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,22 @@ import (

type run struct {
Force bool `short:"f" long:"force" help:"Force run the configuration regardless if it should be skipped."`
DryRun bool `short:"n" long:"dry-run" help:"Test the configuration files without executing the specified binaries and arguments."`
DryRun bool `short:"n" long:"dry-run" help:"Test the configuration files without executing the specified binaries and arguments."` //nolint:lll

Triggers []string `arg:"" help:"Names of the triggers to run." optional:""`
}

var errNeedRoot = errors.New("you must have root privileges to run triggers")

func (r run) Run(flags GlobalFlags) error {
if os.Geteuid() != 0 {
return errors.New("you must have root privileges to run triggers")
return errNeedRoot
}

if util.IsChroot() {
flags.Chroot = true
}

if util.IsLive() {
flags.Live = true
}
Expand All @@ -64,5 +68,6 @@ func (r run) Run(flags GlobalFlags) error {
}
// Run triggers.
tm.Run(s, n)

return nil
}
16 changes: 16 additions & 0 deletions config/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,36 +35,47 @@ func Load(path string) (triggers.Map, error) {
logger.Debug("Directory not found")
return nil, nil
}

return nil, fmt.Errorf("failed to read triggers: %w", err)
}

tm := make(triggers.Map, len(entries))

logger.Debug("Scanning directory")

for _, entry := range entries {
if entry.IsDir() {
continue
}

name := entry.Name()
if !strings.HasSuffix(name, ".toml") {
continue
}

t := triggers.Trigger{
Name: strings.TrimSuffix(name, ".toml"),
Path: filepath.Clean(filepath.Join(path, name)),
}
logger.Debug("Trigger found", "name", t.Name)

err = t.Load(t.Path)
if err != nil {
return nil, err
}

err = t.Validate()
if err != nil {
return nil, fmt.Errorf("failed to read %s from %s: %w", name, path, err)
}

tm[t.Name] = t
}

if len(tm) == 0 {
logger.Debug("No triggers found")
}

return tm, nil
}

Expand All @@ -76,6 +87,7 @@ func LoadAll() (triggers.Map, error) {
if p, err := os.UserHomeDir(); err != nil {
paths = append(paths, p)
}

if os.Getuid() == 0 {
uname := os.Getenv("SUDO_USER")
if uname != "" && uname != "root" {
Expand All @@ -89,13 +101,17 @@ func LoadAll() (triggers.Map, error) {
}

tm := make(triggers.Map)

for _, path := range paths {
trig, err := Load(path)
if err != nil {
return nil, err
}

tm.Merge(trig)
}

slog.Info("Total triggers", "count", len(tm))

return tm, nil
}
4 changes: 2 additions & 2 deletions config/paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
package config

var (
// UsrDir is the path defined during build (Makefile) i.e. /usr/share/defaults/usysconf.d
// UsrDir is the path defined during build (Makefile) i.e. `/usr/share/defaults/usysconf.d`.
UsrDir string
// SysDir is the path defined during build (Makefile) i.e. /etc/usysconf.d
// SysDir is the path defined during build (Makefile) i.e. `/etc/usysconf.d`.
SysDir string
)
Loading