#!/usr/bin/env ruby # coding: utf-8 $:.unshift File.dirname(__FILE__) load 'git-mirror-backend.rb' require 'uri' require 'open-uri' require 'nokogiri' class Cgit < GitMirrorBackend def initialize() @config = {} end def cmd_config(*args) args.each do |arg| key, val = arg.split('=', 2) case key when "url" val = URI(val) unless val.path.end_with?("/") val.path += "/" end end @config[key] = val end return nil end def getHTML(path) Nokogiri::HTML(open(@config['url']+path)) end def cmd_get_meta(path) doc = self.getHTML(path) empty = (doc.css('.error').text == "Repository seems to be empty") if empty default_branch = 'master' else head = open(@config['url']+(path+'/HEAD')).read default_branch = head.split("\n")[0].sub(/^ref: /, '').sub(/^refs\/heads\//, '') end return { 'description' => doc.css('#header .sub')[0].text, 'owner' => doc.css('#header .sub')[1].text, 'default-branch' => default_branch, } end def cmd_set_meta(path, *pairs) raise "no can do" end def cmd_push_url(path) urls = self.getHTML(path).css('a[rel="vcs-git"]').map{|a| a['href']} prefs = ['ssh', 'https', 'http', 'git'] return urls.sort_by{|u| prefs.index(URI(u).scheme)}.first end def cmd_pull_url(path) doc = self.getHTML(path) urls = doc.css('a[rel="vcs-git"]').map{|a| a['href']} empty = (doc.css('.error').text == "Repository seems to be empty") prefs = ['git', 'https', 'http', 'file', 'ssh', 'git-broken', 'https-broken', 'http-broken'] if empty urls.push('file://' + File.dirname(__FILE__) + '/empty-repo') end return urls.sort_by{|u| u = URI(u) scheme = u.scheme # work around a bug in git-daemon if u.scheme == 'git' and u.path.start_with?('/~') scheme += '-broken' end # work around a bug in cgit if u.scheme.start_with?('http') and empty scheme += '-broken' end prefs.index(scheme) }.first end def cmd_repo_mode(path) return "passive" end end if __FILE__ == $0 if ARGV.length != 1 throw "Usage: $0 ACCOUNT_NAME" end Cgit.new().repl(ARGV[1]) end