From 62c4b795be45bc6c7e3e47deec69af44d8015973 Mon Sep 17 00:00:00 2001 From: rick Date: Fri, 8 Oct 2010 13:36:18 -0700 Subject: [PATCH 01/22] add basic GitAccess class --- lib/gollum.rb | 1 + lib/gollum/git_access.rb | 19 +++++++++++++++++++ lib/gollum/wiki.rb | 7 ++++--- 3 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 lib/gollum/git_access.rb diff --git a/lib/gollum.rb b/lib/gollum.rb index 36bcab92..fd2a4ab1 100644 --- a/lib/gollum.rb +++ b/lib/gollum.rb @@ -11,6 +11,7 @@ require 'sanitize' require 'gollum/ruby1.8' # internal +require 'gollum/git_access' require 'gollum/pagination' require 'gollum/blob_entry' require 'gollum/wiki' diff --git a/lib/gollum/git_access.rb b/lib/gollum/git_access.rb new file mode 100644 index 00000000..7f9c299d --- /dev/null +++ b/lib/gollum/git_access.rb @@ -0,0 +1,19 @@ +module Gollum + class GitAccess + attr_reader :path + attr_reader :repo + attr_reader :ref_map + attr_reader :tree_map + + def initialize(path) + @path = path + @repo = Grit::Repo.new(path) + @ref_map = {} + @tree_map = {} + end + + def exist? + @repo.git.exist? + end + end +end \ No newline at end of file diff --git a/lib/gollum/wiki.rb b/lib/gollum/wiki.rb index 172aa9aa..d7f68556 100644 --- a/lib/gollum/wiki.rb +++ b/lib/gollum/wiki.rb @@ -59,7 +59,8 @@ module Gollum # Returns a fresh Gollum::Repo. def initialize(path, options = {}) @path = path - @repo = Grit::Repo.new(path) + @access = options[:access] || GitAccess.new(path) + @repo = @access.repo @base_path = options[:base_path] || "/" @page_class = options[:page_class] || self.class.page_class @file_class = options[:file_class] || self.class.file_class @@ -70,7 +71,7 @@ module Gollum # # Returns true if the repo exists, and false if it does not. def exist? - @repo.git.exist? + @access.exist? end # Public: Get the formatted page for a given page name. @@ -520,7 +521,7 @@ module Gollum data, name = line.split("\t") mode, type, sha = data.split(' ') name = decode_git_path(name) - BlobEntry.new sha, name + BlobEntry.new(sha, name) end # Decode octal sequences (\NNN) in tree path names. From ebf7855c090f26e9a0c0f35c55c792494794a0e1 Mon Sep 17 00:00:00 2001 From: rick Date: Mon, 11 Oct 2010 12:06:35 -0700 Subject: [PATCH 02/22] integrate Gollum::GitAccess --- lib/gollum/blob_entry.rb | 10 ++-- lib/gollum/file.rb | 5 +- lib/gollum/git_access.rb | 98 ++++++++++++++++++++++++++++++++++++++-- lib/gollum/page.rb | 5 +- lib/gollum/wiki.rb | 98 +++++++++------------------------------- test/test_wiki.rb | 49 ++++++++++---------- 6 files changed, 151 insertions(+), 114 deletions(-) diff --git a/lib/gollum/blob_entry.rb b/lib/gollum/blob_entry.rb index b224fc4a..1c3f8f2e 100644 --- a/lib/gollum/blob_entry.rb +++ b/lib/gollum/blob_entry.rb @@ -6,10 +6,13 @@ module Gollum # Gets the String full path for this blob. attr_reader :path - def initialize(sha, path) + attr_reader :size + + def initialize(sha, path, size = nil) @sha = sha @path = path - @dir = @name = @blob = nil + @size = size + @dir = @name = @blob = nil end # Gets the normalized directory path for this blob. @@ -28,7 +31,8 @@ module Gollum # # Returns an unbaked Grit::Blob instance. def blob(repo) - @blob ||= Grit::Blob.create(repo, :id => @sha, :name => @name) + @blob ||= Grit::Blob.create(repo, + :id => @sha, :name => name, :size => @size) end # Gets a Page instance for this blob. diff --git a/lib/gollum/file.rb b/lib/gollum/file.rb index 8e7c33d3..295a5e52 100644 --- a/lib/gollum/file.rb +++ b/lib/gollum/file.rb @@ -53,11 +53,10 @@ module Gollum def find(name, version) checked = name.downcase map = @wiki.tree_map_for(version) - sha = @wiki.ref_map[version] || version if entry = map.detect { |entry| entry.path.downcase == checked } @path = name - @blob = Grit::Blob.create(@wiki.repo, :id => entry.sha, :name => entry.name) - @version = Grit::Commit.create(@wiki.repo, :id => sha) + @blob = entry.blob(@wiki.repo) + @version = @wiki.commit_for(version) self end end diff --git a/lib/gollum/git_access.rb b/lib/gollum/git_access.rb index 7f9c299d..9887f70c 100644 --- a/lib/gollum/git_access.rb +++ b/lib/gollum/git_access.rb @@ -2,18 +2,108 @@ module Gollum class GitAccess attr_reader :path 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], ...], ...} + # + # Returns the Hash cache. attr_reader :tree_map + attr_reader :commit_map def initialize(path) - @path = path - @repo = Grit::Repo.new(path) - @ref_map = {} - @tree_map = {} + @path = path + @repo = Grit::Repo.new(path) + clear + end + + def clear + @ref_map = {} + @tree_map = {} + @commit_map = {} + end + + def refresh + @ref_map.clear end def exist? @repo.git.exist? end + + def ref_to_sha(ref) + @ref_map[ref] ||= ref_to_sha!(ref) + end + + def tree(ref) + sha = ref_to_sha(ref) + @tree_map[sha] ||= tree!(sha) + end + + def blob(sha) + cat_file!(sha) + end + + def commit(ref) + if sha = @ref_map[ref] + @commit_map[sha] ||= commit!(sha) + else + cm = commit!(ref) + @ref_map[ref] = cm.id + @commit_map[cm.id] = cm + end + end + + def ref_to_sha!(ref) + @repo.git.rev_list({:max_count=>1}, ref) + end + + def tree!(sha) + tree = @repo.git.native(:ls_tree, + {:r => true, :l => true, :z => true}, sha) + tree.split("\0").inject([]) do |items, line| + items << parse_tree_line(line) + end + end + + def cat_file!(sha) + @repo.git.cat_file({:p => true}, sha) + end + + def commit!(sha) + @repo.commit(sha) + end + + # Parses a line of output from the `ls-tree` command. + # + # line - A String line of output: + # "100644 blob 839c2291b30495b9a882c17d08254d3c90d8fb53 Home.md" + # + # Returns an Array of BlobEntry instances. + def parse_tree_line(line) + mode, type, sha, size, *name = line.split(/\s+/) + BlobEntry.new(sha, name.to_s, size.to_i) + end + + # Decode octal sequences (\NNN) in tree path names. + # + # path - String path name. + # + # Returns a decoded String. + def decode_git_path(path) + if path[0] == ?" && path[-1] == ?" + path = path[1...-1] + path.gsub!(/\\\d{3}/) { |m| m[1..-1].to_i(8).chr } + end + path.gsub!(/\\[rn"\\]/) { |m| eval(%("#{m.to_s}")) } + path + end end end \ No newline at end of file diff --git a/lib/gollum/page.rb b/lib/gollum/page.rb index ba091458..21a9cbb4 100644 --- a/lib/gollum/page.rb +++ b/lib/gollum/page.rb @@ -272,9 +272,8 @@ module Gollum def find(name, version) map = @wiki.tree_map_for(version) if page = find_page_in_tree(map, name) - sha = @wiki.ref_map[version] || version - page.version = Grit::Commit.create(@wiki.repo, :id => sha) - page.historical = sha == version + page.version = @wiki.commit_for(version) + page.historical = page.version.id == version page end rescue Grit::GitRuby::Repository::NoSuchShaFound diff --git a/lib/gollum/wiki.rb b/lib/gollum/wiki.rb index d7f68556..9b13d6a6 100644 --- a/lib/gollum/wiki.rb +++ b/lib/gollum/wiki.rb @@ -58,13 +58,16 @@ module Gollum # # Returns a fresh Gollum::Repo. def initialize(path, options = {}) + if path.is_a?(GitAccess) + options[:access] = path + path = path.path + end @path = path - @access = options[:access] || GitAccess.new(path) - @repo = @access.repo + @access = options[:access] || GitAccess.new(path) @base_path = options[:base_path] || "/" @page_class = options[:page_class] || self.class.page_class @file_class = options[:file_class] || self.class.file_class - clear_cache + @repo = @access.repo end # Public: check whether the wiki's git repo exists on the filesystem. @@ -109,7 +112,7 @@ module Gollum path = @page_class.cname(name) + '.' + ext blob = OpenStruct.new(:name => path, :data => data) page.populate(blob, path) - page.version = self.repo.commit("HEAD") + page.version = @access.commit('HEAD') page end @@ -138,7 +141,7 @@ module Gollum actor = Grit::Actor.new(commit[:name], commit[:email]) sha1 = index.commit(commit[:message], parents, actor) - @ref_map.clear + @access.refresh update_working_dir(index, '', name, format) sha1 @@ -181,7 +184,7 @@ module Gollum actor = Grit::Actor.new(commit[:name], commit[:email]) sha1 = index.commit(commit[:message], [pcommit], actor) - @ref_map.clear + @access.refresh update_working_dir(index, dir, page.name, page.format) update_working_dir(index, dir, name, format) @@ -210,7 +213,7 @@ module Gollum actor = Grit::Actor.new(commit[:name], commit[:email]) sha1 = index.commit(commit[:message], [pcommit], actor) - @ref_map.clear + @access.refresh update_working_dir(index, dir, page.name, page.format) sha1 @@ -267,6 +270,10 @@ module Gollum @repo.log('master', nil, log_pagination_options(options)) end + def clear_cache + @access.refresh + end + ######################################################################### # # Internal Methods @@ -283,20 +290,6 @@ module Gollum # Returns the String path. attr_reader :path - # 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], ...], ...} - # - # Returns the Hash cache. - attr_reader :tree_map - # Gets the page class used by all instances of this Wiki. attr_reader :page_class @@ -359,8 +352,7 @@ module Gollum def tree_list(ref) tree_map_for(ref).inject([]) do |list, entry| next list unless @page_class.valid_page_name?(entry.name) - sha = ref_map[ref] - list << entry.page(self, @repo.commit(sha)) + list << entry.page(self, @access.commit(ref)) end end @@ -479,6 +471,11 @@ module Gollum @repo.config['user.email'] || self.class.default_committer_email end + def commit_for(ref) + @access.commit(ref) + rescue Grit::GitRuby::Repository::NoSuchShaFound + end + # Finds a full listing of files and their blob SHA for a given ref. Each # listing is cached based on its actual commit SHA. # @@ -486,62 +483,9 @@ module Gollum # # Returns an Array of BlobEntry instances. def tree_map_for(ref) - sha = @ref_map[ref] || ref - @tree_map[sha] || begin - real_sha = @repo.git.rev_list({:max_count=>1}, ref) - @ref_map[ref] = real_sha if real_sha != ref - @tree_map[real_sha] ||= parse_tree_for(real_sha) - end + @access.tree(ref) rescue Grit::GitRuby::Repository::NoSuchShaFound [] end - - # Finds the full listing of files and their blob SHA for a given commit - # SHA. No caching or ref lookups are performed. - # - # sha - String commit SHA. - # - # Returns an Array of BlobEntry instances. - def parse_tree_for(sha) - tree = @repo.git.native(:ls_tree, {:r => true, :z => true}, sha) - items = [] - tree.split("\0").each do |line| - items << parse_tree_line(line) - end - items - end - - # Parses a line of output from the `ls-tree` command. - # - # line - A String line of output: - # "100644 blob 839c2291b30495b9a882c17d08254d3c90d8fb53 Home.md" - # - # Returns an Array of BlobEntry instances. - def parse_tree_line(line) - data, name = line.split("\t") - mode, type, sha = data.split(' ') - name = decode_git_path(name) - BlobEntry.new(sha, name) - end - - # Decode octal sequences (\NNN) in tree path names. - # - # path - String path name. - # - # Returns a decoded String. - def decode_git_path(path) - if path[0] == ?" && path[-1] == ?" - path = path[1...-1] - path.gsub!(/\\\d{3}/) { |m| m[1..-1].to_i(8).chr } - end - path.gsub!(/\\[rn"\\]/) { |m| eval(%("#{m.to_s}")) } - path - end - - # Resets the ref and tree caches for this wiki. - def clear_cache - @ref_map = {} - @tree_map = {} - end end end diff --git a/test/test_wiki.rb b/test/test_wiki.rb index 51cd287b..36642161 100644 --- a/test/test_wiki.rb +++ b/test/test_wiki.rb @@ -2,7 +2,8 @@ require File.join(File.dirname(__FILE__), *%w[helper]) context "Wiki" do setup do - @wiki = Gollum::Wiki.new(testpath("examples/lotr.git")) + @access = Gollum::GitAccess.new(testpath("examples/lotr.git")) + @wiki = Gollum::Wiki.new(@access) end test "repo path" do @@ -60,29 +61,29 @@ context "Wiki" do @wiki.normalize_commit(commit.dup)) end - test "#tree_map_for caches ref and tree" do - assert @wiki.ref_map.empty? - assert @wiki.tree_map.empty? - @wiki.tree_map_for 'master' - assert_equal({"master"=>"60f12f4254f58801b9ee7db7bca5fa8aeefaa56b"}, @wiki.ref_map) - - map = @wiki.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'] - assert_equal 'Bilbo-Baggins.md', map[0].path - assert_equal '', map[0].dir - assert_equal map[0].path, map[0].name - assert_equal 'Mordor/Eye-Of-Sauron.md', map[3].path - assert_equal '/Mordor', map[3].dir - assert_equal 'Eye-Of-Sauron.md', map[3].name - end - - test "#tree_map_for only caches tree for commit" do - assert @wiki.tree_map.empty? - @wiki.tree_map_for '60f12f4254f58801b9ee7db7bca5fa8aeefaa56b' - assert @wiki.ref_map.empty? - - entry = @wiki.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'][0] - assert_equal 'Bilbo-Baggins.md', entry.path - end + #test "#tree_map_for caches ref and tree" do + # assert @wiki.ref_map.empty? + # assert @wiki.tree_map.empty? + # @wiki.tree_map_for 'master' + # assert_equal({"master"=>"60f12f4254f58801b9ee7db7bca5fa8aeefaa56b"}, @wiki.ref_map) + # + # map = @wiki.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'] + # assert_equal 'Bilbo-Baggins.md', map[0].path + # assert_equal '', map[0].dir + # assert_equal map[0].path, map[0].name + # assert_equal 'Mordor/Eye-Of-Sauron.md', map[3].path + # assert_equal '/Mordor', map[3].dir + # assert_equal 'Eye-Of-Sauron.md', map[3].name + #end + # + #test "#tree_map_for only caches tree for commit" do + # assert @access.tree_map.empty? + # @access.tree '60f12f4254f58801b9ee7db7bca5fa8aeefaa56b' + # assert @access.ref_map.empty? + # + # entry = @access.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'][0] + # assert_equal 'Bilbo-Baggins.md', entry.path + #end end context "Wiki page previewing" do From a92a882021e4b889687f7279cf0f36de5cb3685c Mon Sep 17 00:00:00 2001 From: rick Date: Mon, 11 Oct 2010 13:32:14 -0700 Subject: [PATCH 03/22] restore ref_map and tree_map tests --- lib/gollum/git_access.rb | 6 +++++- test/test_git_access.rb | 31 +++++++++++++++++++++++++++++++ test/test_wiki.rb | 27 +-------------------------- 3 files changed, 37 insertions(+), 27 deletions(-) create mode 100644 test/test_git_access.rb diff --git a/lib/gollum/git_access.rb b/lib/gollum/git_access.rb index 9887f70c..a27225b4 100644 --- a/lib/gollum/git_access.rb +++ b/lib/gollum/git_access.rb @@ -39,7 +39,11 @@ module Gollum end def ref_to_sha(ref) - @ref_map[ref] ||= ref_to_sha!(ref) + if ref =~ /^[0-9a-f]{40}$/ + ref + else + @ref_map[ref] ||= ref_to_sha!(ref) + end end def tree(ref) diff --git a/test/test_git_access.rb b/test/test_git_access.rb new file mode 100644 index 00000000..8d991fea --- /dev/null +++ b/test/test_git_access.rb @@ -0,0 +1,31 @@ +require File.join(File.dirname(__FILE__), *%w[helper]) + +context "GitAccess" do + setup do + @access = Gollum::GitAccess.new(testpath("examples/lotr.git")) + end + + test "#tree_map_for caches ref and tree" do + assert @access.ref_map.empty? + assert @access.tree_map.empty? + @access.tree 'master' + assert_equal({"master"=>"60f12f4254f58801b9ee7db7bca5fa8aeefaa56b"}, @access.ref_map) + + map = @access.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'] + assert_equal 'Bilbo-Baggins.md', map[0].path + assert_equal '', map[0].dir + assert_equal map[0].path, map[0].name + assert_equal 'Mordor/Eye-Of-Sauron.md', map[3].path + assert_equal '/Mordor', map[3].dir + assert_equal 'Eye-Of-Sauron.md', map[3].name + end + + test "#tree_map_for only caches tree for commit" do + assert @access.tree_map.empty? + @access.tree '60f12f4254f58801b9ee7db7bca5fa8aeefaa56b' + assert @access.ref_map.empty? + + entry = @access.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'][0] + assert_equal 'Bilbo-Baggins.md', entry.path + end +end \ No newline at end of file diff --git a/test/test_wiki.rb b/test/test_wiki.rb index 36642161..7d9ac0b3 100644 --- a/test/test_wiki.rb +++ b/test/test_wiki.rb @@ -2,8 +2,7 @@ require File.join(File.dirname(__FILE__), *%w[helper]) context "Wiki" do setup do - @access = Gollum::GitAccess.new(testpath("examples/lotr.git")) - @wiki = Gollum::Wiki.new(@access) + @wiki = Gollum::Wiki.new(testpath("examples/lotr.git")) end test "repo path" do @@ -60,30 +59,6 @@ context "Wiki" do assert_equal({:message => 'abc', :name => 'bob', :email => 'foo@bar.com'}, @wiki.normalize_commit(commit.dup)) end - - #test "#tree_map_for caches ref and tree" do - # assert @wiki.ref_map.empty? - # assert @wiki.tree_map.empty? - # @wiki.tree_map_for 'master' - # assert_equal({"master"=>"60f12f4254f58801b9ee7db7bca5fa8aeefaa56b"}, @wiki.ref_map) - # - # map = @wiki.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'] - # assert_equal 'Bilbo-Baggins.md', map[0].path - # assert_equal '', map[0].dir - # assert_equal map[0].path, map[0].name - # assert_equal 'Mordor/Eye-Of-Sauron.md', map[3].path - # assert_equal '/Mordor', map[3].dir - # assert_equal 'Eye-Of-Sauron.md', map[3].name - #end - # - #test "#tree_map_for only caches tree for commit" do - # assert @access.tree_map.empty? - # @access.tree '60f12f4254f58801b9ee7db7bca5fa8aeefaa56b' - # assert @access.ref_map.empty? - # - # entry = @access.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'][0] - # assert_equal 'Bilbo-Baggins.md', entry.path - #end end context "Wiki page previewing" do From 6552323797bc8c97f69002394a89feb8dce17e0e Mon Sep 17 00:00:00 2001 From: rick Date: Mon, 11 Oct 2010 16:01:06 -0700 Subject: [PATCH 04/22] implement GitAccess#commits using grit head --- lib/gollum/git_access.rb | 37 ++++++++++++++++++++++++++++++++++--- test/test_git_access.rb | 17 +++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/lib/gollum/git_access.rb b/lib/gollum/git_access.rb index a27225b4..9f259bee 100644 --- a/lib/gollum/git_access.rb +++ b/lib/gollum/git_access.rb @@ -39,7 +39,7 @@ module Gollum end def ref_to_sha(ref) - if ref =~ /^[0-9a-f]{40}$/ + if sha?(ref) ref else @ref_map[ref] ||= ref_to_sha!(ref) @@ -56,15 +56,46 @@ module Gollum end def commit(ref) - if sha = @ref_map[ref] + ref_is_sha = sha?(ref) + if sha = (!ref_is_sha && @ref_map[ref]) @commit_map[sha] ||= commit!(sha) else cm = commit!(ref) - @ref_map[ref] = cm.id + @ref_map[ref] = cm.id if !ref_is_sha @commit_map[cm.id] = cm end end + def commits(*shas) + shas.flatten! + cached_commits = multi_get(:commit_map, shas) + missing_shas = shas.select do |sha| + !cached_commits.key?(sha) + end + if !missing_shas.empty? + missing_shas.each_slice(500) do |slice| + @repo.batch(slice).each do |commit| + cached_commits[commit.id] = commit + end + end + end + shas.map { |sha| cached_commits[sha] } + end + + def multi_get(name, keys) + value = instance_variable_get("@#{name}") + keys.inject({}) do |memo, key| + if v = value[key] + memo[key] = v + end + memo + end + end + + def sha?(str) + str =~ /^[0-9a-f]{40}$/ + end + def ref_to_sha!(ref) @repo.git.rev_list({:max_count=>1}, ref) end diff --git a/test/test_git_access.rb b/test/test_git_access.rb index 8d991fea..7e62c689 100644 --- a/test/test_git_access.rb +++ b/test/test_git_access.rb @@ -5,6 +5,23 @@ context "GitAccess" do @access = Gollum::GitAccess.new(testpath("examples/lotr.git")) end + test "#commit fills commit_map cache" do + assert @access.commit_map.empty? + actual = @access.repo.commits.first + expected = @access.commit(actual.id) + assert_equal actual.message, expected.message + assert_equal actual.message, @access.commit_map[actual.id].message + end + + test "#commits uses commit_map" do + actual = @access.repo.commits.first + #@access.commit actual.id + @access.commit_map['abc'] = 1 + commits = @access.commits('abc', actual.id) + assert_equal 1, commits[0] + assert_equal actual.message, commits[1].message + end + test "#tree_map_for caches ref and tree" do assert @access.ref_map.empty? assert @access.tree_map.empty? From 300d8eacc57ed002a9beaf451550c2097ad4020b Mon Sep 17 00:00:00 2001 From: rick Date: Mon, 11 Oct 2010 16:15:18 -0700 Subject: [PATCH 05/22] optimize Gollum::Wiki#tree_list --- lib/gollum/file.rb | 2 +- lib/gollum/git_access.rb | 15 +++++++++------ lib/gollum/page.rb | 7 ++++--- lib/gollum/wiki.rb | 6 ++++-- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/lib/gollum/file.rb b/lib/gollum/file.rb index 295a5e52..acea37a6 100644 --- a/lib/gollum/file.rb +++ b/lib/gollum/file.rb @@ -56,7 +56,7 @@ module Gollum if entry = map.detect { |entry| entry.path.downcase == checked } @path = name @blob = entry.blob(@wiki.repo) - @version = @wiki.commit_for(version) + @version = version.is_a?(Grit::Commit) ? version : @wiki.commit_for(version) self end end diff --git a/lib/gollum/git_access.rb b/lib/gollum/git_access.rb index 9f259bee..5fadef6f 100644 --- a/lib/gollum/git_access.rb +++ b/lib/gollum/git_access.rb @@ -56,13 +56,16 @@ module Gollum end def commit(ref) - ref_is_sha = sha?(ref) - if sha = (!ref_is_sha && @ref_map[ref]) - @commit_map[sha] ||= commit!(sha) + if sha?(ref) + @commit_map[ref] ||= commit!(ref) else - cm = commit!(ref) - @ref_map[ref] = cm.id if !ref_is_sha - @commit_map[cm.id] = cm + if sha = @ref_map[ref] + commit(sha) + else + cm = commit!(ref) + @ref_map[ref] = cm.id + @commit_map[cm.id] = cm + end end end diff --git a/lib/gollum/page.rb b/lib/gollum/page.rb index 21a9cbb4..32bdd6ae 100644 --- a/lib/gollum/page.rb +++ b/lib/gollum/page.rb @@ -270,10 +270,11 @@ module Gollum # # Returns a Gollum::Page or nil if the page could not be found. def find(name, version) - map = @wiki.tree_map_for(version) + map = @wiki.tree_map_for(version.to_s) if page = find_page_in_tree(map, name) - page.version = @wiki.commit_for(version) - page.historical = page.version.id == version + page.version = version.is_a?(Grit::Commit) ? + version : @wiki.commit_for(version) + page.historical = page.version.to_s == version.to_s page end rescue Grit::GitRuby::Repository::NoSuchShaFound diff --git a/lib/gollum/wiki.rb b/lib/gollum/wiki.rb index 9b13d6a6..c8a4ee2c 100644 --- a/lib/gollum/wiki.rb +++ b/lib/gollum/wiki.rb @@ -350,9 +350,11 @@ module Gollum # # Returns a flat Array of Gollum::Page instances. def tree_list(ref) - tree_map_for(ref).inject([]) do |list, entry| + sha = @access.ref_to_sha(ref) + commit = @access.commit(sha) + tree_map_for(sha).inject([]) do |list, entry| next list unless @page_class.valid_page_name?(entry.name) - list << entry.page(self, @access.commit(ref)) + list << entry.page(self, commit) end end From b8a50c0ccc139433119c5e18bb0bf1e7907e6788 Mon Sep 17 00:00:00 2001 From: rick Date: Mon, 11 Oct 2010 17:03:44 -0700 Subject: [PATCH 06/22] updated experimental gemspec --- gollum.gemspec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gollum.gemspec b/gollum.gemspec index 521f8bbf..2b13efe3 100644 --- a/gollum.gemspec +++ b/gollum.gemspec @@ -460,6 +460,7 @@ Gem::Specification.new do |s| lib/gollum/frontend/views/layout.rb lib/gollum/frontend/views/page.rb lib/gollum/frontend/views/search.rb + lib/gollum/git_access.rb lib/gollum/markup.rb lib/gollum/page.rb lib/gollum/pagination.rb @@ -504,6 +505,7 @@ Gem::Specification.new do |s| test/examples/lotr.git/refs/heads/master test/helper.rb test/test_file.rb + test/test_git_access.rb test/test_markup.rb test/test_page.rb test/test_wiki.rb From c6dc4acc0298ebaf30fff8a577ae3f0d91716469 Mon Sep 17 00:00:00 2001 From: rick Date: Mon, 11 Oct 2010 18:05:02 -0700 Subject: [PATCH 07/22] add extension points for GitAccess caching --- lib/gollum/git_access.rb | 48 ++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/lib/gollum/git_access.rb b/lib/gollum/git_access.rb index 5fadef6f..ed5a7b59 100644 --- a/lib/gollum/git_access.rb +++ b/lib/gollum/git_access.rb @@ -42,13 +42,13 @@ module Gollum if sha?(ref) ref else - @ref_map[ref] ||= ref_to_sha!(ref) + get_cache(:ref, ref) { ref_to_sha!(ref) } end end def tree(ref) sha = ref_to_sha(ref) - @tree_map[sha] ||= tree!(sha) + get_cache(:tree, sha) { tree!(sha) } end def blob(sha) @@ -57,21 +57,21 @@ module Gollum def commit(ref) if sha?(ref) - @commit_map[ref] ||= commit!(ref) + get_cache(:commit, ref) { commit!(ref) } else - if sha = @ref_map[ref] + if sha = get_cache(:ref, ref) commit(sha) else cm = commit!(ref) - @ref_map[ref] = cm.id - @commit_map[cm.id] = cm + set_cache(:ref, ref, cm.id) + set_cache(:commit, cm.id, cm) end end end def commits(*shas) shas.flatten! - cached_commits = multi_get(:commit_map, shas) + cached_commits = multi_get(:commit, shas) missing_shas = shas.select do |sha| !cached_commits.key?(sha) end @@ -85,16 +85,6 @@ module Gollum shas.map { |sha| cached_commits[sha] } end - def multi_get(name, keys) - value = instance_variable_get("@#{name}") - keys.inject({}) do |memo, key| - if v = value[key] - memo[key] = v - end - memo - end - end - def sha?(str) str =~ /^[0-9a-f]{40}$/ end @@ -119,6 +109,30 @@ module Gollum @repo.commit(sha) end + def get_cache(name, key) + cache = instance_variable_get("@#{name}_map") + value = cache[key] + if value.nil? && block_given? + set_cache(name, key, value = yield) + end + value + end + + def set_cache(name, key, value) + cache = instance_variable_get("@#{name}_map") + cache[key] = value + end + + def multi_get(name, keys) + value = instance_variable_get("@#{name}_map") + keys.inject({}) do |memo, key| + if v = value[key] + memo[key] = v + end + memo + end + end + # Parses a line of output from the `ls-tree` command. # # line - A String line of output: From f2ed24ef8cbdb23153c551b5ec013571352c21e4 Mon Sep 17 00:00:00 2001 From: rick Date: Tue, 12 Oct 2010 10:02:48 -0700 Subject: [PATCH 08/22] extract multi_commit! method from GitAccess --- lib/gollum/git_access.rb | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/gollum/git_access.rb b/lib/gollum/git_access.rb index ed5a7b59..25bace47 100644 --- a/lib/gollum/git_access.rb +++ b/lib/gollum/git_access.rb @@ -75,14 +75,18 @@ module Gollum missing_shas = shas.select do |sha| !cached_commits.key?(sha) end - if !missing_shas.empty? - missing_shas.each_slice(500) do |slice| - @repo.batch(slice).each do |commit| - cached_commits[commit.id] = commit - end + + multi_commit!(missing_shas, cached_commits) if !missing_shas.empty? + + shas.map { |sha| cached_commits[sha] } + end + + def multi_commit!(shas, hash) + shas.each_slice(500) do |slice| + @repo.batch(slice).each do |commit| + hash[commit.id] = commit end end - shas.map { |sha| cached_commits[sha] } end def sha?(str) From e7f2da2d4a5dd42f0174ca03cd69dfc94bec1c44 Mon Sep 17 00:00:00 2001 From: rick Date: Tue, 12 Oct 2010 15:36:36 -0700 Subject: [PATCH 09/22] add caching hooks for Gollum::Markup --- lib/gollum/markup.rb | 39 ++++++++++++++++++++++++++++++++------- lib/gollum/page.rb | 2 +- lib/gollum/wiki.rb | 39 +++++++++++++++++++++++++++++---------- 3 files changed, 62 insertions(+), 18 deletions(-) diff --git a/lib/gollum/markup.rb b/lib/gollum/markup.rb index 2a78bbbf..b9a3bef3 100644 --- a/lib/gollum/markup.rb +++ b/lib/gollum/markup.rb @@ -348,8 +348,11 @@ module Gollum # Returns the placeholder'd String data. def extract_code(data) data.gsub(/^``` ?(.+?)\r?\n(.+?)\r?\n```\r?$/m) do - id = Digest::SHA1.hexdigest($2) - @codemap[id] = { :lang => $1, :code => $2 } + id = Digest::SHA1.hexdigest($2) + cached = check_cache(id) + @codemap[id] = cached ? + { :output => cached } : + { :lang => $1, :code => $2 } id end end @@ -362,14 +365,36 @@ module Gollum # Returns the marked up String data. def process_code(data) @codemap.each do |id, spec| - lang = spec[:lang] - code = spec[:code] - if code.lines.all? { |line| line =~ /\A\r?\n\Z/ || line =~ /^( |\t)/ } - code.gsub!(/^( |\t)/m, '') + formatted = spec[:output] || begin + lang = spec[:lang] + code = spec[:code] + if code.lines.all? { |line| line =~ /\A\r?\n\Z/ || line =~ /^( |\t)/ } + code.gsub!(/^( |\t)/m, '') + end + formatted = Gollum::Albino.new(code, lang).colorize + update_cache(id, formatted) + formatted end - data.gsub!(id, Gollum::Albino.new(code, lang).colorize) + data.gsub!(id, formatted) end data end + + # Hook for getting the formatted value of extracted tag data. + # + # id - String SHA1 hash of original extracted tag data. + # + # Returns the String cached formatted data, or nil. + def check_cache(id) + end + + # Hook for caching the formatted value of extracted tag data. + # + # id - String SHA1 hash of original extracted tag data. + # data - The String formatted value to be cached. + # + # Returns nothing. + def update_cache(id, data) + end end end diff --git a/lib/gollum/page.rb b/lib/gollum/page.rb index 32bdd6ae..32f0ad51 100644 --- a/lib/gollum/page.rb +++ b/lib/gollum/page.rb @@ -120,7 +120,7 @@ module Gollum # # Returns the String data. def formatted_data - @blob && Gollum::Markup.new(self).render(historical?) + @blob && @wiki.markup_class.new(self).render(historical?) end # Public: The format of the page. diff --git a/lib/gollum/wiki.rb b/lib/gollum/wiki.rb index e1d265cd..9e529e17 100644 --- a/lib/gollum/wiki.rb +++ b/lib/gollum/wiki.rb @@ -9,6 +9,9 @@ module Gollum # Sets the file class used by all instances of this Wiki. attr_writer :file_class + # Sets the markup class used by all instances of this Wiki. + attr_writer :markup_class + # Sets the default name for commits. attr_accessor :default_committer_name @@ -36,6 +39,17 @@ module Gollum ::Gollum::File end end + + # Gets the markup class used by all instances of this Wiki. + # Default: Gollum::Markup + def markup_class + @markup_class || + if superclass.respond_to?(:markup_class) + superclass.markup_class + else + ::Gollum::Markup + end + end end self.default_committer_name = 'Anonymous' @@ -51,10 +65,11 @@ module Gollum # repo - The String path to the Git repository that holds the Gollum # site. # options - Optional Hash: - # :base_path - String base path for all Wiki links. - # Default: "/" - # :page_class - The page Class. Default: Gollum::Page - # :file_class - The file Class. Default: Gollum::File + # :base_path - String base path for all Wiki links. + # Default: "/" + # :page_class - The page Class. Default: Gollum::Page + # :file_class - The file Class. Default: Gollum::File + # :markup_class - The markup Class. Default: Gollum::Markup # # Returns a fresh Gollum::Repo. def initialize(path, options = {}) @@ -62,12 +77,13 @@ module Gollum options[:access] = path path = path.path end - @path = path - @access = options[:access] || GitAccess.new(path) - @base_path = options[:base_path] || "/" - @page_class = options[:page_class] || self.class.page_class - @file_class = options[:file_class] || self.class.file_class - @repo = @access.repo + @path = path + @access = options[:access] || GitAccess.new(path) + @base_path = options[:base_path] || "/" + @page_class = options[:page_class] || self.class.page_class + @file_class = options[:file_class] || self.class.file_class + @markup_class = options[:markup_class] || self.class.markup_class + @repo = @access.repo end # Public: check whether the wiki's git repo exists on the filesystem. @@ -298,6 +314,9 @@ module Gollum # Gets the file class used by all instances of this Wiki. attr_reader :file_class + # Gets the markup class used by all instances of this Wiki. + attr_reader :markup_class + # Normalize the data. # # data - The String data to be normalized. From 497b36ad2b49605025f70d3f0075b5fb72c43841 Mon Sep 17 00:00:00 2001 From: rick Date: Tue, 12 Oct 2010 15:46:55 -0700 Subject: [PATCH 10/22] give the markup caching methods a bit more info --- lib/gollum/markup.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/gollum/markup.rb b/lib/gollum/markup.rb index b9a3bef3..bf418b5b 100644 --- a/lib/gollum/markup.rb +++ b/lib/gollum/markup.rb @@ -349,7 +349,7 @@ module Gollum def extract_code(data) data.gsub(/^``` ?(.+?)\r?\n(.+?)\r?\n```\r?$/m) do id = Digest::SHA1.hexdigest($2) - cached = check_cache(id) + cached = check_cache(:code, id) @codemap[id] = cached ? { :output => cached } : { :lang => $1, :code => $2 } @@ -372,7 +372,7 @@ module Gollum code.gsub!(/^( |\t)/m, '') end formatted = Gollum::Albino.new(code, lang).colorize - update_cache(id, formatted) + update_cache(:code, id, formatted) formatted end data.gsub!(id, formatted) @@ -382,19 +382,21 @@ module Gollum # Hook for getting the formatted value of extracted tag data. # - # id - String SHA1 hash of original extracted tag data. + # type - Symbol value identifying what type of data is being extracted. + # id - String SHA1 hash of original extracted tag data. # # Returns the String cached formatted data, or nil. - def check_cache(id) + def check_cache(type, id) end # Hook for caching the formatted value of extracted tag data. # + # type - Symbol value identifying what type of data is being extracted. # id - String SHA1 hash of original extracted tag data. # data - The String formatted value to be cached. # # Returns nothing. - def update_cache(id, data) + def update_cache(type, id, data) end end end From 54917bbdb9f2df527c6a14f06cb9c2bb8415dd9d Mon Sep 17 00:00:00 2001 From: rick Date: Wed, 13 Oct 2010 09:52:04 -0700 Subject: [PATCH 11/22] recover from bad shas --- lib/gollum/git_access.rb | 17 ++++++++++------- lib/gollum/page.rb | 2 +- test/test_git_access.rb | 15 +++++++++++++-- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/lib/gollum/git_access.rb b/lib/gollum/git_access.rb index 25bace47..00ae88f0 100644 --- a/lib/gollum/git_access.rb +++ b/lib/gollum/git_access.rb @@ -47,8 +47,9 @@ module Gollum end def tree(ref) - sha = ref_to_sha(ref) - get_cache(:tree, sha) { tree!(sha) } + if sha = ref_to_sha(ref) + get_cache(:tree, sha) { tree!(sha) } + end end def blob(sha) @@ -62,9 +63,10 @@ module Gollum if sha = get_cache(:ref, ref) commit(sha) else - cm = commit!(ref) - set_cache(:ref, ref, cm.id) - set_cache(:commit, cm.id, cm) + if cm = commit!(ref) + set_cache(:ref, ref, cm.id) + set_cache(:commit, cm.id, cm) + end end end end @@ -95,6 +97,7 @@ module Gollum def ref_to_sha!(ref) @repo.git.rev_list({:max_count=>1}, ref) + rescue Grit::GitRuby::Repository::NoSuchShaFound end def tree!(sha) @@ -119,12 +122,12 @@ module Gollum if value.nil? && block_given? set_cache(name, key, value = yield) end - value + value == :_nil ? nil : value end def set_cache(name, key, value) cache = instance_variable_get("@#{name}_map") - cache[key] = value + cache[key] = value || :_nil end def multi_get(name, keys) diff --git a/lib/gollum/page.rb b/lib/gollum/page.rb index 32f0ad51..a534371c 100644 --- a/lib/gollum/page.rb +++ b/lib/gollum/page.rb @@ -289,7 +289,7 @@ module Gollum # # Returns a Gollum::Page or nil if the page could not be found. def find_page_in_tree(map, name, checked_dir = nil) - return nil if name.to_s.empty? + return nil if !map || name.to_s.empty? if checked_dir = BlobEntry.normalize_dir(checked_dir) checked_dir.downcase! end diff --git a/test/test_git_access.rb b/test/test_git_access.rb index 7e62c689..2d9ac653 100644 --- a/test/test_git_access.rb +++ b/test/test_git_access.rb @@ -15,7 +15,6 @@ context "GitAccess" do test "#commits uses commit_map" do actual = @access.repo.commits.first - #@access.commit actual.id @access.commit_map['abc'] = 1 commits = @access.commits('abc', actual.id) assert_equal 1, commits[0] @@ -27,7 +26,7 @@ context "GitAccess" do assert @access.tree_map.empty? @access.tree 'master' assert_equal({"master"=>"60f12f4254f58801b9ee7db7bca5fa8aeefaa56b"}, @access.ref_map) - + map = @access.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'] assert_equal 'Bilbo-Baggins.md', map[0].path assert_equal '', map[0].dir @@ -45,4 +44,16 @@ context "GitAccess" do entry = @access.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'][0] assert_equal 'Bilbo-Baggins.md', entry.path end + + test "cannot access commit from invalid ref" do + assert_nil @access.commit('foo') + end + + test "cannot access sha from invalid ref" do + assert_nil @access.ref_to_sha('foo') + end + + test "cannot access tree from invalid ref" do + assert_nil @access.tree('foo') + end end \ No newline at end of file From 1a19278fc71ad0e03965aae8ffdf3b9731ed71ef Mon Sep 17 00:00:00 2001 From: rick Date: Wed, 13 Oct 2010 12:06:23 -0700 Subject: [PATCH 12/22] GitAccess#tree should always return an array --- lib/gollum/git_access.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/gollum/git_access.rb b/lib/gollum/git_access.rb index 00ae88f0..409a0197 100644 --- a/lib/gollum/git_access.rb +++ b/lib/gollum/git_access.rb @@ -49,6 +49,8 @@ module Gollum def tree(ref) if sha = ref_to_sha(ref) get_cache(:tree, sha) { tree!(sha) } + else + [] end end From 4dda9fb2ae73793c1065dbc914a9d19839b965f9 Mon Sep 17 00:00:00 2001 From: rick Date: Sat, 20 Nov 2010 13:08:39 -0800 Subject: [PATCH 13/22] tomdoc'd --- lib/gollum/blob_entry.rb | 7 +- lib/gollum/git_access.rb | 129 ++++++++++++++++++++++++++++++++----- lib/gollum/sanitization.rb | 1 - 3 files changed, 118 insertions(+), 19 deletions(-) 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. From db2a6deca95c7b412eb7537157784bbd4ae2d94e Mon Sep 17 00:00:00 2001 From: rick Date: Sat, 20 Nov 2010 14:14:41 -0800 Subject: [PATCH 14/22] tomdoc reorg for git_access.rb --- lib/gollum/git_access.rb | 54 ++++++++++++++++++++++------------------ lib/gollum/wiki.rb | 4 +++ 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/lib/gollum/git_access.rb b/lib/gollum/git_access.rb index 76568f73..9306c893 100644 --- a/lib/gollum/git_access.rb +++ b/lib/gollum/git_access.rb @@ -2,30 +2,6 @@ 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", ...} - # - attr_reader :ref_map - - # Gets a Hash cache of commit SHAs to a recursive tree of blobs. - # - # {"abc123" => [, ]} - # - attr_reader :tree_map - - # Gets a Hash cache of commit SHAs to the Grit::Commit instance. - # - # {"abcd123" => } - # - attr_reader :commit_map - def initialize(path) @path = path @repo = Grit::Repo.new(path) @@ -130,6 +106,36 @@ module Gollum @ref_map.clear end + ######################################################################### + # + # Internal Methods + # + ######################################################################### + + # 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", ...} + # + attr_reader :ref_map + + # Gets a Hash cache of commit SHAs to a recursive tree of blobs. + # + # {"abc123" => [, ]} + # + attr_reader :tree_map + + # Gets a Hash cache of commit SHAs to the Grit::Commit instance. + # + # {"abcd123" => } + # + attr_reader :commit_map + # Raw method for fetching a list of Git commits. # # shas - An Array of String SHAs. diff --git a/lib/gollum/wiki.rb b/lib/gollum/wiki.rb index 249dee12..e94c5087 100644 --- a/lib/gollum/wiki.rb +++ b/lib/gollum/wiki.rb @@ -326,6 +326,10 @@ module Gollum @repo.log('master', nil, log_pagination_options(options)) end + # Public: Refreshes just the cached Git reference data. This should + # be called after every Gollum update. + # + # Returns nothing. def clear_cache @access.refresh end From 76064da1317ffe4286cc6881d87dc4a8973f7ca9 Mon Sep 17 00:00:00 2001 From: rick Date: Thu, 2 Dec 2010 14:35:31 -0800 Subject: [PATCH 15/22] A Gollum::Wiki saves Sanitize instances --- lib/gollum/sanitization.rb | 7 +++++++ lib/gollum/wiki.rb | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/lib/gollum/sanitization.rb b/lib/gollum/sanitization.rb index b9f76aac..153cd570 100644 --- a/lib/gollum/sanitization.rb +++ b/lib/gollum/sanitization.rb @@ -103,6 +103,13 @@ module Gollum :allow_comments => allow_comments? } end + + # Builds a Sanitize instance from the current options. + # + # Returns a Sanitize instance. + def to_sanitize + Sanitize.new(to_hash) + end end end diff --git a/lib/gollum/wiki.rb b/lib/gollum/wiki.rb index e94c5087..9d9b7b10 100644 --- a/lib/gollum/wiki.rb +++ b/lib/gollum/wiki.rb @@ -334,6 +334,26 @@ module Gollum @access.refresh end + # Public: Creates a Sanitize instance using the Wiki's sanitization + # options. + # + # Returns a Sanitize instance. + def sanitizer + if options = sanitization + @sanitizer ||= options.to_sanitize + end + end + + # Public: Creates a Sanitize instance using the Wiki's history sanitization + # options. + # + # Returns a Sanitize instance. + def history_sanitizer + if options = history_sanitization + @history_sanitizer ||= options.to_sanitize + end + end + ######################################################################### # # Internal Methods From bffa4be78f2768f2cc4c8be1025885a95d09710b Mon Sep 17 00:00:00 2001 From: rick Date: Thu, 2 Dec 2010 14:40:24 -0800 Subject: [PATCH 16/22] re-use Sanitize instances in Gollum::Markup --- lib/gollum/markup.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/gollum/markup.rb b/lib/gollum/markup.rb index 95d3de76..73886a66 100644 --- a/lib/gollum/markup.rb +++ b/lib/gollum/markup.rb @@ -27,9 +27,9 @@ module Gollum # # Returns the formatted String content. def render(no_follow = false) - sanitize_options = no_follow ? - @wiki.history_sanitization : - @wiki.sanitization + sanitize = no_follow ? + @wiki.history_sanitizer : + @wiki.sanitizer data = extract_tex(@data) data = extract_code(data) @@ -44,12 +44,16 @@ module Gollum end data = process_tags(data) data = process_code(data) - data = Sanitize.clean(data, sanitize_options.to_hash) if sanitize_options + data = sanitize.clean!(data) if sanitize data = process_tex(data) data.gsub!(/

<\/p>/, '') data end + def doc_to_html(doc) + doc.to_xhtml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XHTML) + end + ######################################################################### # # TeX From 2fe6b7b7f1b4edab1f939f02ec4e957046e53a53 Mon Sep 17 00:00:00 2001 From: rick Date: Thu, 2 Dec 2010 14:47:20 -0800 Subject: [PATCH 17/22] provide access to the parsed Nokogiri document fragment when rendering marked up content. --- lib/gollum/markup.rb | 7 ++++++- lib/gollum/page.rb | 4 ++-- test/test_markup.rb | 25 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/lib/gollum/markup.rb b/lib/gollum/markup.rb index 73886a66..e63e96b1 100644 --- a/lib/gollum/markup.rb +++ b/lib/gollum/markup.rb @@ -44,7 +44,12 @@ module Gollum end data = process_tags(data) data = process_code(data) - data = sanitize.clean!(data) if sanitize + if sanitize || block_given? + doc = Nokogiri::HTML::DocumentFragment.parse(data) + doc = sanitize.clean_node!(doc) if sanitize + yield doc if block_given? + data = doc_to_html(doc) + end data = process_tex(data) data.gsub!(/

<\/p>/, '') data diff --git a/lib/gollum/page.rb b/lib/gollum/page.rb index cf1c9f59..2b9ad5ad 100644 --- a/lib/gollum/page.rb +++ b/lib/gollum/page.rb @@ -132,8 +132,8 @@ module Gollum # Public: The formatted contents of the page. # # Returns the String data. - def formatted_data - @blob && @wiki.markup_class.new(self).render(historical?) + def formatted_data(&block) + @blob && @wiki.markup_class.new(self).render(historical?, &block) end # Public: The format of the page. diff --git a/test/test_markup.rb b/test/test_markup.rb index c75ad1a6..892685af 100644 --- a/test/test_markup.rb +++ b/test/test_markup.rb @@ -25,6 +25,31 @@ context "Markup" do end end + test "Gollum::Markup#render yields a DocumentFragment" do + yielded = false + @wiki.write_page("Yielded", :markdown, "abc", commit_details) + + page = @wiki.page("Yielded") + markup = Gollum::Markup.new(page) + markup.render do |doc| + assert_kind_of Nokogiri::HTML::DocumentFragment, doc + yielded = true + end + assert yielded + end + + test "Gollum::Page#formatted_data yields a DocumentFragment" do + yielded = false + @wiki.write_page("Yielded", :markdown, "abc", commit_details) + + page = @wiki.page("Yielded") + page.formatted_data do |doc| + assert_kind_of Nokogiri::HTML::DocumentFragment, doc + yielded = true + end + assert yielded + end + ######################################################################### # # Links From 09d62fa327ea11d8b34675f89057eba673affad1 Mon Sep 17 00:00:00 2001 From: rick Date: Thu, 2 Dec 2010 14:57:38 -0800 Subject: [PATCH 18/22] history lesson --- HISTORY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index e2620f58..6938de58 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -5,6 +5,8 @@ how `Sanitize.clean` modifies formatted wiki content. * Add `--config` option for the command line, to specify a ruby file that is run during startup. + * Provide access to a parsed Nokogiri::DocumentFragment during markup + rendering for added customization. * Bug Fixes * Use `@wiki.page_class` in Gollum::Markup where appropriate (#63). From 280afb42ea2c6c9562545214706419c913c69b26 Mon Sep 17 00:00:00 2001 From: rick Date: Thu, 2 Dec 2010 17:53:16 -0800 Subject: [PATCH 19/22] extract sub-page logic from Gollum::Page#footer --- lib/gollum/page.rb | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/lib/gollum/page.rb b/lib/gollum/page.rb index 2b9ad5ad..5ec7cfb5 100644 --- a/lib/gollum/page.rb +++ b/lib/gollum/page.rb @@ -196,19 +196,7 @@ module Gollum # # Returns the footer Page or nil if none exists. def footer - return nil if page_match('_Footer', self.filename) - - dirs = self.path.split('/') - dirs.pop - map = @wiki.tree_map_for(self.version.id) - while !dirs.empty? - if page = find_page_in_tree(map, '_Footer', dirs.join('/')) - return page - end - dirs.pop - end - - find_page_in_tree(map, '_Footer', '') + find_sub_page :footer end # Gets a Boolean determining whether this page is a historical version. @@ -356,5 +344,28 @@ module Gollum false end end + + # Loads a sub page. Sub page nanes (footers) are prefixed with + # an underscore to distinguish them from other Pages. + # + # name - String page name. + # + # Returns the Page or nil if none exists. + def find_sub_page(name) + name = "_#{name.to_s.capitalize}" + return nil if page_match(name, self.filename) + + dirs = self.path.split('/') + dirs.pop + map = @wiki.tree_map_for(self.version.id) + while !dirs.empty? + if page = find_page_in_tree(map, name, dirs.join('/')) + return page + end + dirs.pop + end + + find_page_in_tree(map, name, '') + end end end From 2cbe3957cf235193dee6f0477d8f8ab0adefbf7e Mon Sep 17 00:00:00 2001 From: rick Date: Thu, 2 Dec 2010 18:16:37 -0800 Subject: [PATCH 20/22] add Page _Sidebars --- HISTORY.md | 2 + lib/gollum/page.rb | 12 +- test/examples/lotr.git/COMMIT_EDITMSG | 1 + test/examples/lotr.git/config | 9 +- .../examples/lotr.git/hooks/commit-msg.sample | 2 +- .../lotr.git/hooks/post-update.sample | 2 +- .../examples/lotr.git/hooks/pre-commit.sample | 4 +- .../examples/lotr.git/hooks/pre-rebase.sample | 20 +- .../lotr.git/hooks/prepare-commit-msg.sample | 6 +- test/examples/lotr.git/hooks/update.sample | 4 +- test/examples/lotr.git/index | Bin 0 -> 920 bytes test/examples/lotr.git/info/exclude | 2 +- test/examples/lotr.git/info/refs | 1 - test/examples/lotr.git/logs/HEAD | 2 + test/examples/lotr.git/logs/refs/heads/master | 2 + .../84/0ec5b1ba1320e8ec443f28f99566f615d5af10 | Bin 0 -> 241 bytes .../a3/1ca2a7c352c92531a8b99815d15843b259e814 | Bin 0 -> 165 bytes .../a8/ad3c09dd842a3517085bfadd37718856dee813 | Bin 0 -> 156 bytes test/examples/lotr.git/packed-refs | 2 +- test/examples/lotr.git/refs/heads/master | 2 +- .../lotr.git/refs/remotes/origin/HEAD | 1 + test/examples/lotr/Bilbo-Baggins.md | 13 + test/examples/lotr/Data.csv | 3 + test/examples/lotr/Home.textile | 3 + test/examples/lotr/Mordor/Eye-Of-Sauron.md | 37 ++ test/examples/lotr/Mordor/_Footer.md | 1 + test/examples/lotr/Mordor/_Sidebar.md | 1 + test/examples/lotr/Mordor/eye.jpg | Bin 0 -> 9714 bytes test/examples/lotr/Mordor/todo.txt | 1 + test/examples/lotr/My-Precious.md | 1 + test/examples/lotr/_Footer.md | 1 + test/examples/lotr/_Sidebar.md | 1 + test/static/default/Bilbo-Baggins.html | 41 ++ test/static/default/Eye-Of-Sauron.html | 65 +++ test/static/default/My-Precious.html | 29 ++ test/static/default/css/gollum.css | 408 ++++++++++++++++++ test/static/default/css/template.css | 146 +++++++ test/static/default/index.html | 30 ++ test/test_git_access.rb | 4 +- test/test_page.rb | 19 + 40 files changed, 850 insertions(+), 28 deletions(-) create mode 100644 test/examples/lotr.git/COMMIT_EDITMSG create mode 100644 test/examples/lotr.git/index delete mode 100644 test/examples/lotr.git/info/refs create mode 100644 test/examples/lotr.git/logs/HEAD create mode 100644 test/examples/lotr.git/logs/refs/heads/master create mode 100644 test/examples/lotr.git/objects/84/0ec5b1ba1320e8ec443f28f99566f615d5af10 create mode 100644 test/examples/lotr.git/objects/a3/1ca2a7c352c92531a8b99815d15843b259e814 create mode 100644 test/examples/lotr.git/objects/a8/ad3c09dd842a3517085bfadd37718856dee813 create mode 100644 test/examples/lotr.git/refs/remotes/origin/HEAD create mode 100644 test/examples/lotr/Bilbo-Baggins.md create mode 100644 test/examples/lotr/Data.csv create mode 100644 test/examples/lotr/Home.textile create mode 100644 test/examples/lotr/Mordor/Eye-Of-Sauron.md create mode 100644 test/examples/lotr/Mordor/_Footer.md create mode 100644 test/examples/lotr/Mordor/_Sidebar.md create mode 100644 test/examples/lotr/Mordor/eye.jpg create mode 100644 test/examples/lotr/Mordor/todo.txt create mode 100644 test/examples/lotr/My-Precious.md create mode 100644 test/examples/lotr/_Footer.md create mode 100644 test/examples/lotr/_Sidebar.md create mode 100644 test/static/default/Bilbo-Baggins.html create mode 100644 test/static/default/Eye-Of-Sauron.html create mode 100644 test/static/default/My-Precious.html create mode 100644 test/static/default/css/gollum.css create mode 100644 test/static/default/css/template.css create mode 100644 test/static/default/index.html diff --git a/HISTORY.md b/HISTORY.md index 6938de58..e4f977dc 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,7 @@ # HEAD +* Major Enhancements + * Add Page sidebars, similar to Page footers. * Minor Enhancements * Add `:sanitization` and `:history_sanitization` options for customizing how `Sanitize.clean` modifies formatted wiki content. diff --git a/lib/gollum/page.rb b/lib/gollum/page.rb index 5ec7cfb5..5b888964 100644 --- a/lib/gollum/page.rb +++ b/lib/gollum/page.rb @@ -55,7 +55,7 @@ module Gollum # Returns a newly initialized Gollum::Page. def initialize(wiki) @wiki = wiki - @blob = nil + @blob = @footer = @sidebar = nil end # Public: The on-disk filename of the page including extension. @@ -196,7 +196,14 @@ module Gollum # # Returns the footer Page or nil if none exists. def footer - find_sub_page :footer + @footer ||= find_sub_page(:footer) + end + + # Public: The sidebar Page. + # + # Returns the sidebar Page or nil if none exists. + def sidebar + @sidebar ||= find_sub_page(:sidebar) end # Gets a Boolean determining whether this page is a historical version. @@ -352,6 +359,7 @@ module Gollum # # Returns the Page or nil if none exists. def find_sub_page(name) + return nil if self.filename =~ /^_/ name = "_#{name.to_s.capitalize}" return nil if page_match(name, self.filename) diff --git a/test/examples/lotr.git/COMMIT_EDITMSG b/test/examples/lotr.git/COMMIT_EDITMSG new file mode 100644 index 00000000..25541c25 --- /dev/null +++ b/test/examples/lotr.git/COMMIT_EDITMSG @@ -0,0 +1 @@ +add sidebars diff --git a/test/examples/lotr.git/config b/test/examples/lotr.git/config index c53d818d..ec3337a4 100644 --- a/test/examples/lotr.git/config +++ b/test/examples/lotr.git/config @@ -1,5 +1,12 @@ [core] repositoryformatversion = 0 filemode = true - bare = true + bare = false + logallrefupdates = true ignorecase = true +[remote "origin"] + fetch = +refs/heads/*:refs/remotes/origin/* + url = /Users/rick/p/gollum/test/examples/lotr.git +[branch "master"] + remote = origin + merge = refs/heads/master diff --git a/test/examples/lotr.git/hooks/commit-msg.sample b/test/examples/lotr.git/hooks/commit-msg.sample index 6ef1d29d..b58d1184 100755 --- a/test/examples/lotr.git/hooks/commit-msg.sample +++ b/test/examples/lotr.git/hooks/commit-msg.sample @@ -1,7 +1,7 @@ #!/bin/sh # # An example hook script to check the commit log message. -# Called by git-commit with one argument, the name of the file +# Called by "git commit" with one argument, the name of the file # that has the commit message. The hook should exit with non-zero # status after issuing an appropriate message if it wants to stop the # commit. The hook is allowed to edit the commit message file. diff --git a/test/examples/lotr.git/hooks/post-update.sample b/test/examples/lotr.git/hooks/post-update.sample index 5323b56b..ec17ec19 100755 --- a/test/examples/lotr.git/hooks/post-update.sample +++ b/test/examples/lotr.git/hooks/post-update.sample @@ -5,4 +5,4 @@ # # To enable this hook, rename this file to "post-update". -exec git-update-server-info +exec git update-server-info diff --git a/test/examples/lotr.git/hooks/pre-commit.sample b/test/examples/lotr.git/hooks/pre-commit.sample index 439eefda..b187c4bb 100755 --- a/test/examples/lotr.git/hooks/pre-commit.sample +++ b/test/examples/lotr.git/hooks/pre-commit.sample @@ -1,13 +1,13 @@ #!/bin/sh # # An example hook script to verify what is about to be committed. -# Called by git-commit with no arguments. The hook should +# Called by "git commit" with no arguments. The hook should # exit with non-zero status after issuing an appropriate message if # it wants to stop the commit. # # To enable this hook, rename this file to "pre-commit". -if git-rev-parse --verify HEAD >/dev/null 2>&1 +if git rev-parse --verify HEAD >/dev/null 2>&1 then against=HEAD else diff --git a/test/examples/lotr.git/hooks/pre-rebase.sample b/test/examples/lotr.git/hooks/pre-rebase.sample index be1b06e2..9773ed4c 100755 --- a/test/examples/lotr.git/hooks/pre-rebase.sample +++ b/test/examples/lotr.git/hooks/pre-rebase.sample @@ -2,7 +2,7 @@ # # Copyright (c) 2006, 2008 Junio C Hamano # -# The "pre-rebase" hook is run just before "git-rebase" starts doing +# The "pre-rebase" hook is run just before "git rebase" starts doing # its job, and can prevent the command from running by exiting with # non-zero status. # @@ -43,7 +43,7 @@ git show-ref -q "$topic" || { } # Is topic fully merged to master? -not_in_master=`git-rev-list --pretty=oneline ^master "$topic"` +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` if test -z "$not_in_master" then echo >&2 "$topic is fully merged to master; better remove it." @@ -51,11 +51,11 @@ then fi # Is topic ever merged to next? If so you should not be rebasing it. -only_next_1=`git-rev-list ^master "^$topic" ${publish} | sort` -only_next_2=`git-rev-list ^master ${publish} | sort` +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` if test "$only_next_1" = "$only_next_2" then - not_in_topic=`git-rev-list "^$topic" master` + not_in_topic=`git rev-list "^$topic" master` if test -z "$not_in_topic" then echo >&2 "$topic is already up-to-date with master" @@ -64,8 +64,8 @@ then exit 0 fi else - not_in_next=`git-rev-list --pretty=oneline ^${publish} "$topic"` - perl -e ' + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' my $topic = $ARGV[0]; my $msg = "* $topic has commits already merged to public branch:\n"; my (%not_in_next) = map { @@ -157,13 +157,13 @@ B to be deleted. To compute (1): - git-rev-list ^master ^topic next - git-rev-list ^master next + git rev-list ^master ^topic next + git rev-list ^master next if these match, topic has not merged in next at all. To compute (2): - git-rev-list master..topic + git rev-list master..topic if this is empty, it is fully merged to "master". diff --git a/test/examples/lotr.git/hooks/prepare-commit-msg.sample b/test/examples/lotr.git/hooks/prepare-commit-msg.sample index 36524249..f093a02e 100755 --- a/test/examples/lotr.git/hooks/prepare-commit-msg.sample +++ b/test/examples/lotr.git/hooks/prepare-commit-msg.sample @@ -1,7 +1,7 @@ #!/bin/sh # # An example hook script to prepare the commit log message. -# Called by git-commit with the name of the file that has the +# Called by "git commit" with the name of the file that has the # commit message, followed by the description of the commit # message's source. The hook's purpose is to edit the commit # message file. If the hook fails with a non-zero status, @@ -22,10 +22,10 @@ case "$2,$3" in merge,) - perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; + /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; # ,|template,) -# perl -i.bak -pe ' +# /usr/bin/perl -i.bak -pe ' # print "\n" . `git diff --cached --name-status -r` # if /^#/ && $first++ == 0' "$1" ;; diff --git a/test/examples/lotr.git/hooks/update.sample b/test/examples/lotr.git/hooks/update.sample index fd63b2d6..71ab04ed 100755 --- a/test/examples/lotr.git/hooks/update.sample +++ b/test/examples/lotr.git/hooks/update.sample @@ -1,7 +1,7 @@ #!/bin/sh # # An example hook script to blocks unannotated tags from entering. -# Called by git-receive-pack with arguments: refname sha1-old sha1-new +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new # # To enable this hook, rename this file to "update". # @@ -64,7 +64,7 @@ zero="0000000000000000000000000000000000000000" if [ "$newrev" = "$zero" ]; then newrev_type=delete else - newrev_type=$(git-cat-file -t $newrev) + newrev_type=$(git cat-file -t $newrev) fi case "$refname","$newrev_type" in diff --git a/test/examples/lotr.git/index b/test/examples/lotr.git/index new file mode 100644 index 0000000000000000000000000000000000000000..cc6fa46e61c7d3588795358401ee4d5afd596aa3 GIT binary patch literal 920 zcmZ?q402{*U|<4bZl50kia?qHM)NT+Ffww#y2QZHxCF@j3X~E7DxIdYQ#9*x^F-Ig z6#@Fk`J-ez>O9sm2smZtB<1TmC8nom<`wJZrXb8gGw(90c?|l8x7f|+n3m1aSH(E# ziP`oQEg^cW3>+?rC5d{;#br3nxq@a+>96PSgIyG~cR6aVz9Y=WJ8AmODX9!R9{IVc zdL^k9C7C&?Am8CM?;5IkoX00;H^1Y((Oh-ADNxSg>XX+`XKyQI5ckb5O35$Mcdbm- z^-t3cPAo0T&jWiG9&Tvzy~!qwK7#Ns~{auc-}-ck3ov-o}8wbNv@B){x<72`^yJ2IR3dX@I%cj z$xq4GE2${K9Y43w%#&WVP5#B)upfy&T#bRZOnzG4dHX8^=)OwbfTGmo%=}VFD#YpE z+i2#Ay}4z?y6>T@!m6#ycN-K>V)LHd*UZ3$6d{Q4vxE8@Ohe=4BT?pY$74ju%`;i7 Wao6v?OZ(NHzPw}6gVKB7761UPBn+zn literal 0 HcmV?d00001 diff --git a/test/examples/lotr.git/info/exclude b/test/examples/lotr.git/info/exclude index 2c87b72d..a5196d1b 100644 --- a/test/examples/lotr.git/info/exclude +++ b/test/examples/lotr.git/info/exclude @@ -1,4 +1,4 @@ -# git-ls-files --others --exclude-from=.git/info/exclude +# git ls-files --others --exclude-from=.git/info/exclude # Lines that start with '#' are comments. # For a project mostly in C, the following would be a good set of # exclude patterns (uncomment them if you want to use them): diff --git a/test/examples/lotr.git/info/refs b/test/examples/lotr.git/info/refs deleted file mode 100644 index 23535fff..00000000 --- a/test/examples/lotr.git/info/refs +++ /dev/null @@ -1 +0,0 @@ -d61c3de65957b5997c236393b3ad4d70b5cd8931 refs/heads/master diff --git a/test/examples/lotr.git/logs/HEAD b/test/examples/lotr.git/logs/HEAD new file mode 100644 index 00000000..99c12840 --- /dev/null +++ b/test/examples/lotr.git/logs/HEAD @@ -0,0 +1,2 @@ +0000000000000000000000000000000000000000 60f12f4254f58801b9ee7db7bca5fa8aeefaa56b rick 1291341857 -0800 clone: from /Users/rick/p/gollum/test/examples/lotr.git +60f12f4254f58801b9ee7db7bca5fa8aeefaa56b a8ad3c09dd842a3517085bfadd37718856dee813 rick 1291341922 -0800 commit: add sidebars diff --git a/test/examples/lotr.git/logs/refs/heads/master b/test/examples/lotr.git/logs/refs/heads/master new file mode 100644 index 00000000..99c12840 --- /dev/null +++ b/test/examples/lotr.git/logs/refs/heads/master @@ -0,0 +1,2 @@ +0000000000000000000000000000000000000000 60f12f4254f58801b9ee7db7bca5fa8aeefaa56b rick 1291341857 -0800 clone: from /Users/rick/p/gollum/test/examples/lotr.git +60f12f4254f58801b9ee7db7bca5fa8aeefaa56b a8ad3c09dd842a3517085bfadd37718856dee813 rick 1291341922 -0800 commit: add sidebars diff --git a/test/examples/lotr.git/objects/84/0ec5b1ba1320e8ec443f28f99566f615d5af10 b/test/examples/lotr.git/objects/84/0ec5b1ba1320e8ec443f28f99566f615d5af10 new file mode 100644 index 0000000000000000000000000000000000000000..a1e90909183fe47f0f4c651526846679f42b422f GIT binary patch literal 241 zcmV5H)1d}FfcPQQEYF!db67`ac%NP!Cv765^Et{jSigD5tv+XNdLiAXnYCQ6DQ}s$x zD@rnRQW<_de;@3kpuNjcbM+lzHr`3oZ%#=yF#rMu-~6JK{33?MGK-cU4mzo7xMJrF z(Tfqzn<8I`Kn?P()D0*~P0q|O1v_iiHu)EG!+s?Ca5VkRc~936OjU4ZN@`Lf zA!VtRsd`xj=?sO=$_H7Lr#LJ_GoD~-WV2aFhNps5NgaR=O zk@HE>XDnOSz2>LB4$jNEeVNzF_eZ1py5z0hG@6K$#b}H^LjX`mJ@y9w4HcE5_gXkn K-_;Lq0!BNAv`v!$ literal 0 HcmV?d00001 diff --git a/test/examples/lotr.git/packed-refs b/test/examples/lotr.git/packed-refs index 0a68312a..093dfa7f 100644 --- a/test/examples/lotr.git/packed-refs +++ b/test/examples/lotr.git/packed-refs @@ -1,2 +1,2 @@ # pack-refs with: peeled -d61c3de65957b5997c236393b3ad4d70b5cd8931 refs/heads/master +60f12f4254f58801b9ee7db7bca5fa8aeefaa56b refs/remotes/origin/master diff --git a/test/examples/lotr.git/refs/heads/master b/test/examples/lotr.git/refs/heads/master index 3f114d47..c64ca983 100644 --- a/test/examples/lotr.git/refs/heads/master +++ b/test/examples/lotr.git/refs/heads/master @@ -1 +1 @@ -60f12f4254f58801b9ee7db7bca5fa8aeefaa56b \ No newline at end of file +a8ad3c09dd842a3517085bfadd37718856dee813 diff --git a/test/examples/lotr.git/refs/remotes/origin/HEAD b/test/examples/lotr.git/refs/remotes/origin/HEAD new file mode 100644 index 00000000..6efe28ff --- /dev/null +++ b/test/examples/lotr.git/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/master diff --git a/test/examples/lotr/Bilbo-Baggins.md b/test/examples/lotr/Bilbo-Baggins.md new file mode 100644 index 00000000..2cb9156a --- /dev/null +++ b/test/examples/lotr/Bilbo-Baggins.md @@ -0,0 +1,13 @@ +# Bilbo Baggins + +Bilbo Baggins is the protagonist of The [[Hobbit]] and also makes a few +appearances in The Lord of the Rings, two of the most well-known of [[J. R. R. +Tolkien]]'s fantasy writings. The story of The Hobbit featuring Bilbo is also +retold from a different perspective in the Chapter The Quest of Erebor in +Unfinished Tales. + +In Tolkien's narrative conceit, in which all the writings of Middle-earth are +'really' translations from the fictitious volume of The Red Book of Westmarch, +Bilbo is the author of The Hobbit and translator of The Silmarillion. + +From [http://en.wikipedia.org/wiki/Bilbo_Baggins](http://en.wikipedia.org/wiki/Bilbo_Baggins). diff --git a/test/examples/lotr/Data.csv b/test/examples/lotr/Data.csv new file mode 100644 index 00000000..c3b43e9f --- /dev/null +++ b/test/examples/lotr/Data.csv @@ -0,0 +1,3 @@ +FirstName,LastName +Bilbo,Baggins +Frodo,Baggins diff --git a/test/examples/lotr/Home.textile b/test/examples/lotr/Home.textile new file mode 100644 index 00000000..fae7ef53 --- /dev/null +++ b/test/examples/lotr/Home.textile @@ -0,0 +1,3 @@ +h1. The LOTR Wiki + +This wiki is awesome. You can learn about [[Bilbo Baggins]] or some [[evil|Eye Of Sauron]] stuff. diff --git a/test/examples/lotr/Mordor/Eye-Of-Sauron.md b/test/examples/lotr/Mordor/Eye-Of-Sauron.md new file mode 100644 index 00000000..936b83ee --- /dev/null +++ b/test/examples/lotr/Mordor/Eye-Of-Sauron.md @@ -0,0 +1,37 @@ +# Eye **Of** Sauron + +Here are some pictures of the Eye of Sauron! + +Just the photo. + +[[/Mordor/eye.jpg]] + +With alt. + +[[/Mordor/eye.jpg|alt=Eye of Sauron]] + +With frame and caption. + +[[/Mordor/eye.jpg|frame|alt=Eye of Sauron]] + +Align left. + +[[/Mordor/eye.jpg|align=left]] + +Alight center. + +[[/Mordor/eye.jpg|align=center]] + +Alight right. + +[[/Mordor/eye.jpg|align=right]] + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas interdum velit eu justo rutrum vitae semper urna porttitor. Sed viverra bibendum tincidunt. Curabitur vel mi sed nisl vestibulum lobortis eu ac nisl. Morbi fringilla adipiscing felis. Mauris luctus interdum accumsan. Integer leo mauris, dapibus a sollicitudin non, varius non erat. Donec eu dictum orci. Morbi viverra eleifend felis, et adipiscing neque consequat a. Vestibulum accumsan ligula suscipit mi rhoncus ac gravida lectus tincidunt. Donec interdum, [[/Mordor/eye.jpg|float|frame|alt=FIRE FIRE FIRE]] lorem sed interdum molestie, est ipsum pharetra est, sit amet eleifend purus eros at ligula. Aliquam erat volutpat. Sed dignissim interdum ipsum, et pulvinar lectus faucibus et. Ut at lacus risus, non lobortis erat. Proin malesuada sagittis mauris, in posuere turpis tincidunt eu. Nunc accumsan, ligula ut rutrum aliquet, neque metus suscipit ligula, in aliquam augue velit vel orci. Aliquam diam lectus, posuere id faucibus sed, aliquam vel erat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas interdum velit eu justo rutrum vitae semper urna porttitor. Sed viverra bibendum tincidunt. Curabitur vel mi sed nisl vestibulum lobortis eu ac nisl. Morbi fringilla adipiscing felis. Mauris luctus interdum accumsan. Integer leo mauris, dapibus a sollicitudin non, varius non erat. Donec eu dictum orci. [[/Mordor/eye.jpg|float|align=right]] Morbi viverra eleifend felis, et adipiscing neque consequat a. Vestibulum accumsan ligula suscipit mi rhoncus ac gravida lectus tincidunt. Donec interdum, lorem sed interdum molestie, est ipsum pharetra est, sit amet eleifend purus eros at ligula. Aliquam erat volutpat. Sed dignissim interdum ipsum, et pulvinar lectus faucibus et. Ut at lacus risus, non lobortis erat. Proin malesuada sagittis mauris, in posuere turpis tincidunt eu. Nunc accumsan, ligula ut rutrum aliquet, neque metus suscipit ligula, in aliquam augue velit vel orci. Aliquam diam lectus, posuere id faucibus sed, aliquam vel erat. + +Smaller width. + +[[/Mordor/eye.jpg|width=100px]] + +Smaller height. + +[[/Mordor/eye.jpg|height=100px]] diff --git a/test/examples/lotr/Mordor/_Footer.md b/test/examples/lotr/Mordor/_Footer.md new file mode 100644 index 00000000..9697dc65 --- /dev/null +++ b/test/examples/lotr/Mordor/_Footer.md @@ -0,0 +1 @@ +Ones does not simply **walk** into Mordor! diff --git a/test/examples/lotr/Mordor/_Sidebar.md b/test/examples/lotr/Mordor/_Sidebar.md new file mode 100644 index 00000000..9697dc65 --- /dev/null +++ b/test/examples/lotr/Mordor/_Sidebar.md @@ -0,0 +1 @@ +Ones does not simply **walk** into Mordor! diff --git a/test/examples/lotr/Mordor/eye.jpg b/test/examples/lotr/Mordor/eye.jpg new file mode 100644 index 0000000000000000000000000000000000000000..714323c104239440a5c66ab12a67ed07a83c404f GIT binary patch literal 9714 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 RYkk0m?%5YWY^a}S{|lH_;yC~S literal 0 HcmV?d00001 diff --git a/test/examples/lotr/Mordor/todo.txt b/test/examples/lotr/Mordor/todo.txt new file mode 100644 index 00000000..0ade1e29 --- /dev/null +++ b/test/examples/lotr/Mordor/todo.txt @@ -0,0 +1 @@ +[ ] Write section on Ents diff --git a/test/examples/lotr/My-Precious.md b/test/examples/lotr/My-Precious.md new file mode 100644 index 00000000..aab61fe8 --- /dev/null +++ b/test/examples/lotr/My-Precious.md @@ -0,0 +1 @@ +One ring to rule them all! diff --git a/test/examples/lotr/_Footer.md b/test/examples/lotr/_Footer.md new file mode 100644 index 00000000..ecda3205 --- /dev/null +++ b/test/examples/lotr/_Footer.md @@ -0,0 +1 @@ +Lord of the Rings wiki \ No newline at end of file diff --git a/test/examples/lotr/_Sidebar.md b/test/examples/lotr/_Sidebar.md new file mode 100644 index 00000000..ecda3205 --- /dev/null +++ b/test/examples/lotr/_Sidebar.md @@ -0,0 +1 @@ +Lord of the Rings wiki \ No newline at end of file diff --git a/test/static/default/Bilbo-Baggins.html b/test/static/default/Bilbo-Baggins.html new file mode 100644 index 00000000..9dd2c777 --- /dev/null +++ b/test/static/default/Bilbo-Baggins.html @@ -0,0 +1,41 @@ + + + + + + + Bilbo Baggins + + + +

+
+
+
+
+

Bilbo Baggins

+ +

Bilbo Baggins is the protagonist of The Hobbit and also makes a few +appearances in The Lord of the Rings, two of the most well-known of J. R. R. +Tolkien's fantasy writings. The story of The Hobbit featuring Bilbo is also +retold from a different perspective in the Chapter The Quest of Erebor in +Unfinished Tales.

+ +

In Tolkien's narrative conceit, in which all the writings of Middle-earth are +'really' translations from the fictitious volume of The Red Book of Westmarch, +Bilbo is the author of The Hobbit and translator of The Silmarillion.

+ +

From http://en.wikipedia.org/wiki/Bilbo_Baggins.

+
+
+
+ +
+ +
+ + + + diff --git a/test/static/default/Eye-Of-Sauron.html b/test/static/default/Eye-Of-Sauron.html new file mode 100644 index 00000000..6619be30 --- /dev/null +++ b/test/static/default/Eye-Of-Sauron.html @@ -0,0 +1,65 @@ + + + + + + + Eye Of Sauron + + + +
+
+
+
+
+

Eye Of Sauron

+ +

Here are some pictures of the Eye of Sauron!

+ +

Just the photo.

+ +

+ +

With alt.

+ +

Eye of Sauron

+ +

With frame and caption.

+ +

Eye of SauronEye of Sauron

+ +

Align left.

+ +

+ +

Alight center.

+ +

+ +

Alight right.

+ +

+ +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas interdum velit eu justo rutrum vitae semper urna porttitor. Sed viverra bibendum tincidunt. Curabitur vel mi sed nisl vestibulum lobortis eu ac nisl. Morbi fringilla adipiscing felis. Mauris luctus interdum accumsan. Integer leo mauris, dapibus a sollicitudin non, varius non erat. Donec eu dictum orci. Morbi viverra eleifend felis, et adipiscing neque consequat a. Vestibulum accumsan ligula suscipit mi rhoncus ac gravida lectus tincidunt. Donec interdum, FIRE FIRE FIREFIRE FIRE FIRE lorem sed interdum molestie, est ipsum pharetra est, sit amet eleifend purus eros at ligula. Aliquam erat volutpat. Sed dignissim interdum ipsum, et pulvinar lectus faucibus et. Ut at lacus risus, non lobortis erat. Proin malesuada sagittis mauris, in posuere turpis tincidunt eu. Nunc accumsan, ligula ut rutrum aliquet, neque metus suscipit ligula, in aliquam augue velit vel orci. Aliquam diam lectus, posuere id faucibus sed, aliquam vel erat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas interdum velit eu justo rutrum vitae semper urna porttitor. Sed viverra bibendum tincidunt. Curabitur vel mi sed nisl vestibulum lobortis eu ac nisl. Morbi fringilla adipiscing felis. Mauris luctus interdum accumsan. Integer leo mauris, dapibus a sollicitudin non, varius non erat. Donec eu dictum orci. Morbi viverra eleifend felis, et adipiscing neque consequat a. Vestibulum accumsan ligula suscipit mi rhoncus ac gravida lectus tincidunt. Donec interdum, lorem sed interdum molestie, est ipsum pharetra est, sit amet eleifend purus eros at ligula. Aliquam erat volutpat. Sed dignissim interdum ipsum, et pulvinar lectus faucibus et. Ut at lacus risus, non lobortis erat. Proin malesuada sagittis mauris, in posuere turpis tincidunt eu. Nunc accumsan, ligula ut rutrum aliquet, neque metus suscipit ligula, in aliquam augue velit vel orci. Aliquam diam lectus, posuere id faucibus sed, aliquam vel erat.

+ +

Smaller width.

+ +

+ +

Smaller height.

+ +

+
+
+
+ +
+ +
+ + + + diff --git a/test/static/default/My-Precious.html b/test/static/default/My-Precious.html new file mode 100644 index 00000000..588bc404 --- /dev/null +++ b/test/static/default/My-Precious.html @@ -0,0 +1,29 @@ + + + + + + + My Precious + + + +
+
+
+
+
+

One ring to rule them all!

+
+
+
+ +
+ +
+ + + + diff --git a/test/static/default/css/gollum.css b/test/static/default/css/gollum.css new file mode 100644 index 00000000..627d98ef --- /dev/null +++ b/test/static/default/css/gollum.css @@ -0,0 +1,408 @@ +/* + gollum.css + A basic stylesheet for Gollum +*/ + +/* @section core */ +body, html { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 10px; /* -> 1em */ + margin: 0; + padding: 0; +} + +#wiki-wrapper { + margin: 0 auto; + overflow: visible; + width: 80%; +} + +a:link { + color: #4183c4; + text-decoration: none; +} + +a:hover, a:visited { + text-decoration: underline; +} + + +/* @section head */ +#head { + border-bottom: 1px solid #ccc; + margin: 4.5em 0 0.5em; + padding: 0.5em 0; + overflow: hidden; +} + + #head h1 { + font-size: 3.3em; + float: left; + line-height: normal; + margin: 0; + padding: 0.08em 0 0 0; + } + + #head ul.actions { + float: right; + } + + +/* @section content */ +#wiki-content { + height: 1%; + overflow: visible; +} + + #wiki-content .wrap { + height: 1%; + overflow: auto; + } + + /* @section comments */ + #wiki-body #inline-comment { + display: none; /* todo */ + } + + /* @section body */ + #wiki-body { + float: left; + margin-right: 3%; + width: 70%; + } + + /* @section rightbar */ + #wiki-rightbar { + float: right; + width: 27%; + } + + #wiki-rightbar #nav { + background-color: #f7f7f7; + border: 1px solid #ddd; + margin-top: 1.5em; + padding: 1em; + + border-radius: 0.5em; + -moz-border-radius: 0.5em; + -webkit-border-radius: 0.5em; + } + + #wiki-rightbar #nav { + font-size: 1.2em; + line-height: 1.5em; + } + + #wiki-rightbar #nav p.parent { + border-bottom: 1px solid #bbb; + font-weight: bold; + margin: 0 0 0.5em 0; + padding: 0 0 0.5em 0; + text-shadow: 0 1px 0 #fff; + } + + /* Back arrow */ + #wiki-rightbar #nav p.parent:before { + color: #666; + content: "← "; + } + + #wiki-rightbar #nav h3 { + font-size: 1.2em; + color: #333; + margin: 1.2em 0 0; + padding: 0; + text-shadow: 0 1px 0 #fff; + } + + #wiki-rightbar #nav ul { + margin: 0.5em 0 1em; + padding: 0; + } + + #wiki-rightbar #nav ul li { + color: #bbb; + list-style-position: outside; + list-style-type: none; + margin: 0 0 0 1em; + padding: 0; + line-height: 1.75em; + } + + #wiki-rightbar #nav ul li:hover { + list-style-type: square; + } + + #wiki-rightbar #nav ul li a { + font-weight: bold; + text-shadow: 0 1px 0 #fff; + } + + /* @section footer */ + #wiki-footer { + clear: both; + margin: 2em 0 5em; + } + + .has-rightbar #wiki-footer { + width: 70%; + } + + #wiki-footer #footer-content { + background-color: #f7f7f7; + border: 1px solid #ddd; + font-size: 1.2em; + line-height: 1.5em; + margin-top: 1.5em; + padding: 1em; + + border-radius: 0.5em; + -moz-border-radius: 0.5em; + -webkit-border-radius: 0.5em; + } + + #wiki-footer #footer-content h3 { + font-size: 1.2em; + color: #333; + margin: 0; + padding: 0 0 0.2em; + text-shadow: 0 1px 0 #fff; + } + + #wiki-footer #footer-content p { + margin: 0.5em 0 0; + padding: 0; + } + + #wiki-footer #footer-content ul.links { + margin: 0.5em 0 0; + overflow: hidden; + padding: 0; + } + + #wiki-footer #footer-content ul.links li { + color: #999; + float: left; + list-style-position: inside; + list-style-type: square; + padding: 0; + margin-left: 0.75em; + } + + #wiki-footer #footer-content ul.links li a { + font-weight: bold; + text-shadow: 0 1px 0 #fff; + } + + #wiki-footer #footer-content ul.links li:first-child { + list-style-type: none; + margin: 0; + } + + .ff #wiki-footer #footer-content ul.links li:first-child { + margin: 0 -0.75em 0 0; + } + + /* @section page-footer */ + .page #footer { + border-top: 1px solid #ccc; + margin: 1em 0 7em; + } + + #footer p#last-edit { + font-size: 1.2em; + line-height: 1.6em; + color: #999; + margin: 0.9em 0; + } + + #footer p#last-edit span.username { + font-weight: bold; + } + + +/* @section history */ +.history h1 { + color: #999; + font-weight: normal; +} + + .history h1 strong { + color: #000; + font-weight: bold; + } + +#wiki-history { + margin-top: 3em; +} + + #wiki-history fieldset { + border: 0; + margin: 2em 0; + padding: 0; + } + + #wiki-history table, #wiki-history tbody { + border-collapse: collapse; + padding: 0; + margin: 0; + width: 100%; + } + + #wiki-history table tr { + padding: 0; + margin: 0; + } + + #wiki-history table tr { + background-color: #ebf2f6; + } + + #wiki-history table tr td { + border: 1px solid #c0dce9; + font-size: 1.2em; + line-height: 1.6em; + margin: 0; + padding: 0.3em 0.7em; + } + + #wiki-history table tr td.checkbox { + padding: 0.3em; + } + + #wiki-history table tr td.checkbox input { + cursor: pointer; + display: block; + padding-right: 0; + padding-top: 0.4em; + margin-right: -0.2em; + } + + #wiki-history table tr:nth-child(2n), + #wiki-history table tr.alt-row { + background-color: #f3f7fa; + } + + #wiki-history table tr.selected { + background-color: #ffffea !important; + z-index: 100; + } + + #wiki-history table tr td.commit-name { + border-right: none; + } + + #wiki-history table tr td.commit-name span.time-elapsed { + color: #999; + } + + #wiki-history table tr td.author { + width: 20%; + } + + #wiki-history table tr td.author a { + color: #000; + font-weight: bold; + } + + #wiki-history table tr td.author a span.username { + display: block; + padding-top: 3px; + } + + #wiki-history table tr td img { + background-color: #fff; + border: 1px solid #999; + display: block; + float: left; + height: 18px; + overflow: hidden; + margin: 0 0.5em 0 0; + width: 18px; + padding: 2px; + } + + #wiki-history table tr td.commit-name a { + font-size: 0.9em; + font-family: 'Monaco', 'Andale Mono', Consolas, 'Courier New', monospace; + padding: 0 0.2em; + } + + #wiki-history table tr td.revert-action { + border-left: 0; + text-align: right; + } + + #wiki-history table tr td.revert-action a { + font-weight: bold; + } + + #wiki-history table tr td.revert-action a span { + font-size: 0.9em; + font-family: 'Monaco', 'Andale Mono', Consolas, 'Courier New', monospace; + } + +.history #wiki-history ul.actions li, +.history #footer ul.actions li { + margin: 0 0.6em 0 0; +} + + +/* @section edit */ +.edit h1 { + color: #999; + font-weight: normal; +} + + .edit h1 strong { + color: #000; + font-weight: bold; + } + + + +/* @control minibutton */ +ul.actions { + display: block; + list-style-type: none; + overflow: hidden; + padding: 0; + } + + ul.actions li { + float: left; + font-size: 1.2em; + margin-left: 0.6em; + } + +.minibutton a { + background-color: #f7f7f7; + border: 1px solid #d4d4d4; + color: #333; + display: block; + font-weight: bold; + margin: 0; + padding: 0.4em 1em; + + text-shadow: 0 1px 0 #fff; + + filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#f4f4f4', endColorstr='#ececec'); + background: -webkit-gradient(linear, left top, left bottom, from(#f4f4f4), to(#ececec)); + background: -moz-linear-gradient(top, #f4f4f4, #ececec); + + border-radius: 3px; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; +} + +.minibutton a:hover { + background: #3072b3; + border-color: #518cc6 #518cc6 #2a65a0; + color: #fff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.3); + text-decoration: none; + + filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#599bdc', endColorstr='#3072b3'); + background: -webkit-gradient(linear, left top, left bottom, from(#599bdc), to(#3072b3)); + background: -moz-linear-gradient(top, #599bdc, #3072b3); +} \ No newline at end of file diff --git a/test/static/default/css/template.css b/test/static/default/css/template.css new file mode 100644 index 00000000..882877ff --- /dev/null +++ b/test/static/default/css/template.css @@ -0,0 +1,146 @@ +/* + template.css + Wiki content formatting + Keeping this file separate so it can be easily swapped out if you + want to format your wiki content differently from the default. +*/ + +#template { + margin-bottom: 4em; /* Give it some breathing room */ +} + +.has-footer #template { + margin: 0; +} + +#template p { + font-size: 1.4em; + line-height: 1.6em; +} + + /* See http://webtypography.net/Rhythm_and_Proportion/ */ + #template p + p { + margin: -0.75em 0 0; + text-indent: 1em; + } + + /* Everybody loves type ornaments */ + #template p:last-child:after { + color: #999; + content: " ❈"; + font-size: 0.8em; + } + + #template blockquote p:last-child:after { + content: none; + } + +#template a:link { + color: #4183c4; + text-decoration: none; +} + +#template a:hover, #template a:visited { + text-decoration: underline; +} + +#template ul, #template ol { + margin: 1.0em 0 0 2.0em; + list-style-position: outside; + padding: 0; + +} + +#template p + ul, #template p + ol, +#template ul li > ul, #template ol li > ol { + margin-top: 0; +} + +#template ul li > ul, #template ol li > ol { + margin-left: 0; +} + + #template ul { + list-style-type: square; + } + + #template ol li > ol li { + font-size: 1.0em !important; + list-style-type: lower-roman; + list-style-position: inside; + } + + #template ol li > ol li > ol li { + list-style-type: lower-alpha; + } + + #template ol li > ol li > ol li > ol li { + list-style-type: lower-greek; + } + +#template ul li, #template ol li { + font-size: 1.4em; + line-height: 1.6em; + padding-top: 0.1em; /* Line up ordinals */ +} + +#template blockquote { + margin: 0 4.0em 0 2.0em; + padding: 0; +} + + #template blockquote p { + color: #888; + font-style: italic; + } + + +/* Headings */ +#template h1, #template h2, #template h3, +#template h4, #template h5, #template h6 { + margin: 0; + padding: 0.5em 0 0; +} + +#template h1 { + font-size: 2.6em; + font-weight: bold; +} + +#template h2 { + font-size: 2.2em; + font-weight: bold; +} + +#template h3 { + font-size: 2.0em; + font-weight: bold; +} + +#template h4 { + font-size: 1.8em; + font-weight: bold; +} + +#template h5 { + font-size: 1.6em; + font-weight: bold; + +} + +#template h6 { + font-size: 1.4em; + font-weight: bold; + margin-top: 1.0em; + text-transform: uppercase; /* all caps */ +} + + +/* Code-related */ +#template p code { + background-color: #f7f7f7; + border: 1px solid #ddd; + color: #222; /* This is a little heavy when #000 */ + font-family: Consolas, Monaco, "Courier New", monospace; + padding: 0.15em 0.3em; +} \ No newline at end of file diff --git a/test/static/default/index.html b/test/static/default/index.html new file mode 100644 index 00000000..58d42871 --- /dev/null +++ b/test/static/default/index.html @@ -0,0 +1,30 @@ + + + + + + + The LOTR Wiki + + + +
+
+
+
+
+

The LOTR Wiki

+

This wiki is awesome. You can learn about Bilbo Baggins or some evil stuff.

+
+
+
+ +
+ +
+ + + + diff --git a/test/test_git_access.rb b/test/test_git_access.rb index ef13fbeb..ceb24cc6 100644 --- a/test/test_git_access.rb +++ b/test/test_git_access.rb @@ -25,9 +25,9 @@ context "GitAccess" do assert @access.ref_map.empty? assert @access.tree_map.empty? @access.tree 'master' - assert_equal({"master"=>"60f12f4254f58801b9ee7db7bca5fa8aeefaa56b"}, @access.ref_map) + assert_equal({"master"=>"a8ad3c09dd842a3517085bfadd37718856dee813"}, @access.ref_map) - map = @access.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'] + map = @access.tree_map['a8ad3c09dd842a3517085bfadd37718856dee813'] assert_equal 'Bilbo-Baggins.md', map[0].path assert_equal '', map[0].dir assert_equal map[0].path, map[0].name diff --git a/test/test_page.rb b/test/test_page.rb index 1316c713..ed2e7d5b 100644 --- a/test/test_page.rb +++ b/test/test_page.rb @@ -109,6 +109,25 @@ context "Page" do test "footer itself" do footer = @wiki.page("_Footer") assert_nil footer.footer + assert_nil footer.sidebar + end + + test "top level sidebar" do + sidebar = @wiki.page('Home').sidebar + assert_equal 'Lord of the Rings wiki', sidebar.raw_data + assert_equal '_Sidebar.md', sidebar.path + end + + test "nested sidebar" do + sidebar = @wiki.page('Eye Of Sauron').sidebar + assert_equal "Ones does not simply **walk** into Mordor!\n", sidebar.raw_data + assert_equal "Mordor/_Sidebar.md", sidebar.path + end + + test "sidebar itself" do + sidebar = @wiki.page("_Sidebar") + assert_nil sidebar.footer + assert_nil sidebar.sidebar end test "cannot convert non string to human readable page title" do From 948cfa0f015c6bb369546fc67693a0d33baa4060 Mon Sep 17 00:00:00 2001 From: rick Date: Thu, 2 Dec 2010 18:25:31 -0800 Subject: [PATCH 21/22] add sidebar methods to the Page mustache view --- lib/gollum/frontend/views/page.rb | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/gollum/frontend/views/page.rb b/lib/gollum/frontend/views/page.rb index 04f1e64a..84f30b30 100644 --- a/lib/gollum/frontend/views/page.rb +++ b/lib/gollum/frontend/views/page.rb @@ -20,18 +20,29 @@ module Precious end def has_footer - @footer ||= @page.footer - !@footer.nil? + @footer = (@page.footer || false) if @footer.nil? + !!@footer end def footer_content - @footer ||= @page.footer - @footer.formatted_data + has_footer && @footer.formatted_data end def footer_format - @footer ||= @page.footer - @footer.format.to_s + has_footer && @footer.format.to_s + end + + def has_sidebar + @sidebar = (@page.sidebar || false) if @sidebar.nil? + !@sidebar + end + + def sidebar_content + has_sidebar && @sidebar.formatted_data + end + + def sidebar_format + has_sidebar && @sidebar.format.to_s end end end From 7a0f6333d676d4d3f7b81d11390c7ffbb1ad1f77 Mon Sep 17 00:00:00 2001 From: rick Date: Thu, 2 Dec 2010 18:26:37 -0800 Subject: [PATCH 22/22] busted --- lib/gollum/frontend/views/page.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/gollum/frontend/views/page.rb b/lib/gollum/frontend/views/page.rb index 84f30b30..03d20224 100644 --- a/lib/gollum/frontend/views/page.rb +++ b/lib/gollum/frontend/views/page.rb @@ -34,7 +34,7 @@ module Precious def has_sidebar @sidebar = (@page.sidebar || false) if @sidebar.nil? - !@sidebar + !!@sidebar end def sidebar_content