Class: Gitolite::GitoliteAdmin

Inherits:
Object
  • Object
show all
Defined in:
lib/gitolite/gitolite_admin.rb

Constant Summary collapse

CONFIG_FILE =
"gitolite.conf"
CONF_DIR =
"conf"
KEY_DIR =
"keydir"
DEBUG =
false
TIMEOUT =
10
RAISE_ERROR =
true
DEFAULT_COMMIT_MSG =

Gitolite gem’s default commit message

"Committed by the gitolite gem"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, options = {}) ⇒ GitoliteAdmin

Intialize with the path to the gitolite-admin repository



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/gitolite/gitolite_admin.rb', line 80

def initialize(path, options = {})
  @path = path

  @config_file = options[:config_file] || CONFIG_FILE
  @conf_dir    = options[:conf_dir] || CONF_DIR
  @key_dir     = options[:key_dir] || KEY_DIR
  git_env      = options[:env] || {}
  git_raise    = options[:raise] || RAISE_ERROR

  @git_options = {:env => git_env, :raise => git_raise}

  @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

Instance Attribute Details

#gl_adminObject

Returns the value of attribute gl_admin.



4
5
6
# File 'lib/gitolite/gitolite_admin.rb', line 4

def gl_admin
  @gl_admin
end

Class Method Details

.bootstrap(path, options = {}) ⇒ Object

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


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/gitolite/gitolite_admin.rb', line 47

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, {}, config)
  gl_admin.git.native(:commit, {}, '-a', '-m', options[:message] || "Config bootstrapped by the gitolite gem")

  self.new(path)
end

.is_gitolite_admin_repo?(dir) ⇒ Boolean

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

Returns:

  • (Boolean)


23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/gitolite/gitolite_admin.rb', line 23

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

Instance Method Details

#add_key(key) ⇒ Object



123
124
125
126
# File 'lib/gitolite/gitolite_admin.rb', line 123

def add_key(key)
  raise "Key must be of type Gitolite::SSHKey!" unless key.instance_of? Gitolite::SSHKey
  ssh_keys[key.owner] << key
end

#applyObject

Push back to origin



198
199
200
# File 'lib/gitolite/gitolite_admin.rb', line 198

def apply
  @gl_admin.git.native(:push, git_options, "origin", "master")
end

#configObject



108
109
110
# File 'lib/gitolite/gitolite_admin.rb', line 108

def config
  @config ||= load_config
end

#config=(config) ⇒ Object



113
114
115
# File 'lib/gitolite/gitolite_admin.rb', line 113

def config=(config)
  @config = config
end

#git_optionsObject



103
104
105
# File 'lib/gitolite/gitolite_admin.rb', line 103

def git_options
  @git_options.clone
end

#reload!Object

This method will destroy the in-memory data structures and reload everything from the file system



147
148
149
150
# File 'lib/gitolite/gitolite_admin.rb', line 147

def reload!
  @ssh_keys = load_keys
  @config = load_config
end

#reset!Object

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



138
139
140
141
142
# File 'lib/gitolite/gitolite_admin.rb', line 138

def reset!
  @gl_admin.git.native(:reset, git_options.merge(:hard => true), 'HEAD')
  @gl_admin.git.native(:clean, git_options.merge(:d => true, :q => true, :f => true))
  reload!
end

#rm_key(key) ⇒ Object



129
130
131
132
# File 'lib/gitolite/gitolite_admin.rb', line 129

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

#save(commit_message = DEFAULT_COMMIT_MSG, options = {}) ⇒ Object

Writes all changed aspects out to the file system will also stage all changes then commit



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/gitolite/gitolite_admin.rb', line 155

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(@conf_dir_path)
    @gl_admin.git.native(:add, git_options, new_conf)
  end

  # Process ssh keys (if loaded, i.e. may be modified)
  if @ssh_keys
    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(@key_dir, f) }
    to_remove.each do |key|
      @gl_admin.git.native(:rm, git_options, key)
    end

    @ssh_keys.each_value do |key|
      # 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(@key_dir_path)
        @gl_admin.git.native(:add, git_options, new_key)
      end
    end
  end

  args = []

  args << '-a'
  args << '-m'
  args << commit_message

  if options.has_key?(:author) && !options[:author].empty?
    args << "--author='#{options[:author]}'"
  end

  @gl_admin.git.native(:commit, git_options, *args)
end

#save_and_apply(commit_message = DEFAULT_COMMIT_MSG) ⇒ Object

Commits all staged changes and pushes back to origin



204
205
206
207
# File 'lib/gitolite/gitolite_admin.rb', line 204

def save_and_apply(commit_message = DEFAULT_COMMIT_MSG)
  save(commit_message)
  apply
end

#ssh_keysObject



118
119
120
# File 'lib/gitolite/gitolite_admin.rb', line 118

def ssh_keys
  @ssh_keys ||= load_keys
end

#update(options = {}) ⇒ Object

Updates the repo with changes from remote master



211
212
213
214
215
216
217
218
219
# File 'lib/gitolite/gitolite_admin.rb', line 211

def update(options = {})
  options = {:reset => true, :rebase => false}.merge(options)

  reset! if options[:reset]

  @gl_admin.git.native(:pull, git_options.merge(:rebase => options[:rebase]), "origin", "master")

  reload!
end