diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-05-29 22:18:26 +0100 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-05-29 22:18:26 +0100 |
commit | 3bfd0792bf1011b76db07aeba5f5c6903ed9bd60 (patch) | |
tree | cde4c2a9c890f638bc6367b2275d207ec53475f6 | |
parent | bf37f704704f524276ac1bfaab87dd3ac2d5d807 (diff) | |
download | gitano-3bfd0792bf1011b76db07aeba5f5c6903ed9bd60.tar.gz |
GIT: Add annotated tag support
-rw-r--r-- | lib/gitano/git.lua | 2 | ||||
-rw-r--r-- | lib/gitano/git/object.lua | 3 | ||||
-rw-r--r-- | lib/gitano/git/tag.lua | 97 |
3 files changed, 102 insertions, 0 deletions
diff --git a/lib/gitano/git.lua b/lib/gitano/git.lua index ee1edf0..f77e0bd 100644 --- a/lib/gitano/git.lua +++ b/lib/gitano/git.lua @@ -11,6 +11,7 @@ local object = require "gitano.git.object" local commit = require "gitano.git.commit" local tree = require "gitano.git.tree" local repo = require "gitano.git.repository" +local tag = require "gitano.git.tag" return { @@ -21,6 +22,7 @@ return { object = object, commit = commit, tree = tree, + tag = tag, -- Finally LL ll = ll }
\ No newline at end of file diff --git a/lib/gitano/git/object.lua b/lib/gitano/git/object.lua index 7858bcb..a6c32a8 100644 --- a/lib/gitano/git/object.lua +++ b/lib/gitano/git/object.lua @@ -9,6 +9,7 @@ local ll = require "gitano.git.ll" local commit = require "gitano.git.commit" local tree = require "gitano.git.tree" +local tag = require "gitano.git.tag" local repos = setmetatable({}, {__mode="k"}) @@ -27,6 +28,8 @@ local function _objectindex(obj, field) ok, ret = 0, commit.new(repos[obj], obj) elseif obj.type == "tree" then ok, ret = 0, tree.new(repos[obj], obj) + elseif obj.type == "tag" then + ok, ret = 0, tag.new(repos[obj], obj) else error("Unknown type <" .. obj.type .. "> for content parse") end diff --git a/lib/gitano/git/tag.lua b/lib/gitano/git/tag.lua new file mode 100644 index 0000000..4c07691 --- /dev/null +++ b/lib/gitano/git/tag.lua @@ -0,0 +1,97 @@ +-- gitano.git.tag +-- +-- Core Git functionality for Gitano +-- +-- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org> +-- +-- + +local ll = require "gitano.git.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 +} |