Class: Gollum::Committer
- Inherits:
-
Object
- Object
- Gollum::Committer
- Defined in:
- lib/gollum-lib/committer.rb
Overview
Responsible for handling the commit process for a Wiki. It sets up the Git index, provides methods for modifying the tree, and stores callbacks to be fired after the commit has been made. This is specifically designed to handle multiple updated pages in a single commit.
Instance Attribute Summary collapse
-
#options ⇒ Object
readonly
Gets a Hash of commit options.
-
#wiki ⇒ Object
readonly
Gets the instance of the Gollum::Wiki that is being updated.
Instance Method Summary collapse
-
#actor ⇒ Object
Public: The committer for this commit.
-
#add_to_index(dir, name, format, data, allow_same_ext = false) ⇒ Object
Adds a page to the given Index.
-
#after_commit(&block) ⇒ Object
Adds a callback to be fired after a commit.
-
#commit ⇒ Object
Writes the commit to Git and runs the after_commit callbacks.
-
#file_path_scheduled_for_deletion?(map, path) ⇒ Boolean
Determine if a given file is scheduled to be deleted in the next commit for the given Index.
-
#index ⇒ Object
Public: References the Git index for this commit.
-
#initialize(wiki, options = {}) ⇒ Committer
constructor
Initializes the Committer.
-
#method_missing(name, *args) ⇒ Object
Proxies methods t.
-
#page_path_scheduled_for_deletion?(map, path) ⇒ Boolean
Determine if a given page (regardless of format) is scheduled to be deleted in the next commit for the given Index.
-
#parents ⇒ Object
Public: The parent commits to this pending commit.
-
#update_working_dir(dir, name, format) ⇒ Object
Update the given file in the repository’s working directory if there is a working directory present.
Constructor Details
#initialize(wiki, options = {}) ⇒ Committer
Initializes the Committer.
wiki - The Gollum::Wiki instance that is being updated. options - The commit Hash details:
:message - The String commit message.
:name - The String author full name.
:email - The String email address.
:parent - Optional Gollum::Git::Commit parent to this update.
:tree - Optional String SHA of the tree to create the
index from.
:committer - Optional Gollum::Committer instance. If provided,
assume that this operation is part of batch of
updates and the commit happens later.
Returns the Committer instance.
29 30 31 32 33 34 |
# File 'lib/gollum-lib/committer.rb', line 29 def initialize(wiki, = {}) @wiki = wiki @options = @callbacks = [] after_commit { |*args| Hook.execute(:post_commit, *args) } end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object
Proxies methods t
238 239 240 241 |
# File 'lib/gollum-lib/committer.rb', line 238 def method_missing(name, *args) args.map! { |item| item.respond_to?(:force_encoding) ? item.force_encoding('ascii-8bit') : item } index.send(name, *args) end |
Instance Attribute Details
#options ⇒ Object (readonly)
Gets a Hash of commit options.
12 13 14 |
# File 'lib/gollum-lib/committer.rb', line 12 def @options end |
#wiki ⇒ Object (readonly)
Gets the instance of the Gollum::Wiki that is being updated.
9 10 11 |
# File 'lib/gollum-lib/committer.rb', line 9 def wiki @wiki end |
Instance Method Details
#actor ⇒ Object
Public: The committer for this commit.
Returns a Gollum::Git::Actor.
54 55 56 57 58 59 60 |
# File 'lib/gollum-lib/committer.rb', line 54 def actor @actor ||= begin @options[:name] = @wiki.default_committer_name if @options[:name].nil? @options[:email] = @wiki.default_committer_email if @options[:email].nil? Gollum::Git::Actor.new(@options[:name], @options[:email]) end end |
#add_to_index(dir, name, format, data, allow_same_ext = false) ⇒ Object
Adds a page to the given Index.
dir - The String subdirectory of the Gollum::Page without any
prefix or suffix slashes (e.g. "foo/bar").
name - The String Gollum::Page filename_stripped. format - The Symbol Gollum::Page format. data - The String wiki data to store in the tree map. allow_same_ext - A Boolean determining if the tree map allows the same
filename with the same extension.
Raises Gollum::DuplicatePageError if a matching filename already exists. This way, pages are not inadvertently overwritten.
Returns nothing (modifies the Index in place).
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/gollum-lib/committer.rb', line 88 def add_to_index(dir, name, format, data, allow_same_ext = false) # spaces must be dashes dir.gsub!(' ', '-') name.gsub!(' ', '-') path = @wiki.page_file_name(name, format) dir = '/' if dir.strip.empty? fullpath = ::File.join(*[dir, path]) fullpath = fullpath[1..-1] if fullpath =~ /^\// if index.current_tree && (tree = index.current_tree / (@wiki.page_file_dir || '/')) tree = tree / dir unless tree.nil? end if tree downpath = path.downcase.sub(/\.\w+$/, '') tree.blobs.each do |blob| next if page_path_scheduled_for_deletion?(index.tree, fullpath) existing_file = blob.name.downcase.sub(/\.\w+$/, '') existing_file_ext = ::File.extname(blob.name).sub(/^\./, '') new_file_ext = ::File.extname(path).sub(/^\./, '') if downpath == existing_file && !(allow_same_ext && new_file_ext == existing_file_ext) raise DuplicatePageError.new(dir, blob.name, path) end end end fullpath = fullpath.force_encoding('ascii-8bit') if fullpath.respond_to?(:force_encoding) begin data = @wiki.normalize(data) rescue ArgumentError => err # Swallow errors that arise from data being binary raise err unless err..include?('invalid byte sequence') end index.add(fullpath, data) end |
#after_commit(&block) ⇒ Object
Adds a callback to be fired after a commit.
block - A block that expects this Committer instance and the created
commit's SHA1 as the arguments.
Returns nothing.
183 184 185 |
# File 'lib/gollum-lib/committer.rb', line 183 def after_commit(&block) @callbacks << block end |
#commit ⇒ Object
Writes the commit to Git and runs the after_commit callbacks.
Returns the String SHA1 of the new commit.
169 170 171 172 173 174 175 |
# File 'lib/gollum-lib/committer.rb', line 169 def commit sha1 = index.commit(@options[:message], parents, actor, nil, @wiki.ref) @callbacks.each do |cb| cb.call(self, sha1) end sha1 end |
#file_path_scheduled_for_deletion?(map, path) ⇒ Boolean
Determine if a given file is scheduled to be deleted in the next commit for the given Index.
map - The Hash map:
key - The String directory or filename.
val - The Hash submap or the String contents of the file.
path - The String path of the file including extension.
Returns the Boolean response.
222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'lib/gollum-lib/committer.rb', line 222 def file_path_scheduled_for_deletion?(map, path) parts = path.split('/') if parts.size == 1 deletions = map.keys.select { |k| !map[k] } deletions.any? { |d| d == parts.first } else part = parts.shift if (rest = map[part]) file_path_scheduled_for_deletion?(rest, parts.join('/')) else false end end end |
#index ⇒ Object
Public: References the Git index for this commit.
Returns a Gollum::Git::Index.
39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/gollum-lib/committer.rb', line 39 def index @index ||= begin idx = @wiki.repo.index if (tree = [:tree]) idx.read_tree(tree) elsif (parent = parents.first) idx.read_tree(parent.tree.id) end idx end end |
#page_path_scheduled_for_deletion?(map, path) ⇒ Boolean
Determine if a given page (regardless of format) is scheduled to be deleted in the next commit for the given Index.
map - The Hash map:
key - The String directory or filename.
val - The Hash submap or the String contents of the file.
path - The String path of the page file. This may include the format
extension in which case it will be ignored.
Returns the Boolean response.
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/gollum-lib/committer.rb', line 197 def page_path_scheduled_for_deletion?(map, path) parts = path.split('/') if parts.size == 1 deletions = map.keys.select { |k| !map[k] } downfile = parts.first.downcase.sub(/\.\w+$/, '') deletions.any? { |d| d.downcase.sub(/\.\w+$/, '') == downfile } else part = parts.shift if (rest = map[part]) page_path_scheduled_for_deletion?(rest, parts.join('/')) else false end end end |
#parents ⇒ Object
Public: The parent commits to this pending commit.
Returns an array of Gollum::Git::Commit instances.
65 66 67 68 69 70 71 72 |
# File 'lib/gollum-lib/committer.rb', line 65 def parents @parents ||= begin arr = [@options[:parent] || @wiki.repo.commit(@wiki.ref)] arr.flatten! arr.compact! arr end end |
#update_working_dir(dir, name, format) ⇒ Object
Update the given file in the repository’s working directory if there is a working directory present.
dir - The String directory in which the file lives. name - The String name of the page or the stripped filename
(should be pre-canonicalized if required).
format - The Symbol format of the page.
Returns nothing.
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/gollum-lib/committer.rb', line 141 def update_working_dir(dir, name, format) unless @wiki.repo. if @wiki.page_file_dir && dir !~ /^#{@wiki.page_file_dir}/ dir = dir.size.zero? ? @wiki.page_file_dir : ::File.join(@wiki.page_file_dir, dir) end path = if dir == '' @wiki.page_file_name(name, format) else ::File.join(dir, @wiki.page_file_name(name, format)) end path = path.force_encoding('ascii-8bit') if path.respond_to?(:force_encoding) Dir.chdir(::File.join(@wiki.repo.path, '..')) do if file_path_scheduled_for_deletion?(index.tree, path) @wiki.repo.git.rm(path, :force => true) else @wiki.repo.git.checkout(path, 'HEAD') end end end end |