lib/fontcustom/options.rb in fontcustom-1.1.0.pre vs lib/fontcustom/options.rb in fontcustom-1.1.0.pre2
- old
+ new
@@ -1,27 +1,211 @@
+require "yaml"
+require "thor/shell"
+require "thor/shell/basic"
+require "thor/shell/color"
require "thor/core_ext/hash_with_indifferent_access"
+require "fontcustom/util"
module Fontcustom
- # :output and :config are build from arguments
- DEFAULT_OPTIONS = Thor::CoreExt::HashWithIndifferentAccess.new({
- :project_root => Dir.pwd,
- :input => "",
- :templates => %w|css preview|,
- :font_name => "fontcustom",
- :file_hash => true,
- :css_prefix => "icon-",
- :preprocessor_font_path => "",
- :debug => false,
- :verbose => true
- })
+ class Options
+ include Util
- DATA_MODEL = Thor::CoreExt::HashWithIndifferentAccess.new({
- :fonts => [],
- :templates => [],
- :glyphs => [],
- :paths => {
- :css_to_fonts => "",
- :preprocessor_to_fonts => "",
- :preview_to_css => ""
- }
- })
+ attr_reader :project_root, :input, :output, :config, :data_cache, :templates,
+ :font_name, :file_hash, :css_prefix, :preprocessor_path, :skip_first, :debug, :verbose
+
+ def initialize(options = {})
+ check_fontforge
+
+ # 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
+ end
+
+ private
+
+ def set_options
+ set_config_path
+ load_config
+ merge_options
+ set_data_path
+ set_input_paths
+ set_output_paths
+ set_template_paths
+ end
+
+ def set_config_path
+ @config = if @cli_options[:config]
+ path = File.expand_path File.join(@cli_options[:project_root], @cli_options[:config])
+
+ # :config is the path to fontcustom.yml
+ if File.exists?(path) && ! File.directory?(path)
+ path
+
+ # :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 was not found. Check #{relative_to_root(path)} and try again."
+ 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"
+
+ # config/fontcustom.yml is in the project_root
+ elsif File.exists? File.join(@cli_options[:project_root], "config", "fontcustom.yml")
+ File.join @cli_options[:project_root], "config", "fontcustom.yml"
+
+ else
+ false
+ end
+ end
+ end
+
+ def load_config
+ @config_options = {}
+ return unless @config
+ begin
+ config = YAML.load File.open(@config)
+ @config_options = config if config # empty file returns false
+ rescue Exception => e
+ raise Fontcustom::Error, "The configuration file failed to load. Message: #{e.message}"
+ end
+ end
+
+ def merge_options
+ @cli_options.delete_if { |key, val| val == DEFAULT_OPTIONS[key] }
+
+ options = DEFAULT_OPTIONS.dup
+ options = options.merge @config_options
+ options = options.merge @cli_options
+ remove_instance_variable :@config_options
+ remove_instance_variable :@cli_options
+
+ # :config is excluded since it's already been set
+ keys = %w|project_root input output data_cache templates font_name file_hash css_prefix preprocessor_path skip_first debug verbose|
+ keys.each { |key| instance_variable_set("@#{key}", options[key]) }
+
+ @font_name = @font_name.strip.gsub(/\W/, '-')
+ end
+
+ def set_data_path
+ @data_cache = if ! @data_cache.nil?
+ File.expand_path File.join(@project_root, @data_cache)
+ elsif @config
+ File.join File.dirname(@config), '.fontcustom-data'
+ else
+ File.join @project_root, '.fontcustom-data'
+ end
+ end
+
+ def set_input_paths
+ if @input.is_a? Hash
+ @input = Thor::CoreExt::HashWithIndifferentAccess.new @input
+
+ if @input.has_key? "vectors"
+ @input[:vectors] = File.expand_path File.join(@project_root, @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."
+ end
+ else
+ raise Fontcustom::Error, "INPUT (as a hash) should contain a \"vectors\" key."
+ end
+
+ if @input.has_key? "templates"
+ @input[:templates] = File.expand_path File.join(@project_root, @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."
+ end
+ else
+ @input[:templates] = @input[:vectors]
+ end
+ elsif @input.is_a? String
+ input = File.expand_path File.join(@project_root, @input)
+ unless File.directory? input
+ raise Fontcustom::Error, "INPUT (as a string) should be a directory. Check #{relative_to_root(input)} and try again."
+ end
+ @input = Thor::CoreExt::HashWithIndifferentAccess.new({
+ :vectors => input,
+ :templates => input
+ })
+ end
+
+ if Dir[File.join(@input[:vectors], "*.{svg,eps}")].empty?
+ raise Fontcustom::Error, "#{relative_to_root(@input[:vectors])} doesn't contain any vectors (*.svg or *.eps files)."
+ end
+ end
+
+ def set_output_paths
+ if @output.is_a? Hash
+ @output = Thor::CoreExt::HashWithIndifferentAccess.new @output
+ raise Fontcustom::Error, "OUTPUT (as a hash) should contain a \"fonts\" key." unless @output.has_key? "fonts"
+
+ @output.each do |key, val|
+ @output[key] = File.expand_path File.join(@project_root, val)
+ if File.exists?(val) && ! File.directory?(val)
+ raise Fontcustom::Error, "OUTPUT[\"#{key}\"] should be a directory, not a file. Check #{relative_to_root(val)} and try again."
+ end
+ end
+
+ @output[:css] ||= @output[:fonts]
+ @output[:preview] ||= @output[:fonts]
+ else
+ if @output.is_a? String
+ output = File.expand_path File.join(@project_root, @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."
+ end
+ else
+ output = File.join @project_root, @font_name
+ say_message :status, "All generated files will be added into `#{relative_to_root(output)}/` by default."
+ end
+
+ @output = Thor::CoreExt::HashWithIndifferentAccess.new({
+ :fonts => output,
+ :css => output,
+ :preview => output
+ })
+ end
+ end
+
+ # Translates shorthand to full path of packages templates, otherwise,
+ # it checks input and pwd for the template.
+ #
+ # 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|
+ case template
+ when "preview"
+ File.join template_path, "fontcustom-preview.html"
+ when "css"
+ File.join template_path, "fontcustom.css"
+ when "scss"
+ File.join template_path, "_fontcustom.scss"
+ when "scss-rails"
+ File.join template_path, "_fontcustom-rails.scss"
+ when "bootstrap"
+ File.join template_path, "fontcustom-bootstrap.css"
+ when "bootstrap-scss"
+ File.join template_path, "_fontcustom-bootstrap.scss"
+ when "bootstrap-ie7"
+ File.join template_path, "fontcustom-bootstrap-ie7.css"
+ when "bootstrap-ie7-scss"
+ File.join template_path, "_fontcustom-bootstrap-ie7.scss"
+ else
+ path = File.expand_path File.join(@input[:templates], template)
+ raise Fontcustom::Error, "The custom template at #{relative_to_root(path)} does not exist." unless File.exists? path
+ path
+ end
+ end
+ end
+ end
end