// +build hookgen package main // import "github.com/Azareal/Gosora/hook_gen" import ( "fmt" "log" "os" "bytes" "strings" "runtime/debug" "text/template" _ "github.com/Azareal/Gosora/extend" c "github.com/Azareal/Gosora/common" ) type HookVars struct { Imports []string Hooks []Hook } type Hook struct { Name string Params string Params2 string Ret string Type string Any bool } // TODO: Make sure all the errors in this file propagate upwards properly func main() { // Capture panics instead of closing the window at a superhuman speed before the user can read the message on Windows defer func() { if r := recover(); r != nil { fmt.Println(r) debug.PrintStack() return } }() hooks := make(map[string]int) for _, pl := range c.Plugins { if len(pl.Meta.Hooks) > 0 { for _, hook := range pl.Meta.Hooks { hooks[hook]++ } continue } if pl.Init != nil { if e := pl.Init(pl); e != nil { log.Print("early plugin init err: ", e) return } } if pl.Hooks != nil { log.Print("Hooks not nil for ", pl.UName) for hook, _ := range pl.Hooks { hooks[hook] += 1 } } } log.Printf("hooks: %+v\n", hooks) imports := []string{"net/http"} hookVars := HookVars{imports,nil} add := func(name, params, ret, htype string) { var params2 string first := true for _, param := range strings.Split(params,",") { if !first { params2 += "," } pspl := strings.Split(strings.ReplaceAll(strings.TrimSpace(param)," "," ")," ") params2 += pspl[0] first = false } hookVars.Hooks = append(hookVars.Hooks, Hook{name, params, params2, ret, htype, hooks[name] > 0}) } vhookskip := func(name, params string) { add(name,params,"(bool, RouteError)","VhookSkippable_") } vhookskip("forum_check_pre_perms","w http.ResponseWriter,r *http.Request,u *User,fid *int,h *Header") vhookskip("router_after_filters","w http.ResponseWriter,r *http.Request,prefix string") vhookskip("router_pre_route","w http.ResponseWriter,r *http.Request,u *User,prefix string") vhookskip("route_forum_list_start","w http.ResponseWriter,r *http.Request,u *User,h *Header") vhookskip("route_topic_list_start","w http.ResponseWriter,r *http.Request,u *User,h *Header") vhooknoret := func(name, params string) { add(name,params,"","Vhooks") } vhooknoret("router_end","w http.ResponseWriter,r *http.Request,u *User,prefix string,extraData string") vhooknoret("topic_reply_row_assign","r *ReplyUser") fileData := `// Code generated by Gosora's Hook Generator. DO NOT EDIT. /* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */ package common import ({{range .Imports}} "{{.}}"{{end}} ) {{range .Hooks}} func H_{{.Name}}_hook(t *HookTable, {{.Params}}) {{.Ret}} { {{if .Any}} hook := t.{{.Type}}["{{.Name}}"] if hook != nil { {{if .Ret}}return {{end}}hook({{.Params2}}) } {{end}} {{if .Ret}}return false, nil{{end}} }{{end}} ` tmpl := template.Must(template.New("hooks").Parse(fileData)) var b bytes.Buffer if e := tmpl.Execute(&b, hookVars); e != nil { log.Fatal(e) } writeFile("./common/gen_extend.go", string(b.Bytes())) log.Println("Successfully generated the hooks") } func writeFile(name, content string) { f, err := os.Create(name) if err != nil { log.Fatal(err) } _, err = f.WriteString(content) if err != nil { log.Fatal(err) } err = f.Sync() if err != nil { log.Fatal(err) } err = f.Close() if err != nil { log.Fatal(err) } }