summaryrefslogtreecommitdiff
path: root/vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary')
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/command.rb281
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/option.rb89
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/presenter.rb103
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/program.rb55
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/version.rb5
5 files changed, 533 insertions, 0 deletions
diff --git a/vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/command.rb b/vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/command.rb
new file mode 100644
index 0000000..08ddf94
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/command.rb
@@ -0,0 +1,281 @@
+# frozen_string_literal: false
+
+module Mercenary
+ class Command
+ attr_reader :name
+ attr_reader :description
+ attr_reader :syntax
+ attr_accessor :options
+ attr_accessor :commands
+ attr_accessor :actions
+ attr_reader :map
+ attr_accessor :parent
+ attr_reader :trace
+ attr_reader :aliases
+
+ # Public: Creates a new Command
+ #
+ # name - the name of the command
+ # parent - (optional) the instancce of Mercenary::Command which you wish to
+ # be the parent of this command
+ #
+ # Returns nothing
+ def initialize(name, parent = nil)
+ @name = name
+ @options = []
+ @commands = {}
+ @actions = []
+ @map = {}
+ @parent = parent
+ @trace = false
+ @aliases = []
+ end
+
+ # Public: Sets or gets the command version
+ #
+ # version - the command version (optional)
+ #
+ # Returns the version and sets it if an argument is non-nil
+ def version(version = nil)
+ @version = version if version
+ @version
+ end
+
+ # Public: Sets or gets the syntax string
+ #
+ # syntax - the string which describes this command's usage syntax (optional)
+ #
+ # Returns the syntax string and sets it if an argument is present
+ def syntax(syntax = nil)
+ @syntax = syntax if syntax
+ syntax_list = []
+ syntax_list << parent.syntax.to_s.gsub(%r!<[\w\s-]+>!, "").gsub(%r!\[[\w\s-]+\]!, "").strip if parent
+ syntax_list << (@syntax || name.to_s)
+ syntax_list.join(" ")
+ end
+
+ # Public: Sets or gets the command description
+ #
+ # description - the description of what the command does (optional)
+ #
+ # Returns the description and sets it if an argument is present
+ def description(desc = nil)
+ @description = desc if desc
+ @description
+ end
+
+ # Public: Sets the default command
+ #
+ # command_name - the command name to be executed in the event no args are
+ # present
+ #
+ # Returns the default command if there is one, `nil` otherwise
+ def default_command(command_name = nil)
+ if command_name
+ if commands.key?(command_name)
+ @default_command = commands[command_name] if command_name
+ @default_command
+ else
+ raise ArgumentError, "'#{command_name}' couldn't be found in this command's list of commands."
+ end
+ else
+ @default_command
+ end
+ end
+
+ # Public: Adds an option switch
+ #
+ # sym - the variable key which is used to identify the value of the switch
+ # at runtime in the options hash
+ #
+ # Returns nothing
+ def option(sym, *options)
+ new_option = Option.new(sym, options)
+ @options << new_option
+ @map[new_option] = sym
+ end
+
+ # Public: Adds a subcommand
+ #
+ # cmd_name - the name of the command
+ # block - a block accepting the new instance of Mercenary::Command to be
+ # modified (optional)
+ #
+ # Returns nothing
+ def command(cmd_name)
+ cmd = Command.new(cmd_name, self)
+ yield cmd
+ @commands[cmd_name] = cmd
+ end
+
+ # Public: Add an alias for this command's name to be attached to the parent
+ #
+ # cmd_name - the name of the alias
+ #
+ # Returns nothing
+ def alias(cmd_name)
+ logger.debug "adding alias to parent for self: '#{cmd_name}'"
+ aliases << cmd_name
+ @parent.commands[cmd_name] = self
+ end
+
+ # Public: Add an action Proc to be executed at runtime
+ #
+ # block - the Proc to be executed at runtime
+ #
+ # Returns nothing
+ def action(&block)
+ @actions << block
+ end
+
+ # Public: Fetch a Logger (stdlib)
+ #
+ # level - the logger level (a Logger constant, see docs for more info)
+ #
+ # Returns the instance of Logger
+
+ def logger(level = nil)
+ unless @logger
+ @logger = Logger.new(STDOUT)
+ @logger.level = level || Logger::INFO
+ @logger.formatter = proc do |severity, _datetime, _progname, msg|
+ "#{identity} | " << "#{severity.downcase.capitalize}:".ljust(7) << " #{msg}\n"
+ end
+ end
+
+ @logger.level = level unless level.nil?
+ @logger
+ end
+
+ # Public: Run the command
+ #
+ # argv - an array of string args
+ # opts - the instance of OptionParser
+ # config - the output config hash
+ #
+ # Returns the command to be executed
+ def go(argv, opts, config)
+ opts.banner = "Usage: #{syntax}"
+ process_options(opts, config)
+ add_default_options(opts)
+
+ if argv[0] && cmd = commands[argv[0].to_sym]
+ logger.debug "Found subcommand '#{cmd.name}'"
+ argv.shift
+ cmd.go(argv, opts, config)
+ else
+ logger.debug "No additional command found, time to exec"
+ self
+ end
+ end
+
+ # Public: Add this command's options to OptionParser and set a default
+ # action of setting the value of the option to the inputted hash
+ #
+ # opts - instance of OptionParser
+ # config - the Hash in which the option values should be placed
+ #
+ # Returns nothing
+ def process_options(opts, config)
+ options.each do |option|
+ opts.on(*option.for_option_parser) do |x|
+ config[map[option]] = x
+ end
+ end
+ end
+
+ # Public: Add version and help options to the command
+ #
+ # opts - instance of OptionParser
+ #
+ # Returns nothing
+ def add_default_options(opts)
+ option "show_help", "-h", "--help", "Show this message"
+ option "show_version", "-v", "--version", "Print the name and version"
+ option "show_backtrace", "-t", "--trace", "Show the full backtrace when an error occurs"
+ opts.on("-v", "--version", "Print the version") do
+ puts "#{name} #{version}"
+ exit(0)
+ end
+
+ opts.on("-t", "--trace", "Show full backtrace if an error occurs") do
+ @trace = true
+ end
+
+ opts.on_tail("-h", "--help", "Show this message") do
+ puts self
+ exit
+ end
+ end
+
+ # Public: Execute all actions given the inputted args and options
+ #
+ # argv - (optional) command-line args (sans opts)
+ # config - (optional) the Hash configuration of string key to value
+ #
+ # Returns nothing
+ def execute(argv = [], config = {})
+ if actions.empty? && !default_command.nil?
+ default_command.execute
+ else
+ actions.each { |a| a.call(argv, config) }
+ end
+ end
+
+ # Public: Check if this command has a subcommand
+ #
+ # sub_command - the name of the subcommand
+ #
+ # Returns true if this command is the parent of a command of name
+ # 'sub_command' and false otherwise
+ def has_command?(sub_command)
+ commands.key?(sub_command)
+ end
+
+ # Public: Identify this command
+ #
+ # Returns a string which identifies this command
+ def ident
+ "<Command name=#{identity}>"
+ end
+
+ # Public: Get the full identity (name & version) of this command
+ #
+ # Returns a string containing the name and version if it exists
+ def identity
+ "#{full_name} #{version}".strip
+ end
+
+ # Public: Get the name of the current command plus that of
+ # its parent commands
+ #
+ # Returns the full name of the command
+ def full_name
+ the_name = []
+ the_name << parent.full_name if parent&.full_name
+ the_name << name
+ the_name.join(" ")
+ end
+
+ # Public: Return all the names and aliases for this command.
+ #
+ # Returns a comma-separated String list of the name followed by its aliases
+ def names_and_aliases
+ ([name.to_s] + aliases).compact.join(", ")
+ end
+
+ # Public: Build a string containing a summary of the command
+ #
+ # Returns a one-line summary of the command.
+ def summarize
+ " #{names_and_aliases.ljust(20)} #{description}"
+ end
+
+ # Public: Build a string containing the command name, options and any subcommands
+ #
+ # Returns the string identifying this command, its options and its subcommands
+ def to_s
+ Presenter.new(self).print_command
+ end
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/option.rb b/vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/option.rb
new file mode 100644
index 0000000..dfd21d5
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/option.rb
@@ -0,0 +1,89 @@
+# frozen_string_literal: true
+
+module Mercenary
+ class Option
+ attr_reader :config_key, :description, :short, :long, :return_type
+
+ # Public: Create a new Option
+ #
+ # config_key - the key in the config hash to which the value of this option
+ # will map
+ # info - an array containing first the switches, then an optional
+ # return type (e.g. Array), then a description of the option
+ #
+ # Returns nothing
+ def initialize(config_key, info)
+ @config_key = config_key
+ while arg = info.shift
+ begin
+ @return_type = Object.const_get(arg.to_s)
+ next
+ rescue NameError
+ end
+ if arg.start_with?("-")
+ if arg.start_with?("--")
+ @long = arg
+ else
+ @short = arg
+ end
+ next
+ end
+ @description = arg
+ end
+ end
+
+ # Public: Fetch the array containing the info OptionParser is interested in
+ #
+ # Returns the array which OptionParser#on wants
+ def for_option_parser
+ [short, long, return_type, description].flatten.reject { |o| o.to_s.empty? }
+ end
+
+ # Public: Build a string representation of this option including the
+ # switches and description
+ #
+ # Returns a string representation of this option
+ def to_s
+ "#{formatted_switches} #{description}"
+ end
+
+ # Public: Build a beautifully-formatted string representation of the switches
+ #
+ # Returns a formatted string representation of the switches
+ def formatted_switches
+ [
+ switches.first.rjust(10),
+ switches.last.ljust(13),
+ ].join(", ").gsub(%r! , !, " ").gsub(%r!, !, " ")
+ end
+
+ # Public: Hash based on the hash value of instance variables
+ #
+ # Returns a Fixnum which is unique to this Option based on the instance variables
+ def hash
+ instance_variables.map do |var|
+ instance_variable_get(var).hash
+ end.reduce(:^)
+ end
+
+ # Public: Check equivalence of two Options based on equivalence of their
+ # instance variables
+ #
+ # Returns true if all the instance variables are equal, false otherwise
+ def eql?(other)
+ return false unless self.class.eql?(other.class)
+
+ instance_variables.map do |var|
+ instance_variable_get(var).eql?(other.instance_variable_get(var))
+ end.all?
+ end
+
+ # Public: Fetch an array of switches, including the short and long versions
+ #
+ # Returns an array of two strings. An empty string represents no switch in
+ # that position.
+ def switches
+ [short, long].map(&:to_s)
+ end
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/presenter.rb b/vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/presenter.rb
new file mode 100644
index 0000000..11685fe
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/presenter.rb
@@ -0,0 +1,103 @@
+# frozen_string_literal: true
+
+module Mercenary
+ class Presenter
+ attr_accessor :command
+
+ # Public: Make a new Presenter
+ #
+ # command - a Mercenary::Command to present
+ #
+ # Returns nothing
+ def initialize(command)
+ @command = command
+ end
+
+ # Public: Builds a string representation of the command usage
+ #
+ # Returns the string representation of the command usage
+ def usage_presentation
+ " #{command.syntax}"
+ end
+
+ # Public: Builds a string representation of the options
+ #
+ # Returns the string representation of the options
+ def options_presentation
+ return nil unless command_options_presentation || parent_command_options_presentation
+
+ [command_options_presentation, parent_command_options_presentation].compact.join("\n")
+ end
+
+ def command_options_presentation
+ return nil if command.options.empty?
+
+ options = command.options
+ options -= command.parent.options if command.parent
+ options.map(&:to_s).join("\n")
+ end
+
+ # Public: Builds a string representation of the options for parent
+ # commands
+ #
+ # Returns the string representation of the options for parent commands
+ def parent_command_options_presentation
+ return nil unless command.parent
+
+ Presenter.new(command.parent).options_presentation
+ end
+
+ # Public: Builds a string representation of the subcommands
+ #
+ # Returns the string representation of the subcommands
+ def subcommands_presentation
+ return nil if command.commands.empty?
+
+ command.commands.values.uniq.map(&:summarize).join("\n")
+ end
+
+ # Public: Builds the command header, including the command identity and description
+ #
+ # Returns the command header as a String
+ def command_header
+ header = command.identity.to_s
+ header << " -- #{command.description}" if command.description
+ header
+ end
+
+ # Public: Builds a string representation of the whole command
+ #
+ # Returns the string representation of the whole command
+ def command_presentation
+ msg = []
+ msg << command_header
+ msg << "Usage:"
+ msg << usage_presentation
+
+ if opts = options_presentation
+ msg << "Options:\n#{opts}"
+ end
+ if subcommands = subcommands_presentation
+ msg << "Subcommands:\n#{subcommands_presentation}"
+ end
+ msg.join("\n\n")
+ end
+
+ # Public: Turn a print_* into a *_presentation or freak out
+ #
+ # meth - the method being called
+ # args - an array of arguments passed to the missing method
+ # block - the block passed to the missing method
+ #
+ # Returns the value of whatever function is called
+ def method_missing(meth, *args, &block)
+ if meth.to_s =~ %r!^print_(.+)$!
+ send("#{Regexp.last_match(1).downcase}_presentation")
+ else
+ # You *must* call super if you don't handle the method,
+ # otherwise you'll mess up Ruby's method lookup.
+ super
+ end
+ end
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/program.rb b/vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/program.rb
new file mode 100644
index 0000000..a8d0c52
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/program.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+module Mercenary
+ class Program < Command
+ attr_reader :optparse
+ attr_reader :config
+
+ # Public: Creates a new Program
+ #
+ # name - the name of the program
+ #
+ # Returns nothing
+ def initialize(name)
+ @config = {}
+ super(name)
+ end
+
+ # Public: Run the program
+ #
+ # argv - an array of string args (usually ARGV)
+ #
+ # Returns nothing
+ def go(argv)
+ logger.debug("Using args passed in: #{argv.inspect}")
+
+ cmd = nil
+
+ @optparse = OptionParser.new do |opts|
+ cmd = super(argv, opts, @config)
+ end
+
+ begin
+ @optparse.parse!(argv)
+ rescue OptionParser::InvalidOption => e
+ logger.error "Whoops, we can't understand your command."
+ logger.error e.message.to_s
+ logger.error "Run your command again with the --help switch to see available options."
+ abort
+ end
+
+ logger.debug("Parsed config: #{@config.inspect}")
+
+ begin
+ cmd.execute(argv, @config)
+ rescue StandardError => e
+ if cmd.trace
+ raise e
+ else
+ logger.error e.message
+ abort
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/version.rb b/vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/version.rb
new file mode 100644
index 0000000..3f3e475
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/mercenary-0.4.0/lib/mercenary/version.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+module Mercenary
+ VERSION = "0.4.0"
+end