From 26d803fc96c8dbdec5f15768744cb776f5b9699b Mon Sep 17 00:00:00 2001 From: Godsgift Uloamaka Ebite Date: Fri, 24 Oct 2025 17:26:03 +0100 Subject: [PATCH] package-directory-mismatch: ignore mismatch in root directory (#1548) --- rule/package_directory_mismatch.go | 29 ++++++++++++++++++- test/package_directory_mismatch_test.go | 8 +++++ test/utils_test.go | 24 +++++++++++++++ .../rootdir/bad/client.go | 1 + .../rootdir/good/client.go | 1 + .../rootdir/good/go.mod | 1 + .../rootdir/withgit/client.go | 1 + 7 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 testdata/package_directory_mismatch/rootdir/bad/client.go create mode 100644 testdata/package_directory_mismatch/rootdir/good/client.go create mode 100644 testdata/package_directory_mismatch/rootdir/good/go.mod create mode 100644 testdata/package_directory_mismatch/rootdir/withgit/client.go diff --git a/rule/package_directory_mismatch.go b/rule/package_directory_mismatch.go index a0487fb..7178054 100644 --- a/rule/package_directory_mismatch.go +++ b/rule/package_directory_mismatch.go @@ -2,6 +2,7 @@ package rule import ( "fmt" + "os" "path/filepath" "regexp" "strings" @@ -96,7 +97,12 @@ func (r *PackageDirectoryMismatchRule) Apply(file *lint.File, _ lint.Arguments) return nil } - dirPath := filepath.Dir(file.Name) + absPath, err := filepath.Abs(file.Name) + if err != nil { + return nil + } + + dirPath := filepath.Dir(absPath) dirName := filepath.Base(dirPath) if r.ignoredDirs != nil && r.ignoredDirs.MatchString(dirPath) { @@ -120,6 +126,10 @@ func (r *PackageDirectoryMismatchRule) Apply(file *lint.File, _ lint.Arguments) return nil } + if isRootDir(dirPath) { + return nil + } + if file.IsTest() { // treat main_test differently because it's a common package name for tests if packageName == "main_test" { @@ -161,6 +171,23 @@ func (r *PackageDirectoryMismatchRule) Apply(file *lint.File, _ lint.Arguments) } } +// isRootDir checks if the given directory contains go.mod or .git, indicating it's a root directory. +func isRootDir(dirPath string) bool { + entries, err := os.ReadDir(dirPath) + if err != nil { + return false + } + + for _, e := range entries { + switch e.Name() { + case "go.mod", ".git": + return true + } + } + + return false +} + // Name returns the rule name. func (*PackageDirectoryMismatchRule) Name() string { return "package-directory-mismatch" diff --git a/test/package_directory_mismatch_test.go b/test/package_directory_mismatch_test.go index b6e076c..097661c 100644 --- a/test/package_directory_mismatch_test.go +++ b/test/package_directory_mismatch_test.go @@ -55,6 +55,14 @@ func TestPackageDirectoryMismatch(t *testing.T) { testRule(t, "package_directory_mismatch/test/bad_test", &rule.PackageDirectoryMismatchRule{}, config) testRule(t, "package_directory_mismatch/test/bad", &rule.PackageDirectoryMismatchRule{}, config) testRule(t, "package_directory_mismatch/test/main_test", &rule.PackageDirectoryMismatchRule{}, config) + + // Test handling of root directories with go.mod + testRule(t, "package_directory_mismatch/rootdir/good/client", &rule.PackageDirectoryMismatchRule{}, config) + testRule(t, "package_directory_mismatch/rootdir/bad/client", &rule.PackageDirectoryMismatchRule{}, config) + + // Test handling of root directories with .git + mkdirTempDotGit(t, "package_directory_mismatch/rootdir/withgit") + testRule(t, "package_directory_mismatch/rootdir/withgit/client", &rule.PackageDirectoryMismatchRule{}, config) } func TestPackageDirectoryMismatchWithDefaultConfig(t *testing.T) { diff --git a/test/utils_test.go b/test/utils_test.go index 209851d..e33a92d 100644 --- a/test/utils_test.go +++ b/test/utils_test.go @@ -412,3 +412,27 @@ func TestExportedType(t *testing.T) { } } } + +// mkdirTempDotGit adds a temporary .git directory to the given root directory in testdata. +// We can't commit .git directly because of the Git restrictions. +func mkdirTempDotGit(t *testing.T, root string) { + t.Helper() + + baseDir := filepath.Join("..", "testdata", root) + dir, err := filepath.Abs(baseDir) + if err != nil { + t.Fatalf("Failed to resolve abs path: %v", err) + } + + gitDir := filepath.Join(dir, ".git") + if err := os.MkdirAll(gitDir, 0o755); err != nil { + t.Fatalf("Failed to create .git directory: %v", err) + } + + t.Cleanup(func() { + err = os.RemoveAll(gitDir) + if err != nil { + t.Logf("Failed to remove %v: %v", gitDir, err) + } + }) +} diff --git a/testdata/package_directory_mismatch/rootdir/bad/client.go b/testdata/package_directory_mismatch/rootdir/bad/client.go new file mode 100644 index 0000000..782e3a5 --- /dev/null +++ b/testdata/package_directory_mismatch/rootdir/bad/client.go @@ -0,0 +1 @@ +package somepackage // MATCH /package name "somepackage" does not match directory name "bad"/ diff --git a/testdata/package_directory_mismatch/rootdir/good/client.go b/testdata/package_directory_mismatch/rootdir/good/client.go new file mode 100644 index 0000000..7df2116 --- /dev/null +++ b/testdata/package_directory_mismatch/rootdir/good/client.go @@ -0,0 +1 @@ +package somepackage diff --git a/testdata/package_directory_mismatch/rootdir/good/go.mod b/testdata/package_directory_mismatch/rootdir/good/go.mod new file mode 100644 index 0000000..548b224 --- /dev/null +++ b/testdata/package_directory_mismatch/rootdir/good/go.mod @@ -0,0 +1 @@ +module "example.com/project" diff --git a/testdata/package_directory_mismatch/rootdir/withgit/client.go b/testdata/package_directory_mismatch/rootdir/withgit/client.go new file mode 100644 index 0000000..66b5e93 --- /dev/null +++ b/testdata/package_directory_mismatch/rootdir/withgit/client.go @@ -0,0 +1 @@ +package somePackage