ttempdir detects temporary directories not using t.TempDir
This code is based on tenv analyzer.
go install github.com/peczenyj/ttempdir/cmd/ttempdir@latestpackage main
import (
    "fmt"
    "io/ioutil"
    "os"
    "testing"
)
func TestMain(t *testing.T) {
    fmt.Println(os.TempDir())
    dir, err := os.MkdirTemp("", "foo")
    if err != nil {
        t.Fatalf("unable to create temporary directory %v", err)
    }
    defer os.RemoveAll(dir)
}
func TestMain2(t *testing.T) {
    fmt.Println(os.TempDir())
}
func helper() {
    dir, err := ioutil.TempDir("", "foo")
    if err != nil {
        panic(fmt.Errorf("unable to create temporary directory: %w", err))
    }
    defer os.RemoveAll(dir)
}$ ttempdir ./...
./main_test.go:11:14: os.TempDir() should be replaced by `t.TempDir()` in TestMain
./main_test.go:12:2: os.MkdirTemp() should be replaced by `t.TempDir()` in TestMain
./main_test.go:20:14: os.TempDir() should be replaced by `t.TempDir()` in TestMain2This linter defines two option flags: -linter.all and -linter.max-recursion-level
$ ttempdir -h
...
  -linter.all
        the all option will run against all methods in test file
  -linter.max-recursion-level uint
        max recursion level when checking nested arg calls (default 5)
...The option all will run against whole test files (_test.go) regardless of method/function signatures.
It is triggered by the flag -linter.all.
By default, only methods that take *testing.T, *testing.B, and testing.TB as arguments are checked.
package main
import (
    "fmt"
    "io/ioutil"
    "os"
    "testing"
)
func TestMain(t *testing.T) {
    fmt.Println(os.TempDir())
    dir, err := os.MkdirTemp("", "foo")
    if err != nil {
        t.Fatalf("unable to create temporary directory %v", err)
    }
    defer os.RemoveAll(dir)
}
func TestMain2(t *testing.T) {
    fmt.Println(os.TempDir())
}
func helper() {
    dir, err := ioutil.TempDir("", "foo")
    if err != nil {
        panic(fmt.Errorf("unable to create temporary directory: %w", err))
    }
    defer os.RemoveAll(dir)
}$ ttempdir -linter.all ./...
# a
./main_test.go:11:14: os.TempDir() should be replaced by `t.TempDir()` in TestMain
./main_test.go:12:2: os.MkdirTemp() should be replaced by `t.TempDir()` in TestMain
./main_test.go:20:14: os.TempDir() should be replaced by `t.TempDir()` in TestMain2
./main_test.go:24:2: ioutil.TempDir() should be replaced by `testing.TempDir()` in helperThis linter searches on argument lists in a recursive way. By default we limit to 5 the recursion level.
For instance, the example below will not emit any analysis report because os.TempDir() is called on a 6th level of recursion. If needed this can be updated via flag -linter.max-recursion-level.
    t.Log( // recursion level 1
        fmt.Sprintf("%s/foo-%d", // recursion level 2
            filepath.Join( // recursion level 3
                filepath.Clean( // recursion level 4
                    fmt.Sprintf("%s", // recursion level 5
                        os.TempDir(), // max recursion level reached.
                    ),
                ),
                "test",
            ),
            1024,
        ),
    )- run:
    name: install ttempdir
    command: go install github.com/peczenyj/ttempdir/cmd/ttempdir@latest
- run:
    name: run ttempdir
    command: ttempdir ./...- name: install ttempdir
  run: go install github.com/peczenyj/ttempdir/cmd/ttempdir@latest
- name: run ttempdir
  run: ttempdir ./...