summaryrefslogtreecommitdiff
path: root/gitano-admin/global-hooks/post-receive.lua
blob: d1b3864021c2eba6322b16adc1e6df1e99ea4895 (plain)
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
-- mason-notify.post-receive.lua
--
-- Global post-receive hook which notifies Mason of any and all refs updates
-- (except refs/gitano/*) which happen.
--
-- It notifies Mason *before* passing the updates on to the project hook.
--
-- Copyright 2012 Codethink Limited
--
-- This is a part of Trove and re-use is limited to Baserock systems only.
--

local project_hook, repo, updates = ...

local EMPTY_SHA = ("0"):rep(40)

local masonhost = "##MASON_HOST##:##MASON_PORT##"
local basepath = "/1.0"
local urlbases = {
   "git://##TROVE_HOSTNAME##/",
   "ssh://git@##TROVE_HOSTNAME##/",
}

local notify_mason = false

for ref in pairs(updates) do
   if not ref:match("^refs/gitano/") then
      notify_mason = true
   end
end

if notify_mason and repo.name ~= "gitano-admin" then
   -- Build the report...
   local masoninfo, indent_level = {}, 0
   local function _(...)
      masoninfo[#masoninfo+1] = ("    "):rep(indent_level) .. table.concat({...})
   end
   local function indent()
      indent_level = indent_level + 1
   end
   local function dedent()
      indent_level = indent_level - 1
   end
   _ "{" indent()
   
   _ '"urls": [' indent()

   for i = 1, #urlbases do
      local comma = (i==#urlbases) and "" or ","
      _(("%q,"):format(urlbases[i] .. repo.name))
      _(("%q%s"):format(urlbases[i] .. repo.name .. ".git", comma))
   end

   dedent() _ "],"

   _ '"changes": [' indent()

   local toreport = {}
   for ref, info in pairs(updates) do
      if not ref:match("^refs/gitano") then
	 local action
	 if info.oldsha == EMPTY_SHA then
	    action = "create"
	 elseif info.newsha == EMPTY_SHA then
	    action = "delete"
	 else
	    action = "update"
	 end
	 toreport[#toreport+1] = { 
	    ('"ref": %q,'):format(ref),
	    ('"action": %q,'):format(action),
	    ('"old": %q,'):format(info.oldsha),
	    ('"new": %q'):format(info.newsha)
	 }
      end
   end
   for i = 1, #toreport do
      local comma = (i==#toreport) and "" or ","
      _ "{" indent()
      for __, ent in ipairs(toreport[i]) do
	 _(ent)
      end
      dedent() _("}", comma)
   end
   dedent() _ "]"

   dedent() _ "}"

   -- And finalise the JSON object
   _("")
   masoninfo = table.concat(masoninfo, "\n")
   log.state("Notifying Mason of changes...")

   local code, msg, headers, content =
      http.post(masonhost, basepath, "application/json", masoninfo)
   if code ~= "200" then
      log.state("Notification failed somehow")
   end
   for line in content:gmatch("([^\r\n]*)\r?\n") do
      log.state("Mason: " .. line)
   end
end

-- Finally, chain to the project hook
return project_hook(repo, updates)