feat: codeless plugin repos (plugin.mod, no Go) exempt from go.mod checks (WO-WZ-020)
A codeless .bnp repo has no go.mod by design — mirror the ninja CLI classifier (core bnp.IsCodelessRepo) and skip both the standalone-plugin go.mod checks and the backend replace-directive parse for such roots. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
482e4f9d43
commit
e03144e12d
@ -31,7 +31,9 @@ func init() {
|
||||
}
|
||||
}
|
||||
for _, target := range ctx.backendTargets {
|
||||
if samePath(target.root, ctx.backendDir) {
|
||||
// A codeless plugin repo (plugin.mod, no Go) has no go.mod by
|
||||
// design — nothing for the replace-directive check to parse.
|
||||
if samePath(target.root, ctx.backendDir) && !isCodelessPluginRepo(target.root) {
|
||||
for _, v := range checkCMSCoreSDKGoMod(target.root) {
|
||||
v.file = prefixDisplayPath(target.displayOrRoot(), v.file)
|
||||
cmsGoModViolations = append(cmsGoModViolations, v)
|
||||
|
||||
@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/mod/modfile"
|
||||
)
|
||||
@ -121,7 +122,30 @@ func checkCMSCoreSDKGoMod(root string) []pluginGoModViolation {
|
||||
return checkGoModForModuleReplaceDirective(filepath.Join(root, "go.mod"), blockCoreImportPrefix)
|
||||
}
|
||||
|
||||
// isCodelessPluginRepo mirrors the ninja CLI classifier (core
|
||||
// cmd/ninja/internal/bnp.IsCodelessRepo): a plugin.mod with no Go source at
|
||||
// the repo root is a codeless plugin (WO-WZ-020) — declarative-only, no
|
||||
// go.mod and no SDK version to pin.
|
||||
func isCodelessPluginRepo(root string) bool {
|
||||
if !fileExists(filepath.Join(root, "plugin.mod")) {
|
||||
return false
|
||||
}
|
||||
entries, err := os.ReadDir(root)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
for _, e := range entries {
|
||||
if !e.IsDir() && strings.HasSuffix(e.Name(), ".go") {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func checkStandalonePluginGoMod(root, requiredSDKVersion string) []pluginGoModViolation {
|
||||
if isCodelessPluginRepo(root) {
|
||||
return nil
|
||||
}
|
||||
goModPath := filepath.Join(root, "go.mod")
|
||||
parsed, violations := parseGoModForSafety(goModPath)
|
||||
if parsed == nil {
|
||||
|
||||
@ -102,3 +102,31 @@ require git.dev.alexdunmow.com/block/core v0.2.1
|
||||
t.Fatalf("checkStandalonePluginGoMod() returned %d violations, want 0: %#v", len(violations), violations)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckStandalonePluginGoModSkipsCodelessRepo(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
writeTestFile(t, filepath.Join(root, "plugin.mod"), "[plugin]\nname = \"fixture\"\nversion = \"0.1.0\"\n", 0644)
|
||||
writeTestFile(t, filepath.Join(root, "blocks", "blocks.yaml"), "blocks: []\n", 0644)
|
||||
|
||||
if !isCodelessPluginRepo(root) {
|
||||
t.Fatal("isCodelessPluginRepo() = false, want true for plugin.mod with no root Go source")
|
||||
}
|
||||
violations := checkStandalonePluginGoMod(root, "v0.2.1")
|
||||
if len(violations) != 0 {
|
||||
t.Fatalf("checkStandalonePluginGoMod() returned %d violations, want 0 for codeless repo: %#v", len(violations), violations)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckStandalonePluginGoModStillRequiresGoModWithRootGoSource(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
writeTestFile(t, filepath.Join(root, "plugin.mod"), "[plugin]\nname = \"fixture\"\nversion = \"0.1.0\"\n", 0644)
|
||||
writeTestFile(t, filepath.Join(root, "main.go"), "package main\nfunc main() {}\n", 0644)
|
||||
|
||||
if isCodelessPluginRepo(root) {
|
||||
t.Fatal("isCodelessPluginRepo() = true, want false with root Go source")
|
||||
}
|
||||
violations := checkStandalonePluginGoMod(root, "v0.2.1")
|
||||
if len(violations) != 1 || violations[0].rule != "missing-go-mod" {
|
||||
t.Fatalf("checkStandalonePluginGoMod() = %#v, want single missing-go-mod violation", violations)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user