lib/liquidoc.rb in liquidoc-0.9.0 vs lib/liquidoc.rb in liquidoc-0.9.1
- old
+ new
@@ -1,9 +1,9 @@
require 'liquidoc'
+require 'optparse'
require 'yaml'
require 'json'
-require 'optparse'
require 'liquid'
require 'asciidoctor'
require 'asciidoctor-pdf'
require 'logger'
require 'csv'
@@ -49,10 +49,12 @@
@passed_configvars = {}
@parseconfig = false
@verbose = false
@quiet = false
@explicit = false
+@search_index = false
+@search_index_dry = ''
# Instantiate the main Logger object, which is always running
@logger = Logger.new(STDOUT)
@logger.formatter = proc do |severity, datetime, progname, msg|
"#{severity}: #{msg}\n"
@@ -342,10 +344,11 @@
def initialize build, type
build['attributes'] = Hash.new unless build['attributes']
build['props'] = build['properties'] if build['properties']
@build = build
@type = type
+ @build['variables'] = {}
end
def template
@build['template']
end
@@ -443,10 +446,22 @@
# def prop_files_list # force the array back to a list of files (for CLI)
# props['files'].force_array if props['files']
# end
+ def search
+ props['search']
+ end
+
+ def add_search_prop! prop
+ begin
+ self.search.merge!prop
+ rescue
+ raise "PropertyInsertionError"
+ end
+ end
+
# NOTE this section repeats in Class.AsciiDocument
def attributes
@build['attributes']
end
@@ -607,15 +622,11 @@
return ingest_data(datasrc)
end
# Pull in a semi-structured data file, converting contents to a Ruby hash
def ingest_data datasrc
-# Must be passed a proper data object (there must be a better way to validate arg datatypes)
- unless datasrc.is_a? Object
- raise "InvalidDataObject"
- end
- # This proc should really begin here, once the datasrc object is in order
+ raise "InvalidDataObject" unless datasrc.is_a? Object
case datasrc.type
when "yml"
begin
data = YAML.load_file(datasrc.file)
rescue Exception => ex
@@ -675,11 +686,11 @@
end
records << row_h # add the row to the records array
end
end
end
- output = {"data" => records}
+ output = records
rescue Exception => ex
@logger.error "Something went wrong trying to parse the free-form file. #{ex.class} thrown. #{ex.message}"
raise "Freeform parse error"
end
return output
@@ -909,12 +920,12 @@
def generate_site doc, build
case build.backend
when "jekyll"
attrs = doc.attributes
build.add_config_file("_config.yml") unless build.prop_files_array
- jekyll_config = YAML.load_file(build.prop_files_array[0]) # load the first Jekyll config file locally
- attrs.merge! ({"base_dir" => jekyll_config['source']}) # Sets default Asciidoctor base_dir to == Jekyll root
+ jekyll = load_jekyll_data(build) # load the first Jekyll config file locally
+ attrs.merge! ({"base_dir" => jekyll['source']}) # Sets default Asciidoctor base_dir to == Jekyll root
# write all AsciiDoc attributes to a config file for Jekyll to ingest
attrs.merge!(build.attributes) if build.attributes
attrs = {"asciidoctor" => {"attributes" => attrs} }
attrs_yaml = attrs.to_yaml # Convert it all back to Yaml, as we're going to write a file to feed back to Jekyll
File.open("#{@build_dir}/pre/_attributes.yml", 'w') { |file| file.write(attrs_yaml) }
@@ -923,18 +934,35 @@
opts_args = ""
quiet = "--quiet" if @quiet || @explicit
if build.props['arguments']
opts_args = build.props['arguments'].to_opts_args
end
- command = "bundle exec jekyll build --config #{config_list} #{opts_args} #{quiet}"
+ base_args = "--config #{config_list} #{opts_args}"
+ command = "bundle exec jekyll build #{base_args} #{quiet}"
+ if @search_index
+ # TODO enable config-based admin api key ingest once config is dynamic
+ command = algolia_index_cmd(build, @search_api_key, base_args)
+ @logger.warn "Search indexing failed." unless command
+ end
end
- @logger.info "Running #{command}"
- @logger.debug "AsciiDoc attributes: #{doc.attributes.to_yaml} "
- system command
+ if command
+ @logger.info "Running #{command}"
+ @logger.debug "AsciiDoc attributes: #{doc.attributes.to_yaml} "
+ system command
+ end
jekyll_serve(build) if @jekyll_serve
end
+def load_jekyll_data build
+ data = {}
+ build.prop_files_array.each do |file|
+ settings = YAML.load_file(file)
+ data.merge!settings if settings
+ end
+ return data
+end
+
# ===
# DEPLOY procs
# ===
def jekyll_serve build
@@ -946,10 +974,24 @@
end
command = "bundle exec jekyll serve --config #{config_file} #{opts_args} --no-watch --skip-initial-build"
system command
end
+def algolia_index_cmd build, apikey=nil, args
+ unless build.search and build.search['index']
+ @logger.warn "No index configuration found for build; jekyll-algolia operation skipped for this build."
+ return false
+ else
+ unless apikey
+ @logger.warn "No Algolia admin API key passed; skipping jekyll-algolia operation for this build."
+ return false
+ else
+ return "ALGOLIA_INDEX_NAME='#{build.search['index']}' ALGOLIA_API_KEY='#{apikey}' bundle exec jekyll algolia #{@search_index_dry} #{args} "
+ end
+ end
+end
+
# ===
# Text manipulation Classes, Modules, procs, etc
# ===
module HashMash
@@ -1113,11 +1155,11 @@
opts.on("--quiet", "Run with only WARN- and error-level logs written to console.") do |n|
@logger.level = Logger::WARN
@quiet = true
end
- opts.on("--explicit", "Log explicit step descriptions to console as build progresses. (Otherwise writes to file at #{@build_dir}/pre/config-explainer.adoc .)") do |n|
+ opts.on("--explain", "Log explicit step descriptions to console as build progresses. (Otherwise writes to file at #{@build_dir}/pre/config-explainer.adoc .)") do |n|
explainer_init("STDOUT")
@explainer.level = Logger::INFO
@logger.level = Logger::WARN # Suppress all those INFO-level messages
@explicit = true
end
@@ -1128,25 +1170,31 @@
opts.on("--deploy", "EXPERIMENTAL: Trigger a jekyll serve operation against the destination dir of a Jekyll render step.") do
@jekyll_serve = true
end
- opts.on("--var KEY=VALUE", "For passing variables directly to the 'vars.' scope template via command line, for non-config builds only.") do |n|
- pair = {}
- k,v = n.split('=')
- pair[k] = v
- @passed_vars.merge!pair
+ opts.on("--search-index-push", "Runs any search indexing configured in the build step and pushes to Algolia.") do
+ @search_index = true
end
- opts.on("-x", "--cvar KEY=VALUE", "For sending variables to the 'vars.' scope of the config file and triggering Liquid parsing of config.") do |n|
+ opts.on("--search-index-dry", "Runs any search indexing configured in the build step but does NOT push to Algolia.") do
+ @search_index = true
+ @search_index_dry = "--dry-run"
+ end
+
+ opts.on("--search-api-key=STRING", "Passes Algolia Admin API key (which you should keep out of Git).") do |n|
+ @search_api_key = n
+ end
+
+ opts.on("-v", "--var KEY=VALUE", "For passing variables directly to the 'vars.' scope of a template; for dynamic configs, too.") do |n|
pair = {}
k,v = n.split('=')
pair[k] = v
- @passed_configvars.merge!pair
+ @passed_vars.merge!pair
end
- opts.on("--parse-config", "Preprocess the designated configuration file as a Liquid template. Superfluous when passing -x/--cvar arguments.") do
+ opts.on("--parse-config", "Preprocess the designated configuration file as a Liquid template. Superfluous when passing -v/--var arguments.") do
@parseconfig = true
end
opts.on("-h", "--help", "Returns help.") do
puts opts
@@ -1174,7 +1222,7 @@
if @index_file
@logger.warn "Rendering via command line arguments is not yet implemented. Use a config file."
end
else
@logger.debug "Executing... config_build"
- config_build(@config_file, @passed_configvars, @parseconfig)
+ config_build(@config_file, @passed_vars, @parseconfig)
end