From: Gordon Hecker Date: Thu, 18 Jun 2009 18:29:29 +0000 (+0200) Subject: plugin support: load local plugins X-Git-Tag: e2factory-2.3.4pre1~75 X-Git-Url: https://git.e2factory.org/?a=commitdiff_plain;h=ba82a25032d1f8c53e48c83d9ae719c31421df65;p=e2factory.git plugin support: load local plugins Signed-off-by: Gordon Hecker --- diff --git a/generic/Makefile b/generic/Makefile index eac84cb..ce4072e 100644 --- a/generic/Makefile +++ b/generic/Makefile @@ -56,6 +56,7 @@ local: e2generic_local.lc luafile_ll_local.so e2util_local.so sha1.so install-local: local mkdir -p $(LOCALLIBDIR) $(LOCALMAKDIR) + install -m 755 -d $(LOCALPLUGINDIR) install -m 644 e2generic_local.lc $(LOCALLIBDIR) install -m 755 sha1.so $(LOCALLIBDIR) install -m 755 luafile_ll_local.so $(LOCALLIBDIR) @@ -76,6 +77,7 @@ clean: rm -f $(CLEAN_FILES) e2generic_global.lc: strict.lua collection.lua e2lib_global_prefix.lua \ + plugin.lua \ e2lib.lua e2option.lua hash.lua \ transport.lua cache.lua url.lua scm.git.lua \ luafile.lua lua-version-map.lua \ diff --git a/generic/e2lib.lua b/generic/e2lib.lua index eee567d..b09bc40 100644 --- a/generic/e2lib.lua +++ b/generic/e2lib.lua @@ -551,6 +551,10 @@ function e2lib.finish(returncode) if not returncode then returncode = 0 end + local rc, re = plugin.exit_plugins() + if not rc then + e2lib.logf(1, "deinitializing plugins failed (ignoring)") + end e2lib.rmtempdirs() e2lib.rmtempfiles() e2lib.lock:cleanup() diff --git a/generic/plugin.lua b/generic/plugin.lua new file mode 100644 index 0000000..abe01a0 --- /dev/null +++ b/generic/plugin.lua @@ -0,0 +1,144 @@ +module("plugin", package.seeall) + +--- plugin descriptor +-- @class table +-- @name plugin descriptor +-- @field description string: human readable plugin description string, +-- including unique plugin version information +-- @field init function: initialization function +-- @field exit function: deinitialization function +-- @field file string: plugin file name (inserted by plugin loader) +-- @field ctx table: plugin context (inserted by plugin loader) + +--- plugin context +-- @class table +-- @name plugin context +-- @field plugin table: plugin descriptor +-- @field info table: info table (local tools only) + +--- plugin init function +-- @class function +-- @name init +-- @param ctx table: plugin context +-- @return bool +-- @return an error object on failure + +--- plugin exit function +-- @class function +-- @name init +-- @param ctx table: plugin context +-- @return bool +-- @return an error object on failure + +-- list of plugin descriptors +plugins = {} + +--[[ example plugin descriptor: +-- plugin = { +-- description = "...", +-- init = init, +-- exit = exit, +-- file = nil, -- automatically inserted by plugin loader +-- ctx = nil, -- automatically inserted by plugin loader +-- } +--]] + +--- load a plugin +-- @param dir string: plugin directory +-- @param plugin_file string: filename +-- @param ctx table: plugin context +-- @return bool +-- @return an error object on failure +local function load_plugin(dir, p, ctx) + local e = new_error("loading plugin failed: %s", p) + local plugin_file = string.format("%s/%s", dir, p) + local chunk, msg = loadfile(plugin_file) + if not chunk then + return false, e:append("%s", msg) + end + chunk() + if not plugin_descriptor then + return false, e:append("no plugin descriptor in plugin: %s", + plugin_file) + end + local pd = plugin_descriptor + if type(pd.description) ~= "string" then + e:append("description missing in plugin descriptor") + end + if type(pd.init) ~= "function" then + e:append("init function missing in descriptor") + end + if type(pd.exit) ~= "function" then + e:append("exit function missing in descriptor") + end + if e:getcount() > 1 then + return false, e + end + pd.file = p + pd.ctx = ctx + ctx.plugin = pd + table.insert(plugins, pd) + e2lib.logf(4, "loading plugin: %s (%s)", pd.file, pd.description) + return true, nil +end + +--- initialize a plugin +-- @param pd table: plugin descriptor +-- @return bool +-- @return an error object on failure +local function init_plugin(pd) + return pd.init(pd.ctx) +end + +--- deinitialize a plugin +-- @param pd table: plugin descriptor +-- @return bool +local function exit_plugin(pd) + return pd.exit(pd.ctx) +end + +--- load plugins from a directory, and apply the plugin context +-- @param dir string: directory +-- @param ctx table: plugin context +-- @return bool +-- @return an error object on failure +function load_plugins(dir, ctx) + local e = new_error("loading plugins failed") + e2lib.logf(4, "loading plugins from: %s", dir) + for p in e2lib.directory(dir) do + local rc, re = load_plugin(dir, p, ctx) + if not rc then + e2lib.logf(1, "loading plugin: %s failed", p) + return false, e:cat(re) + end + end + return true +end + +--- initialize plugins +-- @return bool +-- @return an error object on failure +function init_plugins() + local e = new_error("initializing plugins failed") + for _, pd in ipairs(plugins) do + local rc, re = init_plugin(pd) + if not rc then + return false, e:cat(re) + end + end + return true, nil +end + +--- deinitialize plugins +-- @return bool +-- @return an error object on failure +function exit_plugins() + local e = new_error("deinitializing plugins failed") + for _, pd in ipairs(plugins) do + local rc, re = exit_plugin(pd) + if not rc then + return false, e:cat(re) + end + end + return true, nil +end diff --git a/local/Makefile b/local/Makefile index 2b85189..9070c9b 100644 --- a/local/Makefile +++ b/local/Makefile @@ -110,6 +110,7 @@ clean: e2local.lc: $(TOPLEVEL)/generic/strict.lua \ result.lua \ loader.lua \ + $(TOPLEVEL)/generic/plugin.lua \ $(TOPLEVEL)/generic/scm.git.lua \ $(TOPLEVEL)/generic/transport.lua \ $(TOPLEVEL)/generic/cache.lua \ diff --git a/local/e2tool.lua b/local/e2tool.lua index 2eed81e..ff81397 100644 --- a/local/e2tool.lua +++ b/local/e2tool.lua @@ -375,6 +375,20 @@ function e2tool.collect_project_info(path) return false, e:cat(re) end + -- load local plugins + local ctx = { -- plugin context + info = info, + } + local plugindir = string.format("%s/.e2/plugins", info.root) + rc, re = plugin.load_plugins(plugindir, ctx) + if not rc then + return false, e:cat(re) + end + rc, re = plugin.init_plugins() + if not rc then + return false, e:cat(re) + end + -- check for configuration compatibility info.config_syntax_compat = buildconfig.SYNTAX info.config_syntax_file = ".e2/syntax" diff --git a/make.vars b/make.vars index 83b1ac6..bc44e18 100644 --- a/make.vars +++ b/make.vars @@ -53,7 +53,8 @@ LOCALPREFIX = $(PROJECTDIR)/.e2 LOCALBINDIR = $(LOCALPREFIX)/bin LOCALLIBDIR = $(LOCALPREFIX)/lib/e2 LOCALMAKDIR = $(LOCALPREFIX)/lib/make -export LOCALPREFIX LOCALBINDIR LOCALLIBDIR LOCALMAKDIR +LOCALPLUGINDIR = $(LOCALPREFIX)/plugins +export LOCALPREFIX LOCALBINDIR LOCALLIBDIR LOCALMAKDIR LOCALPLUGINDIR ARCH = $(shell uname -m) LUA_VERSION = 5.1.3