merge
This commit is contained in:
@@ -12,6 +12,7 @@ require 'gollum/ruby1.8'
|
||||
|
||||
# internal
|
||||
require 'gollum/pagination'
|
||||
require 'gollum/blob_entry'
|
||||
require 'gollum/wiki'
|
||||
require 'gollum/page'
|
||||
require 'gollum/file'
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
module Gollum
|
||||
class BlobEntry
|
||||
# Gets the String SHA for this blob.
|
||||
attr_reader :sha
|
||||
|
||||
# Gets the String full path for this blob.
|
||||
attr_reader :path
|
||||
|
||||
def initialize(sha, path)
|
||||
@sha = sha
|
||||
@path = path
|
||||
@dir = @name = @blob = nil
|
||||
end
|
||||
|
||||
# Gets the normalized directory path for this blob.
|
||||
def dir
|
||||
@dir ||= self.class.normalize_dir(::File.dirname(@path))
|
||||
end
|
||||
|
||||
# Gets the String file base name for this blob.
|
||||
def name
|
||||
@name ||= ::File.basename(@path)
|
||||
end
|
||||
|
||||
# Gets a Grit::Blob instance for this blob.
|
||||
#
|
||||
# repo - Grit::Repo instance for the Grit::Blob.
|
||||
#
|
||||
# Returns an unbaked Grit::Blob instance.
|
||||
def blob(repo)
|
||||
@blob ||= Grit::Blob.create(repo, :id => @sha, :name => @name)
|
||||
end
|
||||
|
||||
# Gets a Page instance for this blob.
|
||||
#
|
||||
# wiki - Gollum::Wiki instance for the Gollum::Page
|
||||
#
|
||||
# Returns a Gollum::Page instance.
|
||||
def page(wiki, commit)
|
||||
blob = self.blob(wiki.repo)
|
||||
page = wiki.page_class.new(wiki).populate(blob, self.dir)
|
||||
page.version = commit
|
||||
page
|
||||
end
|
||||
|
||||
def inspect
|
||||
%(#<Gollum::BlobEntry #{@sha} #{@path}>)
|
||||
end
|
||||
|
||||
# Normalizes a given directory name for searching through tree paths.
|
||||
# Ensures that a directory begins with a slash, or
|
||||
#
|
||||
# normalize_dir("") # => ""
|
||||
# normalize_dir(".") # => ""
|
||||
# normalize_dir("foo") # => "/foo"
|
||||
# normalize_dir("/foo/") # => "/foo"
|
||||
# normalize_dir("/") # => ""
|
||||
#
|
||||
# dir - String directory name.
|
||||
#
|
||||
# Returns a normalized String directory name, or nil if no directory
|
||||
# is given.
|
||||
def self.normalize_dir(dir)
|
||||
if dir
|
||||
dir = ::File.expand_path(dir, '/')
|
||||
dir = '' if dir == '/'
|
||||
end
|
||||
dir
|
||||
end
|
||||
end
|
||||
end
|
||||
+13
-7
@@ -33,6 +33,11 @@ module Gollum
|
||||
# Public: The String path of the file.
|
||||
attr_reader :path
|
||||
|
||||
# Public: The String mime type of the file.
|
||||
def mime_type
|
||||
@blob.mime_type
|
||||
end
|
||||
|
||||
#########################################################################
|
||||
#
|
||||
# Internal Methods
|
||||
@@ -46,13 +51,14 @@ module Gollum
|
||||
#
|
||||
# Returns a Gollum::File or nil if the file could not be found.
|
||||
def find(name, version)
|
||||
if commit = @wiki.repo.commit(version)
|
||||
if (blob = commit.tree / name) && blob.is_a?(Grit::Blob)
|
||||
@blob = blob
|
||||
@path = name
|
||||
@version = commit
|
||||
self
|
||||
end
|
||||
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)
|
||||
self
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
+22
-21
@@ -1,3 +1,4 @@
|
||||
require 'cgi'
|
||||
require 'sinatra'
|
||||
require 'gollum'
|
||||
require 'mustache/sinatra'
|
||||
@@ -12,6 +13,7 @@ module Precious
|
||||
dir = File.dirname(File.expand_path(__FILE__))
|
||||
|
||||
# We want to serve public assets for now
|
||||
|
||||
set :public, "#{dir}/public"
|
||||
set :static, true
|
||||
|
||||
@@ -38,9 +40,9 @@ module Precious
|
||||
show_page_or_file('Home')
|
||||
end
|
||||
|
||||
get '/edit/:name' do
|
||||
@name = params[:name]
|
||||
wiki = Gollum::Wiki.new($path)
|
||||
get '/edit/*' do
|
||||
@name = params[:splat].first
|
||||
wiki = Gollum::Wiki.new(settings.gollum_path)
|
||||
if page = wiki.page(@name)
|
||||
@page = page
|
||||
@content = page.raw_data
|
||||
@@ -50,27 +52,27 @@ module Precious
|
||||
end
|
||||
end
|
||||
|
||||
post '/edit/:name' do
|
||||
name = params[:name]
|
||||
wiki = Gollum::Wiki.new($path)
|
||||
post '/edit/*' do
|
||||
name = params[:splat].first
|
||||
wiki = Gollum::Wiki.new(settings.gollum_path)
|
||||
page = wiki.page(name)
|
||||
format = params[:format].intern
|
||||
name = params[:rename] if params[:rename]
|
||||
|
||||
wiki.update_page(page, name, format, params[:content], commit_message)
|
||||
|
||||
redirect "/#{Gollum::Page.cname name}"
|
||||
redirect "/#{CGI.escape(Gollum::Page.cname(name))}"
|
||||
end
|
||||
|
||||
post '/create/:name' do
|
||||
post '/create/*' do
|
||||
name = params[:page]
|
||||
wiki = Gollum::Wiki.new($path)
|
||||
wiki = Gollum::Wiki.new(settings.gollum_path)
|
||||
|
||||
format = params[:format].intern
|
||||
|
||||
begin
|
||||
wiki.write_page(name, format, params[:content], commit_message)
|
||||
redirect "/#{name}"
|
||||
redirect "/#{CGI.escape(name)}"
|
||||
rescue Gollum::DuplicatePageError => e
|
||||
@message = "Duplicate page: #{e.message}"
|
||||
mustache :error
|
||||
@@ -80,13 +82,13 @@ module Precious
|
||||
post '/preview' do
|
||||
format = params['wiki_format']
|
||||
data = params['text']
|
||||
wiki = Gollum::Wiki.new($path)
|
||||
wiki = Gollum::Wiki.new(settings.gollum_path)
|
||||
wiki.preview_page("Preview", data, format).formatted_data
|
||||
end
|
||||
|
||||
get '/history/:name' do
|
||||
@name = params[:name]
|
||||
wiki = Gollum::Wiki.new($path)
|
||||
wiki = Gollum::Wiki.new(settings.gollum_path)
|
||||
@page = wiki.page(@name)
|
||||
@page_num = [params[:page].to_i, 1].max
|
||||
@versions = @page.versions :page => @page_num
|
||||
@@ -96,10 +98,10 @@ module Precious
|
||||
post '/compare/:name' do
|
||||
@versions = params[:versions] || []
|
||||
if @versions.size < 2
|
||||
redirect "/history/#{params[:name]}"
|
||||
redirect "/history/#{CGI.escape(params[:name])}"
|
||||
else
|
||||
redirect "/compare/%s/%s...%s" % [
|
||||
params[:name],
|
||||
CGI.escape(params[:name]),
|
||||
@versions.last,
|
||||
@versions.first]
|
||||
end
|
||||
@@ -108,7 +110,7 @@ module Precious
|
||||
get '/compare/:name/:version_list' do
|
||||
@name = params[:name]
|
||||
@versions = params[:version_list].split(/\.{2,3}/)
|
||||
wiki = Gollum::Wiki.new($path)
|
||||
wiki = Gollum::Wiki.new(settings.gollum_path)
|
||||
@page = wiki.page(@name)
|
||||
diffs = wiki.repo.diff(@versions.first, @versions.last, @page.path)
|
||||
@diff = diffs.first
|
||||
@@ -117,7 +119,7 @@ module Precious
|
||||
|
||||
get %r{/(.+?)/([0-9a-f]{40})} do
|
||||
name = params[:captures][0]
|
||||
wiki = Gollum::Wiki.new($path)
|
||||
wiki = Gollum::Wiki.new(settings.gollum_path)
|
||||
if page = wiki.page(name, params[:captures][1])
|
||||
@page = page
|
||||
@name = name
|
||||
@@ -130,7 +132,7 @@ module Precious
|
||||
|
||||
get '/search' do
|
||||
@query = params[:q]
|
||||
wiki = Gollum::Wiki.new($path)
|
||||
wiki = Gollum::Wiki.new(settings.gollum_path)
|
||||
@results = wiki.search @query
|
||||
mustache :search
|
||||
end
|
||||
@@ -140,13 +142,14 @@ module Precious
|
||||
end
|
||||
|
||||
def show_page_or_file(name)
|
||||
wiki = Gollum::Wiki.new($path)
|
||||
wiki = Gollum::Wiki.new(settings.gollum_path)
|
||||
if page = wiki.page(name)
|
||||
@page = page
|
||||
@name = name
|
||||
@content = page.formatted_data
|
||||
mustache :page
|
||||
elsif file = wiki.file(name)
|
||||
content_type file.mime_type
|
||||
file.raw_data
|
||||
else
|
||||
@name = name
|
||||
@@ -155,9 +158,7 @@ module Precious
|
||||
end
|
||||
|
||||
def commit_message
|
||||
{ :message => params[:message],
|
||||
:name => `git config --get user.name `.strip,
|
||||
:email => `git config --get user.email`.strip }
|
||||
{ :message => params[:message] }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="guide">
|
||||
<div class="main">
|
||||
<div class="actions">
|
||||
<a href="/{{name}}">« Back</a>
|
||||
<a href="/{{escaped_name}}">« Back</a>
|
||||
</div>
|
||||
<h1>{{title}}: {{before}} → {{after}}</h1>
|
||||
<div id="files">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<a href="/">« Home</a>
|
||||
<h1>{{title}}</h1>
|
||||
|
||||
<form class="new_wiki" method="post" action="/create/{{name}}">
|
||||
<form class="new_wiki" method="post" action="/create/{{escaped_name}}">
|
||||
<div>
|
||||
<label>
|
||||
Title<br />
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<div class="write">
|
||||
<a href="/{{name}}">« Back</a>
|
||||
<a href="/{{escaped_name}}">« Back</a>
|
||||
<h1>{{title}}</h1>
|
||||
|
||||
<form class="edit_wiki" method="post" action="/edit/{{name}}">
|
||||
<form class="edit_wiki" method="post" action="/edit/{{escaped_name}}">
|
||||
<div>
|
||||
<label>
|
||||
Title<br />
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<div class="guide">
|
||||
<div class="main">
|
||||
<div class="actions">
|
||||
<a href="/{{name}}">« Back</a>
|
||||
<a href="/{{escaped_name}}">« Back</a>
|
||||
</div>
|
||||
<h1>{{title}}</h1>
|
||||
<form id="history" method="post" action="/compare/{{name}}">
|
||||
<form id="history" method="post" action="/compare/{{escaped_name}}">
|
||||
<table class="commits" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<th colspan="5">
|
||||
@@ -17,7 +17,7 @@
|
||||
<input name="versions[]" type="checkbox" value="{{id}}" />
|
||||
</td>
|
||||
<td class="sha">
|
||||
<a href="/{{name}}/{{id}}">{{id7}}</a>
|
||||
<a href="/{{escaped_name}}/{{id}}">{{id7}}</a>
|
||||
</td>
|
||||
<td nowrap class="author">
|
||||
<img src="http://www.gravatar.com/avatar/{{gravatar}}?s=16" alt="Gravatar" />
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
<div class="main">
|
||||
<div class="actions">
|
||||
<form action="/search" method="get">
|
||||
<a href="/">Home</a> | <a href="/edit/{{name}}">Edit</a> | <input type="search" name="q" size="10" /> <input type="submit" value="search" />
|
||||
<div>
|
||||
<a href="/">Home</a> |
|
||||
<a href="/edit/{{escaped_name}}">Edit</a> |
|
||||
<input type="search" name="q" size="10" /> <input type="submit" value="search" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<h1>{{title}}</h1>
|
||||
@@ -20,10 +24,10 @@
|
||||
<div style="float: left;">
|
||||
<small>Last edited by <b>{{author}}</b>, {{date}}</small>
|
||||
<div class="actions">
|
||||
<a href="/">Home</a> | <a href="/edit/{{name}}">Edit</a>
|
||||
<a href="/">Home</a> | <a href="/edit/{{escaped_name}}">Edit</a>
|
||||
</div>
|
||||
</div>
|
||||
<div style="float: right;">
|
||||
<a href="/history/{{name}}">View Revision History</a>
|
||||
<a href="/history/{{escaped_name}}">View Revision History</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
require 'cgi'
|
||||
|
||||
module Precious
|
||||
module Views
|
||||
class Layout < Mustache
|
||||
@@ -6,6 +8,10 @@ module Precious
|
||||
|
||||
attr_reader :name
|
||||
|
||||
def escaped_name
|
||||
CGI.escape(@name)
|
||||
end
|
||||
|
||||
def title
|
||||
"Home"
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
require 'digest/sha1'
|
||||
require 'cgi'
|
||||
|
||||
module Gollum
|
||||
class Markup
|
||||
@@ -267,10 +268,10 @@ module Gollum
|
||||
%{<a href="#{name}">#{name}</a>}
|
||||
else
|
||||
if page = @wiki.page(cname)
|
||||
link = ::File.join(@wiki.base_path, Page.cname(page.name))
|
||||
link = ::File.join(@wiki.base_path, CGI.escape(Page.cname(page.name)))
|
||||
presence = "present"
|
||||
else
|
||||
link = ::File.join(@wiki.base_path, cname)
|
||||
link = ::File.join(@wiki.base_path, CGI.escape(cname))
|
||||
presence = "absent"
|
||||
end
|
||||
%{<a class="internal #{presence}" href="#{link}">#{name}</a>}
|
||||
|
||||
+25
-55
@@ -182,20 +182,15 @@ module Gollum
|
||||
|
||||
dirs = self.path.split('/')
|
||||
dirs.pop
|
||||
map = @wiki.tree_map_for(self.version.id)
|
||||
while !dirs.empty?
|
||||
tree = self.version.tree / dirs.join('/')
|
||||
if page = find_page_in_this_tree(tree, dirs.join('/'), '_Footer')
|
||||
if page = find_page_in_tree(map, '_Footer', dirs.join('/'))
|
||||
return page
|
||||
end
|
||||
dirs.pop
|
||||
end
|
||||
|
||||
tree = self.version.tree
|
||||
if page = find_page_in_this_tree(tree, '', '_Footer')
|
||||
return page
|
||||
end
|
||||
|
||||
return nil
|
||||
find_page_in_tree(map, '_Footer', '')
|
||||
end
|
||||
|
||||
#########################################################################
|
||||
@@ -215,7 +210,9 @@ module Gollum
|
||||
#
|
||||
# Returns the String canonical name.
|
||||
def self.cname(name)
|
||||
name.gsub(%r{[ /<>]}, '-')
|
||||
name.respond_to?(:gsub) ?
|
||||
name.gsub(%r{[ /<>]}, '-') :
|
||||
''
|
||||
end
|
||||
|
||||
# Convert a format Symbol into an extension String.
|
||||
@@ -259,61 +256,34 @@ module Gollum
|
||||
#
|
||||
# Returns a Gollum::Page or nil if the page could not be found.
|
||||
def find(name, version)
|
||||
if commit = @wiki.repo.commit(version)
|
||||
if page = find_page_in_tree(commit.tree, name)
|
||||
page.version = commit
|
||||
page
|
||||
end
|
||||
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
|
||||
end
|
||||
rescue Grit::GitRuby::Repository::NoSuchShaFound
|
||||
end
|
||||
|
||||
# Find a page in a given tree.
|
||||
#
|
||||
# tree - The Grit::Tree in which to look.
|
||||
# name - The canonical String page name.
|
||||
# map - The Array tree map from Wiki#tree_map.
|
||||
# name - The canonical String page name.
|
||||
# checked_dir - Optional String of the directory a matching page needs
|
||||
# to be in. The string should
|
||||
#
|
||||
# Returns a Gollum::Page or nil if the page could not be found.
|
||||
def find_page_in_tree(tree, name)
|
||||
treemap = {}
|
||||
trees = [tree]
|
||||
|
||||
while !trees.empty?
|
||||
ptree = trees.shift
|
||||
ptree.contents.each do |item|
|
||||
case item
|
||||
when Grit::Blob
|
||||
if page_match(name, item.name)
|
||||
return self.class.new(@wiki).populate(item, tree_path(treemap, ptree))
|
||||
end
|
||||
when Grit::Tree
|
||||
treemap[item] = ptree
|
||||
trees << item
|
||||
end
|
||||
end
|
||||
def find_page_in_tree(map, name, checked_dir = nil)
|
||||
return nil if name.to_s.empty?
|
||||
if checked_dir = BlobEntry.normalize_dir(checked_dir)
|
||||
checked_dir.downcase!
|
||||
end
|
||||
|
||||
return nil # nothing was found
|
||||
end
|
||||
|
||||
# Find a page in a given tree without recursing into subtrees.
|
||||
#
|
||||
# tree - The Grit::Tree in which to look.
|
||||
# dir - The String path of the given Grit::Tree.
|
||||
# name - The canonical String page name.
|
||||
#
|
||||
# Returns a Gollum::Page or nil if the page could not be found.
|
||||
def find_page_in_this_tree(tree, dir, name)
|
||||
treemap = {}
|
||||
tree.contents.each do |item|
|
||||
case item
|
||||
when Grit::Blob
|
||||
if page_match(name, item.name)
|
||||
path = dir == '' ? '' : ::File.join('/', dir)
|
||||
page = self.class.new(@wiki).populate(item, path)
|
||||
page.version = self.version
|
||||
return page
|
||||
end
|
||||
end
|
||||
map.each do |entry|
|
||||
next if entry.name.to_s.empty?
|
||||
next unless checked_dir.nil? || entry.dir.downcase == checked_dir
|
||||
next unless page_match(name, entry.name)
|
||||
return entry.page(@wiki, @version)
|
||||
end
|
||||
|
||||
return nil # nothing was found
|
||||
|
||||
+214
-38
@@ -63,6 +63,7 @@ module Gollum
|
||||
@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
|
||||
end
|
||||
|
||||
# Public: check whether the wiki's git repo exists on the filesystem.
|
||||
@@ -134,7 +135,12 @@ module Gollum
|
||||
|
||||
parents = pcommit ? [pcommit] : []
|
||||
actor = Grit::Actor.new(commit[:name], commit[:email])
|
||||
index.commit(commit[:message], parents, actor)
|
||||
sha1 = index.commit(commit[:message], parents, actor)
|
||||
|
||||
@ref_map.clear
|
||||
update_working_dir(index, '', name, format)
|
||||
|
||||
sha1
|
||||
end
|
||||
|
||||
# Public: Update an existing page with new content. The location of the
|
||||
@@ -159,19 +165,26 @@ module Gollum
|
||||
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])
|
||||
index.commit(commit[:message], [pcommit], actor)
|
||||
sha1 = index.commit(commit[:message], [pcommit], actor)
|
||||
|
||||
@ref_map.clear
|
||||
update_working_dir(index, dir, page.name, page.format)
|
||||
update_working_dir(index, dir, name, format)
|
||||
|
||||
sha1
|
||||
end
|
||||
|
||||
# Public: Delete a page.
|
||||
@@ -190,8 +203,16 @@ module Gollum
|
||||
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])
|
||||
index.commit(commit[:message], [pcommit], actor)
|
||||
sha1 = index.commit(commit[:message], [pcommit], actor)
|
||||
|
||||
@ref_map.clear
|
||||
update_working_dir(index, dir, page.name, page.format)
|
||||
|
||||
sha1
|
||||
end
|
||||
|
||||
# Public: Lists all pages for this wiki.
|
||||
@@ -200,11 +221,19 @@ module Gollum
|
||||
#
|
||||
# Returns an Array of Gollum::Page instances.
|
||||
def pages(treeish = nil)
|
||||
treeish ||= 'master'
|
||||
if commit = @repo.commit(treeish)
|
||||
tree_list(commit)
|
||||
else
|
||||
[]
|
||||
tree_list(treeish || 'master').sort! do |x, y|
|
||||
x.title.downcase <=> y.title.downcase
|
||||
end
|
||||
end
|
||||
|
||||
# Public: Returns the number of pages accessible from a commit
|
||||
#
|
||||
# ref - A String ref that is either a commit SHA or references one.
|
||||
#
|
||||
# Returns a Fixnum
|
||||
def size(ref = nil)
|
||||
tree_map_for(ref || 'master').inject(0) do |num, entry|
|
||||
num + (@page_class.valid_page_name?(entry.name) ? 1 : 0)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -255,6 +284,26 @@ 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
|
||||
|
||||
# Gets the file class used by all instances of this Wiki.
|
||||
attr_reader :file_class
|
||||
|
||||
# Normalize the data.
|
||||
#
|
||||
# data - The String data to be normalized.
|
||||
@@ -264,33 +313,84 @@ module Gollum
|
||||
data.gsub(/\r/, '')
|
||||
end
|
||||
|
||||
# Fill an array with a list of pages.
|
||||
# Assemble a Page's filename from its name and format.
|
||||
#
|
||||
# commit - The Grit::Commit
|
||||
# tree - The Grit::Tree to start with.
|
||||
# sub_tree - Optional String specifying the parent path of the Page.
|
||||
# name - The String name of the page (may be in human format).
|
||||
# format - The Symbol format of the page.
|
||||
#
|
||||
# Returns a flat Array of Gollum::Page instances.
|
||||
def tree_list(commit, tree = commit.tree, sub_tree = nil)
|
||||
list = []
|
||||
path = tree.name ? "#{sub_tree}/#{tree.name}" : ''
|
||||
tree.contents.each do |item|
|
||||
case item
|
||||
when Grit::Blob
|
||||
if @page_class.valid_page_name?(item.name)
|
||||
page = @page_class.new(self).populate(item, path)
|
||||
page.version = commit
|
||||
list << page
|
||||
end
|
||||
when Grit::Tree
|
||||
list.push *tree_list(commit, item, path)
|
||||
end
|
||||
end
|
||||
list
|
||||
# Returns the String filename.
|
||||
def page_file_name(name, format)
|
||||
ext = @page_class.format_to_ext(format)
|
||||
@page_class.cname(name) + '.' + ext
|
||||
end
|
||||
|
||||
# Determine if a given page path is scheduled to be deleted in the next
|
||||
# commit for the given Index.
|
||||
# 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.
|
||||
#
|
||||
# ref - A String ref that is either a commit SHA or references one.
|
||||
#
|
||||
# Returns a flat Array of Gollum::Page instances.
|
||||
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))
|
||||
end
|
||||
end
|
||||
|
||||
# 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.
|
||||
@@ -310,7 +410,7 @@ module Gollum
|
||||
if rest = map[part]
|
||||
page_path_scheduled_for_deletion?(rest, parts.join('/'))
|
||||
else
|
||||
nil
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -331,8 +431,7 @@ module Gollum
|
||||
#
|
||||
# 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?
|
||||
|
||||
@@ -364,9 +463,86 @@ module Gollum
|
||||
#
|
||||
# Returns the commit Hash
|
||||
def normalize_commit(commit = {})
|
||||
commit[:name] = self.class.default_committer_name if commit[:name].to_s.empty?
|
||||
commit[:email] = self.class.default_committer_email if commit[:email].to_s.empty?
|
||||
commit[:name] = default_committer_name if commit[:name].to_s.empty?
|
||||
commit[:email] = default_committer_email if commit[:email].to_s.empty?
|
||||
commit
|
||||
end
|
||||
|
||||
# Gets the default name for commits.
|
||||
def default_committer_name
|
||||
@default_committer_name ||= \
|
||||
@repo.config['user.name'] || self.class.default_committer_name
|
||||
end
|
||||
|
||||
# Gets the default email for commits.
|
||||
def default_committer_email
|
||||
@default_committer_email ||= \
|
||||
@repo.config['user.email'] || self.class.default_committer_email
|
||||
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.
|
||||
#
|
||||
# ref - A String ref that is either a commit SHA or references one.
|
||||
#
|
||||
# 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
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user