Mercurial > prosody-hg
comparison core/configmanager.lua @ 3923:f95375aceed0
configmanager: Support for wildcards in Include directives
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Mon, 20 Dec 2010 14:06:32 +0000 |
| parents | b1140808598b |
| children | 7cb03d67101b |
comparison
equal
deleted
inserted
replaced
| 3922:b77bafa4c502 | 3923:f95375aceed0 |
|---|---|
| 5 -- This project is MIT/X11 licensed. Please see the | 5 -- This project is MIT/X11 licensed. Please see the |
| 6 -- COPYING file in the source package for more information. | 6 -- COPYING file in the source package for more information. |
| 7 -- | 7 -- |
| 8 | 8 |
| 9 local _G = _G; | 9 local _G = _G; |
| 10 local setmetatable, loadfile, pcall, rawget, rawset, io, error, dofile, type, pairs, table, format = | 10 local setmetatable, loadfile, pcall, rawget, rawset, io, error, dofile, type, pairs, table = |
| 11 setmetatable, loadfile, pcall, rawget, rawset, io, error, dofile, type, pairs, table, string.format; | 11 setmetatable, loadfile, pcall, rawget, rawset, io, error, dofile, type, pairs, table; |
| 12 | 12 local format, math_max = string.format, math.max; |
| 13 | 13 |
| 14 local fire_event = prosody and prosody.events.fire_event or function () end; | 14 local fire_event = prosody and prosody.events.fire_event or function () end; |
| 15 | 15 |
| 16 local lfs = require "lfs"; | |
| 16 local path_sep = package.config:sub(1,1); | 17 local path_sep = package.config:sub(1,1); |
| 17 | 18 |
| 18 module "configmanager" | 19 module "configmanager" |
| 19 | 20 |
| 20 local parsers = {}; | 21 local parsers = {}; |
| 69 -- Helper function to resolve relative paths (needed by config) | 70 -- Helper function to resolve relative paths (needed by config) |
| 70 do | 71 do |
| 71 local rel_path_start = ".."..path_sep; | 72 local rel_path_start = ".."..path_sep; |
| 72 function resolve_relative_path(parent_path, path) | 73 function resolve_relative_path(parent_path, path) |
| 73 if path then | 74 if path then |
| 75 -- Some normalization | |
| 76 parent_path = parent_path:gsub("%"..path_sep.."+$", ""); | |
| 77 path = path:gsub("^%.%"..path_sep.."+", ""); | |
| 78 | |
| 74 local is_relative; | 79 local is_relative; |
| 75 if path_sep == "/" and path:sub(1,1) ~= "/" then | 80 if path_sep == "/" and path:sub(1,1) ~= "/" then |
| 76 is_relative = true; | 81 is_relative = true; |
| 77 elseif path_sep == "\\" and (path:sub(1,1) ~= "/" and path:sub(2,3) ~= ":\\") then | 82 elseif path_sep == "\\" and (path:sub(1,1) ~= "/" and path:sub(2,3) ~= ":\\") then |
| 78 is_relative = true; | 83 is_relative = true; |
| 81 return parent_path..path_sep..path; | 86 return parent_path..path_sep..path; |
| 82 end | 87 end |
| 83 end | 88 end |
| 84 return path; | 89 return path; |
| 85 end | 90 end |
| 91 end | |
| 92 | |
| 93 -- Helper function to convert a glob to a Lua pattern | |
| 94 local function glob_to_pattern(glob) | |
| 95 return "^"..glob:gsub("[%p*?]", function (c) | |
| 96 if c == "*" then | |
| 97 return ".*"; | |
| 98 elseif c == "?" then | |
| 99 return "."; | |
| 100 else | |
| 101 return "%"..c; | |
| 102 end | |
| 103 end).."$"; | |
| 86 end | 104 end |
| 87 | 105 |
| 88 function load(filename, format) | 106 function load(filename, format) |
| 89 format = format or filename:match("%w+$"); | 107 format = format or filename:match("%w+$"); |
| 90 | 108 |
| 135 -- Built-in Lua parser | 153 -- Built-in Lua parser |
| 136 do | 154 do |
| 137 local loadstring, pcall, setmetatable = _G.loadstring, _G.pcall, _G.setmetatable; | 155 local loadstring, pcall, setmetatable = _G.loadstring, _G.pcall, _G.setmetatable; |
| 138 local setfenv, rawget, tostring = _G.setfenv, _G.rawget, _G.tostring; | 156 local setfenv, rawget, tostring = _G.setfenv, _G.rawget, _G.tostring; |
| 139 parsers.lua = {}; | 157 parsers.lua = {}; |
| 140 function parsers.lua.load(data, filename, config) | 158 function parsers.lua.load(data, config_file, config) |
| 141 local env; | 159 local env; |
| 142 -- The ' = true' are needed so as not to set off __newindex when we assign the functions below | 160 -- The ' = true' are needed so as not to set off __newindex when we assign the functions below |
| 143 env = setmetatable({ | 161 env = setmetatable({ |
| 144 Host = true, host = true, VirtualHost = true, | 162 Host = true, host = true, VirtualHost = true, |
| 145 Component = true, component = true, | 163 Component = true, component = true, |
| 197 return handle_config_options(module); | 215 return handle_config_options(module); |
| 198 end | 216 end |
| 199 end | 217 end |
| 200 env.component = env.Component; | 218 env.component = env.Component; |
| 201 | 219 |
| 202 function env.Include(file) | 220 function env.Include(file, wildcard) |
| 203 local f, err = io.open(file); | 221 if file:match("[*?]") then |
| 204 if f then | 222 local path_pos, glob = file:match("()([^"..path_sep.."]+)$"); |
| 205 local data = f:read("*a"); | 223 local path = file:sub(1, math_max(path_pos-2,0)); |
| 206 local file = resolve_relative_path(filename:gsub("[^"..path_sep.."]+$", ""), file); | 224 if #path > 0 then |
| 207 local ret, err = parsers.lua.load(data, file, config); | 225 path = resolve_relative_path(config_file:gsub("[^"..path_sep.."]+$", ""), path); |
| 208 if not ret then error(err:gsub("%[string.-%]", file), 0); end | 226 else |
| 209 end | 227 path = "."; |
| 210 if not f then error("Error loading included "..file..": "..err, 0); end | 228 end |
| 211 return f, err; | 229 local patt = glob_to_pattern(glob); |
| 230 for f in lfs.dir(path) do | |
| 231 if f:sub(1,1) ~= "." and f:match(patt) then | |
| 232 env.Include(path..path_sep..f); | |
| 233 end | |
| 234 end | |
| 235 else | |
| 236 local f, err = io.open(file); | |
| 237 if f then | |
| 238 local data = f:read("*a"); | |
| 239 local file = resolve_relative_path(config_file:gsub("[^"..path_sep.."]+$", ""), file); | |
| 240 local ret, err = parsers.lua.load(data, file, config); | |
| 241 if not ret then error(err:gsub("%[string.-%]", file), 0); end | |
| 242 end | |
| 243 if not f then error("Error loading included "..file..": "..err, 0); end | |
| 244 return f, err; | |
| 245 end | |
| 212 end | 246 end |
| 213 env.include = env.Include; | 247 env.include = env.Include; |
| 214 | 248 |
| 215 function env.RunScript(file) | 249 function env.RunScript(file) |
| 216 return dofile(resolve_relative_path(filename:gsub("[^"..path_sep.."]+$", ""), file)); | 250 return dofile(resolve_relative_path(config_file:gsub("[^"..path_sep.."]+$", ""), file)); |
| 217 end | 251 end |
| 218 | 252 |
| 219 local chunk, err = loadstring(data, "@"..filename); | 253 local chunk, err = loadstring(data, "@"..config_file); |
| 220 | 254 |
| 221 if not chunk then | 255 if not chunk then |
| 222 return nil, err; | 256 return nil, err; |
| 223 end | 257 end |
| 224 | 258 |
