diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-05-07 09:37:18 +0100 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-05-07 09:37:18 +0100 |
commit | 19653ebf8604885e771c88ec95e7e92f6ea976fa (patch) | |
tree | caca1c93fe33b6c784d59d0181325710ecd8890a /lib/gitano/actions.lua | |
parent | dade4fcf8f98ae45301cf51c52e8f189d39b758e (diff) | |
download | gitano-19653ebf8604885e771c88ec95e7e92f6ea976fa.tar.gz |
ACTIONS: Initial CIA.vc report commit-notifications
Diffstat (limited to 'lib/gitano/actions.lua')
-rw-r--r-- | lib/gitano/actions.lua | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/lib/gitano/actions.lua b/lib/gitano/actions.lua index 8a02373..604b886 100644 --- a/lib/gitano/actions.lua +++ b/lib/gitano/actions.lua @@ -70,6 +70,157 @@ local function http_get(host, path) return code, msg, headers, content end +local cia_pattern = [[ +<message> + <generator> + <name>gitano</name> + <version>1</version> + <url>http://www.gitano.org.uk/</url> + </generator> + <source> + <project>%s</project> + <branch>%s</branch> + </source> + <body> +%s + </body> +</message> +]] + +local cia_commit_pattern = [[ + <commit> + <version>%s</version> + <files> + %s + </files> + <author>%s</author> + <log>%s</log> + </commit>]] + +local function cia_branch_update_gen(project, branch, repo, + previoustip, newtip) + local revs = repo.git:rev_list(previoustip, newtip) + local commits = {} + for i = #revs, 1, -1 do + local commit = repo.git:get(revs[i]) + local author = commit.content.author + author = ("%s <%s>"):format(author.realname, author.email) + author = util.html_escape(author) + local logline = commit.content.message:match("^([^\r\n]+)") + logline = util.html_escape(logline) + local mytree = commit.content.tree.content + local parent = commit.content.parents[1] + if parent then + parent = parent.content.tree.content + else + parent = repo.git:get(git.tree.empty_sha).content + end + local treedelta = parent:diff_to(mytree) + local filelist = {} + for i, v in ipairs(treedelta) do + local fmts = { "UNKNOWN_ACTION", "", util.html_escape(v.filename) } + if v.action == "A" then + fmts[1] = "add" + elseif v.action == "D" then + fmts[1] = "remove" + elseif v.action == "R" then + fmts[1] = "rename" + fmts[2] = ([[ to=%q]]):format(fmts[3]) + fmts[3] = util.html_escape(v.src_name) + elseif v.action == "C" then + -- for copy we treat the new file as an add + fmts[1] = "add" + elseif v.action == "M" then + fmts[1] = "modify" + else + log.ddebug("Unknown action", v.action, + "in CIA commit formatter, assuming modify") + fmts[1] = "modify" + end + filelist[#filelist+1] = + ([[<file action="%s"%s>%s</file>]]):format(unpack(fmts)) + end + filelist = table.concat(filelist, "\n ") + local com_msg = cia_commit_pattern:format(commit.sha:sub(1,7), + filelist, + author, + logline) + commits[#commits+1] = cia_pattern:format(project, branch, + com_msg) + end + return commits +end + + +local cia_xmlrpc_pattern = [[ +<?xml version="1.0"?> +<methodCall> + <methodName>hub.deliver</methodName> + <params> + <value><string>%s</string></value> + </params> +</methodCall> +]] + +local function send_to_cia(msg) + if 1 == 0 then + print(msg) + return "200" + end + msg = cia_xmlrpc_pattern:format(util.html_escape(msg)) + log.ddebug("Connect...") + sock = assert(sio.connect("cia.vc", "http")) + + local req = table.concat({ + "POST /RPC2 HTTP/1.0", + "Host: cia.vc", + "Content-Length: " .. tostring(#msg), + "Connection: Close", + "", "" + }, "\r\n") + log.ddebug("Write request") + assert(sock:write(req)) + log.ddebug("Write body") + assert(sock:write(msg)) + log.ddebug("Read response") + local response = assert(sock:read "*a") + + assert(sock:close()) + + local code, msg, _headers, content = response:match("^HTTP/1.[01] (...) ?([^\r\n]+)\r?\n(.-)\r?\n\r?\n(.*)$") + local headers = {} + for k, v in _headers:gmatch("([^:\r\n]+): *([^\r\n]+)") do + local r = headers[k] or {} + r[#r+1] = v + headers[k] = r + end + + return code, msg, headers, content +end + +local function cia_inform_commits(project, branch, repo, previoustip, newtip) + log.ddebug("Attempting CIA report for", branch, "in", project) + log.ddebug("Previous tip was", previoustip, "new tip is", newtip) + log.ddebug("Generating messages...") + local msgs = cia_branch_update_gen(project, branch, repo, + previoustip, newtip) + log.ddebug("Generated", tostring(#msgs), "messages for CIA") + local ok = 0 + for i = 1, #msgs do + local msg = msgs[i] + local code, msg, headers, content = send_to_cia(msg) + if code == "200" then + ok = ok + 1 + else + log.warn("CIA returned", code, + "processing message", tostring(i), "of", tostring(#msgs)) + print(content) + break + end + end + return ok == #msgs +end + local function set_hook_globals(config, repo, globs) for _, k in ipairs({ "table", "string", "pairs", "ipairs", "pcall", "xpcall", "unpack", "tostring", "tonumber", "math", @@ -85,6 +236,7 @@ local function set_hook_globals(config, repo, globs) end globs["log"] = logcopy globs["http_get"] = http_get + globs["cia"] = { inform_commits = cia_inform_commits } end return { |