# 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 "fileutils" require "yaml" require_relative "./shared" require "git" require_relative "./contrib" DOCS_DIR = "../docs".freeze 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"))) # TODO: clean this up using Hash.new and friends # 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"] = [] 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"] << 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 << '