diff --git a/lib/gollum.rb b/lib/gollum.rb index b1eec708..b8c6e6d5 100644 --- a/lib/gollum.rb +++ b/lib/gollum.rb @@ -6,6 +6,7 @@ require 'ostruct' # external require 'grit' +require File.expand_path('../gollum/grit_ext', __FILE__) require 'github/markup' require 'sanitize' diff --git a/lib/gollum/blob_entry.rb b/lib/gollum/blob_entry.rb index 6ce8ac6a..d1f4fd56 100644 --- a/lib/gollum/blob_entry.rb +++ b/lib/gollum/blob_entry.rb @@ -10,10 +10,14 @@ module Gollum # Gets the Fixnum size of this blob. attr_reader :size - def initialize(sha, path, size = nil) + # Gets the Fixnum mode of this blob. + attr_reader :mode + + def initialize(sha, path, size = nil, mode = nil) @sha = sha @path = path @size = size + @mode = mode @dir = @name = @blob = nil end @@ -34,7 +38,7 @@ module Gollum # Returns an unbaked Grit::Blob instance. def blob(repo) @blob ||= Grit::Blob.create(repo, - :id => @sha, :name => name, :size => @size) + :id => @sha, :name => name, :size => @size, :mode => @mode) end # Gets a Page instance for this blob. diff --git a/lib/gollum/file.rb b/lib/gollum/file.rb index e893e9e2..6ba564a2 100644 --- a/lib/gollum/file.rb +++ b/lib/gollum/file.rb @@ -42,7 +42,14 @@ module Gollum # # Returns the String data. def raw_data - @blob && @blob.data + return nil unless @blob + + if @blob.is_symlink + new_path = @blob.symlink_target(self.path) + return IO.read(new_path) if new_path + end + + @blob.data end # Public: The Grit::Commit version of the file. diff --git a/lib/gollum/git_access.rb b/lib/gollum/git_access.rb index 333ac69a..0157f9b2 100644 --- a/lib/gollum/git_access.rb +++ b/lib/gollum/git_access.rb @@ -229,7 +229,7 @@ module Gollum # Returns an Array of BlobEntry instances. def parse_tree_line(line) mode, type, sha, size, *name = line.split(/\s+/) - BlobEntry.new(sha, name.join(' '), size.to_i) + BlobEntry.new(sha, name.join(' '), size.to_i, mode.to_i(8)) end # Decode octal sequences (\NNN) in tree path names. diff --git a/lib/gollum/grit_ext.rb b/lib/gollum/grit_ext.rb new file mode 100644 index 00000000..be77d059 --- /dev/null +++ b/lib/gollum/grit_ext.rb @@ -0,0 +1,20 @@ +# ~*~ encoding: utf-8 ~*~ + +module Grit + class Blob + def is_symlink + self.mode == 0120000 + end + + def symlink_target(base_path = nil) + target = self.data + new_path = File.expand_path(File.join('..', target), base_path) + + if File.file? new_path + return new_path + end + end + + nil + end +end diff --git a/lib/gollum/page.rb b/lib/gollum/page.rb index 2106ed42..4da58670 100644 --- a/lib/gollum/page.rb +++ b/lib/gollum/page.rb @@ -180,7 +180,14 @@ module Gollum # # Returns the String data. def raw_data - @blob && @blob.data + return nil unless @blob + + if @blob.is_symlink + new_path = @blob.symlink_target(::File.join(@wiki.repo.path, self.path)) + return IO.read(new_path) if new_path + end + + @blob.data end # Public: A text data encoded in specified encoding. diff --git a/lib/gollum/wiki.rb b/lib/gollum/wiki.rb index 7ec5c75f..967eccf9 100644 --- a/lib/gollum/wiki.rb +++ b/lib/gollum/wiki.rb @@ -276,7 +276,7 @@ module Gollum page = @page_class.new(self) ext = @page_class.format_to_ext(format.to_sym) name = @page_class.cname(name) + '.' + ext - blob = OpenStruct.new(:name => name, :data => data) + blob = OpenStruct.new(:name => name, :data => data, :is_symlink => false) page.populate(blob) page.version = @access.commit('master') page diff --git a/test/examples/lotr.git/logs/HEAD b/test/examples/lotr.git/logs/HEAD index 6290f7a5..64e98b35 100644 --- a/test/examples/lotr.git/logs/HEAD +++ b/test/examples/lotr.git/logs/HEAD @@ -7,3 +7,4 @@ b0de6e794dfdc7ef3400e894225bfe23308aae5c cfea406f5f77afc7fb673a43e97721234385b1b cfea406f5f77afc7fb673a43e97721234385b1bd 629aa678272b017a4d136d35e77ac94d80b08dc2 Darren Oakley 1341830833 +0100 push 629aa678272b017a4d136d35e77ac94d80b08dc2 7d6aeab8b84c895f21f6c66b84a457b0fced9693 Daniel Kimsey 1352501984 -0500 push 7d6aeab8b84c895f21f6c66b84a457b0fced9693 563cc3701db990caf63e4ce9c3697a062890ca48 James Dabbs 1361843315 -0500 push +563cc3701db990caf63e4ce9c3697a062890ca48 874f597a5659b4c3b153674ea04e406ff393975e Charles Pence 1363478075 -0400 push diff --git a/test/examples/lotr.git/logs/refs/heads/master b/test/examples/lotr.git/logs/refs/heads/master index 6290f7a5..64e98b35 100644 --- a/test/examples/lotr.git/logs/refs/heads/master +++ b/test/examples/lotr.git/logs/refs/heads/master @@ -7,3 +7,4 @@ b0de6e794dfdc7ef3400e894225bfe23308aae5c cfea406f5f77afc7fb673a43e97721234385b1b cfea406f5f77afc7fb673a43e97721234385b1bd 629aa678272b017a4d136d35e77ac94d80b08dc2 Darren Oakley 1341830833 +0100 push 629aa678272b017a4d136d35e77ac94d80b08dc2 7d6aeab8b84c895f21f6c66b84a457b0fced9693 Daniel Kimsey 1352501984 -0500 push 7d6aeab8b84c895f21f6c66b84a457b0fced9693 563cc3701db990caf63e4ce9c3697a062890ca48 James Dabbs 1361843315 -0500 push +563cc3701db990caf63e4ce9c3697a062890ca48 874f597a5659b4c3b153674ea04e406ff393975e Charles Pence 1363478075 -0400 push diff --git a/test/examples/lotr.git/objects/00/f27bad829ca2202dd876132c2bff7328368524 b/test/examples/lotr.git/objects/00/f27bad829ca2202dd876132c2bff7328368524 new file mode 100644 index 00000000..1c68bc2c Binary files /dev/null and b/test/examples/lotr.git/objects/00/f27bad829ca2202dd876132c2bff7328368524 differ diff --git a/test/examples/lotr.git/objects/1b/bc283463be0e1adf922349437be7c484e61e13 b/test/examples/lotr.git/objects/1b/bc283463be0e1adf922349437be7c484e61e13 new file mode 100644 index 00000000..516fb1b4 Binary files /dev/null and b/test/examples/lotr.git/objects/1b/bc283463be0e1adf922349437be7c484e61e13 differ diff --git a/test/examples/lotr.git/objects/87/4f597a5659b4c3b153674ea04e406ff393975e b/test/examples/lotr.git/objects/87/4f597a5659b4c3b153674ea04e406ff393975e new file mode 100644 index 00000000..0b9f239a --- /dev/null +++ b/test/examples/lotr.git/objects/87/4f597a5659b4c3b153674ea04e406ff393975e @@ -0,0 +1,3 @@ +x[ +0E*f$3D7}FKurx,"`rffbRFk"3bPi@6MQsj +DF}ΆRPQn[ZzY*# ;O?ΛF)G0萼!^֊?EP禁`} y;k#Q \ No newline at end of file diff --git a/test/examples/lotr.git/objects/f9/49cf9542820d2a9d62011e3085d107165a26b3 b/test/examples/lotr.git/objects/f9/49cf9542820d2a9d62011e3085d107165a26b3 new file mode 100644 index 00000000..7b10ea5c Binary files /dev/null and b/test/examples/lotr.git/objects/f9/49cf9542820d2a9d62011e3085d107165a26b3 differ diff --git a/test/examples/lotr.git/refs/heads/master b/test/examples/lotr.git/refs/heads/master index 546030a2..115b865a 100644 --- a/test/examples/lotr.git/refs/heads/master +++ b/test/examples/lotr.git/refs/heads/master @@ -1 +1 @@ -563cc3701db990caf63e4ce9c3697a062890ca48 +874f597a5659b4c3b153674ea04e406ff393975e diff --git a/test/test_committer.rb b/test/test_committer.rb index 15b11231..519eb8ac 100644 --- a/test/test_committer.rb +++ b/test/test_committer.rb @@ -50,7 +50,7 @@ context "Wiki" do end test "parents with default master ref" do - ref = '563cc3701db990caf63e4ce9c3697a062890ca48' + ref = '874f597a5659b4c3b153674ea04e406ff393975e' committer = Gollum::Committer.new(@wiki) assert_equal ref, committer.parents.first.sha end diff --git a/test/test_file.rb b/test/test_file.rb index 4c187d92..68b85a70 100644 --- a/test/test_file.rb +++ b/test/test_file.rb @@ -21,6 +21,20 @@ context "File" do assert_equal commit.author.name, file.version.author.name end + test "symbolic link" do + commit = @wiki.repo.commits.first + file = @wiki.file("Data-Two.csv") + + # Since we don't have a checkout here (bare repos in testing), these + # symbolic links won't resolve. Stub IO.read to simulate the behavior + # and make sure all is working well. + path_to_link = File.expand_path(File.join('..', '..', 'Data.csv'), __FILE__) + File.expects(:file?).with(path_to_link).returns(true) + IO.expects(:read).with(path_to_link).returns('symlink test') + + assert_equal file.raw_data, 'symlink test' + end + test "accessing tree" do assert_nil @wiki.file("Mordor") end diff --git a/test/test_git_access.rb b/test/test_git_access.rb index 6e62e663..f058745a 100644 --- a/test/test_git_access.rb +++ b/test/test_git_access.rb @@ -18,7 +18,7 @@ context "GitAccess" do assert @access.ref_map.empty? assert @access.tree_map.empty? @access.tree 'master' - assert_equal({"master"=>"563cc3701db990caf63e4ce9c3697a062890ca48"}, @access.ref_map) + assert_equal({"master"=>"874f597a5659b4c3b153674ea04e406ff393975e"}, @access.ref_map) @access.tree '1db89ebba7e2c14d93b94ff98cfa3708a4f0d4e3' map = @access.tree_map['1db89ebba7e2c14d93b94ff98cfa3708a4f0d4e3'] @@ -50,4 +50,15 @@ context "GitAccess" do test "cannot access tree from invalid ref" do assert_equal [], @access.tree('foo') end + + test "sets #mode for blob entries" do + @access.tree '60f12f4254f58801b9ee7db7bca5fa8aeefaa56b' + file = @access.tree_map['60f12f4254f58801b9ee7db7bca5fa8aeefaa56b'][0] + assert_equal 0100644, file.mode + + @access.tree '874f597a5659b4c3b153674ea04e406ff393975e' + symlink = @access.tree_map['874f597a5659b4c3b153674ea04e406ff393975e'].find { |entry| entry.name == 'Data-Two.csv' } + assert_not_nil symlink + assert_equal 0120000, symlink.mode + end end diff --git a/test/test_page.rb b/test/test_page.rb index a2cd4c6c..08b46253 100644 --- a/test/test_page.rb +++ b/test/test_page.rb @@ -34,6 +34,23 @@ context "Page" do assert_nil @wiki.page('Bilbo_Baggins') end + test "get existing page with symbolic link" do + page = @wiki.page("Hobbit") + assert_equal Gollum::Page, page.class + assert_equal 'Hobbit.md', page.path + assert_equal :markdown, page.format + + # Since we don't have a checkout here (bare repos in testing), these + # symbolic links won't resolve. Stub IO.read to simulate the behavior + # and make sure all is working well. + path_to_link = File.expand_path(File.join('..', 'examples', 'lotr.git', 'Bilbo-Baggins.md'), __FILE__) + File.expects(:file?).with(path_to_link).returns(true).at_least_once + IO.expects(:read).with(path_to_link).returns("# Bilbo Baggins\n\nBilbo Baggins").at_least_once + + assert page.raw_data =~ /^# Bilbo Baggins\n\nBilbo Baggins/ + assert page.formatted_data =~ %r{

Bilbo Baggins

\n\n

Bilbo Baggins} + end + test "get existing page where filename contains whitespace, with hypen" do assert_equal @wiki.page('Samwise Gamgee').path, @wiki.page('Samwise-Gamgee').path end diff --git a/test/test_wiki.rb b/test/test_wiki.rb index 877f7f1a..ab85d819 100644 --- a/test/test_wiki.rb +++ b/test/test_wiki.rb @@ -54,19 +54,19 @@ context "Wiki" do test "list pages" do pages = @wiki.pages assert_equal \ - ['Bilbo-Baggins.md', 'Boromir.md', 'Elrond.md', 'Eye-Of-Sauron.md', 'Home.textile', 'My-Precious.md', 'Samwise Gamgee.mediawiki'], + ['Bilbo-Baggins.md', 'Boromir.md', 'Elrond.md', 'Eye-Of-Sauron.md', 'Hobbit.md', 'Home.textile', 'My-Precious.md', 'Samwise Gamgee.mediawiki'], pages.map { |p| p.filename }.sort end test "list files" do files = @wiki.files assert_equal \ - ['Data.csv', 'Riddles.rd', 'eye.jpg', 'todo.txt'], + ['Data-Two.csv', 'Data.csv', 'Riddles.rd', 'eye.jpg', 'todo.txt'], files.map { |p| p.filename }.sort end test "counts pages" do - assert_equal 7, @wiki.size + assert_equal 8, @wiki.size end test "text_data" do