lib/ascii_binder/helpers.rb in ascii_binder-0.1.9 vs lib/ascii_binder/helpers.rb in ascii_binder-0.1.10
- old
+ new
@@ -1,901 +1,87 @@
-require 'ascii_binder/template_renderer'
-require 'asciidoctor'
-require 'asciidoctor/cli'
-require 'asciidoctor-diagram'
-require 'fileutils'
-require 'find'
-require 'git'
-require 'logger'
-require 'pandoc-ruby'
-require 'pathname'
-require 'sitemap_generator'
-require 'yaml'
-require 'forwardable'
-
module AsciiBinder
module Helpers
- extend Forwardable
-
- def self.source_dir
- @source_dir ||= `git rev-parse --show-toplevel`.chomp
- end
-
- def self.gem_root_dir
- @gem_root_dir ||= File.expand_path("../../../", __FILE__)
- end
-
- def self.set_source_dir(source_dir)
- @source_dir = source_dir
- end
-
- def template_renderer
- @template_renderer ||= TemplateRenderer.new(source_dir, template_dir)
- end
-
- def self.template_dir
- @template_dir ||= File.join(source_dir,'_templates')
- end
-
- def self.preview_dir
- @preview_dir ||= begin
- lpreview_dir = File.join(source_dir,PREVIEW_DIRNAME)
- if not File.exists?(lpreview_dir)
- Dir.mkdir(lpreview_dir)
- end
- lpreview_dir
- end
- end
-
- def self.package_dir
- @package_dir ||= begin
- lpackage_dir = File.join(source_dir,PACKAGE_DIRNAME)
- if not File.exists?(lpackage_dir)
- Dir.mkdir(lpackage_dir)
- end
- lpackage_dir
- end
- end
-
- def self.stylesheet_dir
- @stylesheet_dir ||= File.join(source_dir,STYLESHEET_DIRNAME)
- end
-
- def self.javascript_dir
- @javascript_dir ||= File.join(source_dir,JAVASCRIPT_DIRNAME)
- end
-
- def self.image_dir
- @image_dir ||= File.join(source_dir,IMAGE_DIRNAME)
- end
-
- def_delegators self, :source_dir, :set_source_dir, :template_dir, :preview_dir, :package_dir, :gem_root_dir, :stylesheet_dir, :javascript_dir, :image_dir
-
BUILD_FILENAME = '_build_cfg.yml'
TOPIC_MAP_FILENAME = '_topic_map.yml'
DISTRO_MAP_FILENAME = '_distro_map.yml'
PREVIEW_DIRNAME = '_preview'
PACKAGE_DIRNAME = '_package'
STYLESHEET_DIRNAME = '_stylesheets'
JAVASCRIPT_DIRNAME = '_javascripts'
IMAGE_DIRNAME = '_images'
BLANK_STRING_RE = Regexp.new('^\s*$')
- IFDEF_STRING_RE = Regexp.new('ifdef::(.+?)\[\]')
+ ID_STRING_RE = Regexp.new('^[A-Za-z0-9\-\_]+$')
- def build_date
- Time.now.utc
+ def valid_id?(check_id)
+ return false unless check_id.is_a?(String)
+ return false unless check_id.match ID_STRING_RE
+ return true
end
- def notice(hey,message,newline = false)
- # TODO: (maybe) redirect everything to stderr
- if newline
- puts "\n"
- end
- puts "#{hey}: #{message}"
+ def valid_string?(check_string)
+ return false unless check_string.is_a?(String)
+ return false unless check_string.length > 0
+ return false if check_string.match BLANK_STRING_RE
+ return true
end
- def warning(message,newline = false)
- notice("WARNING",message,newline)
+ def camelize(text)
+ text.gsub(/[^0-9a-zA-Z ]/i, '').split(' ').map{ |t| t.capitalize }.join
end
- def nl_warning(message)
- warning(message,true)
+ def git_root_dir
+ @git_root_dir ||= `git rev-parse --show-toplevel`.chomp
end
- def git
- @git ||= Git.open(source_dir)
+ def gem_root_dir
+ @gem_root_dir ||= File.expand_path("../../../", __FILE__)
end
- def git_checkout branch_name
- target_branch = git.branches.local.select{ |b| b.name == branch_name }[0]
- if not target_branch.nil? and not target_branch.current
- target_branch.checkout
- end
+ def set_docs_root_dir(docs_root_dir)
+ AsciiBinder.const_set("DOCS_ROOT_DIR", docs_root_dir)
end
- def git_stash_all
- # See if there are any changes in need of stashing
- @stash_needed = `cd #{source_dir} && git status --porcelain` !~ /^\s*$/
- if @stash_needed
- puts "\nNOTICE: Stashing uncommited changes and files in working branch."
- `cd #{source_dir} && git stash -u`
- end
+ def docs_root_dir
+ AsciiBinder::DOCS_ROOT_DIR
end
- def git_apply_and_drop
- return unless @stash_needed
- puts "\nNOTE: Re-applying uncommitted changes and files to working branch."
- if system("cd #{source_dir} && git stash pop")
- puts "NOTE: Stash application successful."
- else
- puts "ERROR: Could not apply stashed code. Run `git stash apply` manually."
- end
- @stash_needed = false
+ def template_renderer
+ @template_renderer ||= TemplateRenderer.new(docs_root_dir, template_dir)
end
- # Returns the local git branches; current branch is always first
- def local_branches
- @local_branches ||= begin
- branches = []
- if not git.branches.local.empty?
- branches << git.branches.local.select{ |b| b.current }[0].name
- branches << git.branches.local.select{ |b| not b.current }.map{ |b| b.name }
- end
- branches.flatten
- end
+ def template_dir
+ @template_dir ||= File.join(docs_root_dir,'_templates')
end
- def working_branch
- @working_branch ||= local_branches[0]
- end
-
- def build_config_file
- use_file = TOPIC_MAP_FILENAME
- unless File.exist?(File.join(source_dir,TOPIC_MAP_FILENAME))
- # The new filename '_topic_map.yml' couldn't be found;
- # switch to the old one and warn the user.
- use_file = BUILD_FILENAME
- warning "'#{BUILD_FILENAME}' is a deprecated filename. Rename this to '#{TOPIC_MAP_FILENAME}'."
- end
- use_file
- end
-
- def distro_map_file
- @distro_map_file ||= File.join(source_dir, DISTRO_MAP_FILENAME)
- end
-
- def dir_empty?(dir)
- Dir.entries(dir).select{ |f| not f.start_with?('.') }.empty?
- end
-
- # Protip: Don't cache this! It needs to be reread every time we change branches.
- def build_config
- validate_config(YAML.load_stream(open(File.join(source_dir,build_config_file))))
- end
-
- def create_new_repo
- gem_template_dir = File.join(gem_root_dir,"templates")
-
- # Create the new repo dir
- FileUtils.mkdir_p(source_dir)
-
- # Copy the basic repo content into the new repo dir
- Find.find(gem_template_dir).each do |path|
- next if path == gem_template_dir
- src_path = Pathname.new(path)
- tgt_path = src_path.sub(gem_template_dir,source_dir)
- if src_path.directory?
- FileUtils.mkdir_p(tgt_path.to_s)
- else
- FileUtils.cp src_path.to_s, tgt_path.to_s
+ def preview_dir
+ @preview_dir ||= begin
+ lpreview_dir = File.join(docs_root_dir,PREVIEW_DIRNAME)
+ if not File.exists?(lpreview_dir)
+ Dir.mkdir(lpreview_dir)
end
+ lpreview_dir
end
-
- # Initialize the git repo
- Git.init(source_dir)
end
- def find_topic_files
- file_list = []
- Find.find(source_dir).each do |path|
- # Only consider .adoc files and ignore README, and anything in
- # directories whose names begin with 'old' or '_' (underscore)
- next if path.nil? or not path =~ /.*\.adoc/ or path =~ /README/ or path =~ /\/old\// or path =~ /\/_/
- src_path = Pathname.new(path).sub(source_dir,'').to_s
- next if src_path.split('/').length < 3
- file_list << src_path
- end
- file_list.map{ |path|
- parts = path.split('/').slice(1..-1);
- parts.slice(0..-2).join('/') + '/' + parts[-1].split('.')[0]
- }
- end
-
- def remove_found_config_files(branch,branch_build_config,branch_topic_files)
- nonexistent_topics = []
- branch_build_config.each do |topic_group|
- tg_dir = topic_group['Dir']
- topic_group['Topics'].each do |topic|
- if topic.has_key?('File')
- topic_path = tg_dir + '/' + topic['File']
- result = branch_topic_files.delete(topic_path)
- if result.nil?
- nonexistent_topics << topic_path
- end
- elsif topic.has_key?('Dir')
- topic_path = tg_dir + '/' + topic['Dir'] + '/'
- topic['Topics'].each do |subtopic|
- result = branch_topic_files.delete(topic_path + subtopic['File'])
- if result.nil?
- nonexistent_topics << topic_path + subtopic['File']
- end
- end
- end
+ def package_dir
+ @package_dir ||= begin
+ lpackage_dir = File.join(docs_root_dir,PACKAGE_DIRNAME)
+ if not File.exists?(lpackage_dir)
+ Dir.mkdir(lpackage_dir)
end
+ lpackage_dir
end
- if nonexistent_topics.length > 0
- nl_warning "The #{build_config_file} file on branch '#{branch}' references nonexistant topics:\n" + nonexistent_topics.map{ |topic| "- #{topic}" }.join("\n")
- end
end
- def distro_map
- @distro_map ||= YAML.load_file(distro_map_file)
+ def stylesheet_dir
+ @stylesheet_dir ||= File.join(docs_root_dir,STYLESHEET_DIRNAME)
end
- def site_map
- site_map = {}
- distro_map.each do |distro,distro_config|
- if not site_map.has_key?(distro_config["site"])
- site_map[distro_config["site"]] = { :distros => {}, :name => distro_config['site_name'], :url => distro_config['site_url'], :branches => ['master'] }
- end
- site_map[distro_config["site"]][:distros][distro] = distro_config["branches"]
- distro_config["branches"].keys.each do |branch_key|
- next if site_map[distro_config["site"]][:branches].include?(branch_key)
- site_map[distro_config["site"]][:branches] << branch_key
- end
- end
- site_map
+ def javascript_dir
+ @javascript_dir ||= File.join(docs_root_dir,JAVASCRIPT_DIRNAME)
end
- def distro_branches(use_distro='')
- use_distro_list = use_distro == '' ? distro_map.keys : [use_distro]
- distro_map.select{ |dkey,dval| use_distro_list.include?(dkey) }.map{ |distro,dconfig| dconfig["branches"].keys }.flatten.uniq
- end
-
- def branch_group_branches
- @branch_group_branches ||= begin
- group_branches = Hash.new
- group_branches[:working_only] = [local_branches[0]]
- group_branches[:publish] = distro_branches
- site_map.each do |site,site_config|
- group_branches["publish_#{site}".to_sym] = site_config[:branches]
- end
- group_branches[:all] = local_branches
- group_branches
- end
- end
-
- def page(args)
- # TODO: This process of rebuilding the entire nav for every page will not scale well.
- # As the doc set increases, we will need to think about refactoring this.
- args[:breadcrumb_root], args[:breadcrumb_group], args[:breadcrumb_subgroup], args[:breadcrumb_topic] = extract_breadcrumbs(args)
-
- args[:breadcrumb_subgroup_block] = ''
- args[:subtopic_shim] = ''
- if args[:breadcrumb_subgroup]
- args[:breadcrumb_subgroup_block] = "<li class=\"hidden-xs active\">#{args[:breadcrumb_subgroup]}</li>"
- args[:subtopic_shim] = '../'
- end
-
- template_path = File.expand_path("#{source_dir}/_templates/page.html.erb")
- template_renderer.render(template_path, args)
- end
-
- def extract_breadcrumbs(args)
- breadcrumb_root = breadcrumb_group = breadcrumb_subgroup = breadcrumb_topic = nil
-
- root_group = args[:navigation].first
- selected_group = args[:navigation].detect { |group| group[:id] == args[:group_id] }
- selected_subgroup = selected_group[:topics].detect { |subgroup| subgroup[:id] == args[:subgroup_id] }
- current_is_subtopic = selected_subgroup ? true : false
-
- if root_group
- root_topic = root_group[:topics].first
- breadcrumb_root = linkify_breadcrumb(root_topic[:path], "#{args[:distro]} #{args[:version]}", current_is_subtopic) if root_topic
- end
-
- if selected_group
- group_topic = selected_group[:topics].first
- breadcrumb_group = linkify_breadcrumb(group_topic[:path], selected_group[:name], current_is_subtopic) if group_topic
-
- if selected_subgroup
- subgroup_topic = selected_subgroup[:topics].first
- breadcrumb_subgroup = linkify_breadcrumb(subgroup_topic[:path], selected_subgroup[:name], current_is_subtopic) if subgroup_topic
-
- selected_topic = selected_subgroup[:topics].detect { |topic| topic[:id] == args[:topic_id] }
- breadcrumb_topic = linkify_breadcrumb(nil, selected_topic[:name], current_is_subtopic) if selected_topic
- else
- selected_topic = selected_group[:topics].detect { |topic| topic[:id] == args[:topic_id] }
- breadcrumb_topic = linkify_breadcrumb(nil, selected_topic[:name], current_is_subtopic) if selected_topic
- end
- end
-
- return breadcrumb_root, breadcrumb_group, breadcrumb_subgroup, breadcrumb_topic
- end
-
- def linkify_breadcrumb(href, text, extra_level)
- addl_level = extra_level ? '../' : ''
- href ? "<a href=\"#{addl_level}#{href}\">#{text}</a>" : text
- end
-
- def parse_distros distros_string, for_validation=false
- values = distros_string.split(',').map(&:strip)
- # Don't bother with glob expansion if 'all' is in the list.
- return distro_map.keys if values.include?('all')
-
- expanded = expand_distro_globs(values)
- return expanded if for_validation
- return expanded.uniq
- end
-
- def expand_distro_globs(values)
- values.flat_map do |value|
- value_regex = Regexp.new("\\A#{value.gsub("*", ".*")}\\z")
- distro_map.keys.select { |k| value_regex.match(k) }
- end.uniq
- end
-
- def validate_distros distros_string
- return false if not distros_string.is_a?(String)
- values = parse_distros(distros_string, true)
- values.each do |v|
- return false if not v == 'all' and not distro_map.keys.include?(v)
- end
- return true
- end
-
- def validate_topic_group group, info
- # Check for presence of topic group keys
- ['Name','Dir','Topics'].each do |group_key|
- if not group.has_key?(group_key)
- raise "One of the topic groups in #{build_config_file} is missing the '#{group_key}' key."
- end
- end
- # Check for right format of topic group values
- ['Name','Dir'].each do |group_key|
- if [true, false].include?(group[group_key])
- raise "One of the topic groups in #{build_config_file} is using a reserved YAML keyword for the #{group_key} setting. In order to prevent your text from being turned into a true/false value, wrap it in quotes."
- end
- if not group[group_key].kind_of?(String)
- raise "One of the topic groups in #{build_config_file} is not using a string for the #{group_key} setting; current value is #{group[group_key].inspect}"
- end
- if group[group_key].empty? or group[group_key].match BLANK_STRING_RE
- raise "One of the topic groups in #{build_config_file} is using a blank value for the #{group_key} setting."
- end
- end
- if not File.exists?(File.join(source_dir,info[:path]))
- raise "In #{build_config_file}, the directory path '#{info[:path]}' for topic group #{group['Name']} does not exist under #{source_dir}"
- end
- # Validate the Distros setting
- if group.has_key?('Distros')
- if not validate_distros(group['Distros'])
- key_list = distro_map.keys.map{ |k| "'#{k}'" }.sort.join(', ')
- raise "In #{build_config_file}, the Distros value #{group['Distros'].inspect} for topic group #{group['Name']} is not valid. Legal values are 'all', #{key_list}, or a comma-separated list of legal values."
- end
- group['Distros'] = parse_distros(group['Distros'])
- else
- group['Distros'] = parse_distros('all')
- end
- if not group['Topics'].is_a?(Array)
- raise "The #{group['Name']} topic group in #{build_config_file} is malformed; the build system is expecting an array of 'Topic' definitions."
- end
- # Generate an ID for this topic group
- group['ID'] = camelize group['Name']
- if info.has_key?(:parent_id)
- group['ID'] = "#{info[:parent_id]}::#{group['ID']}"
- end
- end
-
- def validate_topic_item item, info
- ['Name','File'].each do |topic_key|
- if not item[topic_key].is_a?(String)
- raise "In #{build_config_file}, topic group #{info[:group]}, one of the topics is not using a string for the '#{topic_key}' setting; current value is #{item[topic_key].inspect}"
- end
- if item[topic_key].empty? or item[topic_key].match BLANK_STRING_RE
- raise "In #{build_config_file}, topic group #{topic_group['Name']}, one of the topics is using a blank value for the '#{topic_key}' setting"
- end
- end
- # Normalize the filenames
- if item['File'].end_with?('.adoc')
- item['File'] = item['File'][0..-6]
- end
- if not File.exists?(File.join(source_dir,info[:path],"#{item['File']}.adoc"))
- raise "In #{build_config_file}, could not find file #{item['File']} under directory #{info[:path]} for topic #{item['Name']} in topic group #{info[:group]}."
- end
- if item.has_key?('Distros')
- if not validate_distros(item['Distros'])
- key_list = distro_map.keys.map{ |k| "'#{k}'" }.sort.join(', ')
- raise "In #{build_config_file}, the Distros value #{item['Distros'].inspect} for topic item #{item['Name']} in topic group #{info[:group]} is not valid. Legal values are 'all', #{key_list}, or a comma-separated list of legal values."
- end
- item['Distros'] = parse_distros(item['Distros'])
- else
- item['Distros'] = parse_distros('all')
- end
- # Generate an ID for this topic
- item['ID'] = "#{info[:group_id]}::#{camelize(item['Name'])}"
- end
-
- def validate_config config_data
- # Validate/normalize the config file straight away
- if not config_data.is_a?(Array)
- raise "The configuration in #{build_config_file} is malformed; the build system is expecting an array of topic groups."
- end
- config_data.each do |topic_group|
- validate_topic_group(topic_group, { :path => topic_group['Dir'] })
- # Now buzz through the topics
- topic_group['Topics'].each do |topic|
- # Is this an actual topic or a subtopic group?
- is_subtopic_group = topic.has_key?('Dir') and topic.has_key?('Topics') and not topic.has_key?('File')
- is_topic_item = topic.has_key?('File') and not topic.has_key?('Dir') and not topic.has_key?('Topics')
- if not is_subtopic_group and not is_topic_item
- raise "This topic could not definitively be determined to be a topic item or a subtopic group:\n#{topic.inspect}"
- end
- if is_topic_item
- validate_topic_item(topic, { :group => topic_group['Name'], :group_id => topic_group['ID'], :path => topic_group['Dir'] })
- elsif is_subtopic_group
- topic_path = "#{topic_group['Dir']}/#{topic['Dir']}"
- validate_topic_group(topic, { :path => topic_path, :parent_id => topic_group['ID'] })
- topic['Topics'].each do |subtopic|
- validate_topic_item(subtopic, { :group => "#{topic_group['Name']}/#{topic['Name']}", :group_id => topic['ID'], :path => topic_path })
- end
- end
- end
- end
- config_data
- end
-
- def camelize text
- text.gsub(/[^0-9a-zA-Z ]/i, '').split(' ').map{ |t| t.capitalize }.join
- end
-
- def nav_tree distro, branch_build_config
- navigation = []
- branch_build_config.each do |topic_group|
- next if not topic_group['Distros'].include?(distro)
- next if topic_group['Topics'].select{ |t| t['Distros'].include?(distro) }.length == 0
- topic_list = []
- topic_group['Topics'].each do |topic|
- next if not topic['Distros'].include?(distro)
- if topic.has_key?('File')
- topic_list << {
- :path => "../#{topic_group['Dir']}/#{topic['File']}.html",
- :name => topic['Name'],
- :id => topic['ID'],
- }
- elsif topic.has_key?('Dir')
- next if topic['Topics'].select{ |t| t['Distros'].include?(distro) }.length == 0
- subtopic_list = []
- topic['Topics'].each do |subtopic|
- next if not subtopic['Distros'].include?(distro)
- subtopic_list << {
- :path => "../#{topic_group['Dir']}/#{topic['Dir']}/#{subtopic['File']}.html",
- :name => subtopic['Name'],
- :id => subtopic['ID'],
- }
- end
- topic_list << { :name => topic['Name'], :id => topic['ID'], :topics => subtopic_list }
- end
- end
- navigation << { :name => topic_group['Name'], :id => topic_group['ID'], :topics => topic_list }
- end
- navigation
- end
-
- def asciidoctor_page_attrs(more_attrs=[])
- [
- 'source-highlighter=coderay',
- 'coderay-css=style',
- 'linkcss!',
- 'icons=font',
- 'idprefix=',
- 'idseparator=-',
- 'sectanchors',
- 'data-uri',
- ].concat(more_attrs)
- end
-
- def generate_docs(branch_group,build_distro,single_page)
- # First, test to see if the docs repo has any commits. If the user has just
- # run `asciibinder create`, there will be no commits to work from, yet.
- if local_branches.empty?
- raise "Before you can build the docs, you need at least one commit in your docs repo."
- end
-
- single_page_dir = []
- single_page_file = nil
- if not single_page.nil?
- single_page_dir = single_page.split(':')[0].split('/')
- single_page_file = single_page.split(':')[1]
- puts "Rebuilding '#{single_page_dir.join('/')}/#{single_page_file}' on branch '#{working_branch}'."
- end
-
- if not build_distro == ''
- if not distro_map.has_key?(build_distro)
- exit
- else
- puts "Building only the #{distro_map[build_distro]["name"]} distribution."
- end
- elsif single_page.nil?
- puts "Building all distributions."
- end
-
- # First, notify the user of missing local branches
- missing_branches = []
- distro_branches(build_distro).sort.each do |dbranch|
- next if local_branches.include?(dbranch)
- missing_branches << dbranch
- end
- if missing_branches.length > 0 and single_page.nil?
- puts "\nNOTE: The following branches do not exist in your local git repo:"
- missing_branches.each do |mbranch|
- puts "- #{mbranch}"
- end
- puts "The build will proceed but these branches will not be generated."
- end
-
- # Generate all distros for all branches in the indicated branch group
- branch_group_branches[branch_group].each do |local_branch|
- # Skip known missing branches; this will only come up for the :publish branch group
- next if missing_branches.include?(local_branch)
-
- # Single-page regen only occurs for the working branch
- if not local_branch == working_branch
- if single_page.nil?
- # Checkout the branch
- puts "\nCHANGING TO BRANCH '#{local_branch}'"
- git_checkout(local_branch)
- else
- next
- end
- end
-
- # Note the image files checked in to this branch.
- branch_image_files = Find.find(source_dir).select{ |path| not path.nil? and (path =~ /.*\.png$/ or path =~ /.*\.png\.cache$/) }
-
- first_branch = single_page.nil?
-
- if local_branch =~ /^\(detached from .*\)/
- local_branch = 'detached'
- end
-
- # The branch_orphan_files list starts with the set of all
- # .adoc files found in the repo, and will be whittled
- # down from there.
- branch_orphan_files = find_topic_files
- branch_build_config = build_config
- remove_found_config_files(local_branch,branch_build_config,branch_orphan_files)
-
- if branch_orphan_files.length > 0 and single_page.nil?
- nl_warning "Branch '#{local_branch}' includes the following .adoc files that are not referenced in the #{build_config_file} file:\n" + branch_orphan_files.map{ |file| "- #{file}" }.join("\n")
- end
-
- # Run all distros.
- distro_map.each do |distro,distro_config|
- if not build_distro == ''
- # Only building a single distro; build for all indicated branches, skip the others.
- if not build_distro == distro
- next
- end
- else
- current_distro_branches = distro_branches(distro)
-
- # In publish mode we only build "valid" distro-branch combos from the distro map
- if branch_group.to_s.start_with?("publish") and not current_distro_branches.include?(local_branch)
- next
- end
-
- # In "build all" mode we build every distro on the working branch plus the publish distro-branch combos
- if branch_group == :all and not local_branch == working_branch and not current_distro_branches.include?(local_branch)
- next
- end
- end
-
- site_name = distro_config["site_name"]
-
- branch_config = { "name" => "Branch Build", "dir" => local_branch }
- dev_branch = true
- if distro_config["branches"].has_key?(local_branch)
- branch_config = distro_config["branches"][local_branch]
- dev_branch = false
- end
-
- if first_branch
- puts "\nBuilding #{distro_config["name"]} for branch '#{local_branch}'"
- first_branch = false
- end
-
- # Create the target dir
- branch_path = File.join(preview_dir,distro,branch_config["dir"])
- branch_stylesheet_dir = File.join(branch_path,STYLESHEET_DIRNAME)
- branch_javascript_dir = File.join(branch_path,JAVASCRIPT_DIRNAME)
- branch_image_dir = File.join(branch_path,IMAGE_DIRNAME)
-
- # Copy files into the preview area.
- [[stylesheet_dir, '*css', branch_stylesheet_dir],
- [javascript_dir, '*js', branch_javascript_dir],
- [image_dir, '*', branch_image_dir]].each do |dgroup|
- src_dir = dgroup[0]
- glob = dgroup[1]
- tgt_dir = dgroup[2]
- if Dir.exist?(src_dir) and not dir_empty?(src_dir)
- FileUtils.mkdir_p tgt_dir
- FileUtils.cp_r Dir.glob(File.join(src_dir,glob)), tgt_dir
- end
- end
-
- # Build the landing page
- navigation = nav_tree(distro,branch_build_config)
-
- # Build the topic files for this branch & distro
- branch_build_config.each do |topic_group|
- next if not topic_group['Distros'].include?(distro)
- next if topic_group['Topics'].select{ |t| t['Distros'].include?(distro) }.length == 0
- next if not single_page.nil? and not single_page_dir[0] == topic_group['Dir']
- topic_group['Topics'].each do |topic|
- src_group_path = File.join(source_dir,topic_group['Dir'])
- tgt_group_path = File.join(branch_path,topic_group['Dir'])
- if not File.exists?(tgt_group_path)
- Dir.mkdir(tgt_group_path)
- end
- next if not topic['Distros'].include?(distro)
- if topic.has_key?('File')
- next if not single_page.nil? and not topic['File'] == single_page_file
- topic_path = File.join(topic_group['Dir'],topic['File'])
- configure_and_generate_page({
- :distro => distro,
- :distro_config => distro_config,
- :branch_config => branch_config,
- :navigation => navigation,
- :topic => topic,
- :topic_group => topic_group,
- :topic_path => topic_path,
- :src_group_path => src_group_path,
- :tgt_group_path => tgt_group_path,
- :single_page => single_page,
- :site_name => site_name,
- })
- elsif topic.has_key?('Dir')
- next if not single_page.nil? and not single_page_dir.join('/') == topic_group['Dir'] + '/' + topic['Dir']
- topic['Topics'].each do |subtopic|
- next if not subtopic['Distros'].include?(distro)
- next if not single_page.nil? and not subtopic['File'] == single_page_file
- src_group_path = File.join(source_dir,topic_group['Dir'],topic['Dir'])
- tgt_group_path = File.join(branch_path,topic_group['Dir'],topic['Dir'])
- if not File.exists?(tgt_group_path)
- Dir.mkdir(tgt_group_path)
- end
- topic_path = File.join(topic_group['Dir'],topic['Dir'],subtopic['File'])
- configure_and_generate_page({
- :distro => distro,
- :distro_config => distro_config,
- :branch_config => branch_config,
- :navigation => navigation,
- :topic => subtopic,
- :topic_group => topic_group,
- :topic_subgroup => topic,
- :topic_path => topic_path,
- :src_group_path => src_group_path,
- :tgt_group_path => tgt_group_path,
- :single_page => single_page,
- :site_name => site_name,
- })
- end
- end
- end
- end
-
- if not single_page.nil?
- next
- end
-
- # Create a distro landing page
- # This is backwards compatible code. We can remove it when no
- # official repo uses index.adoc. We are moving to flat HTML
- # files for index.html
- src_file_path = File.join(source_dir,'index.adoc')
- if File.exists?(src_file_path)
- topic_adoc = File.open(src_file_path,'r').read
- page_attrs = asciidoctor_page_attrs([
- "imagesdir=#{File.join(source_dir,'_site_images')}",
- distro,
- "product-title=#{distro_config["name"]}",
- "product-version=Updated #{build_date}",
- "product-author=#{distro_config["author"]}"
- ])
- topic_html = Asciidoctor.render topic_adoc, :header_footer => true, :safe => :unsafe, :attributes => page_attrs
- File.write(File.join(preview_dir,distro,'index.html'),topic_html)
- end
- end
-
- if not single_page.nil?
- return
- end
-
- # Remove DITAA-generated images
- ditaa_image_files = Find.find(source_dir).select{ |path| not path.nil? and not (path =~ /_preview/ or path =~ /_package/) and (path =~ /.*\.png$/ or path =~ /.*\.png\.cache$/) and not branch_image_files.include?(path) }
- if not ditaa_image_files.empty?
- puts "\nRemoving ditaa-generated files from repo before changing branches."
- ditaa_image_files.each do |dfile|
- File.unlink(dfile)
- end
- end
-
- if local_branch == working_branch
- # We're moving away from the working branch, so save off changed files
- git_stash_all
- end
- end
-
- # Return to the original branch
- git_checkout(working_branch)
-
- # If necessary, restore temporarily stashed files
- git_apply_and_drop
-
- puts "\nAll builds completed."
- end
-
- def configure_and_generate_page options
- distro = options[:distro]
- distro_config = options[:distro_config]
- branch_config = options[:branch_config]
- navigation = options[:navigation]
- topic = options[:topic]
- topic_group = options[:topic_group]
- topic_subgroup = options[:topic_subgroup]
- topic_path = options[:topic_path]
- src_group_path = options[:src_group_path]
- tgt_group_path = options[:tgt_group_path]
- single_page = options[:single_page]
- site_name = options[:site_name]
-
- # Distro Map settings can be overridden on a per-branch
- # basis. This only works for top-level (string) values
- # of the distro config and -not- the 'site' key.
- branchwise_distro_config = {}
- distro_config.each do |key,value|
- next unless distro_config[key].kind_of?(String)
- branchwise_distro_config[key] = value
- end
- if branch_config.has_key?('distro-overrides')
- branch_config['distro-overrides'].each do |key,value|
- if key == 'site'
- puts "WARNING: The 'site' value of the distro config cannot be overriden on a branch-by-branch basis."
- next
- end
- branchwise_distro_config[key] = value
- end
- end
-
- src_file_path = File.join(src_group_path,"#{topic['File']}.adoc")
- tgt_file_path = File.join(tgt_group_path,"#{topic['File']}.html")
- if single_page.nil?
- puts " - #{topic_path}"
- end
- topic_adoc = File.open(src_file_path,'r').read
- page_attrs = asciidoctor_page_attrs([
- "imagesdir=#{src_group_path}/images",
- distro,
- "product-title=#{branchwise_distro_config["name"]}",
- "product-version=#{branch_config["name"]}",
- "product-author=#{branchwise_distro_config["author"]}"
- ])
-
- doc = Asciidoctor.load topic_adoc, :header_footer => false, :safe => :unsafe, :attributes => page_attrs
- article_title = doc.doctitle || topic['Name']
-
- topic_html = doc.render
- dir_depth = ''
- if branch_config['dir'].split('/').length > 1
- dir_depth = '../' * (branch_config['dir'].split('/').length - 1)
- end
- if not topic_subgroup.nil?
- dir_depth = '../' + dir_depth
- end
- page_args = {
- :distro_key => distro,
- :distro => branchwise_distro_config["name"],
- :site_name => site_name,
- :site_url => branchwise_distro_config["site_url"],
- :topic_url => "#{branch_config['dir']}/#{topic_path}.html",
- :version => branch_config["name"],
- :group_title => topic_group['Name'],
- :subgroup_title => topic_subgroup && topic_subgroup['Name'],
- :topic_title => topic['Name'],
- :article_title => article_title,
- :content => topic_html,
- :navigation => navigation,
- :group_id => topic_group['ID'],
- :subgroup_id => topic_subgroup && topic_subgroup['ID'],
- :topic_id => topic['ID'],
- :css_path => "../../#{dir_depth}#{branch_config["dir"]}/#{STYLESHEET_DIRNAME}/",
- :javascripts_path => "../../#{dir_depth}#{branch_config["dir"]}/#{JAVASCRIPT_DIRNAME}/",
- :images_path => "../../#{dir_depth}#{branch_config["dir"]}/#{IMAGE_DIRNAME}/",
- :site_home_path => "../../#{dir_depth}index.html",
- :template_path => template_dir,
- }
- full_file_text = page(page_args)
- File.write(tgt_file_path,full_file_text)
- end
-
- # package_docs
- # This method generates the docs and then organizes them the way they will be arranged
- # for the production websites.
- def package_docs(package_site)
- site_map.each do |site,site_config|
- next if not package_site == '' and not package_site == site
- site_config[:distros].each do |distro,branches|
- branches.each do |branch,branch_config|
- src_dir = File.join(preview_dir,distro,branch_config["dir"])
- tgt_tdir = branch_config["dir"].split('/')
- tgt_tdir.pop
- tgt_dir = ''
- if tgt_tdir.length > 0
- tgt_dir = File.join(package_dir,site,tgt_tdir.join('/'))
- else
- tgt_dir = File.join(package_dir,site)
- end
- next if not File.directory?(src_dir)
- FileUtils.mkdir_p(tgt_dir)
- FileUtils.cp_r(src_dir,tgt_dir)
- end
- site_dir = File.join(package_dir,site)
- if File.directory?(site_dir)
- puts "\nBuilding #{site} site."
-
- # Any files in the root of the docs repo with names ending in:
- # *-#{site}.html
- # will get copied into the root dir of the packaged site with
- # the site name stripped out.
- #
- # Example: for site name 'commercial', the files:
- # * index-commercial.html would end up as #{site_root}/index.html
- # * search-commercial.html would end up as #{site_root}/search.html
- # * index-community.html would be ignored
- site_files = Dir.glob(File.join(source_dir, '*-' + site + '.html'))
- unless site_files.empty?
- site_files.each do |fpath|
- target_basename = File.basename(fpath).gsub(/-#{site}\.html$/, '.html')
- FileUtils.cp(fpath,File.join(package_dir,site,target_basename))
- end
- else
- FileUtils.cp(File.join(preview_dir,distro,'index.html'),File.join(package_dir,site,'index.html'))
- end
- ['_images','_stylesheets'].each do |support_dir|
- FileUtils.cp_r(File.join(source_dir,support_dir),File.join(package_dir,site,support_dir))
- end
-
- # Now build a sitemap
- site_dir_path = Pathname.new(site_dir)
- SitemapGenerator::Sitemap.create(
- :default_host => site_config[:url],
- :public_path => site_dir_path,
- :compress => false,
- :filename => File.join(site_dir,'sitemap')
- ) do
- file_list = Find.find(site_dir).select{ |path| not path.nil? and path =~ /.*\.html$/ }.map{ |path| '/' + Pathname.new(path).relative_path_from(site_dir_path).to_s }
- file_list.each do |file|
- add(file, :changefreq => 'daily')
- end
- end
- end
- end
- end
- end
-
- def clean_up
- if not system("rm -rf #{source_dir}/_preview/* #{source_dir}/_package/*")
- puts "Nothing to clean."
- end
+ def image_dir
+ @image_dir ||= File.join(docs_root_dir,IMAGE_DIRNAME)
end
end
end