diff options
Diffstat (limited to 'bin/gitano-pre-receive-hook')
-rw-r--r-- | bin/gitano-pre-receive-hook | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/bin/gitano-pre-receive-hook b/bin/gitano-pre-receive-hook new file mode 100644 index 0000000..ba9b511 --- /dev/null +++ b/bin/gitano-pre-receive-hook @@ -0,0 +1,96 @@ +#!/usr/bin/env lua +-- -*- Lua -*- +-- gitano-pre-receive-hook +-- +-- Git (with) Augmented network operations -- pre-receive hook handler +-- +-- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org> +-- +-- + +local gitano = require "gitano" +local luxio = require "luxio" +local sio = require "luxio.simple" +local sp = require "luxio.subprocess" + +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 |