summaryrefslogtreecommitdiff
path: root/lib/gall/tag.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gall/tag.lua')
-rw-r--r--lib/gall/tag.lua97
1 files changed, 97 insertions, 0 deletions
diff --git a/lib/gall/tag.lua b/lib/gall/tag.lua
new file mode 100644
index 0000000..707af31
--- /dev/null
+++ b/lib/gall/tag.lua
@@ -0,0 +1,97 @@
+-- gall.tag
+--
+-- Git Abstraction Layer for Lua -- Tag object interface
+--
+-- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org>
+--
+--
+
+local ll = require "gall.ll"
+
+local objs = setmetatable({}, {__mode="k"})
+local repos = setmetatable({}, {__mode="k"})
+local parsed = setmetatable({}, {__mode="k"})
+
+local _new
+
+local function parse_person(pers)
+ local real, email, when, tz = pers:match("^(.-) <([^>]+)> ([0-9]+) ([+-][0-9]+)$")
+ return {
+ realname = real,
+ email = email,
+ unixtime = when,
+ timezone = tz
+ }
+end
+
+local function tagindex(tag, field)
+ if not parsed[tag] then
+ local raw = objs[tag].raw
+ local headers, body, signature = {}, ""
+ local state = "headers"
+
+ for l in raw:gmatch("([^\n]*)\n") do
+ if state == "headers" then
+ local first, second = l:match("^([^ ]+) (.+)$")
+ if first then
+ if headers[first] then
+ headers[first][#headers[first]+1] = second
+ else
+ headers[first] = { second }
+ end
+ else
+ state = "message"
+ end
+ elseif state == "message" then
+ if l == PGP_SIG_START then
+ signature = l .. "\n"
+ state = "signature"
+ else
+ body = body .. l .. "\n"
+ end
+ else
+ signature = signature .. l .. "\n"
+ end
+ end
+
+ -- there's always one object
+ rawset(tag, "object", repos[tag]:get(headers.object[1]))
+ -- Always one type
+ rawset(tag, "type", headers.type[1])
+ -- Always one tag name
+ rawset(tag, "tag", headers.tag[1])
+ -- Always one tagger
+ rawset(tag, "tagger", parse_person(headers.tag[1]))
+ -- A message
+ rawset(tag, "message", body)
+ -- And an optional signature
+ rawset(tag, "signature", signature)
+ -- Promote the SHA
+ rawset(tag, "sha", objs[tag].sha)
+
+ -- Signal we are parsed
+ parsed[tag] = true
+ end
+
+ return rawget(tag, field)
+end
+
+local function tagtostring(tag)
+ return "<GitTag(" .. tostring(objs[tag].sha) .. ") in " .. tostring(repos[tag]) .. ">"
+end
+
+local tagmeta = {
+ __index = tagindex,
+ __tostring = tagtostring
+}
+
+function _new(repo, obj)
+ local ret = setmetatable({}, tagmeta)
+ objs[ret] = obj
+ repos[ret] = repo
+ return ret
+end
+
+return {
+ new = _new
+}