diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-09-01 10:18:49 +0100 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2012-09-01 10:18:49 +0100 |
commit | 69bb19899d3651f8290b59002c0c9482bb8f3833 (patch) | |
tree | 14dec263fede21de81bceba7c9a911df3704fd94 | |
parent | 52099fedf754dd740025fa2b2b1980fef409cb65 (diff) | |
parent | 2ca181a87a6d3661146791f5391c01ca635df44f (diff) | |
download | gitano-69bb19899d3651f8290b59002c0c9482bb8f3833.tar.gz |
Merge pre-receive hook support
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | bin/gitano-pre-receive-hook.in | 101 | ||||
-rw-r--r-- | lib/gitano/repository.lua | 2 |
3 files changed, 103 insertions, 2 deletions
@@ -18,7 +18,7 @@ SHARE_INST_PATH := $(DESTDIR)$(SHARE_PATH) SKEL_INST_PATH := $(SHARE_INST_PATH)/skel LIB_BINS := gitano-auth gitano-post-receive-hook gitano-update-hook \ - gitano-update-ssh + gitano-update-ssh gitano-pre-receive-hook BINS := gitano-setup diff --git a/bin/gitano-pre-receive-hook.in b/bin/gitano-pre-receive-hook.in new file mode 100644 index 0000000..4dd6ff3 --- /dev/null +++ b/bin/gitano-pre-receive-hook.in @@ -0,0 +1,101 @@ +-- @@SHEBANG +-- -*- Lua -*- +-- gitano-pre-receive-hook +-- +-- Git (with) Augmented network operations -- pre-receive hook handler +-- +-- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org> +-- +-- + +-- @@GITANO_LUA_PATH + +local gitano = require "gitano" +local luxio = require "luxio" +local sio = require "luxio.simple" +local sp = require "luxio.subprocess" + +-- @@GITANO_BIN_PATH +-- @@GITANO_SHARE_PATH + +local start_log_level = gitano.log.get_level() +-- Clamp level at info until we have checked if the caller +-- is an admin or not +gitano.log.cap_level(gitano.log.level.INFO) + +local repo_root = luxio.getenv("GITANO_ROOT") +local username = luxio.getenv("GITANO_USER") or "gitano/anonymous" +local keytag = luxio.getenv("GITANO_KEYTAG") or "unknown" +local project = luxio.getenv("GITANO_PROJECT") or "" +local source = luxio.getenv("GITANO_SOURCE") or "ssh" + +-- Now load the administration data + +local admin_repo = gitano.git.repository.new((repo_root or "") .. "/gitano-admin.git") + +if not admin_repo then + gitano.log.fatal("Unable to locate administration repository. Cannot continue"); +end + +local admin_head = admin_repo:get(admin_repo.HEAD) + +if not admin_head then + gitano.log.fatal("Unable to find the HEAD of the administration repository. Cannot continue"); +end + +local config, msg = gitano.config.parse(admin_head) + +if not config then + gitano.log.critical("Unable to parse administration repository.") + gitano.log.critical(" * " .. (msg or "No error?")) + gitano.log.fatal("Cannot continue") +end + +-- Now, are we an admin? +if config.groups["gitano-admin"].filtered_members[username] then + -- Yep, so blithely reset logging level + gitano.log.set_level(start_log_level) +end + +if not config.global.silent then + -- Not silent, bump to chatty level automatically + gitano.log.bump_level(gitano.log.level.CHAT) +end + +local repo, msg = gitano.repository.find(config, project) +if not repo then + gitano.log.critical("Unable to locate repository.") + gitano.log.critical(" * " .. (tostring(msg))) + gitano.log.fatal("Cannot continue") +end + +if repo.is_nascent then + gitano.log.fatal("Repository " .. repo.name .. " is nascent") +end + +-- pre-receive is can prevent updates. Its name is a bit misleading. +-- pre-receive is called once all the objects have been pushed, but before the +-- individual update hooks are called. It gets the same input as post-receive +-- but can opt to reject the entire push. If you need to make decisions based +-- upon multiple refs being updated simultaneously, then this is the badger for +-- you. + +local updates = {} +for oldsha, newsha, refname in + (sio.stdin:read("*a")):gmatch("([^ ]+) ([^ ]+) ([^\n]+)") do + gitano.log.ddebug("pre-receive:", oldsha, newsha, refname) + updates[refname] = {oldsha, newsha, oldsha=oldsha, newsha=newsha} +end + +if repo:uses_hook("pre-receive") then + gitano.log.debug("Configuring for pre-receive hook") + gitano.actions.set_supple_globals("pre-receive") + gitano.log.info("Running repository pre-receive hook") + local ok, msg = gitano.supple.run_hook(repo, "pre-receive", updates) + if not ok then + gitano.log.crit(msg or "No reason given, but errored somehow.") + end + gitano.log.info("Finished") +end + +return 0 diff --git a/lib/gitano/repository.lua b/lib/gitano/repository.lua index 7b3f875..ded34d4 100644 --- a/lib/gitano/repository.lua +++ b/lib/gitano/repository.lua @@ -281,7 +281,7 @@ end function repo_method:check_and_upgrade_hooks() log.ddebug("Checking hooks for", self.name) - for _, hook in ipairs {"update", "post-receive"} do + for _, hook in ipairs {"pre-receive", "update", "post-receive"} do local hookfile = ("%s/hooks/%s"):format(self:fs_path(), hook) local hooktarget = ("%s/gitano-%s-hook"):format(config.lib_bin_path(), hook) |