Files

61 lines
1.5 KiB
Go

package registry
import (
"fmt"
"os"
"path/filepath"
"strings"
)
// emitModuleVersionHeader writes <dir_path>/version_generated.h for a module.
// The header exposes constants the C++ side can read:
//
// FN_MODULE_<NAME>_VERSION (const char*)
// FN_MODULE_<NAME>_NAME (const char*)
// FN_MODULE_<NAME>_DESCRIPTION (const char*)
//
// For C++ modules only (lang == "cpp"). For other langs, returns nil silently.
// Idempotent: only rewrites when content differs.
func emitModuleVersionHeader(m *Module, root string) error {
if m.Lang != "cpp" {
return nil
}
if m.DirPath == "" {
return nil
}
upper := strings.ToUpper(m.Name)
macroPrefix := "FN_MODULE_" + upper
guard := macroPrefix + "_VERSION_GENERATED_H"
body := fmt.Sprintf(`// Auto-generated by `+"`fn index`"+` — do not edit.
// Module: %s
// Source of truth: modules/%s/module.md
#ifndef %s
#define %s
#define %s_NAME %q
#define %s_VERSION %q
#define %s_DESCRIPTION %q
#endif // %s
`, m.Name, m.Name,
guard, guard,
macroPrefix, m.Name,
macroPrefix, m.Version,
macroPrefix, m.Description,
guard)
headerPath := filepath.Join(root, m.DirPath, "version_generated.h")
// Idempotent: skip write when content already matches.
if existing, err := os.ReadFile(headerPath); err == nil && string(existing) == body {
return nil
}
if err := os.MkdirAll(filepath.Dir(headerPath), 0o755); err != nil {
return fmt.Errorf("mkdir %s: %w", filepath.Dir(headerPath), err)
}
return os.WriteFile(headerPath, []byte(body), 0o644)
}