util/pluginloader.lua
author Kim Alvefur <zash@zash.se>
Sun, 27 Aug 2023 15:46:19 +0200
branch0.12
changeset 13258 a2ba3f06dcf4
parent 12391 05c250fa335a
child 12979 d10957394a3c
permissions -rw-r--r--
util.prosodyctl.check: Correct modern replacement for 'disallow_s2s' The code would have suggested adding to modules_enabled instead of modules_disabled
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1522
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 1441
diff changeset
     1
-- Prosody IM
2923
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
     2
-- Copyright (C) 2008-2010 Matthew Wild
b7049746bd29 Update copyright headers for 2010
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
     3
-- Copyright (C) 2008-2010 Waqas Hussain
5776
bd0ff8ae98a8 Remove all trailing whitespace
Florian Zeitz <florob@babelmonkeys.de>
parents: 5073
diff changeset
     4
--
1522
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 1441
diff changeset
     5
-- This project is MIT/X11 licensed. Please see the
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 1441
diff changeset
     6
-- COPYING file in the source package for more information.
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 1441
diff changeset
     7
--
8385
e5d00bf4a4d5 util: Various minor changes to please [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7118
diff changeset
     8
-- luacheck: ignore 113/CFG_PLUGINDIR
1522
569d58d21612 Add copyright header to those files missing one
Matthew Wild <mwild1@gmail.com>
parents: 1441
diff changeset
     9
4121
ea7e3f22f898 util.pluginloader: Add support for multiple plugin directories.
Waqas Hussain <waqas20@gmail.com>
parents: 3411
diff changeset
    10
local dir_sep, path_sep = package.config:match("^(%S+)%s(%S+)");
11133
387d442497e7 util.pluginloader: Extract Lua version once
Kim Alvefur <zash@zash.se>
parents: 10209
diff changeset
    11
local lua_version = _VERSION:match(" (.+)$");
4121
ea7e3f22f898 util.pluginloader: Add support for multiple plugin directories.
Waqas Hussain <waqas20@gmail.com>
parents: 3411
diff changeset
    12
local plugin_dir = {};
ea7e3f22f898 util.pluginloader: Add support for multiple plugin directories.
Waqas Hussain <waqas20@gmail.com>
parents: 3411
diff changeset
    13
for path in (CFG_PLUGINDIR or "./plugins/"):gsub("[/\\]", dir_sep):gmatch("[^"..path_sep.."]+") do
ea7e3f22f898 util.pluginloader: Add support for multiple plugin directories.
Waqas Hussain <waqas20@gmail.com>
parents: 3411
diff changeset
    14
	path = path..dir_sep; -- add path separator to path end
12391
05c250fa335a Spelling: Fix various spelling mistakes (thanks timeless)
Kim Alvefur <zash@zash.se>
parents: 12259
diff changeset
    15
	path = path:gsub(dir_sep..dir_sep.."+", dir_sep); -- coalesce multiple separators
4121
ea7e3f22f898 util.pluginloader: Add support for multiple plugin directories.
Waqas Hussain <waqas20@gmail.com>
parents: 3411
diff changeset
    16
	plugin_dir[#plugin_dir + 1] = path;
ea7e3f22f898 util.pluginloader: Add support for multiple plugin directories.
Waqas Hussain <waqas20@gmail.com>
parents: 3411
diff changeset
    17
end
1359
015d624a2a71 util.pluginloader: Initial commit - a plugin resource loader
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    18
5073
ecc89a60b2ba util.pluginloader: Remove unused imports
Matthew Wild <mwild1@gmail.com>
parents: 5072
diff changeset
    19
local io_open = io.open;
5021
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4154
diff changeset
    20
local envload = require "util.envload".envload;
2276
d9302be05f86 util.pluginloader: Support for fetching plugins from the data store
Matthew Wild <mwild1@gmail.com>
parents: 1522
diff changeset
    21
12254
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    22
local pluginloader_methods = {};
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    23
local pluginloader_mt = { __index = pluginloader_methods };
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    24
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    25
function pluginloader_methods:load_file(names)
4149
3c1b153c2856 util.pluginloader: Return full file path from internal file loader on success, not just the name.
Waqas Hussain <waqas20@gmail.com>
parents: 4121
diff changeset
    26
	local file, err, path;
12255
21ed12cfe300 util.pluginloader: Support for a per-file load filter
Matthew Wild <mwild1@gmail.com>
parents: 12254
diff changeset
    27
	local load_filter_cb = self._options.load_filter_cb;
4121
ea7e3f22f898 util.pluginloader: Add support for multiple plugin directories.
Waqas Hussain <waqas20@gmail.com>
parents: 3411
diff changeset
    28
	for i=1,#plugin_dir do
4154
3785a9bb7f11 util.pluginloader: Rewritten resource loading to be cleaner, and added support for prosody-modules directory layout. "/" in plugin names is no longer supported.
Waqas Hussain <waqas20@gmail.com>
parents: 4152
diff changeset
    29
		for j=1,#names do
3785a9bb7f11 util.pluginloader: Rewritten resource loading to be cleaner, and added support for prosody-modules directory layout. "/" in plugin names is no longer supported.
Waqas Hussain <waqas20@gmail.com>
parents: 4152
diff changeset
    30
			path = plugin_dir[i]..names[j];
3785a9bb7f11 util.pluginloader: Rewritten resource loading to be cleaner, and added support for prosody-modules directory layout. "/" in plugin names is no longer supported.
Waqas Hussain <waqas20@gmail.com>
parents: 4152
diff changeset
    31
			file, err = io_open(path);
3785a9bb7f11 util.pluginloader: Rewritten resource loading to be cleaner, and added support for prosody-modules directory layout. "/" in plugin names is no longer supported.
Waqas Hussain <waqas20@gmail.com>
parents: 4152
diff changeset
    32
			if file then
3785a9bb7f11 util.pluginloader: Rewritten resource loading to be cleaner, and added support for prosody-modules directory layout. "/" in plugin names is no longer supported.
Waqas Hussain <waqas20@gmail.com>
parents: 4152
diff changeset
    33
				local content = file:read("*a");
3785a9bb7f11 util.pluginloader: Rewritten resource loading to be cleaner, and added support for prosody-modules directory layout. "/" in plugin names is no longer supported.
Waqas Hussain <waqas20@gmail.com>
parents: 4152
diff changeset
    34
				file:close();
12255
21ed12cfe300 util.pluginloader: Support for a per-file load filter
Matthew Wild <mwild1@gmail.com>
parents: 12254
diff changeset
    35
				local metadata;
21ed12cfe300 util.pluginloader: Support for a per-file load filter
Matthew Wild <mwild1@gmail.com>
parents: 12254
diff changeset
    36
				if load_filter_cb then
21ed12cfe300 util.pluginloader: Support for a per-file load filter
Matthew Wild <mwild1@gmail.com>
parents: 12254
diff changeset
    37
					path, content, metadata = load_filter_cb(path, content);
21ed12cfe300 util.pluginloader: Support for a per-file load filter
Matthew Wild <mwild1@gmail.com>
parents: 12254
diff changeset
    38
				end
21ed12cfe300 util.pluginloader: Support for a per-file load filter
Matthew Wild <mwild1@gmail.com>
parents: 12254
diff changeset
    39
				if content and path then
21ed12cfe300 util.pluginloader: Support for a per-file load filter
Matthew Wild <mwild1@gmail.com>
parents: 12254
diff changeset
    40
					return content, path, metadata;
21ed12cfe300 util.pluginloader: Support for a per-file load filter
Matthew Wild <mwild1@gmail.com>
parents: 12254
diff changeset
    41
				end
4154
3785a9bb7f11 util.pluginloader: Rewritten resource loading to be cleaner, and added support for prosody-modules directory layout. "/" in plugin names is no longer supported.
Waqas Hussain <waqas20@gmail.com>
parents: 4152
diff changeset
    42
			end
3785a9bb7f11 util.pluginloader: Rewritten resource loading to be cleaner, and added support for prosody-modules directory layout. "/" in plugin names is no longer supported.
Waqas Hussain <waqas20@gmail.com>
parents: 4152
diff changeset
    43
		end
4121
ea7e3f22f898 util.pluginloader: Add support for multiple plugin directories.
Waqas Hussain <waqas20@gmail.com>
parents: 3411
diff changeset
    44
	end
4154
3785a9bb7f11 util.pluginloader: Rewritten resource loading to be cleaner, and added support for prosody-modules directory layout. "/" in plugin names is no longer supported.
Waqas Hussain <waqas20@gmail.com>
parents: 4152
diff changeset
    45
	return file, err;
1359
015d624a2a71 util.pluginloader: Initial commit - a plugin resource loader
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    46
end
015d624a2a71 util.pluginloader: Initial commit - a plugin resource loader
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    47
12254
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    48
function pluginloader_methods:load_resource(plugin, resource)
12255
21ed12cfe300 util.pluginloader: Support for a per-file load filter
Matthew Wild <mwild1@gmail.com>
parents: 12254
diff changeset
    49
	resource = resource or "mod_"..plugin..".lua";
4154
3785a9bb7f11 util.pluginloader: Rewritten resource loading to be cleaner, and added support for prosody-modules directory layout. "/" in plugin names is no longer supported.
Waqas Hussain <waqas20@gmail.com>
parents: 4152
diff changeset
    50
	local names = {
6029
dd3d4cfbd3cb util.pluginloader: Always use path separator from package.config (thanks Junne)
Kim Alvefur <zash@zash.se>
parents: 5073
diff changeset
    51
		"mod_"..plugin..dir_sep..plugin..dir_sep..resource; -- mod_hello/hello/mod_hello.lua
dd3d4cfbd3cb util.pluginloader: Always use path separator from package.config (thanks Junne)
Kim Alvefur <zash@zash.se>
parents: 5073
diff changeset
    52
		"mod_"..plugin..dir_sep..resource;                  -- mod_hello/mod_hello.lua
dd3d4cfbd3cb util.pluginloader: Always use path separator from package.config (thanks Junne)
Kim Alvefur <zash@zash.se>
parents: 5073
diff changeset
    53
		plugin..dir_sep..resource;                          -- hello/mod_hello.lua
dd3d4cfbd3cb util.pluginloader: Always use path separator from package.config (thanks Junne)
Kim Alvefur <zash@zash.se>
parents: 5073
diff changeset
    54
		resource;                                           -- mod_hello.lua
11134
10485a3ef78b util.pluginloader: Look for top level mod_something.lua in luarocks-style tree
Kim Alvefur <zash@zash.se>
parents: 11133
diff changeset
    55
		"share"..dir_sep.."lua"..dir_sep..lua_version..dir_sep..resource;
10209
ff8de86b75f0 util.pluginloader: Added a new path to the variable local_names
João Duarte <jvsDuarte08@gmail.com>
parents: 8385
diff changeset
    56
		"share"..dir_sep.."lua"..dir_sep..lua_version..dir_sep.."mod_"..plugin..dir_sep..resource;
4154
3785a9bb7f11 util.pluginloader: Rewritten resource loading to be cleaner, and added support for prosody-modules directory layout. "/" in plugin names is no longer supported.
Waqas Hussain <waqas20@gmail.com>
parents: 4152
diff changeset
    57
	};
3410
32b018eeeb3b util.pluginloader: Fix loading of plugins, plugin libraries and resources in subfolders (e.g., when loading 'a/b', load 'a/mod_b.lua', and not 'mod_a/b.lua').
Waqas Hussain <waqas20@gmail.com>
parents: 3233
diff changeset
    58
12254
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    59
	return self:load_file(names);
1359
015d624a2a71 util.pluginloader: Initial commit - a plugin resource loader
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    60
end
015d624a2a71 util.pluginloader: Initial commit - a plugin resource loader
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    61
12254
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    62
function pluginloader_methods:load_code(plugin, resource, env)
12255
21ed12cfe300 util.pluginloader: Support for a per-file load filter
Matthew Wild <mwild1@gmail.com>
parents: 12254
diff changeset
    63
	local content, err, metadata = self:load_resource(plugin, resource);
1359
015d624a2a71 util.pluginloader: Initial commit - a plugin resource loader
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    64
	if not content then return content, err; end
4150
2894ca33ec45 util.pluginloader: Return file path on success in pluginloader.load_code().
Waqas Hussain <waqas20@gmail.com>
parents: 4149
diff changeset
    65
	local path = err;
5021
85b2689dbcfe Eliminate direct setfenv usage
Florian Zeitz <florob@babelmonkeys.de>
parents: 4154
diff changeset
    66
	local f, err = envload(content, "@"..path, env);
4150
2894ca33ec45 util.pluginloader: Return file path on success in pluginloader.load_code().
Waqas Hussain <waqas20@gmail.com>
parents: 4149
diff changeset
    67
	if not f then return f, err; end
12255
21ed12cfe300 util.pluginloader: Support for a per-file load filter
Matthew Wild <mwild1@gmail.com>
parents: 12254
diff changeset
    68
	return f, path, metadata;
1359
015d624a2a71 util.pluginloader: Initial commit - a plugin resource loader
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    69
end
015d624a2a71 util.pluginloader: Initial commit - a plugin resource loader
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
    70
12254
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    71
function pluginloader_methods:load_code_ext(plugin, resource, extension, env)
12255
21ed12cfe300 util.pluginloader: Support for a per-file load filter
Matthew Wild <mwild1@gmail.com>
parents: 12254
diff changeset
    72
	local content, err, metadata = self:load_resource(plugin, resource.."."..extension);
11135
40abef01f4b9 util.pluginloader: Look for module libs in mod_plugin/lib.lua
Kim Alvefur <zash@zash.se>
parents: 11134
diff changeset
    73
	if not content and extension == "lib.lua" then
12255
21ed12cfe300 util.pluginloader: Support for a per-file load filter
Matthew Wild <mwild1@gmail.com>
parents: 12254
diff changeset
    74
		content, err, metadata = self:load_resource(plugin, resource..".lua");
11135
40abef01f4b9 util.pluginloader: Look for module libs in mod_plugin/lib.lua
Kim Alvefur <zash@zash.se>
parents: 11134
diff changeset
    75
	end
7118
805d068d2fd5 modulemanager, util.pluginloader: Move logic for locating some module libraries to pluginloader, to fix problems with non-filesystem errors being masked by the second load_code call
Matthew Wild <mwild1@gmail.com>
parents: 6780
diff changeset
    76
	if not content then
12255
21ed12cfe300 util.pluginloader: Support for a per-file load filter
Matthew Wild <mwild1@gmail.com>
parents: 12254
diff changeset
    77
		content, err, metadata = self:load_resource(resource, resource.."."..extension);
7118
805d068d2fd5 modulemanager, util.pluginloader: Move logic for locating some module libraries to pluginloader, to fix problems with non-filesystem errors being masked by the second load_code call
Matthew Wild <mwild1@gmail.com>
parents: 6780
diff changeset
    78
		if not content then
805d068d2fd5 modulemanager, util.pluginloader: Move logic for locating some module libraries to pluginloader, to fix problems with non-filesystem errors being masked by the second load_code call
Matthew Wild <mwild1@gmail.com>
parents: 6780
diff changeset
    79
			return content, err;
805d068d2fd5 modulemanager, util.pluginloader: Move logic for locating some module libraries to pluginloader, to fix problems with non-filesystem errors being masked by the second load_code call
Matthew Wild <mwild1@gmail.com>
parents: 6780
diff changeset
    80
		end
805d068d2fd5 modulemanager, util.pluginloader: Move logic for locating some module libraries to pluginloader, to fix problems with non-filesystem errors being masked by the second load_code call
Matthew Wild <mwild1@gmail.com>
parents: 6780
diff changeset
    81
	end
805d068d2fd5 modulemanager, util.pluginloader: Move logic for locating some module libraries to pluginloader, to fix problems with non-filesystem errors being masked by the second load_code call
Matthew Wild <mwild1@gmail.com>
parents: 6780
diff changeset
    82
	local path = err;
805d068d2fd5 modulemanager, util.pluginloader: Move logic for locating some module libraries to pluginloader, to fix problems with non-filesystem errors being masked by the second load_code call
Matthew Wild <mwild1@gmail.com>
parents: 6780
diff changeset
    83
	local f, err = envload(content, "@"..path, env);
805d068d2fd5 modulemanager, util.pluginloader: Move logic for locating some module libraries to pluginloader, to fix problems with non-filesystem errors being masked by the second load_code call
Matthew Wild <mwild1@gmail.com>
parents: 6780
diff changeset
    84
	if not f then return f, err; end
12259
a3ad9cf740d6 util.pluginloader: Fix method to return any module metadata (luacheck)
Matthew Wild <mwild1@gmail.com>
parents: 12255
diff changeset
    85
	return f, path, metadata;
7118
805d068d2fd5 modulemanager, util.pluginloader: Move logic for locating some module libraries to pluginloader, to fix problems with non-filesystem errors being masked by the second load_code call
Matthew Wild <mwild1@gmail.com>
parents: 6780
diff changeset
    86
end
805d068d2fd5 modulemanager, util.pluginloader: Move logic for locating some module libraries to pluginloader, to fix problems with non-filesystem errors being masked by the second load_code call
Matthew Wild <mwild1@gmail.com>
parents: 6780
diff changeset
    87
12254
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    88
local function init(options)
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    89
	return setmetatable({
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    90
		_options = options or {};
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    91
	}, pluginloader_mt);
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    92
end
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    93
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    94
local function bind(self, method)
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    95
	return function (...)
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    96
		return method(self, ...);
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    97
	end;
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    98
end
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
    99
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
   100
local default_loader = init();
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
   101
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6031
diff changeset
   102
return {
12254
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
   103
	load_file = bind(default_loader, default_loader.load_file);
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
   104
	load_resource = bind(default_loader, default_loader.load_resource);
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
   105
	load_code = bind(default_loader, default_loader.load_code);
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
   106
	load_code_ext = bind(default_loader, default_loader.load_code_ext);
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
   107
e157e5c79daa util.pluginloader: Support for multiple pluginloader instances, and options
Matthew Wild <mwild1@gmail.com>
parents: 11135
diff changeset
   108
	init = init;
6780
5de6b93d0190 util.*: Remove use of module() function, make all module functions local and return them in a table at the end
Kim Alvefur <zash@zash.se>
parents: 6031
diff changeset
   109
};