diff --git a/builder.go b/builder.go index a9e4b78..aeca53d 100644 --- a/builder.go +++ b/builder.go @@ -45,6 +45,15 @@ type Builder struct { Debug bool `json:"debug,omitempty"` BuildFlags string `json:"build_flags,omitempty"` ModFlags string `json:"mod_flags,omitempty"` + + // Experimental: Inject extra imports into the build. These + // imports are to add Go modules that may be needed in the + // Prequels. + ExtraImports []string + // Experimental: Inject extra code before running Caddy's `main`. + // If any of the prequels requires an import, it's you responsibility + // to add the import to the ExtraImports slice. + Prequels []string } // Build builds Caddy at the configured version with the diff --git a/cmd/main.go b/cmd/main.go index ede7cd8..2077bbc 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -223,6 +223,8 @@ func runDev(ctx context.Context, args []string) error { SkipBuild: skipBuild, SkipCleanup: skipCleanup, Debug: buildDebugOutput, + ExtraImports: []string{`caddy "github.com/caddyserver/caddy/v2"`, `"fmt"`, `"github.com/spf13/cobra"`}, + Prequels: []string{interfaceValidationCommand}, } err = builder.Build(ctx, binOutput) if err != nil { @@ -439,3 +441,22 @@ func goModule() *debug.Module { } return mod } + +const interfaceValidationCommand = ` + caddycmd.RegisterCommand(caddycmd.Command{ + Name: "validate-interfaces", + Short: "Validate that all modules conform to their namespaces", + CobraFunc: func(cmd *cobra.Command) { + cmd.RunE = caddycmd.WrapCommandFuncForCobra(func(f caddycmd.Flags) (int, error) { + for _, v := range caddy.Modules() { + mod, _ := caddy.GetModule(v) + if ok, err := caddy.ConformsToNamespace(mod.New(), mod.ID.Namespace()); !ok { + return caddy.ExitCodeFailedStartup, fmt.Errorf("module %s does not conform to its namespace: %v", mod.ID, err) + } + } + fmt.Println("All modules conform to their namespaces.") + return caddy.ExitCodeSuccess, nil + }) + }, + }) +` diff --git a/environment.go b/environment.go index fc36e5b..ed191f4 100644 --- a/environment.go +++ b/environment.go @@ -51,7 +51,9 @@ func (b Builder) newEnvironment(ctx context.Context) (*environment, error) { // create the context for the main module template tplCtx := goModTemplateContext{ - CaddyModule: caddyModulePath, + CaddyModule: caddyModulePath, + ExtraImports: b.ExtraImports, + Prequels: b.Prequels, } for _, p := range b.Plugins { tplCtx.Plugins = append(tplCtx.Plugins, p.PackagePath) @@ -86,7 +88,7 @@ func (b Builder) newEnvironment(ctx context.Context) (*environment, error) { // write the main module file to temporary folder mainPath := filepath.Join(tempFolder, "main.go") log.Printf("[INFO] Writing main module: %s\n%s", mainPath, buf.Bytes()) - err = os.WriteFile(mainPath, buf.Bytes(), 0644) + err = os.WriteFile(mainPath, buf.Bytes(), 0o644) if err != nil { return nil, err } @@ -317,8 +319,10 @@ func (env environment) execGoGet(ctx context.Context, modulePath, moduleVersion, } type goModTemplateContext struct { - CaddyModule string - Plugins []string + CaddyModule string + Plugins []string + ExtraImports []string + Prequels []string } const mainModuleTemplate = `package main @@ -331,9 +335,15 @@ import ( {{- range .Plugins}} _ "{{.}}" {{- end}} + {{- range .ExtraImports}} + {{.}} + {{- end}} ) func main() { + {{- range .Prequels}} + {{.}} + {{- end}} caddycmd.Main() } `