mirror of
https://github.com/caddyserver/xcaddy.git
synced 2025-01-22 08:36:28 +01:00
cmd: add synthetic command validate-interfaces
The command is injected when running xcaddy with one of Caddy's commands, though `validate-interfaces` does not exist in Caddy itself. This is useful for [guest modules](https://caddyserver.com/docs/extending-caddy) developers to validate their implementation meets the expectation of the host module.
This commit is contained in:
parent
18eadf4260
commit
971664d22f
3 changed files with 44 additions and 4 deletions
|
@ -45,6 +45,15 @@ type Builder struct {
|
||||||
Debug bool `json:"debug,omitempty"`
|
Debug bool `json:"debug,omitempty"`
|
||||||
BuildFlags string `json:"build_flags,omitempty"`
|
BuildFlags string `json:"build_flags,omitempty"`
|
||||||
ModFlags string `json:"mod_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
|
// Build builds Caddy at the configured version with the
|
||||||
|
|
21
cmd/main.go
21
cmd/main.go
|
@ -223,6 +223,8 @@ func runDev(ctx context.Context, args []string) error {
|
||||||
SkipBuild: skipBuild,
|
SkipBuild: skipBuild,
|
||||||
SkipCleanup: skipCleanup,
|
SkipCleanup: skipCleanup,
|
||||||
Debug: buildDebugOutput,
|
Debug: buildDebugOutput,
|
||||||
|
ExtraImports: []string{`caddy "github.com/caddyserver/caddy/v2"`, `"fmt"`, `"github.com/spf13/cobra"`},
|
||||||
|
Prequels: []string{interfaceValidationCommand},
|
||||||
}
|
}
|
||||||
err = builder.Build(ctx, binOutput)
|
err = builder.Build(ctx, binOutput)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -439,3 +441,22 @@ func goModule() *debug.Module {
|
||||||
}
|
}
|
||||||
return mod
|
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
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
`
|
||||||
|
|
|
@ -51,7 +51,9 @@ func (b Builder) newEnvironment(ctx context.Context) (*environment, error) {
|
||||||
|
|
||||||
// create the context for the main module template
|
// create the context for the main module template
|
||||||
tplCtx := goModTemplateContext{
|
tplCtx := goModTemplateContext{
|
||||||
CaddyModule: caddyModulePath,
|
CaddyModule: caddyModulePath,
|
||||||
|
ExtraImports: b.ExtraImports,
|
||||||
|
Prequels: b.Prequels,
|
||||||
}
|
}
|
||||||
for _, p := range b.Plugins {
|
for _, p := range b.Plugins {
|
||||||
tplCtx.Plugins = append(tplCtx.Plugins, p.PackagePath)
|
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
|
// write the main module file to temporary folder
|
||||||
mainPath := filepath.Join(tempFolder, "main.go")
|
mainPath := filepath.Join(tempFolder, "main.go")
|
||||||
log.Printf("[INFO] Writing main module: %s\n%s", mainPath, buf.Bytes())
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -317,8 +319,10 @@ func (env environment) execGoGet(ctx context.Context, modulePath, moduleVersion,
|
||||||
}
|
}
|
||||||
|
|
||||||
type goModTemplateContext struct {
|
type goModTemplateContext struct {
|
||||||
CaddyModule string
|
CaddyModule string
|
||||||
Plugins []string
|
Plugins []string
|
||||||
|
ExtraImports []string
|
||||||
|
Prequels []string
|
||||||
}
|
}
|
||||||
|
|
||||||
const mainModuleTemplate = `package main
|
const mainModuleTemplate = `package main
|
||||||
|
@ -331,9 +335,15 @@ import (
|
||||||
{{- range .Plugins}}
|
{{- range .Plugins}}
|
||||||
_ "{{.}}"
|
_ "{{.}}"
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
{{- range .ExtraImports}}
|
||||||
|
{{.}}
|
||||||
|
{{- end}}
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
{{- range .Prequels}}
|
||||||
|
{{.}}
|
||||||
|
{{- end}}
|
||||||
caddycmd.Main()
|
caddycmd.Main()
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
Loading…
Reference in a new issue