]> git.e2factory.org Git - e2factory.git/commitdiff
plugin support: load local plugins
authorGordon Hecker <gh@emlix.com>
Thu, 18 Jun 2009 18:29:29 +0000 (20:29 +0200)
committerGordon Hecker <gh@emlix.com>
Fri, 12 Feb 2010 09:51:55 +0000 (10:51 +0100)
Signed-off-by: Gordon Hecker <gh@emlix.com>
generic/Makefile
generic/e2lib.lua
generic/plugin.lua [new file with mode: 0644]
local/Makefile
local/e2tool.lua
make.vars

index eac84cb8deeb8749449899d939a7cab352e50a4f..ce4072ed5d42e392e1018f8b0d7bde355926271b 100644 (file)
@@ -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 \
index eee567d6e1f3c5207811a514e87ed66ec3a73d7b..b09bc401ef2baf32555c071af402edbb0135086f 100644 (file)
@@ -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 (file)
index 0000000..abe01a0
--- /dev/null
@@ -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
index 2b851897f16a66efb9fae1dcfd2e6cb75cd59a83..9070c9b7cc0a61b2704438e3ffe926a2efae9ee0 100644 (file)
@@ -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 \
index 2eed81e31ea7279a1bae39e538014523e887a546..ff81397ff2aaf7fd50628bc2f68b7d652f199b75 100644 (file)
@@ -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"
index 83b1ac66eaeabb11b3520cd6598964cd86224123..bc44e18919f37d6b00bec98d73afc42d0dd49b25 100644 (file)
--- 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