lib/resme/cli/command_semantics.rb in resme-0.3.2 vs lib/resme/cli/command_semantics.rb in resme-0.4.0
- old
+ new
@@ -1,193 +1,195 @@
-require 'resme/version'
-require 'readline'
-require 'fileutils'
-require 'date'
-require 'yaml'
-require 'erb'
-require 'json'
-require 'kwalify'
+require "resme/version"
+require "readline"
+require "fileutils"
+require "date"
+require "yaml"
+require "erb"
+require "json"
+require "kwalify"
module Resme
module CommandSemantics
- APPNAME = 'resme'
+ APPNAME = "resme"
VERSION = Resme::VERSION
#
# Main App Starts Here!
#
- def self.version opts = nil, argv = []
+ def self.version(opts = nil, argv = [])
puts "#{APPNAME} version #{VERSION}"
end
- def self.man opts = nil, argv = []
- path = File.join(File.dirname(__FILE__), "/../../../README.md")
+ def self.man(opts = nil, argv = [])
+ path = File.join(File.dirname(__FILE__), "/../../../README.org")
file = File.open(path, "r")
- contents = file.read
- puts contents
+ puts file.read
end
- def self.help opts = nil, argv = []
+ def self.help(opts = nil, argv = [])
all_commands = CommandSyntax.commands
if argv != []
- argv.map { |x| puts all_commands[x.to_sym][2] }
+ argv.map do |x|
+ puts all_commands[x.to_sym][:help]
+ puts "\n\n"
+ end
else
- puts "#{APPNAME} command [options] [args]"
- puts ""
- puts "Available commands:"
- puts ""
- all_commands.keys.each do |key|
- puts " " + all_commands[key][0].banner
+ puts "#{APPNAME} command [options] [args]\n"
+ puts "Available commands:\n"
+ all_commands.each_key do |key|
+ puts " #{all_commands[key][:options].banner}"
end
end
end
- def self.console opts, argv = []
+ def self.console(opts, argv = [])
all_commands = CommandSyntax.commands
all_commands.delete(:console)
i = 0
while true
string = Readline.readline("#{APPNAME}:%03d> " % i, true)
- string.gsub!(/^#{APPNAME} /, "") # as a courtesy, remove any leading appname string
- if string == "exit" or string == "quit" or string == "." then
- exit 0
- end
- reps all_commands, string.split(' ')
+ # as a courtesy, remove any leading appname string
+ string.gsub!(/^#{APPNAME} /, "")
+ exit 0 if %w[exit quit .].include? string
+ execute all_commands, string.split(" ")
i = i + 1
end
end
# read-eval-print step
- def self.reps all_commands, argv
+ # check if argv is in any of all_commands, parse options
+ # according to the specification in all_commands and invoke
+ # a function in this class to actually do the work
+ def self.execute(all_commands, argv)
if argv == [] or argv[0] == "--help" or argv[0] == "-h"
- CommandSemantics.help
+ help
exit 0
else
command = argv[0]
- syntax_and_semantics = all_commands[command.to_sym]
- if syntax_and_semantics
- opts = syntax_and_semantics[0]
- function = syntax_and_semantics[1]
-
- begin
- parser = Slop::Parser.new(opts)
+ command_spec = all_commands[command.to_sym]
- result = parser.parse(argv[1..-1])
- options = result.to_hash
- arguments = result.arguments
+ if command_spec
+ command_name = command_spec[:name]
+ option_parser = command_spec[:options]
- eval "CommandSemantics::#{function}(options, arguments)"
- rescue Slop::Error => e
- puts "#{APPNAME}: #{e}"
+ begin
+ argv.shift # remove command name from ARGV
+ options = {}
+ parser = option_parser.parse!(into: options)
+ eval "CommandSemantics::#{command_name}(options, argv)"
rescue Exception => e
- puts e
+ puts "#{APPNAME} error: #{e}"
+ puts "Help with \"#{APPNAME} help #{command_name}\""
end
else
- puts "#{APPNAME}: '#{command}' is not a valid command. See '#{APPNAME} help'"
+ puts "#{APPNAME} error: "#{command}" is not a valid command."
+ puts "List commands with \"#{APPNAME} help\"."
end
end
end
#
# APP SPECIFIC COMMANDS
#
- def self.check opts, argv
- schema = Kwalify::Yaml.load_file(File.join(File.dirname(__FILE__), "/../templates/schema.yml"))
- ## or
- # schema = YAML.load_file('schema.yaml')
+ def self.check(opts, argv)
+ path = File.join(File.dirname(__FILE__), "/../templates/schema.yml")
+ schema = Kwalify::Yaml.load_file(path)
- ## create validator
+ # create validator
validator = Kwalify::Validator.new(schema)
-
- ## load document
+ # load document
document = Kwalify::Yaml.load_file(argv[0])
- ## or
- #document = YAML.load_file('document.yaml')
-
- ## validate
+ # validate
errors = validator.validate(document)
- ## show errors
+ # show errors
if errors && !errors.empty?
for e in errors
puts "[#{e.path}] #{e.message}"
end
else
puts "The file #{argv[0]} validates."
end
end
- def self.init opts, argv
+ def self.init(opts, argv)
output = opts[:output] || "resume.yml"
force = opts[:force]
- template = File.join(File.dirname(__FILE__), "/../templates/resume.yml")
+ path = File.dirname(__FILE__), "/../templates/resume.yml"
+ template = File.join(path)
- # avoid catastrophy
- if File.exist?(output) and not force
- puts "Error: file #{output} already exists. Use --force if you want to overwrite it"
+ # avoid catastrophe
+ if File.exist?(output) && !force
+ puts "#{APPNAME} error: file #{output} already exists."
+ puts "Use --force if you want to overwrite it."
else
content = File.read(template)
backup_and_write output, content
puts "YML resume template generated in #{output}"
end
end
- def self.md opts, argv
- output = opts[:output] || "resume-#{Date.today}.md"
- template = File.join(File.dirname(__FILE__), "/../templates/resume.md.erb")
-
- render argv, template, output
- puts "Resume generated in #{output}"
+ def self.list(opts, argv)
+ data = {}
+ argv.each do |file|
+ data = data.merge(YAML.load_file(file, permitted_classes: [Date]))
+ end
+ puts "Sections included in #{argv.join(", ")}:"
+ data.keys.each do |key|
+ puts "- #{key}: #{(data[key] || []).size} entries"
+ end
end
- def self.org opts, argv
- output = opts[:output] || "resume-#{Date.today}.org"
- template = File.join(File.dirname(__FILE__), "/../templates/resume.org.erb")
+ def self.generate(opts, argv)
+ format = opts[:to] == "europass" ? "xml" : opts[:to]
+ output = opts[:output] || "resume-#{Date.today}.#{format}"
- render argv, template, output
- puts "Resume generated in #{output}"
- end
+ if opts[:erb]
+ template = opts[:erb]
+ else
+ template = File.join(File.dirname(__FILE__), "/../templates/resume.#{format}.erb")
+ end
- def self.json opts, argv
- output = opts[:output] || "resume-#{Date.today}.json"
- template = File.join(File.dirname(__FILE__), "/../templates/resume.json.erb")
+ skipped_sections = opts[:skip] || []
- render argv, template, output
- puts "Resume generated in #{output}"
- end
+ if !File.exists?(template)
+ puts "#{APPNAME} error: format #{format} is not understood."
+ end
- def self.europass opts, argv
- output = opts[:output] || "resume-#{Date.today}.xml"
- template = File.join(File.dirname(__FILE__), "/../templates/europass/eu.xml.erb")
-
- render argv, template, output
+ render argv, template, output, skipped_sections
puts "Resume generated in #{output}"
- puts "Render via, e.g., http://interop.europass.cedefop.europa.eu/web-services/remote-upload/"
+
+ if format == "xml" then
+ puts "Europass XML generated. Render via, e.g., http://interop.europass.cedefop.europa.eu/web-services/remote-upload/"
+ end
end
private
- def self.render yml_files, template_filename, output_filename
- data = Hash.new
+ def self.render(yml_files, template_name, output_name, skipped_sections)
+ data = {}
yml_files.each do |file|
- data = data.merge(YAML.load_file(file))
+ data = data.merge(YAML.load_file(file, permitted_classes: [Date]))
end
- template = File.read(template_filename)
- output = ERB.new(template, nil, '-').result(binding)
+ skipped_sections.each do |section|
+ data.reject! { |k| k == section }
+ end
+ template = File.read(template_name)
+ output = ERB.new(template, trim_mode: "-").result(binding)
# it is difficult to write readable ERBs with no empty lines...
# we use gsub to replace multiple empty lines with \n\n in the final output
output.gsub!(/([\t ]*\n){3,}/, "\n\n")
- backup_and_write output_filename, output
+ backup_and_write output_name, output
end
- def self.backup filename
+ def self.backup(filename)
FileUtils::cp filename, filename + "~"
puts "Backup copy #{filename} created in #{filename}~."
end
- def self.backup_and_write filename, content
+ def self.backup_and_write(filename, content)
backup(filename) if File.exist?(filename)
File.open(filename, "w") { |f| f.puts content }
end
end
end