diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..9065bc62 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,38 @@ +version: 2 +updates: + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "daily" + labels: + - "dependencies" + commit-message: + prefix: "feat" + include: "scope" + - package-ecosystem: "gomod" + directory: "/examples" + schedule: + interval: "daily" + labels: + - "dependencies" + commit-message: + prefix: "chore" + include: "scope" + - package-ecosystem: "gomod" + directory: "/tutorials" + schedule: + interval: "daily" + labels: + - "dependencies" + commit-message: + prefix: "chore" + include: "scope" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + labels: + - "dependencies" + commit-message: + prefix: "chore" + include: "scope" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..cadfe512 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,33 @@ +name: build +on: [push, pull_request] + +jobs: + build: + strategy: + matrix: + go-version: [~1.17, ^1] + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + env: + GO111MODULE: "on" + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Install Go + uses: actions/setup-go@v4 + with: + go-version: ${{ matrix.go-version }} + cache: true + + - name: Download Go modules + run: go mod download + working-directory: ./exp/teatest + + - name: Build + run: go build -v ./... + working-directory: ./exp/teatest + + - name: Test + run: go test -v ./... + working-directory: ./exp/teatest diff --git a/.github/workflows/lint-soft.yml b/.github/workflows/lint-soft.yml new file mode 100644 index 00000000..17418d4c --- /dev/null +++ b/.github/workflows/lint-soft.yml @@ -0,0 +1,27 @@ +name: lint-soft +on: + push: + pull_request: + +permissions: + contents: read + # Optional: allow read access to pull request. Use with `only-new-issues` option. + pull-requests: read + +jobs: + golangci: + name: lint-soft + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v4 + with: + go-version: stable + cache: true + - uses: golangci/golangci-lint-action@v3 + with: + # Optional: golangci-lint command line arguments. + args: --config .golangci-soft.yml --issues-exit-code=0 + # Optional: show only new issues if it's a pull request. The default value is `false`. + only-new-issues: true + working-directory: ./exp/teatest diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..5f5c0f3b --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,27 @@ +name: lint +on: + push: + pull_request: + +permissions: + contents: read + # Optional: allow read access to pull request. Use with `only-new-issues` option. + pull-requests: read + +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v4 + with: + go-version: stable + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + # Optional: golangci-lint command line arguments. + #args: + # Optional: show only new issues if it's a pull request. The default value is `false`. + only-new-issues: true + working-directory: ./exp/teatest diff --git a/.github/workflows/soft-serve.yml b/.github/workflows/soft-serve.yml new file mode 100644 index 00000000..8eb3221d --- /dev/null +++ b/.github/workflows/soft-serve.yml @@ -0,0 +1,12 @@ +name: soft-serve + +on: + push: + branches: + - master + +jobs: + soft-serve: + uses: charmbracelet/meta/.github/workflows/soft-serve.yml@main + secrets: + ssh-key: "${{ secrets.CHARM_SOFT_SERVE_KEY }}" diff --git a/.golangci-soft.yml b/.golangci-soft.yml new file mode 100644 index 00000000..55255e59 --- /dev/null +++ b/.golangci-soft.yml @@ -0,0 +1,47 @@ +run: + tests: false + +issues: + include: + - EXC0001 + - EXC0005 + - EXC0011 + - EXC0012 + - EXC0013 + + max-issues-per-linter: 0 + max-same-issues: 0 + +linters: + enable: + # - dupl + - exhaustive + # - exhaustivestruct + - goconst + - godot + - godox + - gomnd + - gomoddirectives + - goprintffuncname + # - ifshort + # - lll + - misspell + - nakedret + - nestif + - noctx + - nolintlint + - prealloc + - wrapcheck + + # disable default linters, they are already enabled in .golangci.yml + disable: + - deadcode + - errcheck + - gosimple + - govet + - ineffassign + - staticcheck + - structcheck + - typecheck + - unused + - varcheck diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..a5a91d0d --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,29 @@ +run: + tests: false + +issues: + include: + - EXC0001 + - EXC0005 + - EXC0011 + - EXC0012 + - EXC0013 + + max-issues-per-linter: 0 + max-same-issues: 0 + +linters: + enable: + - bodyclose + - exportloopref + - goimports + - gosec + - nilerr + - predeclared + - revive + - rowserrcheck + - sqlclosecheck + - tparallel + - unconvert + - unparam + - whitespace diff --git a/exp/teatest/teatest.go b/exp/teatest/teatest.go index e7ae6db9..c39aeaac 100644 --- a/exp/teatest/teatest.go +++ b/exp/teatest/teatest.go @@ -83,7 +83,7 @@ func WaitFor( func doWaitFor(r io.Reader, condition func(bts []byte) bool, options ...WaitForOption) error { wf := WaitingForContext{ Duration: time.Second, - CheckInterval: 50 * time.Millisecond, + CheckInterval: 50 * time.Millisecond, //nolint: gomnd } for _, opt := range options { @@ -227,19 +227,19 @@ func RequireEqualOutput(tb testing.TB, out []byte) { golden := filepath.Join("testdata", tb.Name()+".golden") if *update { - if err := os.MkdirAll(filepath.Dir(golden), 0o755); err != nil { // nolint: gomnd + if err := os.MkdirAll(filepath.Dir(golden), 0o755); err != nil { //nolint: gomnd tb.Fatal(err) } - if err := os.WriteFile(golden, out, 0o600); err != nil { // nolint: gomnd + if err := os.WriteFile(golden, out, 0o600); err != nil { //nolint: gomnd tb.Fatal(err) } } path := filepath.Join(tb.TempDir(), tb.Name()+".out") - if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { // nolint: gomnd + if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { //nolint: gomnd tb.Fatal(err) } - if err := os.WriteFile(path, out, 0o600); err != nil { // nolint: gomnd + if err := os.WriteFile(path, out, 0o600); err != nil { //nolint: gomnd tb.Fatal(err) } @@ -257,20 +257,22 @@ func safe(rw io.ReadWriter) io.ReadWriter { return &safeReadWriter{rw: rw} } +// safeReadWriter implements io.ReadWriter, but locks reads and writes. type safeReadWriter struct { rw io.ReadWriter - m sync.Mutex + m sync.RWMutex } -// Read implements io.ReadWriter +// Read implements io.ReadWriter. func (s *safeReadWriter) Read(p []byte) (n int, err error) { - s.m.Lock() - defer s.m.Unlock() - return s.rw.Read(p) + s.m.RLock() + defer s.m.RUnlock() + return s.rw.Read(p) //nolint: wrapcheck } +// Write implements io.ReadWriter. func (s *safeReadWriter) Write(p []byte) (int, error) { s.m.Lock() defer s.m.Unlock() - return s.rw.Write(p) + return s.rw.Write(p) //nolint: wrapcheck }