package dev import ( "bytes" "path/filepath" "text/template" "dappco.re/go/core/i18n" coreio "dappco.re/go/core/io" "forge.lthn.ai/core/cli/pkg/cli" ) func addTestGenCommand(parent *cli.Command) { testGenCmd := &cli.Command{ Use: "test-gen", Short: i18n.T("cmd.dev.api.test_gen.short"), Long: i18n.T("cmd.dev.api.test_gen.long"), RunE: func(cmd *cli.Command, args []string) error { if err := runTestGen(); err != nil { return cli.Wrap(err, i18n.Label("error")) } cli.Text(i18n.T("i18n.done.sync", "public API tests")) return nil }, } parent.AddCommand(testGenCmd) } func runTestGen() error { pkgDir := "pkg" internalDirs, err := coreio.Local.List(pkgDir) if err != nil { return cli.Wrap(err, "failed to read pkg directory") } for _, dir := range internalDirs { if !dir.IsDir() || dir.Name() == "core" { continue } serviceName := dir.Name() internalFile := filepath.Join(pkgDir, serviceName, serviceName+".go") publicDir := serviceName publicTestFile := filepath.Join(publicDir, serviceName+"_test.go") if !coreio.Local.IsFile(internalFile) { continue } symbols, err := getExportedSymbols(internalFile) if err != nil { return cli.Wrap(err, cli.Sprintf("error getting symbols for service '%s'", serviceName)) } if len(symbols) == 0 { continue } if err := generatePublicAPITestFile(publicDir, publicTestFile, serviceName, symbols); err != nil { return cli.Wrap(err, cli.Sprintf("error generating public API test file for service '%s'", serviceName)) } } return nil } const publicAPITestTemplate = `// Code generated by "core dev api test-gen"; DO NOT EDIT. package {{.ServiceName}} import ( impl "forge.lthn.ai/core/cli/{{.ServiceName}}" ) {{range .Symbols}} {{- if eq .Kind "type"}} type _ = impl.{{.Name}} {{- else if eq .Kind "const"}} const _ = impl.{{.Name}} {{- else if eq .Kind "var"}} var _ = impl.{{.Name}} {{- else if eq .Kind "func"}} var _ = impl.{{.Name}} {{- end}} {{end}} ` func generatePublicAPITestFile(dir, path, serviceName string, symbols []symbolInfo) error { if err := coreio.Local.EnsureDir(dir); err != nil { return err } tmpl, err := template.New("publicAPITest").Parse(publicAPITestTemplate) if err != nil { return err } data := struct { ServiceName string Symbols []symbolInfo }{ ServiceName: serviceName, Symbols: symbols, } var buf bytes.Buffer if err := tmpl.Execute(&buf, data); err != nil { return err } return coreio.Local.Write(path, buf.String()) }