Extract Lua infrastructure into a plugin
This commit is contained in:
parent
efa0816333
commit
b58c15d121
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,3 +3,4 @@
|
||||||
!/public/themes/sourcehut
|
!/public/themes/sourcehut
|
||||||
/plugins/*
|
/plugins/*
|
||||||
!/plugins/base
|
!/plugins/base
|
||||||
|
!/plugins/lua
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
9
plugins/lua/plugin.go
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
package koushinlua
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.sr.ht/~emersion/koushin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
koushin.RegisterPluginLoader(loadAllLuaPlugins)
|
||||||
|
}
|
18
server.go
18
server.go
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue