Extract Lua infrastructure into a plugin

This commit is contained in:
Simon Ser 2020-01-20 22:04:50 +01:00
parent efa0816333
commit b58c15d121
No known key found for this signature in database
GPG key ID: 0FDE7BE0E88F5E48
7 changed files with 32 additions and 24 deletions

1
.gitignore vendored
View file

@ -3,3 +3,4 @@
!/public/themes/sourcehut !/public/themes/sourcehut
/plugins/* /plugins/*
!/plugins/base !/plugins/base
!/plugins/lua

View file

@ -13,6 +13,7 @@ import (
"github.com/labstack/gommon/log" "github.com/labstack/gommon/log"
_ "git.sr.ht/~emersion/koushin/plugins/base" _ "git.sr.ht/~emersion/koushin/plugins/base"
_ "git.sr.ht/~emersion/koushin/plugins/lua"
) )
func main() { func main() {

View file

@ -6,7 +6,8 @@ import (
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
) )
const pluginDir = "plugins" // PluginDir is the path to the plugins directory.
const PluginDir = "plugins"
// Plugin extends koushin with additional functionality. // Plugin extends koushin with additional functionality.
type Plugin interface { type Plugin interface {

View file

@ -19,7 +19,7 @@ func (p *goPlugin) Name() string {
func (p *goPlugin) LoadTemplate(t *template.Template) error { func (p *goPlugin) LoadTemplate(t *template.Template) error {
t.Funcs(p.p.templateFuncs) t.Funcs(p.p.templateFuncs)
paths, err := filepath.Glob(pluginDir + "/" + p.p.Name + "/public/*.html") paths, err := filepath.Glob(PluginDir + "/" + p.p.Name + "/public/*.html")
if err != nil { if err != nil {
return err return err
} }
@ -40,7 +40,7 @@ func (p *goPlugin) SetRoutes(group *echo.Group) {
}) })
} }
group.Static("/plugins/"+p.p.Name+"/assets", pluginDir+"/"+p.p.Name+"/public/assets") group.Static("/plugins/"+p.p.Name+"/assets", PluginDir+"/"+p.p.Name+"/public/assets")
} }
func (p *goPlugin) Inject(ctx *Context, name string, data RenderData) error { func (p *goPlugin) Inject(ctx *Context, name string, data RenderData) error {

View file

@ -1,4 +1,4 @@
package koushin package koushinlua
import ( import (
"fmt" "fmt"
@ -8,6 +8,7 @@ import (
"github.com/labstack/echo/v4" "github.com/labstack/echo/v4"
"github.com/yuin/gopher-lua" "github.com/yuin/gopher-lua"
"layeh.com/gopher-luar" "layeh.com/gopher-luar"
"git.sr.ht/~emersion/koushin"
) )
type luaRoute struct { type luaRoute struct {
@ -68,7 +69,7 @@ func (p *luaPlugin) setRoute(l *lua.LState) int {
return 0 return 0
} }
func (p *luaPlugin) inject(name string, data RenderData) error { func (p *luaPlugin) inject(name string, data koushin.RenderData) error {
f, ok := p.renderCallbacks[name] f, ok := p.renderCallbacks[name]
if !ok { if !ok {
return nil return nil
@ -86,7 +87,7 @@ func (p *luaPlugin) inject(name string, data RenderData) error {
return nil return nil
} }
func (p *luaPlugin) Inject(ctx *Context, name string, data RenderData) error { func (p *luaPlugin) Inject(ctx *koushin.Context, name string, data koushin.RenderData) error {
if err := p.inject("*", data); err != nil { if err := p.inject("*", data); err != nil {
return err return err
} }
@ -157,21 +158,24 @@ func loadLuaPlugin(filename string) (*luaPlugin, error) {
return p, nil return p, nil
} }
func loadAllLuaPlugins(log echo.Logger) ([]Plugin, error) { func loadAllLuaPlugins(s *koushin.Server) ([]koushin.Plugin, error) {
filenames, err := filepath.Glob(pluginDir + "/*/main.lua") log := s.Logger()
filenames, err := filepath.Glob(koushin.PluginDir + "/*/main.lua")
if err != nil { if err != nil {
return nil, fmt.Errorf("filepath.Glob failed: %v", err) return nil, fmt.Errorf("filepath.Glob failed: %v", err)
} }
plugins := make([]Plugin, 0, len(filenames)) plugins := make([]koushin.Plugin, 0, len(filenames))
for _, filename := range filenames { for _, filename := range filenames {
log.Printf("Loading Lua plugin '%v'", filename) log.Printf("Loading Lua plugin %q", filename)
p, err := loadLuaPlugin(filename) p, err := loadLuaPlugin(filename)
if err != nil { if err != nil {
for _, p := range plugins { for _, p := range plugins {
p.Close() p.Close()
} }
return nil, fmt.Errorf("failed to load Lua plugin '%v': %v", filename, err) return nil, fmt.Errorf("failed to load Lua plugin %q: %v", filename, err)
} }
plugins = append(plugins, p) plugins = append(plugins, p)
} }

9
plugins/lua/plugin.go Normal file
View file

@ -0,0 +1,9 @@
package koushinlua
import (
"git.sr.ht/~emersion/koushin"
)
func init() {
koushin.RegisterPluginLoader(loadAllLuaPlugins)
}

View file

@ -18,9 +18,8 @@ type Server struct {
e *echo.Echo e *echo.Echo
Sessions *SessionManager Sessions *SessionManager
mutex sync.RWMutex // used for server reload mutex sync.RWMutex // used for server reload
plugins []Plugin plugins []Plugin
luaPlugins []Plugin
// maps protocols to URLs (protocol can be empty for auto-discovery) // maps protocols to URLs (protocol can be empty for auto-discovery)
upstreams map[string]*url.URL upstreams map[string]*url.URL
@ -188,12 +187,6 @@ func (s *Server) load() error {
plugins = append(plugins, l...) plugins = append(plugins, l...)
} }
luaPlugins, err := loadAllLuaPlugins(s.e.Logger)
if err != nil {
return fmt.Errorf("failed to load plugins: %v", err)
}
plugins = append(plugins, luaPlugins...)
renderer := newRenderer(s.e.Logger, s.defaultTheme) renderer := newRenderer(s.e.Logger, s.defaultTheme)
if err := renderer.Load(plugins); err != nil { if err := renderer.Load(plugins); err != nil {
return fmt.Errorf("failed to load templates: %v", err) return fmt.Errorf("failed to load templates: %v", err)
@ -204,15 +197,14 @@ func (s *Server) load() error {
s.mutex.Lock() s.mutex.Lock()
defer s.mutex.Unlock() defer s.mutex.Unlock()
// Close previous Lua plugins // Close previous plugins
for _, p := range s.luaPlugins { for _, p := range s.plugins {
if err := p.Close(); err != nil { if err := p.Close(); err != nil {
s.e.Logger.Printf("Failed to unload plugin '%v': %v", p.Name(), err) s.e.Logger.Printf("Failed to unload plugin %q: %v", p.Name(), err)
} }
} }
s.plugins = plugins s.plugins = plugins
s.luaPlugins = luaPlugins
s.e.Renderer = renderer s.e.Renderer = renderer
for _, p := range plugins { for _, p := range plugins {