# encoding: utf-8 # Copyright:: Copyright (c) 2015 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # require 'erb' require 'ruby-progressbar' require 'fileutils' require 'yaml' require_relative './shared' WWW_DIR = File.expand_path(File.join(__dir__, '..', 'www')).freeze DOCS_DIR = File.expand_path(File.join(__dir__, '..', 'docs')).freeze begin require 'git' require_relative './contrib' rescue LoadError puts 'contrib tasks are unavailable because the git gem is not available.' end class Markdown class << self def h1(msg) "# #{msg}\n\n" end def h2(msg) "## #{msg}\n\n" end def h3(msg) "### #{msg}\n\n" end def code(msg, syntax = nil) "```#{syntax}\n"\ "#{msg}\n"\ "```\n\n" end def li(msg) "* #{msg.gsub("\n", "\n ")}\n" end def ul(msg) msg + "\n" end def p(msg) "#{msg}\n\n" end def a(name, dst = nil) dst ||= name "[#{name}](#{dst})" end def suffix '.md' end def meta(opts) o = opts.map { |k, v| "#{k}: #{v}" }.join("\n") "---\n#{o}\n---\n\n" end end end class RST class << self def h1(msg) "=====================================================\n"\ "#{msg}\n"\ "=====================================================\n\n"\ end def h2(msg) "#{msg}\n"\ "=====================================================\n\n"\ end def h3(msg) "#{msg}\n"\ "-----------------------------------------------------\n\n"\ end def code(msg, syntax = nil) ".. code-block:: #{syntax}\n\n"\ " #{msg.gsub("\n", "\n ")}\n\n" end def li(msg) "#{msg.gsub("\n", "\n ")}\n\n" end def ul(msg) msg end def p(msg) "#{msg}\n\n" end def a(name, _dst = nil) # FIXME: needs link handling "`#{name}`_" end def suffix '.rst' end def meta(_o) '' # ignore for now end end end class ResourceDocs def initialize(root) @paths = {} # cache of paths @root = root # relative root path for all docs end def render(path) @paths[path] ||= render_path(path) end def partial(x) render(x + '.md.erb') end def overview_page(resource_doc_files) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength renderer = Markdown markdown = renderer.meta(title: 'InSpec Resources Reference') markdown << renderer.h1('InSpec Resources Reference') markdown << renderer.p('The following list of InSpec resources are available.') contrib_config = YAML.load(File.read(File.join(CONTRIB_DIR, 'contrib.yaml'))) # Build a list of resources keyed on the group they are a part of. # We'll determine the group using regexes. group_regexes = [ # These are hardcoded present in the main repo. If they become resource # packs, this should change. { group_name: 'AWS', regex: /^aws_/ }, { group_name: 'Azure', regex: /^azure(rm)?_/ }, ] # Also pick up regexes and group names from contrib resource packs. contrib_config['resource_packs'].values.each do |project_info| group_regexes << { group_name: project_info['doc_group_title'], regex: Regexp.new(project_info['resource_file_regex']) } end # OK, apply the regexes we have to the resource doc file list we were passed. # doc_file looks like /resources/foo.md.erb - trim off directory and file extension trimmed_doc_files = resource_doc_files.dup.map { |file| File.basename(file).sub(/\.md(\.erb)?$/, '') } resources_by_group = Hash[group_regexes.map { |info| [info[:group_name], []] }] # Initialize each group to an empty array resources_by_group['OS resources'] = [] trimmed_doc_files.each do |doc_file| matched = false group_regexes.each do |group_info| next if matched if doc_file =~ group_info[:regex] resources_by_group[group_info[:group_name]] << doc_file matched = true end end # Any resources that don't match a regex are assumed to be 'os' resources. resources_by_group['OS resources'] << doc_file unless matched end # Now transform the resource lists into HTML markdown_resource_links_by_group = {} resources_by_group.each do |group_name, resource_list| markdown_resource_links_by_group[group_name] = resource_list.map do |resource_name| renderer.li(renderer.a(resource_name.gsub('_', '\\_'), 'resources/' + resource_name + '.html')) end.join('') end # Remove any groups that have no resource docs. resources_by_group.reject! { |_, resource_list| resource_list.empty? } # Generate the big buttons that jump to the section of the page for each group. markdown << '