lib/gitolite/gitolite_admin.rb in jbox-gitolite-1.1.10 vs lib/gitolite/gitolite_admin.rb in jbox-gitolite-1.1.11
- old
+ new
@@ -1,209 +1,241 @@
require File.join(File.dirname(__FILE__), "dirty_proxy")
module Gitolite
class GitoliteAdmin
+
attr_accessor :gl_admin
- CONF = "gitolite.conf"
- CONFDIR = "conf"
- KEYDIR = "keydir"
- DEBUG = false
+ CONFIG_FILE = "gitolite.conf"
+ CONF_DIR = "conf"
+ KEY_DIR = "keydir"
+ DEBUG = false
+ TIMEOUT = 10
- #Gitolite gem's default git commit message
+ # Gitolite gem's default commit message
DEFAULT_COMMIT_MSG = "Committed by the gitolite gem"
+ class << self
+
+ # Checks to see if the given path is a gitolite-admin repository
+ # A valid repository contains a conf folder, keydir folder,
+ # and a configuration file within the conf folder
+ def is_gitolite_admin_repo?(dir)
+ # First check if it is a git repository
+ begin
+ Grit::Repo.new(dir)
+ rescue Grit::NoSuchPathError, Grit::InvalidGitRepositoryError
+ return false
+ end
+
+ # If we got here it is a valid git repo,
+ # now check directory structure
+ File.exists?(File.join(dir, 'conf')) &&
+ File.exists?(File.join(dir, 'keydir')) &&
+ !Dir.glob(File.join(dir, 'conf', '*.conf')).empty?
+ end
+
+
+ # This method will bootstrap a gitolite-admin repo
+ # at the given path. A typical gitolite-admin
+ # repo will have the following tree:
+ #
+ # gitolite-admin
+ # conf
+ # gitolite.conf
+ # keydir
+ def bootstrap(path, options = {})
+ if self.is_gitolite_admin_repo?(path)
+ if options[:overwrite]
+ FileUtils.rm_rf(File.join(path, '*'))
+ else
+ return self.new(path)
+ end
+ end
+
+ FileUtils.mkdir_p([File.join(path, "conf"), File.join(path, "keydir")])
+
+ options[:perm] ||= "RW+"
+ options[:refex] ||= ""
+ options[:user] ||= "git"
+
+ c = Config.init
+ r = Config::Repo.new(options[:repo] || "gitolite-admin")
+ r.add_permission(options[:perm], options[:refex], options[:user])
+ c.add_repo(r)
+ config = c.to_file(File.join(path, "conf"))
+
+ gl_admin = Grit::Repo.init(path)
+ gl_admin.git.native(:add, {:chdir => gl_admin.working_dir}, config)
+ gl_admin.git.native(:commit, {:chdir => gl_admin.working_dir}, '-a', '-m', options[:message] || "Config bootstrapped by the gitolite gem")
+
+ self.new(path)
+ end
+
+ end
+
+
# Intialize with the path to
# the gitolite-admin repository
def initialize(path, options = {})
@path = path
- @gl_admin = Grit::Repo.new(path)
- @conf = options[:conf] || CONF
- @confdir = options[:confdir] || CONFDIR
- @keydir = options[:keydir] || KEYDIR
+ @config_file = options[:config_file] || CONFIG_FILE
+ @conf_dir = options[:conf_dir] || CONF_DIR
+ @key_dir = options[:key_dir] || KEY_DIR
+ @env = options[:env] || {}
+
+ @config_file_path = File.join(@path, @conf_dir, @config_file)
+ @conf_dir_path = File.join(@path, @conf_dir)
+ @key_dir_path = File.join(@path, @key_dir)
+
+ Grit::Git.git_timeout = options[:timeout] || TIMEOUT
Grit.debug = options[:debug] || DEBUG
+ @gl_admin = Grit::Repo.new(path)
+
+ reload!
end
- # This method will bootstrap a gitolite-admin repo
- # at the given path. A typical gitolite-admin
- # repo will have the following tree:
- #
- # gitolite-admin
- # conf
- # gitolite.conf
- # keydir
- def self.bootstrap(path, options = {})
- if self.is_gitolite_admin_repo?(path)
- if options[:overwrite]
- FileUtils.rm_rf(File.join(path, '*'))
- else
- return self.new(path)
- end
- end
- FileUtils.mkdir_p([File.join(path,"conf"), File.join(path,"keydir")])
+ def config
+ @config ||= load_config
+ end
- options[:perm] ||= "RW+"
- options[:refex] ||= ""
- options[:user] ||= "git"
- c = Config.init
- r = Config::Repo.new(options[:repo] || "gitolite-admin")
- r.add_permission(options[:perm], options[:refex], options[:user])
- c.add_repo(r)
- config = c.to_file(File.join(path, "conf"))
+ def config=(config)
+ @config = config
+ end
- repo = Grit::Repo.init(path)
- Dir.chdir(path) do
- repo.add(config)
- repo.commit_index(options[:message] || "Config bootstrapped by the gitolite gem")
- end
- self.new(path)
+ def ssh_keys
+ @ssh_keys ||= load_keys
end
- #Writes all changed aspects out to the file system
- #will also stage all changes
- def save(commit_message = DEFAULT_COMMIT_MSG)
- confdir = File.join(@gl_admin.working_dir, @confdir)
- keydir = File.join(@gl_admin.working_dir, @keydir)
+ def add_key(key)
+ raise "Key must be of type Gitolite::SSHKey!" unless key.instance_of? Gitolite::SSHKey
+ ssh_keys[key.owner] << key
+ end
+
+
+ def rm_key(key)
+ raise "Key must be of type Gitolite::SSHKey!" unless key.instance_of? Gitolite::SSHKey
+ ssh_keys[key.owner].delete key
+ end
+
+
+ # This method will destroy all local tracked changes, resetting the local gitolite
+ # git repo to HEAD and reloading the entire repository
+ # Note that this will also delete all untracked files
+ def reset!
+ @gl_admin.git.native(:reset, {:env => @env, :chdir => @gl_admin.working_dir, :hard => true}, 'HEAD')
+ @gl_admin.git.native(:clean, {:env => @env, :chdir => @gl_admin.working_dir, :d => true, :q => true, :f => true})
+ reload!
+ end
+
+
+ # This method will destroy the in-memory data structures and reload everything
+ # from the file system
+ def reload!
+ @ssh_keys = load_keys
+ @config = load_config
+ end
+
+
+ # Writes all changed aspects out to the file system
+ # will also stage all changes then commit
+ def save(commit_message = DEFAULT_COMMIT_MSG, options = {})
+
#Process config file (if loaded, i.e. may be modified)
if @config
- new_conf = @config.to_file(confdir).gsub(@gl_admin.working_dir + '/', '')
- @gl_admin.git.native(:add, {:chdir => @gl_admin.working_dir}, new_conf)
+ new_conf = @config.to_file(@conf_dir_path)
+ @gl_admin.git.native(:add, {:env => @env, :chdir => @gl_admin.working_dir}, new_conf)
end
#Process ssh keys (if loaded, i.e. may be modified)
if @ssh_keys
- files = list_keys(keydir).map{|f| File.basename f}
- keys = @ssh_keys.values.map{|f| f.map {|t| t.filename}}.flatten
+ files = list_keys.map{|f| File.basename f}
+ keys = @ssh_keys.values.map{|f| f.map {|t| t.filename}}.flatten
- to_remove = (files - keys).map { |f| File.join(@keydir, f) }
+ to_remove = (files - keys).map { |f| File.join(@key_dir, f) }
to_remove.each do |key|
- @gl_admin.git.native(:rm, {:chdir => @gl_admin.working_dir}, key)
+ @gl_admin.git.native(:rm, {:env => @env, :chdir => @gl_admin.working_dir}, key)
end
@ssh_keys.each_value do |key|
- #Write only keys from sets that has been modified
+ # Write only keys from sets that has been modified
next if key.respond_to?(:dirty?) && !key.dirty?
key.each do |k|
- new_key = k.to_file(keydir).gsub(@gl_admin.working_dir + '/', '')
- @gl_admin.git.native(:add, {:chdir => @gl_admin.working_dir}, new_key)
+ new_key = k.to_file(@key_dir_path)
+ @gl_admin.git.native(:add, {:env => @env, :chdir => @gl_admin.working_dir}, new_key)
end
end
end
- @gl_admin.git.native(:commit, {:chdir => @gl_admin.working_dir}, '-a', '-m', commit_message)
- end
+ args = []
- # This method will destroy all local tracked changes, resetting the local gitolite
- # git repo to HEAD and reloading the entire repository
- # Note that this will also delete all untracked files
- def reset!
- Dir.chdir(@gl_admin.working_dir) do
- @gl_admin.git.reset({:hard => true}, 'HEAD')
- @gl_admin.git.clean({:d => true, :q => true, :f => true})
+ if options.has_key?(:author) && !options[:author].empty?
+ args << "--author='#{options[:author]}'"
end
- reload!
- end
- # This method will destroy the in-memory data structures and reload everything
- # from the file system
- def reload!
- @ssh_keys = load_keys
- @config = load_config
+ @gl_admin.git.native(:commit, {:env => @env, :chdir => @gl_admin.working_dir}, '-a', '-m', commit_message, args.join(' '))
end
+
# Push back to origin
def apply
- @gl_admin.git.native(:push, {:chdir => @gl_admin.working_dir}, "origin", "master")
+ @gl_admin.git.native(:push, {:env => @env, :chdir => @gl_admin.working_dir}, "origin", "master")
end
+
# Commits all staged changes and pushes back to origin
def save_and_apply(commit_message = DEFAULT_COMMIT_MSG)
- self.save(commit_message)
- self.apply
+ save(commit_message)
+ apply
end
+
# Updates the repo with changes from remote master
def update(options = {})
options = {:reset => true, :rebase => false}.merge(options)
reset! if options[:reset]
- @gl_admin.git.native(:pull, {:chdir => @gl_admin.working_dir, :rebase => options[:rebase]}, "origin", "master")
+ @gl_admin.git.native(:pull, {:env => @env, :chdir => @gl_admin.working_dir, :rebase => options[:rebase]}, "origin", "master")
reload!
end
- def add_key(key)
- raise "Key must be of type Gitolite::SSHKey!" unless key.instance_of? Gitolite::SSHKey
- ssh_keys[key.owner] << key
- end
- def rm_key(key)
- raise "Key must be of type Gitolite::SSHKey!" unless key.instance_of? Gitolite::SSHKey
- ssh_keys[key.owner].delete key
- end
+ private
- #Checks to see if the given path is a gitolite-admin repository
- #A valid repository contains a conf folder, keydir folder,
- #and a configuration file within the conf folder
- def self.is_gitolite_admin_repo?(dir)
- # First check if it is a git repository
- begin
- Grit::Repo.new(dir)
- rescue Grit::InvalidGitRepositoryError
- return false
- end
- # If we got here it is a valid git repo,
- # now check directory structure
- File.exists?(File.join(dir, 'conf')) &&
- File.exists?(File.join(dir, 'keydir')) &&
- !Dir.glob(File.join(dir, 'conf', '*.conf')).empty?
+ def load_config
+ Config.new(@config_file_path)
end
- def ssh_keys
- @ssh_keys ||= load_keys
- end
- def config
- @config ||= load_config
+ def list_keys
+ Dir.glob(@key_dir_path + '/**/*.pub')
end
- def config=(config)
- @config = config
- end
- private
- #Loads all .pub files in the gitolite-admin
- #keydir directory
- def load_keys(path = nil)
- path ||= File.join(@path, @keydir)
- keys = Hash.new {|k,v| k[v] = DirtyProxy.new([])}
+ # Loads all .pub files in the gitolite-admin
+ # keydir directory
+ def load_keys
+ keys = Hash.new {|k,v| k[v] = DirtyProxy.new([])}
- list_keys(path).each do |key|
- new_key = SSHKey.from_file(key)
- owner = new_key.owner
+ list_keys.each do |key|
+ new_key = SSHKey.from_file(key)
+ owner = new_key.owner
- keys[owner] << new_key
- end
- #Mark key sets as unmodified (for dirty checking)
- keys.values.each{|set| set.clean_up!}
-
- keys
+ keys[owner] << new_key
end
- def load_config(path = nil)
- path ||= File.join(@path, @confdir, @conf)
- Config.new(path)
- end
+ # Mark key sets as unmodified (for dirty checking)
+ keys.values.each{|set| set.clean_up!}
- def list_keys(path)
- keys = Dir.glob(path + '/**/*.pub')
- keys
- end
+ keys
+ end
+
end
end