package main import ( "os" "path/filepath" "strings" ) // buildmodePluginViolation is one occurrence of a `-buildmode=plugin` build // target inside a plugin repo — the legacy `.so` compile that the wasm // migration retires (WO-WZ-009 lands this check; WO-WZ-017 activates it). type buildmodePluginViolation struct { file string line int snippet string } // buildmodePluginScanFiles names the build-orchestration files that legitimately // carry a `go build` invocation; we scan only these to avoid flagging docs or // generated Go that merely mentions the string. func buildmodePluginScanFiles(name string) bool { base := filepath.Base(name) switch base { case "Makefile", "makefile", "GNUmakefile": return true } return strings.HasSuffix(base, ".sh") } // checkBuildmodePlugin walks each plugin root's build files for a // `-buildmode=plugin` occurrence. A ported plugin builds wasm via // `ninja plugin build`; a lingering `.so` target means the port is incomplete. func checkBuildmodePlugin(roots []pluginScanTarget) []buildmodePluginViolation { var out []buildmodePluginViolation for _, target := range roots { _ = filepath.WalkDir(target.root, func(path string, d os.DirEntry, err error) error { if err != nil { return nil //nolint:nilerr // unreadable path is not a violation } if d.IsDir() { if d.Name() == ".git" || d.Name() == "node_modules" || d.Name() == "vendor" { return filepath.SkipDir } return nil } if !buildmodePluginScanFiles(path) { return nil } data, readErr := os.ReadFile(path) if readErr != nil { return nil } for i, line := range strings.Split(string(data), "\n") { if strings.Contains(line, "-buildmode=plugin") { rel := path if r, e := filepath.Rel(target.root, path); e == nil { rel = filepath.Join(target.display, r) } out = append(out, buildmodePluginViolation{ file: rel, line: i + 1, snippet: strings.TrimSpace(line), }) } } return nil }) } return out }