Makistos
10/25/2013 - 12:42 PM

The Gitorious repository hosting service, which you can install on your own server, hashes the Git repositories which makes it hard to link

The Gitorious repository hosting service, which you can install on your own server, hashes the Git repositories which makes it hard to link to them from other services. This script creates more readable links to those repositories. #git #gitorious #ruby #scm

#!/usr/bin/ruby -d

####
#
#  create_unhashed_links.rb
#
#  Creates links that are unhashed to the Gitorious repositories.
#  Helps link the repositories to Redmine.
#
#  Spaces in project names are replaced with underscores.
#
#  Most stuff is hardcoded, including gitorious repository location.
#
#  History
#    01.10.2009/MEP ; Initial revision
#    05.10.2009/MEP ; Rewrote: optimized database handling, more Ruby-like code.
#    09.10.2009/MEP ; Changed db_pw to production server's.
#    14.10.2009/MEP ; Fixed bug : gitorious rep path was not added to link.
#    14.10.2009/MEP ; Git db pw has to be given as a parameter now.
####

require "mysql"

gitorious_host = 'localhost'
db_user = 'git'
db_name = 'gitorious_production'

hashed_repository_path = '/var/www/gitorious/repositories'
pt_repository_path = '/git'

# Database object
class GitoriousDb

  def initialize(host, user, pw, name)
    @dbConn = Mysql::new(host, user, pw, name)
  end

  # Opens the recordset containing the repository info required
  def get_repos
    @rs = @dbConn.query("select projects.title as proj_name, repositories.name as repo_name, repositories.hashed_path from repositories, projects where repositories.project_id = projects.id")
    puts "Repositories: " + @rs.num_rows.to_s if $DEBUG
    return @rs
  end
  
  # Returns next row in recordset
  def get_next_repo
    retval = @rs.fetch_hash
    return retval
  end
  
end

class RepoLinker
  
  def initialize(gitorious_dir, link_dir, git_db)
    @gitorious_dir = gitorious_dir
    @link_dir = link_dir
    @git_db = git_db
  end
 
  def create_links(repo)
    link_name = create_link_name(repo)
    full_repo_path = create_repo_path(repo['hashed_path'])
    create_link(full_repo_path, link_name)
  end

  # Creates the full path and name for the link to be created. Currently it looks like
  # <base_dir>/<project_name>/<repository_name>.git
  def create_link_name(fields)
    return "#{@link_dir}/#{fields['proj_name']}/#{fields['repo_name']}.git".gsub(/ /, '_')
  end

  def create_repo_path(rel_path)
    return "#{@gitorious_dir}/#{rel_path}.git"
  end
    
  # Creates the link from the gitorious repo to the plain text link and also creates missing directories.
  # Checks that the directories and the link do not exist before attempting to create them.
  # *Parameters:*
  #  _source_ : Full path and file name to gitorious repository
  #  _link_   : Full path and link name for the plain text link
  def create_link(source, link)
    path = ''
    link.each('/') do |dir|
      path << dir
      if dir !~ /.git$/
	puts "Path: #{path}" if $DEBUG
        Dir.mkdir(path) unless File.exists?(path)
      else
	puts "Link: #{path}" if $DEBUG
        File.symlink(source, path) unless File.symlink?(path)
      end
    end
  end
  
end

db_pw = ARGV[0]

db = GitoriousDb.new(gitorious_host, db_user, db_pw, db_name)
rl = RepoLinker.new(hashed_repository_path, pt_repository_path, db)

db.get_repos

repo = db.get_next_repo

while repo
  rl.create_links(repo)
  repo.each_pair {|key, value| puts "#{key} is #{value}" } if $DEBUG
  repo = db.get_next_repo
end