Skip to content

Instantly share code, notes, and snippets.

@AnotherKamila
Created August 2, 2012 17:25
Show Gist options
  • Save AnotherKamila/3238901 to your computer and use it in GitHub Desktop.
Save AnotherKamila/3238901 to your computer and use it in GitHub Desktop.
post-receive hook receiver to pull new revisions into the given repo
#!/usr/bin/coffee
# a small app to pull new revisions to a specified github repo
# to be used as the other end of post-receive hooks
#
# url should contain the (absolute) path to the repo in the `repo` parameter
# example: http://rhoeas.tk/pull?repo=~kamila/www/my.rhoeas.tk
http = require 'http'
url = require 'url'
fs = require 'fs'
{ exec } = require 'child_process'
handle = (req, res) ->
reply = (message, status = 200) ->
now = new Date()
if status != 204 then console.log "[#{now.toDateString()} #{now.toLocaleTimeString()}] #{if status == 200 then '◯' else '†'}(#{status}) #{message}"
res.writeHead status
res.end message+'\n' or ''
query = (url.parse req.url, true).query
noop = query.noop; if noop then reply '', 204 ; return
repo = query.repo or ''
if not repo.match /^[-\/\._~a-zA-Z]+$/ then reply "#{repo}: does not look like a repo path", 400; return
fs.exists repo, (exists) ->
if not exists then reply "#{repo}: directory does not exist", 400; return
exec "cd '#{repo}'; git pull", (err, stdout, stderr) ->
if err
if err.code == 128 then reply "#{repo}: not a git repository", 400; return
if err.code != 0 then reply "git error:\n\n#{stderr}", 500; return
if stdout.match 'up-to-date' then ans = "#{repo}: " + stdout.trim()
else ans = (stderr.split '\n')[1].replace(/\s+/g,' ').trim() # tells the original and new revisions and origin
reply ans
srv = (http.createServer handle).listen process.env.PORT or 7855, 'localhost'
process.on 'SIGINT', ->
srv.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment