Merge branch 'use_gollum_wikis' of https://github.com/DanKnox/gitlabhq into DanKnox-use_gollum_wikis
Conflicts: app/views/layouts/project_resource.html.haml app/views/wikis/edit.html.haml app/views/wikis/pages.html.haml app/views/wikis/show.html.haml spec/features/gitlab_flavored_markdown_spec.rb
This commit is contained in:
commit
71ab011a17
30 changed files with 1252 additions and 86 deletions
118
app/models/gollum_wiki.rb
Normal file
118
app/models/gollum_wiki.rb
Normal file
|
@ -0,0 +1,118 @@
|
|||
class GollumWiki
|
||||
|
||||
MARKUPS = {
|
||||
"Markdown" => :markdown,
|
||||
"RDoc" => :rdoc
|
||||
}
|
||||
|
||||
class CouldNotCreateWikiError < StandardError; end
|
||||
|
||||
# Returns a string describing what went wrong after
|
||||
# an operation fails.
|
||||
attr_reader :error_message
|
||||
|
||||
def initialize(project, user = nil)
|
||||
@project = project
|
||||
@user = user
|
||||
end
|
||||
|
||||
def path_with_namespace
|
||||
@project.path_with_namespace + ".wiki"
|
||||
end
|
||||
|
||||
def url_to_repo
|
||||
gitlab_shell.url_to_repo(path_with_namespace)
|
||||
end
|
||||
|
||||
def ssh_url_to_repo
|
||||
url_to_repo
|
||||
end
|
||||
|
||||
def http_url_to_repo
|
||||
http_url = [Gitlab.config.gitlab.url, "/", path_with_namespace, ".git"].join('')
|
||||
end
|
||||
|
||||
# Returns the Gollum::Wiki object.
|
||||
def wiki
|
||||
@wiki ||= begin
|
||||
Gollum::Wiki.new(path_to_repo)
|
||||
rescue Grit::NoSuchPathError
|
||||
create_repo!
|
||||
end
|
||||
end
|
||||
|
||||
# Returns an Array of Gitlab WikiPage instances or an
|
||||
# empty Array if this Wiki has no pages.
|
||||
def pages
|
||||
wiki.pages.map { |page| WikiPage.new(self, page, true) }
|
||||
end
|
||||
|
||||
# Returns the last 30 Commit objects accross the entire
|
||||
# repository.
|
||||
def recent_history
|
||||
Commit.fresh_commits(wiki.repo, 30)
|
||||
end
|
||||
|
||||
# Finds a page within the repository based on a tile
|
||||
# or slug.
|
||||
#
|
||||
# title - The human readable or parameterized title of
|
||||
# the page.
|
||||
#
|
||||
# Returns an initialized WikiPage instance or nil
|
||||
def find_page(title, version = nil)
|
||||
if page = wiki.page(title, version)
|
||||
WikiPage.new(self, page, true)
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def create_page(title, content, format = :markdown, message = nil)
|
||||
commit = commit_details(:created, message, title)
|
||||
|
||||
wiki.write_page(title, format, content, commit)
|
||||
rescue Gollum::DuplicatePageError => e
|
||||
@error_message = "Duplicate page: #{e.message}"
|
||||
return false
|
||||
end
|
||||
|
||||
def update_page(page, content, format = :markdown, message = nil)
|
||||
commit = commit_details(:updated, message, page.title)
|
||||
|
||||
wiki.update_page(page, page.name, format, content, commit)
|
||||
end
|
||||
|
||||
def delete_page(page, message = nil)
|
||||
wiki.delete_page(page, commit_details(:deleted, message, page.title))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def create_repo!
|
||||
if gitlab_shell.add_repository(path_with_namespace)
|
||||
Gollum::Wiki.new(path_to_repo)
|
||||
else
|
||||
raise CouldNotCreateWikiError
|
||||
end
|
||||
end
|
||||
|
||||
def commit_details(action, message = nil, title = nil)
|
||||
commit_message = message || default_message(action, title)
|
||||
|
||||
{email: @user.email, name: @user.name, message: commit_message}
|
||||
end
|
||||
|
||||
def default_message(action, title)
|
||||
"#{@user.username} #{action} page: #{title}"
|
||||
end
|
||||
|
||||
def gitlab_shell
|
||||
@gitlab_shell ||= Gitlab::Shell.new
|
||||
end
|
||||
|
||||
def path_to_repo
|
||||
@path_to_repo ||= File.join(Gitlab.config.gitlab_shell.repos_path, "#{path_with_namespace}.git")
|
||||
end
|
||||
|
||||
end
|
181
app/models/wiki_page.rb
Normal file
181
app/models/wiki_page.rb
Normal file
|
@ -0,0 +1,181 @@
|
|||
class WikiPage
|
||||
include ActiveModel::Validations
|
||||
include ActiveModel::Conversion
|
||||
include StaticModel
|
||||
extend ActiveModel::Naming
|
||||
|
||||
def self.primary_key
|
||||
'slug'
|
||||
end
|
||||
|
||||
def self.model_name
|
||||
ActiveModel::Name.new(self, nil, 'wiki')
|
||||
end
|
||||
|
||||
def to_key
|
||||
[:slug]
|
||||
end
|
||||
|
||||
validates :title, presence: true
|
||||
validates :content, presence: true
|
||||
|
||||
# The Gitlab GollumWiki instance.
|
||||
attr_reader :wiki
|
||||
|
||||
# The raw Gollum::Page instance.
|
||||
attr_reader :page
|
||||
|
||||
# The attributes Hash used for storing and validating
|
||||
# new Page values before writing to the Gollum repository.
|
||||
attr_accessor :attributes
|
||||
|
||||
def initialize(wiki, page = nil, persisted = false)
|
||||
@wiki = wiki
|
||||
@page = page
|
||||
@persisted = persisted
|
||||
@attributes = {}.with_indifferent_access
|
||||
|
||||
set_attributes if persisted?
|
||||
end
|
||||
|
||||
# The escaped URL path of this page.
|
||||
def slug
|
||||
@attributes[:slug]
|
||||
end
|
||||
|
||||
alias :to_param :slug
|
||||
|
||||
# The formatted title of this page.
|
||||
def title
|
||||
@attributes[:title] || ""
|
||||
end
|
||||
|
||||
# Sets the title of this page.
|
||||
def title=(new_title)
|
||||
@attributes[:title] = new_title
|
||||
end
|
||||
|
||||
# The raw content of this page.
|
||||
def content
|
||||
@attributes[:content]
|
||||
end
|
||||
|
||||
# The processed/formatted content of this page.
|
||||
def formatted_content
|
||||
@attributes[:formatted_content]
|
||||
end
|
||||
|
||||
# The markup format for the page.
|
||||
def format
|
||||
@attributes[:format] || :markdown
|
||||
end
|
||||
|
||||
# The commit message for this page version.
|
||||
def message
|
||||
version.try(:message)
|
||||
end
|
||||
|
||||
# The Gitlab Commit instance for this page.
|
||||
def version
|
||||
return nil unless persisted?
|
||||
|
||||
@version ||= Commit.new(@page.version)
|
||||
end
|
||||
|
||||
# Returns an array of Gitlab Commit instances.
|
||||
def versions
|
||||
return [] unless persisted?
|
||||
|
||||
@page.versions.map { |v| Commit.new(v) }
|
||||
end
|
||||
|
||||
# Returns the Date that this latest version was
|
||||
# created on.
|
||||
def created_at
|
||||
@page.version.date
|
||||
end
|
||||
|
||||
# Returns boolean True or False if this instance
|
||||
# is an old version of the page.
|
||||
def historical?
|
||||
@page.historical?
|
||||
end
|
||||
|
||||
# Returns boolean True or False if this instance
|
||||
# has been fully saved to disk or not.
|
||||
def persisted?
|
||||
@persisted == true
|
||||
end
|
||||
|
||||
# Creates a new Wiki Page.
|
||||
#
|
||||
# attr - Hash of attributes to set on the new page.
|
||||
# :title - The title for the new page.
|
||||
# :content - The raw markup content.
|
||||
# :format - Optional symbol representing the
|
||||
# content format. Can be any type
|
||||
# listed in the GollumWiki::MARKUPS
|
||||
# Hash.
|
||||
# :message - Optional commit message to set on
|
||||
# the new page.
|
||||
#
|
||||
# Returns the String SHA1 of the newly created page
|
||||
# or False if the save was unsuccessful.
|
||||
def create(attr = {})
|
||||
@attributes.merge!(attr)
|
||||
|
||||
save :create_page, title, content, format, message
|
||||
end
|
||||
|
||||
# Updates an existing Wiki Page, creating a new version.
|
||||
#
|
||||
# new_content - The raw markup content to replace the existing.
|
||||
# format - Optional symbol representing the content format.
|
||||
# See GollumWiki::MARKUPS Hash for available formats.
|
||||
# message - Optional commit message to set on the new version.
|
||||
#
|
||||
# Returns the String SHA1 of the newly created page
|
||||
# or False if the save was unsuccessful.
|
||||
def update(new_content = "", format = :markdown, message = nil)
|
||||
@attributes[:content] = new_content
|
||||
@attributes[:format] = format
|
||||
|
||||
save :update_page, @page, content, format, message
|
||||
end
|
||||
|
||||
# Destroys the WIki Page.
|
||||
#
|
||||
# Returns boolean True or False.
|
||||
def delete
|
||||
if wiki.delete_page(@page)
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_attributes
|
||||
attributes[:slug] = @page.escaped_url_path
|
||||
attributes[:title] = @page.title
|
||||
attributes[:content] = @page.raw_data
|
||||
attributes[:formatted_content] = @page.formatted_data
|
||||
attributes[:format] = @page.format
|
||||
end
|
||||
|
||||
def save(method, *args)
|
||||
if valid? && wiki.send(method, *args)
|
||||
@page = wiki.wiki.paged(title)
|
||||
|
||||
set_attributes
|
||||
|
||||
@persisted = true
|
||||
else
|
||||
errors.add(:base, wiki.error_message) if wiki.error_message
|
||||
@persisted = false
|
||||
end
|
||||
@persisted
|
||||
end
|
||||
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue