Skip to content
This repository has been archived by the owner on Apr 19, 2019. It is now read-only.

Commit

Permalink
Update working dir (if present) when edited via the API. Closes gollum#6
Browse files Browse the repository at this point in the history
.
  • Loading branch information
mojombo committed Aug 30, 2010
1 parent 0500c7e commit 94f05b0
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 15 deletions.
1 change: 1 addition & 0 deletions HISTORY.md
Expand Up @@ -4,6 +4,7 @@
* Optimize page write/update/delete to use Grit::Index::read_tree instead
of manually recreating entire index contents.
* Added --irb option for the gollum command.
* Update working dir (if present) when edited via the API (#6)
* Minor Enhancements
* Support a `:gollum_path` Sinatra setting for `Precious::App`
* Bug Fixes
Expand Down
2 changes: 1 addition & 1 deletion gollum.gemspec
Expand Up @@ -23,7 +23,7 @@ Gem::Specification.new do |s|
s.rdoc_options = ["--charset=UTF-8"]
s.extra_rdoc_files = %w[README.md LICENSE]

s.add_dependency('grit', "~> 2.2")
s.add_dependency('grit', "~> 2.3")
s.add_dependency('github-markup', [">= 0.4.0", "< 1.0.0"])
s.add_dependency('albino', "~> 1.0")
s.add_dependency('sinatra', "~> 1.0")
Expand Down
102 changes: 89 additions & 13 deletions lib/gollum/wiki.rb
Expand Up @@ -135,9 +135,12 @@ def write_page(name, format, data, commit = {})

parents = pcommit ? [pcommit] : []
actor = Grit::Actor.new(commit[:name], commit[:email])
sha = index.commit(commit[:message], parents, actor)
sha1 = index.commit(commit[:message], parents, actor)

@ref_map.clear
sha
update_working_dir(index, '', name, format)

sha1
end

# Public: Update an existing page with new content. The location of the
Expand All @@ -162,21 +165,26 @@ def update_page(page, name, format, data, commit = {})
format ||= page.format
index = self.repo.index

dir = ::File.dirname(page.path)
dir = '' if dir == '.'

index.read_tree(pcommit.tree.id)

if page.name == name && page.format == format
index.add(page.path, normalize(data))
else
index.delete(page.path)
dir = ::File.dirname(page.path)
dir = '' if dir == '.'
add_to_index(index, dir, name, format, data, :allow_same_ext)
end

actor = Grit::Actor.new(commit[:name], commit[:email])
sha = index.commit(commit[:message], [pcommit], actor)
sha1 = index.commit(commit[:message], [pcommit], actor)

@ref_map.clear
sha
update_working_dir(index, dir, page.name, page.format)
update_working_dir(index, dir, name, format)

sha1
end

# Public: Delete a page.
Expand All @@ -195,10 +203,16 @@ def delete_page(page, commit)
index.read_tree(pcommit.tree.id)
index.delete(page.path)

dir = ::File.dirname(page.path)
dir = '' if dir == '.'

actor = Grit::Actor.new(commit[:name], commit[:email])
sha = index.commit(commit[:message], [pcommit], actor)
sha1 = index.commit(commit[:message], [pcommit], actor)

@ref_map.clear
sha
update_working_dir(index, dir, page.name, page.format)

sha1
end

# Public: Lists all pages for this wiki.
Expand Down Expand Up @@ -265,6 +279,45 @@ def normalize(data)
data.gsub(/\r/, '')
end

# Assemble a Page's filename from its name and format.
#
# name - The String name of the page (may be in human format).
# format - The Symbol format of the page.
#
# Returns the String filename.
def page_file_name(name, format)
ext = @page_class.format_to_ext(format)
@page_class.cname(name) + '.' + ext
end

# Update the given file in the repository's working directory if there
# is a working directory present.
#
# index - The Grit::Index with which to sync.
# dir - The String directory in which the file lives.
# name - The String name of the page (may be in human format).
# format - The Symbol format of the page.
#
# Returns nothing.
def update_working_dir(index, dir, name, format)
unless @repo.bare
path =
if dir == ''
page_file_name(name, format)
else
::File.join(dir, page_file_name(name, format))
end

Dir.chdir(::File.join(@repo.path, '..')) do
if file_path_scheduled_for_deletion?(index.tree, path)
@repo.git.rm({'f' => true}, '--', path)
else
@repo.git.checkout({}, 'HEAD', '--', path)
end
end
end
end

# Fill an array with a list of pages.
#
# commit - The Grit::Commit
Expand All @@ -290,8 +343,32 @@ def tree_list(commit, tree = commit.tree, sub_tree = nil)
list
end

# Determine if a given page path is scheduled to be deleted in the next
# commit for the given Index.
# Determine if a given file is scheduled to be deleted in the next commit
# for the given Index.
#
# map - The Hash map:
# key - The String directory or filename.
# val - The Hash submap or the String contents of the file.
# path - The String path of the file including extension.
#
# Returns the Boolean response.
def file_path_scheduled_for_deletion?(map, path)
parts = path.split('/')
if parts.size == 1
deletions = map.keys.select { |k| !map[k] }
deletions.any? { |d| d == parts.first }
else
part = parts.shift
if rest = map[part]
file_path_scheduled_for_deletion?(rest, parts.join('/'))
else
false
end
end
end

# Determine if a given page (regardless of format) is scheduled to be
# deleted in the next commit for the given Index.
#
# map - The Hash map:
# key - The String directory or filename.
Expand All @@ -311,7 +388,7 @@ def page_path_scheduled_for_deletion?(map, path)
if rest = map[part]
page_path_scheduled_for_deletion?(rest, parts.join('/'))
else
nil
false
end
end
end
Expand All @@ -332,8 +409,7 @@ def page_path_scheduled_for_deletion?(map, path)
#
# Returns nothing (modifies the Index in place).
def add_to_index(index, dir, name, format, data, allow_same_ext = false)
ext = @page_class.format_to_ext(format)
path = @page_class.cname(name) + '.' + ext
path = page_file_name(name, format)

dir = '/' if dir.strip.empty?

Expand Down
6 changes: 6 additions & 0 deletions test/helper.rb
Expand Up @@ -18,6 +18,12 @@ def testpath(path)
File.join(TEST_DIR, path)
end

def commit_details
{ :message => "Did something at #{Time.now}",
:name => "Tom Preston-Werner",
:email => "tom@github.com" }
end

# test/spec/mini 3
# http://gist.github.com/25455
# chris@ozmm.org
Expand Down
57 changes: 56 additions & 1 deletion test/test_wiki.rb
Expand Up @@ -238,4 +238,59 @@
teardown do
FileUtils.rm_r(File.join(File.dirname(__FILE__), *%w[examples test.git]))
end
end
end

context "Wiki sync with working directory" do
setup do
@path = testpath('examples/wdtest')
Grit::Repo.init(@path)
@wiki = Gollum::Wiki.new(@path)
end

test "write a page" do
@wiki.write_page("New Page", :markdown, "Hi", commit_details)
assert_equal "Hi", File.read(File.join(@path, "New-Page.md"))
end

test "update a page with same name and format" do
@wiki.write_page("New Page", :markdown, "Hi", commit_details)
page = @wiki.page("New Page")
@wiki.update_page(page, page.name, page.format, "Bye", commit_details)
assert_equal "Bye", File.read(File.join(@path, "New-Page.md"))
end

test "update a page with different name and same format" do
@wiki.write_page("New Page", :markdown, "Hi", commit_details)
page = @wiki.page("New Page")
@wiki.update_page(page, "New Page 2", page.format, "Bye", commit_details)
assert_equal "Bye", File.read(File.join(@path, "New-Page-2.md"))
assert !File.exist?(File.join(@path, "New-Page.md"))
end

test "update a page with same name and different format" do
@wiki.write_page("New Page", :markdown, "Hi", commit_details)
page = @wiki.page("New Page")
@wiki.update_page(page, page.name, :textile, "Bye", commit_details)
assert_equal "Bye", File.read(File.join(@path, "New-Page.textile"))
assert !File.exist?(File.join(@path, "New-Page.md"))
end

test "update a page with different name and different format" do
@wiki.write_page("New Page", :markdown, "Hi", commit_details)
page = @wiki.page("New Page")
@wiki.update_page(page, "New Page 2", :textile, "Bye", commit_details)
assert_equal "Bye", File.read(File.join(@path, "New-Page-2.textile"))
assert !File.exist?(File.join(@path, "New-Page.md"))
end

test "delete a page" do
@wiki.write_page("New Page", :markdown, "Hi", commit_details)
page = @wiki.page("New Page")
@wiki.delete_page(page, commit_details)
assert !File.exist?(File.join(@path, "New-Page.md"))
end

teardown do
FileUtils.rm_r(@path)
end
end

0 comments on commit 94f05b0

Please sign in to comment.