Merge branch 'DanKnox-use_gollum_wikis'
This commit is contained in:
commit
3c050a29a7
31 changed files with 1253 additions and 99 deletions
7
Gemfile
7
Gemfile
|
@ -99,6 +99,13 @@ gem "colored"
|
||||||
# GitLab settings
|
# GitLab settings
|
||||||
gem 'settingslogic'
|
gem 'settingslogic'
|
||||||
|
|
||||||
|
# Wiki
|
||||||
|
# - Use latest master to resolve Gem dependency with Pygemnts
|
||||||
|
# github-linquist needs pygments 0.4.2 but Gollum 2.4.11
|
||||||
|
# requires pygments 0.3.2. The latest master Gollum has been updated
|
||||||
|
# to use pygments 0.4.2. Change this after next Gollum release.
|
||||||
|
gem "gollum", "~> 2.4.0", git: "git://github.com/github/gollum.git"
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
gem "foreman"
|
gem "foreman"
|
||||||
gem "git"
|
gem "git"
|
||||||
|
|
29
Gemfile.lock
29
Gemfile.lock
|
@ -1,3 +1,19 @@
|
||||||
|
GIT
|
||||||
|
remote: git://github.com/github/gollum.git
|
||||||
|
revision: 544d499ab170c9d9b355b7a0160afc74139ee2a4
|
||||||
|
specs:
|
||||||
|
gollum (2.4.11)
|
||||||
|
github-markdown (~> 0.5.3)
|
||||||
|
github-markup (>= 0.7.5, < 1.0.0)
|
||||||
|
grit (~> 2.5.0)
|
||||||
|
mustache (>= 0.99.4, < 1.0.0)
|
||||||
|
nokogiri (~> 1.5.6)
|
||||||
|
pygments.rb (~> 0.4.2)
|
||||||
|
sanitize (~> 2.0.3)
|
||||||
|
sinatra (~> 1.3.5)
|
||||||
|
stringex (~> 1.5.1)
|
||||||
|
useragent (~> 0.4.16)
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: https://github.com/ctran/annotate_models.git
|
remote: https://github.com/ctran/annotate_models.git
|
||||||
revision: be4e26825b521f0b2d86b181e2dff89901aa9b1e
|
revision: be4e26825b521f0b2d86b181e2dff89901aa9b1e
|
||||||
|
@ -145,6 +161,7 @@ GEM
|
||||||
escape_utils (~> 0.2.3)
|
escape_utils (~> 0.2.3)
|
||||||
mime-types (~> 1.19)
|
mime-types (~> 1.19)
|
||||||
pygments.rb (>= 0.2.13)
|
pygments.rb (>= 0.2.13)
|
||||||
|
github-markdown (0.5.3)
|
||||||
github-markup (0.7.5)
|
github-markup (0.7.5)
|
||||||
gitlab-grack (1.0.0)
|
gitlab-grack (1.0.0)
|
||||||
rack (~> 1.4.1)
|
rack (~> 1.4.1)
|
||||||
|
@ -176,6 +193,10 @@ GEM
|
||||||
grape-entity (0.2.0)
|
grape-entity (0.2.0)
|
||||||
activesupport
|
activesupport
|
||||||
multi_json (>= 1.3.2)
|
multi_json (>= 1.3.2)
|
||||||
|
grit (2.5.0)
|
||||||
|
diff-lcs (~> 1.1)
|
||||||
|
mime-types (~> 1.15)
|
||||||
|
posix-spawn (~> 0.3.6)
|
||||||
grit_ext (0.6.2)
|
grit_ext (0.6.2)
|
||||||
charlock_holmes (~> 0.6.9)
|
charlock_holmes (~> 0.6.9)
|
||||||
growl (1.0.3)
|
growl (1.0.3)
|
||||||
|
@ -237,7 +258,8 @@ GEM
|
||||||
sprockets (~> 2.0)
|
sprockets (~> 2.0)
|
||||||
multi_json (1.6.1)
|
multi_json (1.6.1)
|
||||||
multi_xml (0.5.3)
|
multi_xml (0.5.3)
|
||||||
multipart-post (1.2.0)
|
multipart-post (1.1.5)
|
||||||
|
mustache (0.99.4)
|
||||||
mysql2 (0.3.11)
|
mysql2 (0.3.11)
|
||||||
net-ldap (0.2.2)
|
net-ldap (0.2.2)
|
||||||
nokogiri (1.5.6)
|
nokogiri (1.5.6)
|
||||||
|
@ -373,6 +395,8 @@ GEM
|
||||||
rspec-mocks (~> 2.12.0)
|
rspec-mocks (~> 2.12.0)
|
||||||
rubyntlm (0.1.1)
|
rubyntlm (0.1.1)
|
||||||
rubyzip (0.9.9)
|
rubyzip (0.9.9)
|
||||||
|
sanitize (2.0.3)
|
||||||
|
nokogiri (>= 1.4.4, < 1.6)
|
||||||
sass (3.2.5)
|
sass (3.2.5)
|
||||||
sass-rails (3.2.5)
|
sass-rails (3.2.5)
|
||||||
railties (~> 3.2.0)
|
railties (~> 3.2.0)
|
||||||
|
@ -429,6 +453,7 @@ GEM
|
||||||
tilt (~> 1.1, != 1.3.0)
|
tilt (~> 1.1, != 1.3.0)
|
||||||
stamp (0.5.0)
|
stamp (0.5.0)
|
||||||
state_machine (1.1.2)
|
state_machine (1.1.2)
|
||||||
|
stringex (1.5.1)
|
||||||
temple (0.5.5)
|
temple (0.5.5)
|
||||||
test_after_commit (0.0.1)
|
test_after_commit (0.0.1)
|
||||||
therubyracer (0.10.2)
|
therubyracer (0.10.2)
|
||||||
|
@ -451,6 +476,7 @@ GEM
|
||||||
kgio (~> 2.6)
|
kgio (~> 2.6)
|
||||||
rack
|
rack
|
||||||
raindrops (~> 0.7)
|
raindrops (~> 0.7)
|
||||||
|
useragent (0.4.16)
|
||||||
virtus (0.5.4)
|
virtus (0.5.4)
|
||||||
backports (~> 2.6.1)
|
backports (~> 2.6.1)
|
||||||
descendants_tracker (~> 0.0.1)
|
descendants_tracker (~> 0.0.1)
|
||||||
|
@ -499,6 +525,7 @@ DEPENDENCIES
|
||||||
gitlab_meta (= 5.0)
|
gitlab_meta (= 5.0)
|
||||||
gitlab_omniauth-ldap (= 1.0.2)
|
gitlab_omniauth-ldap (= 1.0.2)
|
||||||
gitlab_yaml_db (= 1.0.0)
|
gitlab_yaml_db (= 1.0.0)
|
||||||
|
gollum (~> 2.4.0)!
|
||||||
gon
|
gon
|
||||||
grape (~> 0.3.1)
|
grape (~> 0.3.1)
|
||||||
grape-entity (~> 0.2.0)
|
grape-entity (~> 0.2.0)
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
@import "sections/login.scss";
|
@import "sections/login.scss";
|
||||||
@import "sections/editor.scss";
|
@import "sections/editor.scss";
|
||||||
@import "sections/admin.scss";
|
@import "sections/admin.scss";
|
||||||
|
@import "sections/wiki.scss";
|
||||||
|
|
||||||
@import "highlight/white.scss";
|
@import "highlight/white.scss";
|
||||||
@import "highlight/dark.scss";
|
@import "highlight/dark.scss";
|
||||||
|
|
6
app/assets/stylesheets/sections/wiki.scss
Normal file
6
app/assets/stylesheets/sections/wiki.scss
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
h3.page_title .edit-wiki-header {
|
||||||
|
width: 780px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
padding-right: 7px;
|
||||||
|
}
|
|
@ -2,58 +2,94 @@ class WikisController < ProjectResourceController
|
||||||
before_filter :authorize_read_wiki!
|
before_filter :authorize_read_wiki!
|
||||||
before_filter :authorize_write_wiki!, only: [:edit, :create, :history]
|
before_filter :authorize_write_wiki!, only: [:edit, :create, :history]
|
||||||
before_filter :authorize_admin_wiki!, only: :destroy
|
before_filter :authorize_admin_wiki!, only: :destroy
|
||||||
|
before_filter :load_gollum_wiki
|
||||||
|
|
||||||
def pages
|
def pages
|
||||||
@wiki_pages = @project.wikis.group(:slug).ordered
|
@wiki_pages = @gollum_wiki.pages
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
@most_recent_wiki = @project.wikis.where(slug: params[:id]).ordered.first
|
@wiki = @gollum_wiki.find_page(params[:id], params[:version_id])
|
||||||
if params[:version_id]
|
|
||||||
@wiki = @project.wikis.find(params[:version_id])
|
|
||||||
else
|
|
||||||
@wiki = @most_recent_wiki
|
|
||||||
end
|
|
||||||
|
|
||||||
if @wiki
|
if @wiki
|
||||||
render 'show'
|
render 'show'
|
||||||
else
|
else
|
||||||
if can?(current_user, :write_wiki, @project)
|
return render('empty') unless can?(current_user, :write_wiki, @project)
|
||||||
@wiki = @project.wikis.new(slug: params[:id])
|
@wiki = WikiPage.new(@gollum_wiki)
|
||||||
|
@wiki.title = params[:id]
|
||||||
|
|
||||||
render 'edit'
|
render 'edit'
|
||||||
else
|
|
||||||
render 'empty'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit
|
||||||
@wiki = @project.wikis.where(slug: params[:id]).ordered.first
|
@wiki = @gollum_wiki.find_page(params[:id])
|
||||||
@wiki = Wiki.regenerate_from @wiki
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
@wiki = @gollum_wiki.find_page(params[:id])
|
||||||
|
|
||||||
|
return render('empty') unless can?(current_user, :write_wiki, @project)
|
||||||
|
|
||||||
|
if @wiki.update(content, format, message)
|
||||||
|
redirect_to [@project, @wiki], notice: 'Wiki was successfully updated.'
|
||||||
|
else
|
||||||
|
render 'edit'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@wiki = @project.wikis.new(params[:wiki])
|
@wiki = WikiPage.new(@gollum_wiki)
|
||||||
@wiki.user = current_user
|
|
||||||
|
|
||||||
respond_to do |format|
|
if @wiki.create(wiki_params)
|
||||||
if @wiki.save
|
redirect_to project_wiki_path(@project, @wiki), notice: 'Wiki was successfully updated.'
|
||||||
format.html { redirect_to [@project, @wiki], notice: 'Wiki was successfully updated.' }
|
|
||||||
else
|
else
|
||||||
format.html { render action: "edit" }
|
render action: "edit"
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def history
|
def history
|
||||||
@wiki_pages = @project.wikis.where(slug: params[:id]).ordered
|
unless @wiki = @gollum_wiki.find_page(params[:id])
|
||||||
|
redirect_to project_wiki_path(@project, :home), notice: "Page not found"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@wikis = @project.wikis.where(slug: params[:id]).delete_all
|
@wiki = @gollum_wiki.find_page(params[:id])
|
||||||
|
@wiki.delete if @wiki
|
||||||
|
redirect_to project_wiki_path(@project, :home), notice: "Page was successfully deleted"
|
||||||
|
end
|
||||||
|
|
||||||
respond_to do |format|
|
def git_access
|
||||||
format.html { redirect_to project_wiki_path(@project, :index), notice: "Page was successfully deleted" }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def load_gollum_wiki
|
||||||
|
@gollum_wiki = GollumWiki.new(@project, current_user)
|
||||||
|
|
||||||
|
# Call #wiki to make sure the Wiki Repo is initialized
|
||||||
|
@gollum_wiki.wiki
|
||||||
|
rescue GollumWiki::CouldNotCreateWikiError => ex
|
||||||
|
flash[:notice] = "Could not create Wiki Repository at this time. Please try again later."
|
||||||
|
redirect_to @project
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def wiki_params
|
||||||
|
params[:wiki].slice(:title, :content, :format, :message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def content
|
||||||
|
params[:wiki][:content]
|
||||||
|
end
|
||||||
|
|
||||||
|
def format
|
||||||
|
params[:wiki][:format]
|
||||||
|
end
|
||||||
|
|
||||||
|
def message
|
||||||
|
params[:wiki][:message]
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -49,4 +49,12 @@ module GitlabMarkdownHelper
|
||||||
|
|
||||||
@markdown.render(text).html_safe
|
@markdown.render(text).html_safe
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def render_wiki_content(wiki_page)
|
||||||
|
if wiki_page.format == :markdown
|
||||||
|
markdown(wiki_page.content)
|
||||||
|
else
|
||||||
|
wiki_page.formatted_content.html_safe
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
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
|
|
@ -18,6 +18,11 @@ class ProjectObserver < ActiveRecord::Observer
|
||||||
project.path_with_namespace
|
project.path_with_namespace
|
||||||
)
|
)
|
||||||
|
|
||||||
|
GitlabShellWorker.perform_async(
|
||||||
|
:remove_repository,
|
||||||
|
project.path_with_namespace + ".wiki"
|
||||||
|
)
|
||||||
|
|
||||||
project.satellite.destroy
|
project.satellite.destroy
|
||||||
|
|
||||||
log_info("Project \"#{project.name}\" was removed")
|
log_info("Project \"#{project.name}\" was removed")
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
%span.count.merge_counter= @project.merge_requests.opened.count
|
%span.count.merge_counter= @project.merge_requests.opened.count
|
||||||
|
|
||||||
= nav_link(html_options: {class: "#{project_wiki_tab_class}"}) do
|
= nav_link(html_options: {class: "#{project_wiki_tab_class}"}) do
|
||||||
= link_to 'Wiki', project_wiki_path(@project, :index)
|
= link_to 'Wiki', project_wiki_path(@project, :home)
|
||||||
|
|
||||||
- if can? current_user, :admin_project, @project
|
- if can? current_user, :admin_project, @project
|
||||||
= nav_link(html_options: {class: "#{project_tab_class}"}) do
|
= nav_link(html_options: {class: "#{project_tab_class}"}) do
|
||||||
|
|
|
@ -8,9 +8,12 @@
|
||||||
|
|
||||||
.ui-box.ui-box-show
|
.ui-box.ui-box-show
|
||||||
.ui-box-head
|
.ui-box-head
|
||||||
= f.label :title
|
%h3.page_title
|
||||||
.input= f.text_field :title, class: 'span8'
|
.edit-wiki-header
|
||||||
= f.hidden_field :slug
|
= @wiki.title.titleize
|
||||||
|
= f.hidden_field :title, value: @wiki.title
|
||||||
|
= f.select :format, options_for_select(GollumWiki::MARKUPS, {selected: @wiki.format}), {}, class: "pull-right input-medium"
|
||||||
|
= f.label :format, class: "pull-right", style: "padding-right: 20px;"
|
||||||
.ui-box-body
|
.ui-box-body
|
||||||
.input
|
.input
|
||||||
%span.cgray
|
%span.cgray
|
||||||
|
@ -22,6 +25,9 @@
|
||||||
.ui-box-bottom
|
.ui-box-bottom
|
||||||
= f.label :content
|
= f.label :content
|
||||||
.input= f.text_area :content, class: 'span8 js-gfm-input'
|
.input= f.text_area :content, class: 'span8 js-gfm-input'
|
||||||
|
.ui-box-bottom
|
||||||
|
= f.label :commit_message
|
||||||
|
.input= f.text_field :message, class: 'span8'
|
||||||
.actions
|
.actions
|
||||||
= f.submit 'Save', class: "btn-save btn"
|
= f.submit 'Save', class: "btn-save btn"
|
||||||
= link_to "Cancel", project_wiki_path(@project, :index), class: "btn btn-cancel"
|
= link_to "Cancel", project_wiki_path(@project, :index), class: "btn btn-cancel"
|
||||||
|
|
16
app/views/wikis/_main_links.html.haml
Normal file
16
app/views/wikis/_main_links.html.haml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
%span.pull-right
|
||||||
|
= link_to project_wiki_path(@project, :home), class: "btn btn-small grouped" do
|
||||||
|
Home
|
||||||
|
= link_to pages_project_wikis_path(@project), class: "btn btn-small grouped" do
|
||||||
|
Pages
|
||||||
|
- if (@wiki && @wiki.persisted?)
|
||||||
|
= link_to history_project_wiki_path(@project, @wiki), class: "btn btn-small grouped" do
|
||||||
|
History
|
||||||
|
- if can?(current_user, :write_wiki, @project)
|
||||||
|
- if @wiki && @wiki.persisted?
|
||||||
|
= link_to edit_project_wiki_path(@project, @wiki), class: "btn btn-small grouped" do
|
||||||
|
%i.icon-edit
|
||||||
|
Edit
|
||||||
|
= link_to git_access_project_wikis_path(@project), class: "btn btn-small grouped" do
|
||||||
|
%i.icon-download-alt
|
||||||
|
Git Access
|
|
@ -1,7 +1,7 @@
|
||||||
%ul.nav.nav-tabs
|
%ul.nav.nav-tabs
|
||||||
- if @project.wiki_enabled
|
- if @project.wiki_enabled
|
||||||
= nav_link(controller: 'wikis') do
|
= nav_link(controller: 'wikis') do
|
||||||
= link_to 'Wiki', project_wiki_path(@project, :index)
|
= link_to 'Wiki', project_wiki_path(@project, :home)
|
||||||
|
|
||||||
- if @project.wall_enabled
|
- if @project.wall_enabled
|
||||||
= nav_link(path: 'projects#wall') do
|
= nav_link(path: 'projects#wall') do
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
%h3.page_title Editing page
|
%h3.page_title
|
||||||
|
Editing page
|
||||||
|
= render partial: 'main_links'
|
||||||
= render 'form'
|
= render 'form'
|
||||||
|
|
||||||
.pull-right
|
.pull-right
|
||||||
- if can? current_user, :admin_wiki, @project
|
- if @wiki.persisted? && can?(current_user, :admin_wiki, @project)
|
||||||
= link_to project_wiki_path(@project, @wiki), confirm: "Are you sure you want to delete this page?", method: :delete, class: "btn btn-small btn-remove" do
|
= link_to project_wiki_path(@project, @wiki), confirm: "Are you sure you want to delete this page?", method: :delete, class: "btn btn-small btn-remove" do
|
||||||
Delete this page
|
Delete this page
|
||||||
|
|
36
app/views/wikis/git_access.html.haml
Normal file
36
app/views/wikis/git_access.html.haml
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
%h3.page_title
|
||||||
|
Git Access
|
||||||
|
%strong= @gollum_wiki.path_with_namespace
|
||||||
|
= render partial: 'main_links'
|
||||||
|
|
||||||
|
%br
|
||||||
|
.content
|
||||||
|
.project_clone_panel
|
||||||
|
.row
|
||||||
|
.span7
|
||||||
|
.form-horizontal
|
||||||
|
.input-prepend.project_clone_holder
|
||||||
|
%button{class: "btn active", :"data-clone" => @gollum_wiki.ssh_url_to_repo} SSH
|
||||||
|
%button{class: "btn", :"data-clone" => @gollum_wiki.http_url_to_repo}= Gitlab.config.gitlab.protocol.upcase
|
||||||
|
= text_field_tag :project_clone, @gollum_wiki.url_to_repo, class: "one_click_select input-xxlarge", readonly: true
|
||||||
|
.git-empty
|
||||||
|
%fieldset
|
||||||
|
%legend Install Gollum:
|
||||||
|
%pre.dark
|
||||||
|
:preserve
|
||||||
|
gem install gollum
|
||||||
|
|
||||||
|
%legend Clone Your Wiki:
|
||||||
|
%pre.dark
|
||||||
|
:preserve
|
||||||
|
git clone #{@gollum_wiki.path_with_namespace}.git
|
||||||
|
cd #{@gollum_wiki.path_with_namespace}
|
||||||
|
|
||||||
|
%legend Start Gollum And Edit Locally:
|
||||||
|
%pre.dark
|
||||||
|
:preserve
|
||||||
|
gollum
|
||||||
|
== Sinatra/1.3.5 has taken the stage on 4567 for development with backup from Thin
|
||||||
|
>> Thin web server (v1.5.0 codename Knife)
|
||||||
|
>> Maximum connections set to 1024
|
||||||
|
>> Listening on 0.0.0.0:4567, CTRL+C to stop
|
|
@ -1,23 +1,29 @@
|
||||||
%h3.page_title
|
%h3.page_title
|
||||||
%span.cgray History for
|
%span.cgray History for
|
||||||
= @wiki_pages.first.title
|
= @wiki.title.titleize
|
||||||
|
= render partial: 'main_links'
|
||||||
%br
|
%br
|
||||||
%table
|
%table
|
||||||
%thead
|
%thead
|
||||||
%tr
|
%tr
|
||||||
%th Page version
|
%th Page version
|
||||||
|
%th Author
|
||||||
|
%th Commit Message
|
||||||
%th Last updated
|
%th Last updated
|
||||||
%th Updated by
|
%th Format
|
||||||
%tbody
|
%tbody
|
||||||
- @wiki_pages.each_with_index do |wiki_page, i|
|
- @wiki.versions.each do |version|
|
||||||
|
- commit = CommitDecorator.new(version)
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
%strong
|
= link_to project_wiki_path(@project, @wiki, version_id: commit.id) do
|
||||||
= link_to project_wiki_path(@project, wiki_page, version_id: wiki_page.id) do
|
= commit.short_id
|
||||||
Version
|
%td= commit.author_link avatar: true, size: 24
|
||||||
= @wiki_pages.count - i
|
|
||||||
%td
|
%td
|
||||||
= wiki_page.created_at.to_s(:short)
|
= commit.title
|
||||||
(#{time_ago_in_words(wiki_page.created_at)}
|
%td
|
||||||
ago)
|
= time_ago_in_words(version.date)
|
||||||
%td= link_to_member(@project, wiki_page.user)
|
ago
|
||||||
|
%td
|
||||||
|
%strong
|
||||||
|
= @wiki.page.wiki.page(@wiki.page.name, commit.id).try(:format)
|
||||||
|
|
|
@ -1,21 +1,25 @@
|
||||||
= render 'wikis/nav'
|
= render 'wikis/nav'
|
||||||
%h3.page_title All Pages
|
%h3.page_title
|
||||||
|
All Pages
|
||||||
|
= render partial: 'main_links'
|
||||||
%br
|
%br
|
||||||
%table
|
%table
|
||||||
%thead
|
%thead
|
||||||
%tr
|
%tr
|
||||||
%th Title
|
%th Title
|
||||||
%th Slug
|
%th Format
|
||||||
%th Last updated
|
%th Last updated
|
||||||
%th Updated by
|
%th Updated by
|
||||||
%tbody
|
%tbody
|
||||||
- @wiki_pages.each do |wiki_page|
|
- @wiki_pages.each do |wiki_page|
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
%strong= link_to wiki_page.title, project_wiki_path(@project, wiki_page)
|
%strong= link_to wiki_page.title.titleize, project_wiki_path(@project, wiki_page)
|
||||||
%td= wiki_page.slug
|
%td
|
||||||
|
%strong= wiki_page.format
|
||||||
%td
|
%td
|
||||||
= wiki_page.created_at.to_s(:short) do
|
= wiki_page.created_at.to_s(:short) do
|
||||||
(#{time_ago_in_words(wiki_page.created_at)}
|
(#{time_ago_in_words(wiki_page.created_at)}
|
||||||
ago)
|
ago)
|
||||||
%td= link_to_member(@project, wiki_page.user)
|
- commit = CommitDecorator.decorate(wiki_page.version)
|
||||||
|
%td= commit.author_link avatar: true, size: 24
|
||||||
|
|
|
@ -1,24 +1,17 @@
|
||||||
= render 'wikis/nav'
|
= render 'wikis/nav'
|
||||||
- if @wiki != @most_recent_wiki
|
%h3.page_title
|
||||||
.alert
|
= @wiki.title.titleize
|
||||||
|
= render partial: 'main_links'
|
||||||
|
%br
|
||||||
|
- if @wiki.historical?
|
||||||
|
.warning_message
|
||||||
This is an old version of this page.
|
This is an old version of this page.
|
||||||
You can view the #{link_to "most recent version", project_wiki_path(@project, @wiki)} or browse the #{link_to "history", history_project_wiki_path(@project, @wiki)}.
|
You can view the #{link_to "most recent version", project_wiki_path(@project, @wiki)} or browse the #{link_to "history", history_project_wiki_path(@project, @wiki)}.
|
||||||
|
|
||||||
.file_holder
|
.file_holder
|
||||||
.file_title
|
|
||||||
= @wiki.title
|
|
||||||
%span.options
|
|
||||||
= link_to pages_project_wikis_path(@project), class: "btn btn-tiny grouped" do
|
|
||||||
Pages
|
|
||||||
- if can? current_user, :write_wiki, @project
|
|
||||||
= link_to history_project_wiki_path(@project, @wiki), class: "btn btn-tiny grouped" do
|
|
||||||
History
|
|
||||||
= link_to edit_project_wiki_path(@project, @wiki), class: "btn btn-tiny grouped" do
|
|
||||||
%i.icon-edit
|
|
||||||
Edit
|
|
||||||
|
|
||||||
.file_content.wiki
|
.file_content.wiki
|
||||||
= preserve do
|
= preserve do
|
||||||
= markdown @wiki.content
|
= render_wiki_content(@wiki)
|
||||||
|
|
||||||
%p.time Last edited by #{link_to_member @project, @wiki.user}, #{time_ago_in_words @wiki.created_at} ago
|
- commit = CommitDecorator.new(@wiki.version)
|
||||||
|
%p.time Last edited by #{commit.author_link(avatar: true, size: 16)} #{time_ago_in_words @wiki.created_at} ago
|
||||||
|
|
|
@ -185,6 +185,8 @@ Gitlab::Application.routes.draw do
|
||||||
resources :wikis, only: [:show, :edit, :destroy, :create] do
|
resources :wikis, only: [:show, :edit, :destroy, :create] do
|
||||||
collection do
|
collection do
|
||||||
get :pages
|
get :pages
|
||||||
|
put ':id' => 'wikis#update'
|
||||||
|
get :git_access
|
||||||
end
|
end
|
||||||
|
|
||||||
member do
|
member do
|
||||||
|
|
|
@ -5,5 +5,32 @@ Feature: Project Wiki
|
||||||
Given I visit project wiki page
|
Given I visit project wiki page
|
||||||
|
|
||||||
Scenario: Add new page
|
Scenario: Add new page
|
||||||
Given I create Wiki page
|
Given I create the Wiki Home page
|
||||||
Then I should see newly created wiki page
|
Then I should see the newly created wiki page
|
||||||
|
|
||||||
|
Scenario: Edit existing page
|
||||||
|
Given I have an existing Wiki page
|
||||||
|
And I browse to that Wiki page
|
||||||
|
And I click on the Edit button
|
||||||
|
And I change the content
|
||||||
|
Then I should see the updated content
|
||||||
|
|
||||||
|
Scenario: View page history
|
||||||
|
Given I have an existing wiki page
|
||||||
|
And That page has two revisions
|
||||||
|
And I browse to that Wiki page
|
||||||
|
And I click the History button
|
||||||
|
Then I should see both revisions
|
||||||
|
|
||||||
|
Scenario: Destroy Wiki page
|
||||||
|
Given I have an existing wiki page
|
||||||
|
And I browse to that Wiki page
|
||||||
|
And I click on the Edit button
|
||||||
|
And I click on the "Delete this page" button
|
||||||
|
Then The page should be deleted
|
||||||
|
|
||||||
|
Scenario: View all pages
|
||||||
|
Given I have an existing wiki page
|
||||||
|
And I browse to that Wiki page
|
||||||
|
And I click on the "Pages" button
|
||||||
|
Then I should see the existing page in the pages list
|
||||||
|
|
|
@ -4,17 +4,73 @@ class ProjectWiki < Spinach::FeatureSteps
|
||||||
include SharedNote
|
include SharedNote
|
||||||
include SharedPaths
|
include SharedPaths
|
||||||
|
|
||||||
Given 'I create Wiki page' do
|
Given 'I create the Wiki Home page' do
|
||||||
fill_in "Title", :with => 'Test title'
|
|
||||||
fill_in "Content", :with => '[link test](test)'
|
fill_in "Content", :with => '[link test](test)'
|
||||||
click_on "Save"
|
click_on "Save"
|
||||||
end
|
end
|
||||||
|
|
||||||
Then 'I should see newly created wiki page' do
|
Then 'I should see the newly created wiki page' do
|
||||||
page.should have_content "Test title"
|
page.should have_content "Home"
|
||||||
page.should have_content "link test"
|
page.should have_content "link test"
|
||||||
|
|
||||||
click_link "link test"
|
click_link "link test"
|
||||||
page.should have_content "Editing page"
|
page.should have_content "Editing page"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Given 'I have an existing Wiki page' do
|
||||||
|
wiki.create_page("existing", "content", :markdown, "first commit")
|
||||||
|
@page = wiki.find_page("existing")
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I browse to that Wiki page' do
|
||||||
|
visit project_wiki_path(project, @page)
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I click on the Edit button' do
|
||||||
|
click_on "Edit"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I change the content' do
|
||||||
|
fill_in "Content", :with => 'Updated Wiki Content'
|
||||||
|
click_on "Save"
|
||||||
|
end
|
||||||
|
|
||||||
|
Then 'I should see the updated content' do
|
||||||
|
page.should have_content "Updated Wiki Content"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'That page has two revisions' do
|
||||||
|
@page.update("new content", :markdown, "second commit")
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I click the History button' do
|
||||||
|
click_on "History"
|
||||||
|
end
|
||||||
|
|
||||||
|
Then 'I should see both revisions' do
|
||||||
|
page.should have_content current_user.name
|
||||||
|
page.should have_content "first commit"
|
||||||
|
page.should have_content "second commit"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I click on the "Delete this page" button' do
|
||||||
|
click_on "Delete this page"
|
||||||
|
end
|
||||||
|
|
||||||
|
Then 'The page should be deleted' do
|
||||||
|
page.should have_content "Page was successfully deleted"
|
||||||
|
end
|
||||||
|
|
||||||
|
And 'I click on the "Pages" button' do
|
||||||
|
click_on "Pages"
|
||||||
|
end
|
||||||
|
|
||||||
|
Then 'I should see the existing page in the pages list' do
|
||||||
|
page.should have_content current_user.name
|
||||||
|
page.should have_content @page.title.titleize
|
||||||
|
end
|
||||||
|
|
||||||
|
def wiki
|
||||||
|
@gollum_wiki = GollumWiki.new(project, current_user)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -165,7 +165,7 @@ module SharedPaths
|
||||||
end
|
end
|
||||||
|
|
||||||
Given "I visit my project's wiki page" do
|
Given "I visit my project's wiki page" do
|
||||||
visit project_wiki_path(@project, :index)
|
visit project_wiki_path(@project, :home)
|
||||||
end
|
end
|
||||||
|
|
||||||
When 'I visit project hooks page' do
|
When 'I visit project hooks page' do
|
||||||
|
@ -260,7 +260,7 @@ module SharedPaths
|
||||||
end
|
end
|
||||||
|
|
||||||
Given 'I visit project wiki page' do
|
Given 'I visit project wiki page' do
|
||||||
visit project_wiki_path(@project, :index)
|
visit project_wiki_path(@project, :home)
|
||||||
end
|
end
|
||||||
|
|
||||||
def root_ref
|
def root_ref
|
||||||
|
|
|
@ -37,6 +37,9 @@ DatabaseCleaner.strategy = :truncation
|
||||||
Spinach.hooks.before_scenario do
|
Spinach.hooks.before_scenario do
|
||||||
# Use tmp dir for FS manipulations
|
# Use tmp dir for FS manipulations
|
||||||
Gitlab.config.gitlab_shell.stub(repos_path: Rails.root.join('tmp', 'test-git-base-path'))
|
Gitlab.config.gitlab_shell.stub(repos_path: Rails.root.join('tmp', 'test-git-base-path'))
|
||||||
|
Gitlab::Shell.any_instance.stub(:add_repository) do |path|
|
||||||
|
create_temp_repo("#{Rails.root}/tmp/test-git-base-path/#{path}.git")
|
||||||
|
end
|
||||||
FileUtils.rm_rf Gitlab.config.gitlab_shell.repos_path
|
FileUtils.rm_rf Gitlab.config.gitlab_shell.repos_path
|
||||||
FileUtils.mkdir_p Gitlab.config.gitlab_shell.repos_path
|
FileUtils.mkdir_p Gitlab.config.gitlab_shell.repos_path
|
||||||
DatabaseCleaner.start
|
DatabaseCleaner.start
|
||||||
|
@ -51,3 +54,9 @@ Spinach.hooks.before_run do
|
||||||
|
|
||||||
include FactoryGirl::Syntax::Methods
|
include FactoryGirl::Syntax::Methods
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create_temp_repo(path)
|
||||||
|
FileUtils.mkdir_p path
|
||||||
|
command = "git init --quiet --bare #{path};"
|
||||||
|
system(command)
|
||||||
|
end
|
||||||
|
|
|
@ -12,10 +12,18 @@ module Gitlab
|
||||||
# ref - branch name
|
# ref - branch name
|
||||||
#
|
#
|
||||||
get "/allowed" do
|
get "/allowed" do
|
||||||
|
# Check for *.wiki repositories.
|
||||||
|
# Strip out the .wiki from the pathname before finding the
|
||||||
|
# project. This applies the correct project permissions to
|
||||||
|
# the wiki repository as well.
|
||||||
|
project_path = params[:project]
|
||||||
|
project_path.gsub!(/\.wiki/,'') if project_path =~ /\.wiki/
|
||||||
|
|
||||||
key = Key.find(params[:key_id])
|
key = Key.find(params[:key_id])
|
||||||
project = Project.find_with_namespace(params[:project])
|
project = Project.find_with_namespace(project_path)
|
||||||
git_cmd = params[:action]
|
git_cmd = params[:action]
|
||||||
|
|
||||||
|
|
||||||
if key.is_deploy_key
|
if key.is_deploy_key
|
||||||
project == key.project && git_cmd == 'git-upload-pack'
|
project == key.project && git_cmd == 'git-upload-pack'
|
||||||
else
|
else
|
||||||
|
|
20
lib/tasks/gitlab/migrate_wiki.rake
Normal file
20
lib/tasks/gitlab/migrate_wiki.rake
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
namespace :gitlab do
|
||||||
|
namespace :wiki do
|
||||||
|
|
||||||
|
# This task will migrate all of the existing Wiki
|
||||||
|
# content stored in your database into the new
|
||||||
|
# Gollum Wiki system. A new repository named
|
||||||
|
# namespace/project.wiki.git will be created for
|
||||||
|
# each project that currently has Wiki pages in
|
||||||
|
# the database.
|
||||||
|
#
|
||||||
|
# Notes:
|
||||||
|
# * The existing Wiki content will remain in your
|
||||||
|
# database in-tact.
|
||||||
|
desc "GITLAB | Migrate Wiki content from database to Gollum repositories."
|
||||||
|
task :migrate => :environment do
|
||||||
|
wiki_migrator = WikiToGollumMigrator.new
|
||||||
|
wiki_migrator.migrate!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
103
lib/wiki_to_gollum_migrator.rb
Normal file
103
lib/wiki_to_gollum_migrator.rb
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
class WikiToGollumMigrator
|
||||||
|
|
||||||
|
attr_reader :projects
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
@projects = []
|
||||||
|
|
||||||
|
Project.find_in_batches(batch_size: 50) do |batch|
|
||||||
|
batch.each { |p| @projects << p if p.wikis.any? }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def migrate!
|
||||||
|
projects.each do |project|
|
||||||
|
log "\nMigrating Wiki for '#{project.path_with_namespace}'"
|
||||||
|
wiki = create_gollum_repo(project)
|
||||||
|
create_pages project, wiki
|
||||||
|
log "Project '#{project.path_with_namespace}' migrated. " + "[OK]".green
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def create_gollum_repo(project)
|
||||||
|
GollumWiki.new(project, nil).wiki
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_pages(project, wiki)
|
||||||
|
pages = project.wikis.group(:slug).all
|
||||||
|
|
||||||
|
pages.each do |page|
|
||||||
|
create_page_and_revisions(project, page)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_page_and_revisions(project, page)
|
||||||
|
# Grab all revisions of the page
|
||||||
|
revisions = project.wikis.where(slug: page.slug).ordered.all
|
||||||
|
|
||||||
|
# Remove the first revision created from the array
|
||||||
|
# and use it to create the Gollum page. Each successive revision
|
||||||
|
# will then be applied to the new Gollum page as an update.
|
||||||
|
first_rev = revisions.pop
|
||||||
|
|
||||||
|
wiki = GollumWiki.new(project, page.user)
|
||||||
|
wiki_page = WikiPage.new(wiki)
|
||||||
|
|
||||||
|
attributes = extract_attributes_from_page(first_rev)
|
||||||
|
|
||||||
|
if wiki_page.create(attributes)
|
||||||
|
log " Created page '#{wiki_page.title}' " + "[OK]".green
|
||||||
|
|
||||||
|
# Reverse the revisions to create them in the correct
|
||||||
|
# chronological order.
|
||||||
|
create_revisions(project, wiki_page, revisions.reverse)
|
||||||
|
else
|
||||||
|
log " Failed to create page '#{wiki_page.title}' " + "[FAILED]".red
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_revisions(project, page, revisions)
|
||||||
|
revisions.each do |revision|
|
||||||
|
log " Creating revisions..."
|
||||||
|
# Reinitialize a new GollumWiki instance for each page
|
||||||
|
# and revision created so the correct User is shown in
|
||||||
|
# the commit message.
|
||||||
|
wiki = GollumWiki.new(project, revision.user)
|
||||||
|
wiki_page = wiki.find_page(page.slug)
|
||||||
|
|
||||||
|
attributes = extract_attributes_from_page(revision)
|
||||||
|
|
||||||
|
content = attributes[:content]
|
||||||
|
|
||||||
|
if wiki_page.update(content)
|
||||||
|
log " Created revision " + "[OK]".green
|
||||||
|
else
|
||||||
|
log " Failed to create revision " + "[FAILED]".red
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def extract_attributes_from_page(page)
|
||||||
|
attributes = page.attributes
|
||||||
|
.with_indifferent_access
|
||||||
|
.slice(:title, :content)
|
||||||
|
|
||||||
|
# Change 'index' pages to 'home' pages to match Gollum standards
|
||||||
|
if attributes[:title].downcase == "index"
|
||||||
|
attributes[:title] = "home" unless home_already_exists?(project)
|
||||||
|
end
|
||||||
|
|
||||||
|
attributes
|
||||||
|
end
|
||||||
|
|
||||||
|
def home_already_exists?(project)
|
||||||
|
project.wikis.where(title: 'home').any? || project.wikis.where(title: 'Home').any?
|
||||||
|
end
|
||||||
|
|
||||||
|
def log(message)
|
||||||
|
puts message
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -207,25 +207,4 @@ describe "Gitlab Flavored Markdown" do
|
||||||
page.should have_link("##{issue.id}")
|
page.should have_link("##{issue.id}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
describe "for wikis" do
|
|
||||||
before do
|
|
||||||
visit project_wiki_path(project, :index)
|
|
||||||
fill_in "Title", with: "Circumvent ##{issue.id}"
|
|
||||||
fill_in "Content", with: "# Other pages\n\n* [Foo](foo)\n* [Bar](bar)\n\nAlso look at ##{issue.id} :-)"
|
|
||||||
click_on "Save"
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should NOT render title in wikis#show" do
|
|
||||||
within(".content .file_title") do # page title
|
|
||||||
page.should have_content("Circumvent ##{issue.id}")
|
|
||||||
page.should_not have_link("##{issue.id}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should render content in wikis#show" do
|
|
||||||
page.should have_link("##{issue.id}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -363,4 +363,28 @@ describe GitlabMarkdownHelper do
|
||||||
markdown(":smile:").should include("src=\"#{url_to_image("emoji/smile")}")
|
markdown(":smile:").should include("src=\"#{url_to_image("emoji/smile")}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#render_wiki_content" do
|
||||||
|
before do
|
||||||
|
@wiki = stub('WikiPage')
|
||||||
|
@wiki.stub(:content).and_return('wiki content')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should use Gitlab Flavored Markdown for markdown files" do
|
||||||
|
@wiki.stub(:format).and_return(:markdown)
|
||||||
|
|
||||||
|
helper.should_receive(:markdown).with('wiki content')
|
||||||
|
|
||||||
|
helper.render_wiki_content(@wiki)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should use the Gollum renderer for all other file types" do
|
||||||
|
@wiki.stub(:format).and_return(:rdoc)
|
||||||
|
formatted_content_stub = stub('formatted_content')
|
||||||
|
formatted_content_stub.should_receive(:html_safe)
|
||||||
|
@wiki.stub(:formatted_content).and_return(formatted_content_stub)
|
||||||
|
|
||||||
|
helper.render_wiki_content(@wiki)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
114
spec/lib/wiki_to_gollum_migrator_spec.rb
Normal file
114
spec/lib/wiki_to_gollum_migrator_spec.rb
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
require "spec_helper"
|
||||||
|
|
||||||
|
describe WikiToGollumMigrator do
|
||||||
|
|
||||||
|
def create_wiki_for(project)
|
||||||
|
3.times { @pages[project.id] << create_page(project) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_revisions_for(project)
|
||||||
|
@pages[project.id].each do |page|
|
||||||
|
create_revision(page)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_page(project)
|
||||||
|
page = project.wikis.new(title: "Page #{rand(1000)}", content: "Content")
|
||||||
|
page.user = project.owner
|
||||||
|
page.slug = page.title.parameterize
|
||||||
|
page.save!
|
||||||
|
page
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_revision(page)
|
||||||
|
revision = page.dup
|
||||||
|
revision.content = "Updated Content"
|
||||||
|
revision.save!
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_temp_repo(path)
|
||||||
|
FileUtils.mkdir_p path
|
||||||
|
command = "git init --quiet --bare #{path};"
|
||||||
|
system(command)
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
@repo_path = "#{Rails.root}/tmp/test-git-base-path"
|
||||||
|
@projects = []
|
||||||
|
@pages = Hash.new {|h,k| h[k] = Array.new }
|
||||||
|
|
||||||
|
@projects << create(:project)
|
||||||
|
@projects << create(:project)
|
||||||
|
|
||||||
|
@projects.each do |project|
|
||||||
|
create_wiki_for project
|
||||||
|
create_revisions_for project
|
||||||
|
end
|
||||||
|
|
||||||
|
@project_without_wiki = create(:project)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "Before the migration" do
|
||||||
|
it "has two projects with valid wikis" do
|
||||||
|
@projects.each do |project|
|
||||||
|
pages = project.wikis.group(:slug).all
|
||||||
|
pages.count.should == 3
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "has two revision for each page" do
|
||||||
|
@projects.each do |project|
|
||||||
|
@pages[project.id].each do |page|
|
||||||
|
revisions = project.wikis.where(slug: page.slug)
|
||||||
|
revisions.count.should == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#initialize" do
|
||||||
|
it "finds all projects that have existing wiki pages" do
|
||||||
|
Project.count.should == 3
|
||||||
|
subject.projects.count.should == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "#migrate!" do
|
||||||
|
before do
|
||||||
|
Gitlab::Shell.any_instance.stub(:add_repository) do |path|
|
||||||
|
create_temp_repo("#{@repo_path}/#{path}.git")
|
||||||
|
end
|
||||||
|
|
||||||
|
subject.stub(:log).as_null_object
|
||||||
|
|
||||||
|
subject.migrate!
|
||||||
|
end
|
||||||
|
|
||||||
|
it "creates a new Gollum Wiki for each project" do
|
||||||
|
@projects.each do |project|
|
||||||
|
wiki_path = project.path_with_namespace + ".wiki.git"
|
||||||
|
full_path = @repo_path + "/" + wiki_path
|
||||||
|
File.exist?(full_path).should be_true
|
||||||
|
File.directory?(full_path).should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "creates a gollum page for each unique Wiki page" do
|
||||||
|
@projects.each do |project|
|
||||||
|
wiki = GollumWiki.new(project, nil)
|
||||||
|
wiki.pages.count.should == 3
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "creates a new revision for each old revision of the page" do
|
||||||
|
@projects.each do |project|
|
||||||
|
wiki = GollumWiki.new(project, nil)
|
||||||
|
wiki.pages.each do |page|
|
||||||
|
page.versions.count.should == 2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
196
spec/models/gollum_wiki_spec.rb
Normal file
196
spec/models/gollum_wiki_spec.rb
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
require "spec_helper"
|
||||||
|
|
||||||
|
describe GollumWiki do
|
||||||
|
|
||||||
|
def create_temp_repo(path)
|
||||||
|
FileUtils.mkdir_p path
|
||||||
|
command = "git init --quiet #{path};"
|
||||||
|
system(command)
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_temp_repo(path)
|
||||||
|
FileUtils.rm_rf path
|
||||||
|
end
|
||||||
|
|
||||||
|
def commit_details
|
||||||
|
commit = {name: user.name, email: user.email, message: "test commit"}
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_page(name, content)
|
||||||
|
subject.wiki.write_page(name, :markdown, content, commit_details)
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy_page(page)
|
||||||
|
subject.wiki.delete_page(page, commit_details)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:project) { create(:project) }
|
||||||
|
let(:repository) { project.repository }
|
||||||
|
let(:user) { project.owner }
|
||||||
|
let(:gitlab_shell) { Gitlab::Shell.new }
|
||||||
|
|
||||||
|
subject { GollumWiki.new(project, user) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
create_temp_repo(subject.send(:path_to_repo))
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#path_with_namespace" do
|
||||||
|
it "returns the project path with namespace with the .wiki extension" do
|
||||||
|
subject.path_with_namespace.should == project.path_with_namespace + ".wiki"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#url_to_repo" do
|
||||||
|
it "returns the correct ssh url to the repo" do
|
||||||
|
subject.url_to_repo.should == gitlab_shell.url_to_repo(subject.path_with_namespace)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#ssh_url_to_repo" do
|
||||||
|
it "equals #url_to_repo" do
|
||||||
|
subject.ssh_url_to_repo.should == subject.url_to_repo
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#http_url_to_repo" do
|
||||||
|
it "provides the full http url to the repo" do
|
||||||
|
gitlab_url = Gitlab.config.gitlab.url
|
||||||
|
repo_http_url = "#{gitlab_url}/#{subject.path_with_namespace}.git"
|
||||||
|
subject.http_url_to_repo.should == repo_http_url
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#wiki" do
|
||||||
|
it "contains a Gollum::Wiki instance" do
|
||||||
|
subject.wiki.should be_a Gollum::Wiki
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
Gitlab::Shell.any_instance.stub(:add_repository) do
|
||||||
|
create_temp_repo("#{Rails.root}/tmp/test-git-base-path/non-existant.wiki.git")
|
||||||
|
end
|
||||||
|
project.stub(:path_with_namespace).and_return("non-existant")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "creates a new wiki repo if one does not yet exist" do
|
||||||
|
wiki = GollumWiki.new(project, user)
|
||||||
|
wiki.create_page("index", "test content").should_not == false
|
||||||
|
|
||||||
|
FileUtils.rm_rf wiki.send(:path_to_repo)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises CouldNotCreateWikiError if it can't create the wiki repository" do
|
||||||
|
Gitlab::Shell.any_instance.stub(:add_repository).and_return(false)
|
||||||
|
expect { GollumWiki.new(project, user).wiki }.to raise_exception(GollumWiki::CouldNotCreateWikiError)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#pages" do
|
||||||
|
before do
|
||||||
|
create_page("index", "This is an awesome new Gollum Wiki")
|
||||||
|
@pages = subject.pages
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
destroy_page(@pages.first.page)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns an array of WikiPage instances" do
|
||||||
|
@pages.first.should be_a WikiPage
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns the correct number of pages" do
|
||||||
|
@pages.count.should == 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#find_page" do
|
||||||
|
before do
|
||||||
|
create_page("index page", "This is an awesome Gollum Wiki")
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
destroy_page(subject.pages.first.page)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns the latest version of the page if it exists" do
|
||||||
|
page = subject.find_page("index page")
|
||||||
|
page.title.should == "index page"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns nil if the page does not exist" do
|
||||||
|
subject.find_page("non-existant").should == nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "can find a page by slug" do
|
||||||
|
page = subject.find_page("index-page")
|
||||||
|
page.title.should == "index page"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns a WikiPage instance" do
|
||||||
|
page = subject.find_page("index page")
|
||||||
|
page.should be_a WikiPage
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#create_page" do
|
||||||
|
after do
|
||||||
|
destroy_page(subject.pages.first.page)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "creates a new wiki page" do
|
||||||
|
subject.create_page("test page", "this is content").should_not == false
|
||||||
|
subject.pages.count.should == 1
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns false when a duplicate page exists" do
|
||||||
|
subject.create_page("test page", "content")
|
||||||
|
subject.create_page("test page", "content").should == false
|
||||||
|
end
|
||||||
|
|
||||||
|
it "stores an error message when a duplicate page exists" do
|
||||||
|
2.times { subject.create_page("test page", "content") }
|
||||||
|
subject.error_message.should =~ /Duplicate page:/
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sets the correct commit message" do
|
||||||
|
subject.create_page("test page", "some content", :markdown, "commit message")
|
||||||
|
subject.pages.first.page.version.message.should == "commit message"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#update_page" do
|
||||||
|
before do
|
||||||
|
create_page("update-page", "some content")
|
||||||
|
@gollum_page = subject.wiki.paged("update-page")
|
||||||
|
subject.update_page(@gollum_page, "some other content", :markdown, "updated page")
|
||||||
|
@page = subject.pages.first.page
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
destroy_page(@page)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "updates the content of the page" do
|
||||||
|
@page.raw_data.should == "some other content"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sets the correct commit message" do
|
||||||
|
@page.version.message.should == "updated page"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#delete_page" do
|
||||||
|
before do
|
||||||
|
create_page("index", "some content")
|
||||||
|
@page = subject.wiki.paged("index")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "deletes the page" do
|
||||||
|
subject.delete_page(@page)
|
||||||
|
subject.pages.count.should == 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
164
spec/models/wiki_page_spec.rb
Normal file
164
spec/models/wiki_page_spec.rb
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
require "spec_helper"
|
||||||
|
|
||||||
|
describe WikiPage do
|
||||||
|
|
||||||
|
def create_temp_repo(path)
|
||||||
|
FileUtils.mkdir_p path
|
||||||
|
command = "git init --quiet #{path};"
|
||||||
|
system(command)
|
||||||
|
end
|
||||||
|
|
||||||
|
def remove_temp_repo(path)
|
||||||
|
FileUtils.rm_rf path
|
||||||
|
end
|
||||||
|
|
||||||
|
def commit_details
|
||||||
|
commit = {name: user.name, email: user.email, message: "test commit"}
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_page(name, content)
|
||||||
|
wiki.wiki.write_page(name, :markdown, content, commit_details)
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy_page(title)
|
||||||
|
page = wiki.wiki.paged(title)
|
||||||
|
wiki.wiki.delete_page(page, commit_details)
|
||||||
|
end
|
||||||
|
|
||||||
|
let(:project) { create(:project) }
|
||||||
|
let(:repository) { project.repository }
|
||||||
|
let(:user) { project.owner }
|
||||||
|
let(:wiki) { GollumWiki.new(project, user) }
|
||||||
|
|
||||||
|
subject { WikiPage.new(wiki) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
create_temp_repo(wiki.send(:path_to_repo))
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#initialize" do
|
||||||
|
context "when initialized with an existing gollum page" do
|
||||||
|
before do
|
||||||
|
create_page("test page", "test content")
|
||||||
|
@page = wiki.wiki.paged("test page")
|
||||||
|
@wiki_page = WikiPage.new(wiki, @page, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sets the slug attribute" do
|
||||||
|
@wiki_page.slug.should == "test-page"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sets the title attribute" do
|
||||||
|
@wiki_page.title.should == "test page"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sets the formatted content attribute" do
|
||||||
|
@wiki_page.content.should == "test content"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sets the format attribute" do
|
||||||
|
@wiki_page.format.should == :markdown
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sets the message attribute" do
|
||||||
|
@wiki_page.message.should == "test commit"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sets the version attribute" do
|
||||||
|
@wiki_page.version.should be_a Commit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "validations" do
|
||||||
|
before do
|
||||||
|
subject.attributes = {title: 'title', content: 'content'}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "validates presence of title" do
|
||||||
|
subject.attributes.delete(:title)
|
||||||
|
subject.valid?.should be_false
|
||||||
|
end
|
||||||
|
|
||||||
|
it "validates presence of content" do
|
||||||
|
subject.attributes.delete(:content)
|
||||||
|
subject.valid?.should be_false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
before do
|
||||||
|
@wiki_attr = {title: "Index", content: "Home Page", format: "markdown"}
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#create" do
|
||||||
|
after do
|
||||||
|
destroy_page("Index")
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with valid attributes" do
|
||||||
|
it "saves the wiki page" do
|
||||||
|
subject.create(@wiki_attr)
|
||||||
|
wiki.find_page("Index").should_not be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns true" do
|
||||||
|
subject.create(@wiki_attr).should == true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#update" do
|
||||||
|
before do
|
||||||
|
create_page("Update", "content")
|
||||||
|
@page = wiki.find_page("Update")
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
destroy_page("Update")
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with valid attributes" do
|
||||||
|
it "updates the content of the page" do
|
||||||
|
@page.update("new content")
|
||||||
|
@page = wiki.find_page("Update")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns true" do
|
||||||
|
@page.update("more content").should be_true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#destroy" do
|
||||||
|
before do
|
||||||
|
create_page("Delete Page", "content")
|
||||||
|
@page = wiki.find_page("Delete Page")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should delete the page" do
|
||||||
|
@page.delete
|
||||||
|
wiki.pages.should be_empty
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should return true" do
|
||||||
|
@page.delete.should == true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#versions" do
|
||||||
|
before do
|
||||||
|
create_page("Update", "content")
|
||||||
|
@page = wiki.find_page("Update")
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
destroy_page("Update")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns an array of all commits for the page" do
|
||||||
|
3.times { |i| @page.update("content #{i}") }
|
||||||
|
@page.versions.count.should == 4
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in a new issue