gitlabhq/lib/wiki_to_gollum_migrator.rb
Dan Knox 330fe4162e Fix Wiki migration task and add more test coverage.
There was an error in the #extract_attributes_from_page method that
caused an exception when checking to see if a page named "Home"
already exists.

The check occurs to handle the renaming of the main index page to
"Home" to match the Gollum standard. If there is already a page
called "Home" then the migrator will leave that page and create
the Index page as usual. Users will need to manually rename their
old "Home" page to something else then rename their "Index" page
to "Home". Fortunately, I would be highly surprised if this case
ever comes up.

I also added more verbosity to the logging so if an error does
occur, it will be easier to track down which Wiki page is causing
the problem.
2013-03-16 18:01:48 -07:00

125 lines
3.4 KiB
Ruby

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
def rollback!
log "\nBeginning Wiki Migration Rollback..."
projects.each do |project|
destroy_gollum_repo project
end
log "\nWiki Rollback Complete."
end
private
def create_gollum_repo(project)
GollumWiki.new(project, nil).wiki
end
def destroy_gollum_repo(project)
log " Removing Wiki repo for project: #{project.path_with_namespace}"
path = GollumWiki.new(project, nil).path_with_namespace
if Gitlab::Shell.new.remove_repository(path)
log " Wiki destroyed successfully. " + "[OK}".green
else
log " Problem destroying wiki. Please remove it manually. " + "[FAILED]".red
end
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, project)
log " Creating page '#{first_rev.title}'..."
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)
log " Creating revisions..."
revisions.each do |revision|
# 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, project)
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, project)
attributes = page.attributes
.with_indifferent_access
.slice(:title, :content)
slug = page.slug
# Change 'index' pages to 'home' pages to match Gollum standards
if slug.downcase == "index"
attributes[:title] = "home" unless home_already_exists?(project)
end
attributes
end
def home_already_exists?(project)
project.wikis.where(slug: 'home').any? || project.wikis.where(slug: 'Home').any?
end
def log(message)
puts message
end
end