330fe4162e
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.
125 lines
3.4 KiB
Ruby
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
|