pull/78/head
Hunter Long 2018-10-08 03:06:25 -07:00
parent 3d6daf0b90
commit 2ade95f14a
7 changed files with 185 additions and 130 deletions

View File

@ -45,7 +45,7 @@ build: compile
# build Statup plugins
build-plugin:
$(GOBUILD) $(BUILDVERSION) -buildmode=plugin -o $(BINARY_NAME) -v ./dev/plugin
$(GOBUILD) $(BUILDVERSION) -buildmode=plugin -o ./dev/plugin/example.so -v ./dev/plugin
# build Statup debug app
build-debug: compile

View File

@ -21,6 +21,7 @@ import (
"fmt"
"github.com/hunterlong/statup/core"
"github.com/hunterlong/statup/handlers"
"github.com/hunterlong/statup/plugin"
"github.com/hunterlong/statup/source"
"github.com/hunterlong/statup/utils"
"github.com/joho/godotenv"
@ -80,7 +81,7 @@ func CatchCLI(args []string) error {
cmd := args[1]
switch cmd {
case "plugins":
LoadPlugins(true)
plugin.LoadPlugins(true)
}
return errors.New("end")
case "export":

View File

@ -21,6 +21,7 @@ import (
"github.com/hunterlong/statup/core"
"github.com/hunterlong/statup/handlers"
_ "github.com/hunterlong/statup/notifiers"
"github.com/hunterlong/statup/plugin"
"github.com/hunterlong/statup/source"
"github.com/hunterlong/statup/utils"
"github.com/joho/godotenv"
@ -108,7 +109,7 @@ func mainProcess() {
core.Configs.MigrateDatabase()
core.InitApp()
if !core.SetupMode {
LoadPlugins(false)
plugin.LoadPlugins(false)
fmt.Println(handlers.RunHTTPServer(ipAddress, port))
os.Exit(1)
}
@ -121,65 +122,3 @@ func ForEachPlugin() {
//}
}
}
func LoadPlugins(debug bool) {
//utils.Log(1, fmt.Sprintf("Loading any available Plugins from /plugins directory"))
//if _, err := os.Stat("./plugins"); os.IsNotExist(err) {
// os.Mkdir("./plugins", os.ModePerm)
//}
//
////ForEachPlugin()
//files, err := ioutil.ReadDir("./plugins")
//if err != nil {
// utils.Log(2, fmt.Sprintf("Plugins directory was not found. Error: %v\n", err))
// return
//}
//for _, f := range files {
// utils.Log(1, fmt.Sprintf("Attempting to load plugin '%v'", f.Name()))
// ext := strings.Split(f.Name(), ".")
// if len(ext) != 2 {
// utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
// continue
// }
// if ext[1] != "so" {
// utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
// continue
// }
// plug, err := plg.Open("plugins/" + f.Name())
// if err != nil {
// utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
// continue
// }
// symPlugin, err := plug.Lookup("Plugin")
// if err != nil {
// utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
// continue
// }
//
// if debug {
// utils.Log(1, fmt.Sprintf("Plugin '%v' struct:", f.Name()))
// utils.Log(1, structs.Map(symPlugin))
// }
//
// var plugActions types.PluginActions
// plugActions, ok := symPlugin.(types.PluginActions)
// if !ok {
// utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly, error: %v", f.Name(), err))
// if debug {
// //fmt.Println(symPlugin.(plugin.PluginActions))
// }
// continue
// }
//
// if debug {
// TestPlugin(plugActions)
// } else {
// plugActions.OnLoad(*core.DbSession)
// core.CoreApp.Plugins = append(core.CoreApp.Plugins, plugActions.GetInfo())
// core.CoreApp.AllPlugins = append(core.CoreApp.AllPlugins, plugActions)
// }
//}
//if !debug {
// utils.Log(1, fmt.Sprintf("Loaded %v Plugins\n", len(core.CoreApp.Plugins)))
//}
}

22
dev/plugin/main.go Normal file
View File

@ -0,0 +1,22 @@
package main
import (
"github.com/hunterlong/statup/plugin"
)
type Example struct {
*plugin.Plugin
}
var example = &Example{&plugin.Plugin{
Name: "Example",
Description: "This is an example plugin",
}}
func main() {
}
func (e *Example) Select() *plugin.Plugin {
return e.Plugin
}

69
plugin/interfaces.go Normal file
View File

@ -0,0 +1,69 @@
package plugin
import (
"github.com/hunterlong/statup/core/notifier"
"github.com/jinzhu/gorm"
"net/http"
)
type PluginObject struct {
PluginInfo
}
type Pluginer interface {
Select() *PluginObject
}
type Databaser interface {
StatupDatabase(*gorm.DB)
}
type Router interface {
Routes() []interface{}
AddRoute(string, string, http.HandlerFunc) error
}
type Asseter interface {
Asset(string) ([]byte, error)
}
type Notifier interface {
notifier.Notifier
notifier.BasicEvents
}
type AdvancedNotifier interface {
notifier.Notifier
notifier.BasicEvents
notifier.UserEvents
notifier.CoreEvents
notifier.NotifierEvents
}
type Routing struct {
URL string
Method string
Handler func(http.ResponseWriter, *http.Request)
}
type Info struct {
Name string
Description string
Form string
}
type Database *gorm.DB
type Plugin struct {
Name string
Description string
}
type PluginDatabase interface {
Database(gorm.DB)
Update() error
}
type PluginInfo struct {
i *Info
}

View File

@ -16,9 +16,16 @@
package plugin
import (
"github.com/hunterlong/statup/core/notifier"
"github.com/jinzhu/gorm"
"fmt"
"github.com/fatih/structs"
"github.com/hunterlong/statup/core"
"github.com/hunterlong/statup/types"
"github.com/hunterlong/statup/utils"
"io/ioutil"
"net/http"
"os"
"plugin"
"strings"
)
//
@ -33,12 +40,16 @@ import (
// work even if there's an update or addition.
//
type PluginObject struct{}
var (
AllPlugins []*PluginObject
dir string
)
func init() {
utils.InitLogs()
dir = utils.Directory
}
func Add(p Pluginer) *PluginObject {
return &PluginObject{}
}
@ -47,67 +58,65 @@ func (p *PluginObject) AddRoute(s string, i string, f http.HandlerFunc) {
}
type Pluginer interface {
Select() *PluginObject
}
type Databaser interface {
StatupDatabase(*gorm.DB)
}
type Router interface {
AddRoute(string, string, http.HandlerFunc) error
}
type Notifier interface {
notifier.Notifier
notifier.BasicEvents
}
type AdvancedNotifier interface {
notifier.Notifier
notifier.BasicEvents
notifier.UserEvents
notifier.CoreEvents
notifier.NotifierEvents
}
var (
DB *gorm.DB
)
type Routing struct {
URL string
Method string
Handler func(http.ResponseWriter, *http.Request)
}
type Info struct {
Name string
Description string
Form string
}
type Database *gorm.DB
type Plugin struct {
Name string
Description string
}
type PluginDatabase interface {
Database(gorm.DB)
Update() error
}
type PluginInfo struct {
i *Info
}
func SetDatabase(database *gorm.DB) {
DB = database
}
func (p *PluginInfo) Form() string {
return "okkokokkok"
}
func LoadPlugins(debug bool) {
pluginDir := dir + "/plugins"
utils.Log(1, fmt.Sprintf("Loading any available Plugins from /plugins directory"))
if _, err := os.Stat(pluginDir); os.IsNotExist(err) {
os.Mkdir(pluginDir, os.ModePerm)
}
//ForEachPlugin()
files, err := ioutil.ReadDir(pluginDir)
if err != nil {
utils.Log(2, fmt.Sprintf("Plugins directory was not found. Error: %v\n", err))
return
}
for _, f := range files {
utils.Log(1, fmt.Sprintf("Attempting to load plugin '%v'", f.Name()))
ext := strings.Split(f.Name(), ".")
if len(ext) != 2 {
utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
continue
}
if ext[1] != "so" {
utils.Log(3, fmt.Sprintf("Plugin '%v' must end in .so extension", f.Name()))
continue
}
plug, err := plugin.Open("plugins/" + f.Name())
if err != nil {
utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
continue
}
symPlugin, err := plug.Lookup("Plugin")
if err != nil {
utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly. %v", f.Name(), err))
continue
}
if debug {
utils.Log(1, fmt.Sprintf("Plugin '%v' struct:", f.Name()))
utils.Log(1, structs.Map(symPlugin))
}
var plugActions types.PluginActions
plugActions, ok := symPlugin.(types.PluginActions)
if !ok {
utils.Log(3, fmt.Sprintf("Plugin '%v' could not load correctly, error: %v", f.Name(), err))
if debug {
//fmt.Println(symPlugin.(plugin.PluginActions))
}
continue
}
plugActions.OnLoad(*core.DbSession)
core.CoreApp.Plugins = append(core.CoreApp.Plugins, plugActions.GetInfo())
core.CoreApp.AllPlugins = append(core.CoreApp.AllPlugins, plugActions)
}
if !debug {
utils.Log(1, fmt.Sprintf("Loaded %v Plugins\n", len(core.CoreApp.Plugins)))
}
}

View File

@ -16,6 +16,8 @@
package plugin
import (
"github.com/hunterlong/statup/source"
"github.com/hunterlong/statup/utils"
"github.com/jinzhu/gorm"
"github.com/stretchr/testify/assert"
"net/http"
@ -27,6 +29,11 @@ var (
example *PluginObject
)
func init() {
utils.InitLogs()
source.Assets()
}
func (p *PluginObject) StatupDatabase(db *gorm.DB) {
database = db
}
@ -35,10 +42,18 @@ func (p *PluginObject) Select() *PluginObject {
return p
}
func (p *PluginObject) Info() *PluginObject {
return p
}
func setupHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok"))
}
func TestLoadPlugins(t *testing.T) {
LoadPlugins(false)
}
func TestAdd(t *testing.T) {
err := Add(example)
assert.NotNil(t, err)