1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
-- gitano.supple
--
-- Supple interface code for Gitano
--
-- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org>
--
--
local supple = require 'supple'
local log = require 'gitano.log'
local config = require 'gitano.config'
local repo_proxies = {}
local proxied_repo = {}
local proxy_repo_methods = {}
local function proxy_repo_tostring(proxy)
return ("<ProxyRepository [%s]>"):format((proxied_repo[proxy] or {}).name or "Unknown")
end
function proxy_repo_methods:get(shaish)
local repo = proxied_repo[self]
return repo.git:get(shaish)
end
function proxy_repo_methods:get_config(confname)
local repo = proxied_repo[self]
return repo.project_config.settings[confname]
end
function proxy_repo_methods:get_config_list(confname)
local repo = proxied_repo[self]
return repo.project_config:get_list(confname)
end
local proxy_repo_meta = {
__index = proxy_repo_methods,
__tostring = proxy_repo_tostring,
}
local function get_repo_proxy(repo)
local proxy = repo_proxies[repo]
if proxy then
return proxy
end
proxy = setmetatable({}, proxy_repo_meta)
proxied_repo[proxy] = repo
repo_proxies[repo] = proxy
proxy.name = repo.name
return proxy
end
local function unproxy_repo(proxy)
return proxied_repo[proxy] or proxy
end
local repo, loadedhooks
local function load_repo_module(fromrepo, prefix, module)
local modfile = prefix .. "/" .. module:gsub("%.", "/") .. ".lua"
local content, err
if fromrepo then
-- Load from the repository's admin reference
content, err = repo:load_from_admin_ref(modfile)
if not content and err:match("^Not found:") then
content, err = "--nothing\n", "@empty_hook"
end
else
-- Load from the config repo
content, err = config.load_file_content(repo.config, modfile)
if not content then
if err:match("^Not found: ") then
content, err = config.get_default_hook_content(repo.config,
modfile)
end
end
end
return content, err
end
local function load_module_src(modname)
local pfx, mod = modname:match("^([^%.]+)%.(.+)$")
if not (pfx and mod) then
error("Unable to load " .. modname .. " (Not the right name format)")
end
if pfx == "lib" then
return load_repo_module(repo, pfx, mod)
elseif pfx == "hooks" and not loadedhooks then
return load_repo_module(repo, pfx, mod)
elseif pfx == "globalhooks" and not loadedhooks then
local mod, err = load_repo_module(nil, "global-hooks", mod)
loadedhooks = true
return mod, err
elseif pfx == "global" then
return load_repo_module(nil, "hooklib", mod)
end
error("Unable to load " .. modname)
end
local function load_module(modname)
log.debug("Hook requested load_module(",modname,")")
local src, name = load_module_src(modname)
if not src then
error(name)
end
log.ddebug("Attempting to loadstring in the sandbox")
return supple.host.loadstring(src, "@" .. name)
end
local function set_globals(globs)
globs.load_module = load_module
log.ddebug("Setting globals in supple")
supple.host.set_globals(globs)
end
local supple_runtime_code = [[
local loadmodule = load_module
load_module = nil
function require(modname)
return loadmodule(modname)()
end
return (function(hookname, repo, info, ...)
local hookf = loadmodule("hooks." .. hookname)
local ghookf = loadmodule("globalhooks." .. hookname)
actor = {}
for k, v in pairs(info) do
actor[k] = v
end
info = nil
return ghookf(hookf, repo, ...)
end)(...)
]]
local function run_hook(hook, _repo, info, ...)
local proxy = get_repo_proxy(_repo)
repo = _repo
log.ddebug("Entering supple.host.run()")
return supple.host.run(supple_runtime_code, "@gitano.supple.runtime",
hook, proxy, info, ...)
end
return {
unproxy_repo = unproxy_repo,
set_globals = set_globals,
run_hook = run_hook,
}
|