diff --git a/lib/gollum/blob_entry.rb b/lib/gollum/blob_entry.rb index 1c3f8f2e..cbadc01c 100644 --- a/lib/gollum/blob_entry.rb +++ b/lib/gollum/blob_entry.rb @@ -3,9 +3,10 @@ module Gollum # Gets the String SHA for this blob. attr_reader :sha - # Gets the String full path for this blob. + # Gets the full path String for this blob. attr_reader :path + # Gets the Fixnum size of this blob. attr_reader :size def initialize(sha, path, size = nil) @@ -15,12 +16,12 @@ module Gollum @dir = @name = @blob = nil end - # Gets the normalized directory path for this blob. + # Gets the normalized directory path String for this blob. def dir @dir ||= self.class.normalize_dir(::File.dirname(@path)) end - # Gets the String file base name for this blob. + # Gets the file base name String for this blob. def name @name ||= ::File.basename(@path) end diff --git a/lib/gollum/git_access.rb b/lib/gollum/git_access.rb index 409a0197..76568f73 100644 --- a/lib/gollum/git_access.rb +++ b/lib/gollum/git_access.rb @@ -1,21 +1,29 @@ module Gollum + # Controls all access to the Git objects from Gollum. Extend this class to + # add custom caching for special cases. class GitAccess + # Gets the String path to the Git repository. attr_reader :path + + # Gets the Grit::Repo instance for the Git repository. attr_reader :repo # Gets a Hash cache of refs to commit SHAs. # # {"master" => "abc123", ...} # - # Returns the Hash cache. attr_reader :ref_map # Gets a Hash cache of commit SHAs to a recursive tree of blobs. # - # {"abc123" => [["lib/foo.rb", "blob-sha"], [file, sha], ...], ...} + # {"abc123" => [, ]} # - # Returns the Hash cache. attr_reader :tree_map + + # Gets a Hash cache of commit SHAs to the Grit::Commit instance. + # + # {"abcd123" => } + # attr_reader :commit_map def initialize(path) @@ -24,20 +32,19 @@ module Gollum clear end - def clear - @ref_map = {} - @tree_map = {} - @commit_map = {} - end - - def refresh - @ref_map.clear - end - + # Public: Determines whether the Git repository exists on disk. + # + # Returns true if it exists, or false. def exist? @repo.git.exist? end + # Public: Converts a given Git reference to a SHA, using the cache if + # available. + # + # ref - a String Git reference (ex: "master") + # + # Returns a String. def ref_to_sha(ref) if sha?(ref) ref @@ -46,6 +53,12 @@ module Gollum end end + # Public: Gets a recursive list of Git blobs for the whole tree at the + # given commit. + # + # ref - A String Git reference or Git SHA to a commit. + # + # Returns an Array of BlobEntry instances. def tree(ref) if sha = ref_to_sha(ref) get_cache(:tree, sha) { tree!(sha) } @@ -54,10 +67,20 @@ module Gollum end end + # Public: Fetches the contents of the Git blob at the given SHA. + # + # sha - A String Git SHA. + # + # Returns the String content of the blob. def blob(sha) cat_file!(sha) end + # Public: Looks up the Git commit using the given Git SHA or ref. + # + # ref - A String Git SHA or ref. + # + # Returns a Grit::Commit. def commit(ref) if sha?(ref) get_cache(:commit, ref) { commit!(ref) } @@ -73,6 +96,11 @@ module Gollum end end + # Public: Gets a list of Git commits. + # + # *shas - An Array of String SHAs. + # + # Returns an Array of Grit::Commit instances. def commits(*shas) shas.flatten! cached_commits = multi_get(:commit, shas) @@ -85,23 +113,62 @@ module Gollum shas.map { |sha| cached_commits[sha] } end - def multi_commit!(shas, hash) + # Public: Clears all of the cached data that this GitAccess is tracking. + # + # Returns nothing. + def clear + @ref_map = {} + @tree_map = {} + @commit_map = {} + end + + # Public: Refreshes just the cached Git reference data. This should + # be called after every Gollum update. + # + # Returns nothing. + def refresh + @ref_map.clear + end + + # Raw method for fetching a list of Git commits. + # + # shas - An Array of String SHAs. + # hash - Optional Hash to store the found commits, indexed by their SHA. + # + # Returns the same Hash instance. + def multi_commit!(shas, hash = {}) shas.each_slice(500) do |slice| @repo.batch(slice).each do |commit| hash[commit.id] = commit end end + hash end + # Checks to see if the given String is a 40 character hex SHA. + # + # str - Possible String SHA. + # + # Returns true if the String is a SHA, or false. def sha?(str) - str =~ /^[0-9a-f]{40}$/ + !!(str =~ /^[0-9a-f]{40}$/) end + # Looks up the Git SHA for the given Git ref. + # + # ref - String Git ref. + # + # Returns a String SHA. def ref_to_sha!(ref) @repo.git.rev_list({:max_count=>1}, ref) rescue Grit::GitRuby::Repository::NoSuchShaFound end + # Looks up the Git blobs for a given commit. + # + # sha - String commit SHA. + # + # Returns an Array of BlobEntry instances. def tree!(sha) tree = @repo.git.native(:ls_tree, {:r => true, :l => true, :z => true}, sha) @@ -110,14 +177,32 @@ module Gollum end end + # Reads the content from the Git db at the given SHA. + # + # sha - The String SHA. + # + # Returns the String content of the Git object. def cat_file!(sha) @repo.git.cat_file({:p => true}, sha) end + # Reads a Git commit. + # + # sha - The string SHA of the Git commit. + # + # Returns a Grit::Commit. def commit!(sha) @repo.commit(sha) end + # Attempts to get the given data from a cache. If it doesn't exist, it'll + # pass the results of the yielded block to the cache for future accesses. + # + # name - The cache prefix used in building the full cache key. + # key - The unique cache key suffix, usually a String Git SHA. + # + # Yields a block to pass to the cache. + # Returns the cached result. def get_cache(name, key) cache = instance_variable_get("@#{name}_map") value = cache[key] @@ -127,11 +212,25 @@ module Gollum value == :_nil ? nil : value end + # Writes some data to the internal cache. + # + # name - The cache prefix used in building the full cache key. + # key - The unique cache key suffix, usually a String Git SHA. + # value - The value to write to the cache. + # + # Returns nothing. def set_cache(name, key, value) cache = instance_variable_get("@#{name}_map") cache[key] = value || :_nil end + # Gets multiple values from the cache in a single call. + # + # name - The cache prefix used in building the full cache key. + # keys - Array of cache key names to fetch. + # + # Returns a Hash of the objects that were found in the cache, indexed by + # the cache key. def multi_get(name, keys) value = instance_variable_get("@#{name}_map") keys.inject({}) do |memo, key| diff --git a/lib/gollum/sanitization.rb b/lib/gollum/sanitization.rb index 72ba2ec9..b9f76aac 100644 --- a/lib/gollum/sanitization.rb +++ b/lib/gollum/sanitization.rb @@ -1,5 +1,4 @@ module Gollum - # Encapsulate sanitization options. # # This class does not yet support all options of Sanitize library.