class Pandocomatic::CLI
Command
line options parser for pandocomatic using optimist.
Public Class Methods
match_file_types(input, output)
click to toggle source
# File lib/pandocomatic/cli.rb, line 264 def self.match_file_types(input, output) return if matching_file_types? input, output raise CLIError.new(:output_is_not_a_file, nil, input) if File.file? input raise CLIError.new(:output_is_not_a_directory, nil, input) if File.directory? input end
matching_file_types?(input, output)
click to toggle source
If output does not exist, the output can be created with the same type. If output does exist, however, it should have the same type as the input.
# File lib/pandocomatic/cli.rb, line 260 def self.matching_file_types?(input, output) !File.exist?(output) or File.ftype(input) == File.ftype(output) end
options_need_to_be_validated?(options)
click to toggle source
rubocop:enable Metrics
# File lib/pandocomatic/cli.rb, line 226 def self.options_need_to_be_validated?(options) !(options[:version_given]) and !(options[:help_given]) end
parse!(args)
click to toggle source
Parse the arguments, returns a triplet with the global options, an optional subcommand, and the (optional) options for that subcommand.
As a side effect, this method will create and install a logger for Pandocomatic::LOG.
@param args [String, Array] A command-line invocation string or a list of strings like ARGV
@return [Configuration] The configuration for running pandocomatic given the command-line options.
# File lib/pandocomatic/cli.rb, line 42 def self.parse!(args) args = args.split if args.is_a? String begin parse_options args || Configuration.new({ help: true, help_given: true }) rescue Optimist::CommandlineError => e raise CLIError.new(:problematic_invocation, e, args) end end
parse_options(args)
click to toggle source
Parse pandocomatic’s global options.
@return [Configuration]
# File lib/pandocomatic/cli.rb, line 57 def self.parse_options(args) parser = Optimist::Parser.new do # General options opt :dry_run, 'Do a dry run', short: '-y' opt :verbose, 'Run verbosely', short: '-V' opt :modified_only, 'Modified files only', short: '-m' opt :enable, 'Enable feature', short: '-e', multi: true, type: String # Logging opt :log, 'Log to file', short: '-l', type: String, default: 'pandocomatic.log' opt :log_level, 'Log level', type: String, default: 'INFO' # Configuration of the converter opt :data_dir, 'Data dir', short: '-d', type: String opt :config, 'Configuration file', short: '-c', type: String opt :root_path, 'Root path', short: '-r', type: String # What to convert and where to put it opt :output, 'Output', short: '-o', type: String opt :input, 'Input', short: '-i', type: String, multi: true opt :stdout, 'Output to standard out', short: '-s' # Common opt :show_version, 'Version', short: '-v', long: 'version' opt :show_help, 'Help', short: '-h', long: 'help' end # All options should be parsed according to the specification given in the parser # parser#parse removes arguments from args during parsing. Keep a copy for error reporting. given_arguments = args.dup begin options = parser.parse args rescue Optimist::CommandlineError => e raise CLIError.new(:problematic_invocation, e, given_arguments) end if options[:log_given] log_file = options[:log] log_level = options[:log_level] end Pandocomatic::LOG.install_file_logger(log_file, log_level) options = use_custom_version options options = use_custom_help options if options_need_to_be_validated? options Pandocomatic::LOG.debug 'Validating command-line arguments:' # if no input option is specified, all items following the last option # are treated as input files. if !(options[:input_given]) Pandocomatic::LOG.debug '✓ Option \'--input\' not used: ' \ 'treat all arguments after last option as input files or directories.' options[:input] = args options[:input_given] = true elsif !args.empty? raise CLIError, :no_mixed_inputs end # There should be an input specified raise CLIError, :no_input_given if options[:input].nil? || options[:input].empty? # Support multiple input files for conversion multiple_inputs = options[:input].size > 1 if multiple_inputs Pandocomatic::LOG.debug '✓ Convert multiple input files or directories.' else Pandocomatic::LOG.debug '✓ Convert single input file or directory.' end # The input files or directories should exist input = options[:input].map do |input_file| raise CLIError.new(:input_does_not_exist, nil, input_file) unless File.exist? input_file raise CLIError.new(:input_is_not_readable, nil, input_file) unless File.readable? input_file # If there are multiple input files, these files cannot be directories if multiple_inputs && File.directory?(input_file) raise CLIError.new(:multiple_input_files_only, nil, input_file) end File.absolute_path input_file end Pandocomatic::LOG.debug '✓ Input files and directories exist.' # You cannot use the --stdout option while converting directories if options[:stdout_given] && File.directory?(input.first) options[:stdout] = false raise CLIError, :cannot_use_stdout_with_directory end Pandocomatic::LOG.debug '✓ Write output to STDOUT.' if options[:stdout_given] if options[:output_given] # You cannot use --stdout with --output if options[:stdout_given] options[:stdout] = false raise CLIError, :cannot_use_both_output_and_stdout else Pandocomatic::LOG.debug "✓ Write output to '#{options[:output]}'." output = File.absolute_path options[:output] # Input and output should be both files or directories match_file_types input.first, output Pandocomatic::LOG.debug '✓ Input and outputs types match.' # The output, if it already exist, should be writable unless (!File.exist? output) || File.writable?(output) raise CLIError.new(:output_is_not_writable, nil, output) end Pandocomatic::LOG.debug '✓ Existing output is writable.' if File.exist? output end elsif !multiple_inputs && File.directory?(input.first) raise CLIError, :no_output_given end # If the input is a directory, an output directory should be # specified as well. If the input is a file, the output could be # specified in the input file, or STDOUT could be used. # No check for root_path: a user can supply one that does not exists # at this location and still work on the output location. # Data dir, if specified, should be an existing and readable directory if options[:data_dir_given] data_dir = File.absolute_path options[:data_dir] raise CLIError.new(:data_dir_does_not_exist, nil, options[:data_dir]) unless File.exist? data_dir raise CLIError.new(:data_dir_is_not_readable, nil, data_dir) unless File.readable? data_dir raise CLIError.new(:data_dir_is_not_a_directory, nil, data_dir) unless File.directory? data_dir end Pandocomatic::LOG.debug "✓ Can read data directory '#{options[:data_dir]}'." if options[:data_dir_given] # Config file, if specified, should be an existing and readable file if options[:config_given] config = File.absolute_path options[:config] raise CLIError.new(:config_file_does_not_exist, nil, options[:config]) unless File.exist? config raise CLIError.new(:config_file_is_not_readable, nil, config) unless File.readable? config raise CLIError.new(:config_file_is_not_a_file, nil, config) unless File.file? config end Pandocomatic::LOG.debug "✓ Can read configuration file '#{options[:config]}'." if options[:config_given] if options[:enable_given] Pandocomatic::LOG.info '- Checking feature toggles:' features = [] options[:enable].each do |feature_string| feature = feature_string.downcase.sub('-', '_').to_sym unless Pandocomatic::FEATURES.include? feature raise CLIError.new(:feature_toggle_does_not_exist, nil, feature_string) end Pandocomatic::LOG.info " ✓ Enabling feature '#{feature}'." features << feature end options[:enable] = features end end Configuration.new(options, input) end
use_custom_help(options)
click to toggle source
# File lib/pandocomatic/cli.rb, line 247 def self.use_custom_help(options) if options[:show_help] options.delete :show_help options.delete :show_help_given options[:help] = true options[:help_given] = true end options end
use_custom_version(options)
click to toggle source
# File lib/pandocomatic/cli.rb, line 237 def self.use_custom_version(options) if options[:show_version] options.delete :show_version options.delete :show_version_given options[:version] = true options[:version_given] = true end options end