lib/fontcustom/options.rb in fontcustom-1.2.0 vs lib/fontcustom/options.rb in fontcustom-1.3.0.beta
- old
+ new
@@ -1,45 +1,45 @@
require "yaml"
-require "thor/shell"
-require "thor/shell/basic"
-require "thor/shell/color"
-require "fontcustom/util"
module Fontcustom
class Options
- include Util
+ include Utility
- attr_reader :project_root, :input, :output, :config, :templates, :font_name, :css_prefix, :manifest, :preprocessor_path, :autowidth, :no_hash, :debug, :quiet, :skip_first
+ attr_accessor :options
- def initialize(options = {})
- check_fontforge
- options = symbolize_hash(options)
-
- # Overwrite example defaults (used in Thor's help) with real defaults, if unchanged
- EXAMPLE_OPTIONS.keys.each do |key|
- options.delete(key) if options[key] == EXAMPLE_OPTIONS[key]
- end
- @cli_options = DEFAULT_OPTIONS.dup.merge options
-
- @shell = Thor::Shell::Color.new
- set_options
+ def initialize(cli_options = {})
+ @cli_options = symbolize_hash(cli_options)
+ parse_options
end
private
- def set_options
+ def parse_options
+ overwrite_examples
set_config_path
load_config
merge_options
- set_data_path
+ clean_font_name
+ set_manifest_path
set_input_paths
set_output_paths
set_template_paths
end
+ # We give Thor fake defaults to generate more useful help messages.
+ # Here, we delete any CLI options that match those examples.
+ # TODO There's *got* a be a cleaner way to customize Thor help messages.
+ def overwrite_examples
+ EXAMPLE_OPTIONS.keys.each do |key|
+ @cli_options.delete(key) if @cli_options[key] == EXAMPLE_OPTIONS[key]
+ end
+ @cli_options = DEFAULT_OPTIONS.dup.merge @cli_options
+ @cli_options[:project_root] ||= Dir.pwd
+ end
+
def set_config_path
- @config = if @cli_options[:config]
+ @cli_options[:config] = if @cli_options[:config]
path = expand_path @cli_options[:config]
# :config is the path to fontcustom.yml
if File.exists?(path) && ! File.directory?(path)
path
@@ -47,11 +47,11 @@
# :config is a dir containing fontcustom.yml
elsif File.exists? File.join(path, "fontcustom.yml")
File.join path, "fontcustom.yml"
else
- raise Fontcustom::Error, "The configuration file wasn't found. Check `#{relative_to_root(path)}` and try again."
+ raise Fontcustom::Error, "No configuration file found at `#{relative_to_root(path)}`."
end
else
# fontcustom.yml is in the project_root
if File.exists? File.join(@cli_options[:project_root], "fontcustom.yml")
File.join @cli_options[:project_root], "fontcustom.yml"
@@ -66,112 +66,120 @@
end
end
def load_config
@config_options = {}
- if @config
- say_message :status, "Loading configuration file at `#{relative_to_root(@config)}`."
+ if @cli_options[:config]
+ say_message :debug, "Using settings from `#{relative_to_root(@cli_options[:config])}`." if @cli_options[:debug]
begin
- config = YAML.load File.open(@config)
+ config = YAML.load File.open(@cli_options[:config])
if config # empty YAML returns false
@config_options = symbolize_hash(config)
else
- say_message :status, "Configuration file was empty. Using defaults."
+ say_message :warn, "`#{relative_to_root(@cli_options[:config])}` was empty. Using defaults."
end
rescue Exception => e
- raise Fontcustom::Error, "The configuration file failed to load. Message: #{e.message}"
+ raise Fontcustom::Error, "Error parsing `#{relative_to_root(@cli_options[:config])}`:\n#{e.message}"
end
- else
- say_message :status, "No configuration file set. Generate one with `fontcustom config` to save your settings."
end
end
def merge_options
@cli_options.delete_if { |key, val| val == DEFAULT_OPTIONS[key] }
+ @options = DEFAULT_OPTIONS.merge(@config_options).merge(@cli_options)
+ end
- options = DEFAULT_OPTIONS.dup
- options = options.merge @config_options
- options = options.merge symbolize_hash(@cli_options)
- send :remove_instance_variable, :@config_options
- send :remove_instance_variable, :@cli_options
-
- # :config is excluded since it's already been set
- keys = %w|project_root input output manifest templates font_name css_prefix preprocessor_path skip_first autowidth no_hash debug quiet|
- keys.each { |key| instance_variable_set("@#{key}", options[key.to_sym]) }
-
- @font_name = @font_name.strip.gsub(/\W/, "-")
+ def clean_font_name
+ @options[:font_name] = @options[:font_name].strip.gsub(/\W/, "-")
end
- def set_data_path
- @manifest = if ! @manifest.nil?
- expand_path @manifest
- elsif @config
- File.join File.dirname(@config), ".fontcustom-manifest.json"
+ def set_manifest_path
+ @options[:manifest] = if ! @options[:manifest].nil?
+ expand_path @options[:manifest]
+ elsif @options[:config]
+ File.join File.dirname(@options[:config]), ".fontcustom-manifest.json"
else
- File.join @project_root, ".fontcustom-manifest.json"
+ File.join @options[:project_root], ".fontcustom-manifest.json"
end
end
def set_input_paths
- if @input.is_a? Hash
- @input = symbolize_hash(@input)
- if @input.has_key? :vectors
- @input[:vectors] = expand_path @input[:vectors]
- unless File.directory? @input[:vectors]
- raise Fontcustom::Error, "INPUT[:vectors] should be a directory. Check `#{relative_to_root(@input[:vectors])}` and try again."
+ if @options[:input].is_a? Hash
+ @options[:input] = symbolize_hash(@options[:input])
+ if @options[:input].has_key? :vectors
+ @options[:input][:vectors] = expand_path @options[:input][:vectors]
+ unless File.directory? @options[:input][:vectors]
+ raise Fontcustom::Error,
+ "INPUT[:vectors] (`#{relative_to_root(@options[:input][:vectors])}`) should be "\
+ "a directory. Check `#{relative_to_root(@options[:config])}` or your CLI options."
end
else
- raise Fontcustom::Error, "INPUT (as a hash) should contain a :vectors key."
+ raise Fontcustom::Error,
+ "INPUT should have a :vectors key. Check `#{relative_to_root(@options[:config])}` "\
+ "or your CLI options."
end
- if @input.has_key? :templates
- @input[:templates] = expand_path @input[:templates]
- unless File.directory? @input[:templates]
- raise Fontcustom::Error, "INPUT[:templates] should be a directory. Check `#{relative_to_root(@input[:templates])}` and try again."
+ if @options[:input].has_key? :templates
+ @options[:input][:templates] = expand_path @options[:input][:templates]
+ unless File.directory? @options[:input][:templates]
+ raise Fontcustom::Error,
+ "INPUT[:templates] (`#{relative_to_root(@options[:input][:templates])}`) "\
+ "should be a directory. Check `#{relative_to_root(@options[:config])}` or "\
+ "your CLI options."
end
else
- @input[:templates] = @input[:vectors]
+ @options[:input][:templates] = @options[:input][:vectors]
end
else
- input = @input ? expand_path(@input) : @project_root
+ input = @options[:input] ? expand_path(@options[:input]) : @options[:project_root]
unless File.directory? input
- raise Fontcustom::Error, "INPUT (as a string) should be a directory. Check `#{relative_to_root(input)}` and try again."
+ raise Fontcustom::Error,
+ "INPUT (`#{relative_to_root(input)}`) should be a directory. Check "\
+ "`#{relative_to_root(@options[:config])}` or your CLI options."
end
- @input = { :vectors => input, :templates => input }
+ @options[:input] = { :vectors => input, :templates => input }
end
- if Dir[File.join(@input[:vectors], "*.svg")].empty?
- raise Fontcustom::Error, "`#{relative_to_root(@input[:vectors])}` doesn't contain any SVGs."
+ if Dir[File.join(@options[:input][:vectors], "*.svg")].empty?
+ raise Fontcustom::Error, "`#{relative_to_root(@options[:input][:vectors])}` doesn't contain any SVGs."
end
end
def set_output_paths
- if @output.is_a? Hash
- @output = symbolize_hash(@output)
- raise Fontcustom::Error, "OUTPUT (as a hash) should contain a :fonts key." unless @output.has_key? :fonts
+ if @options[:output].is_a? Hash
+ @options[:output] = symbolize_hash(@options[:output])
+ unless @options[:output].has_key? :fonts
+ raise Fontcustom::Error,
+ "OUTPUT should have a :fonts key. Check `#{relative_to_root(@options[:config])}` "\
+ "or your CLI options."
+ end
- @output.each do |key, val|
- @output[key] = expand_path val
+ @options[:output].each do |key, val|
+ @options[:output][key] = expand_path val
if File.exists?(val) && ! File.directory?(val)
- raise Fontcustom::Error, "OUTPUT[:#{key.to_s}] should be a directory, not a file. Check `#{relative_to_root(val)}` and try again."
+ raise Fontcustom::Error,
+ "OUTPUT[:#{key.to_s}] (`#{relative_to_root(@options[:output][key])}`) should be "\
+ "a directory. Check `#{relative_to_root(@options[:config])}` or your CLI options."
end
end
- @output[:css] ||= @output[:fonts]
- @output[:preview] ||= @output[:fonts]
+ @options[:output][:css] ||= @options[:output][:fonts]
+ @options[:output][:preview] ||= @options[:output][:fonts]
else
- if @output.is_a? String
- output = expand_path @output
+ if @options[:output].is_a? String
+ output = expand_path @options[:output]
if File.exists?(output) && ! File.directory?(output)
- raise Fontcustom::Error, "OUTPUT should be a directory, not a file. Check `#{relative_to_root(output)}` and try again."
+ raise Fontcustom::Error,
+ "OUTPUT (`#{relative_to_root(output)}`) should be a directory. Check "\
+ "`#{relative_to_root(@options[:config])}` or your CLI options."
end
else
- output = File.join @project_root, @font_name
- say_message :status, "All generated files will be saved to `#{relative_to_root(output)}/`."
+ output = File.join @options[:project_root], @options[:font_name]
+ say_message :debug, "Generated files will be saved to `#{relative_to_root(output)}/`." if @options[:debug]
end
- @output = {
+ @options[:output] = {
:fonts => output,
:css => output,
:preview => output
}
end
@@ -183,11 +191,11 @@
# Could arguably belong in Generator::Template, however, it's nice to
# be able to catch template errors before any generator runs.
def set_template_paths
template_path = File.join Fontcustom.gem_lib, "templates"
- @templates = @templates.map do |template|
+ @options[:templates] = @options[:templates].map do |template|
case template
when "preview"
File.join template_path, "fontcustom-preview.html"
when "css"
File.join template_path, "fontcustom.css"
@@ -202,11 +210,16 @@
when "bootstrap-ie7"
File.join template_path, "fontcustom-bootstrap-ie7.css"
when "bootstrap-ie7-scss"
File.join template_path, "_fontcustom-bootstrap-ie7.scss"
else
- template = File.expand_path File.join(@input[:templates], template) unless template[0] == "/"
- raise Fontcustom::Error, "The custom template at `#{relative_to_root(template)}` does not exist." unless File.exists? template
+ template = File.expand_path File.join(@options[:input][:templates], template) unless template[0] == "/"
+ unless File.exists? template
+ config = @options[:config] ? " `#{relative_to_root(@options[:config])}` or" : ""
+ raise Fontcustom::Error,
+ "Custom template `#{relative_to_root(template)}` doesn't exist. "\
+ "Check#{config} your CLI options."
+ end
template
end
end
end
end