Warning: file_get_contents(https://raw.githubusercontent.com/Den1xxx/Filemanager/master/languages/ru.json): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 88
Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 215
Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 216
Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 217
Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 218
Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 219
Warning: Cannot modify header information - headers already sent by (output started at /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php:88) in /home/afelisqd/cppseducation.sc.tz/admin/images/photos/17587263121019776732_admin-dbb.php on line 220
PK ! q@ q@ lib/thor.rbnu [ require_relative "thor/base"
class Bundler::Thor
$thor_runner ||= false
class << self
# Allows for custom "Command" package naming.
#
# === Parameters
# name
# options
#
def package_name(name, _ = {})
@package_name = name.nil? || name == "" ? nil : name
end
# Sets the default command when thor is executed without an explicit command to be called.
#
# ==== Parameters
# meth:: name of the default command
#
def default_command(meth = nil)
if meth
@default_command = meth == :none ? "help" : meth.to_s
else
@default_command ||= from_superclass(:default_command, "help")
end
end
alias_method :default_task, :default_command
# Registers another Bundler::Thor subclass as a command.
#
# ==== Parameters
# klass:: Bundler::Thor subclass to register
# command:: Subcommand name to use
# usage:: Short usage for the subcommand
# description:: Description for the subcommand
def register(klass, subcommand_name, usage, description, options = {})
if klass <= Bundler::Thor::Group
desc usage, description, options
define_method(subcommand_name) { |*args| invoke(klass, args) }
else
desc usage, description, options
subcommand subcommand_name, klass
end
end
# Defines the usage and the description of the next command.
#
# ==== Parameters
# usage
# description
# options
#
def desc(usage, description, options = {})
if options[:for]
command = find_and_refresh_command(options[:for])
command.usage = usage if usage
command.description = description if description
else
@usage = usage
@desc = description
@hide = options[:hide] || false
end
end
# Defines the long description of the next command.
#
# ==== Parameters
# long description
#
def long_desc(long_description, options = {})
if options[:for]
command = find_and_refresh_command(options[:for])
command.long_description = long_description if long_description
else
@long_desc = long_description
end
end
# Maps an input to a command. If you define:
#
# map "-T" => "list"
#
# Running:
#
# thor -T
#
# Will invoke the list command.
#
# ==== Parameters
# Hash[String|Array => Symbol]:: Maps the string or the strings in the array to the given command.
#
def map(mappings = nil, **kw)
@map ||= from_superclass(:map, {})
if mappings && !kw.empty?
mappings = kw.merge!(mappings)
else
mappings ||= kw
end
if mappings
mappings.each do |key, value|
if key.respond_to?(:each)
key.each { |subkey| @map[subkey] = value }
else
@map[key] = value
end
end
end
@map
end
# Declares the options for the next command to be declared.
#
# ==== Parameters
# Hash[Symbol => Object]:: The hash key is the name of the option and the value
# is the type of the option. Can be :string, :array, :hash, :boolean, :numeric
# or :required (string). If you give a value, the type of the value is used.
#
def method_options(options = nil)
@method_options ||= {}
build_options(options, @method_options) if options
@method_options
end
alias_method :options, :method_options
# Adds an option to the set of method options. If :for is given as option,
# it allows you to change the options from a previous defined command.
#
# def previous_command
# # magic
# end
#
# method_option :foo => :bar, :for => :previous_command
#
# def next_command
# # magic
# end
#
# ==== Parameters
# name:: The name of the argument.
# options:: Described below.
#
# ==== Options
# :desc - Description for the argument.
# :required - If the argument is required or not.
# :default - Default value for this argument. It cannot be required and have default values.
# :aliases - Aliases for this option.
# :type - The type of the argument, can be :string, :hash, :array, :numeric or :boolean.
# :banner - String to show on usage notes.
# :hide - If you want to hide this option from the help.
#
def method_option(name, options = {})
scope = if options[:for]
find_and_refresh_command(options[:for]).options
else
method_options
end
build_option(name, options, scope)
end
alias_method :option, :method_option
# Prints help information for the given command.
#
# ==== Parameters
# shell
# command_name
#
def command_help(shell, command_name)
meth = normalize_command_name(command_name)
command = all_commands[meth]
handle_no_command_error(meth) unless command
shell.say "Usage:"
shell.say " #{banner(command).split("\n").join("\n ")}"
shell.say
class_options_help(shell, nil => command.options.values)
if command.long_description
shell.say "Description:"
shell.print_wrapped(command.long_description, :indent => 2)
else
shell.say command.description
end
end
alias_method :task_help, :command_help
# Prints help information for this class.
#
# ==== Parameters
# shell
#
def help(shell, subcommand = false)
list = printable_commands(true, subcommand)
Bundler::Thor::Util.thor_classes_in(self).each do |klass|
list += klass.printable_commands(false)
end
list.sort! { |a, b| a[0] <=> b[0] }
if defined?(@package_name) && @package_name
shell.say "#{@package_name} commands:"
else
shell.say "Commands:"
end
shell.print_table(list, :indent => 2, :truncate => true)
shell.say
class_options_help(shell)
end
# Returns commands ready to be printed.
def printable_commands(all = true, subcommand = false)
(all ? all_commands : commands).map do |_, command|
next if command.hidden?
item = []
item << banner(command, false, subcommand)
item << (command.description ? "# #{command.description.gsub(/\s+/m, ' ')}" : "")
item
end.compact
end
alias_method :printable_tasks, :printable_commands
def subcommands
@subcommands ||= from_superclass(:subcommands, [])
end
alias_method :subtasks, :subcommands
def subcommand_classes
@subcommand_classes ||= {}
end
def subcommand(subcommand, subcommand_class)
subcommands << subcommand.to_s
subcommand_class.subcommand_help subcommand
subcommand_classes[subcommand.to_s] = subcommand_class
define_method(subcommand) do |*args|
args, opts = Bundler::Thor::Arguments.split(args)
invoke_args = [args, opts, {:invoked_via_subcommand => true, :class_options => options}]
invoke_args.unshift "help" if opts.delete("--help") || opts.delete("-h")
invoke subcommand_class, *invoke_args
end
subcommand_class.commands.each do |_meth, command|
command.ancestor_name = subcommand
end
end
alias_method :subtask, :subcommand
# Extend check unknown options to accept a hash of conditions.
#
# === Parameters
# options: A hash containing :only and/or :except keys
def check_unknown_options!(options = {})
@check_unknown_options ||= {}
options.each do |key, value|
if value
@check_unknown_options[key] = Array(value)
else
@check_unknown_options.delete(key)
end
end
@check_unknown_options
end
# Overwrite check_unknown_options? to take subcommands and options into account.
def check_unknown_options?(config) #:nodoc:
options = check_unknown_options
return false unless options
command = config[:current_command]
return true unless command
name = command.name
if subcommands.include?(name)
false
elsif options[:except]
!options[:except].include?(name.to_sym)
elsif options[:only]
options[:only].include?(name.to_sym)
else
true
end
end
# Stop parsing of options as soon as an unknown option or a regular
# argument is encountered. All remaining arguments are passed to the command.
# This is useful if you have a command that can receive arbitrary additional
# options, and where those additional options should not be handled by
# Bundler::Thor.
#
# ==== Example
#
# To better understand how this is useful, let's consider a command that calls
# an external command. A user may want to pass arbitrary options and
# arguments to that command. The command itself also accepts some options,
# which should be handled by Bundler::Thor.
#
# class_option "verbose", :type => :boolean
# stop_on_unknown_option! :exec
# check_unknown_options! :except => :exec
#
# desc "exec", "Run a shell command"
# def exec(*args)
# puts "diagnostic output" if options[:verbose]
# Kernel.exec(*args)
# end
#
# Here +exec+ can be called with +--verbose+ to get diagnostic output,
# e.g.:
#
# $ thor exec --verbose echo foo
# diagnostic output
# foo
#
# But if +--verbose+ is given after +echo+, it is passed to +echo+ instead:
#
# $ thor exec echo --verbose foo
# --verbose foo
#
# ==== Parameters
# Symbol ...:: A list of commands that should be affected.
def stop_on_unknown_option!(*command_names)
@stop_on_unknown_option = stop_on_unknown_option | command_names
end
def stop_on_unknown_option?(command) #:nodoc:
command && stop_on_unknown_option.include?(command.name.to_sym)
end
# Disable the check for required options for the given commands.
# This is useful if you have a command that does not need the required options
# to work, like help.
#
# ==== Parameters
# Symbol ...:: A list of commands that should be affected.
def disable_required_check!(*command_names)
@disable_required_check = disable_required_check | command_names
end
def disable_required_check?(command) #:nodoc:
command && disable_required_check.include?(command.name.to_sym)
end
protected
def stop_on_unknown_option #:nodoc:
@stop_on_unknown_option ||= []
end
# help command has the required check disabled by default.
def disable_required_check #:nodoc:
@disable_required_check ||= [:help]
end
# The method responsible for dispatching given the args.
def dispatch(meth, given_args, given_opts, config) #:nodoc: # rubocop:disable MethodLength
meth ||= retrieve_command_name(given_args)
command = all_commands[normalize_command_name(meth)]
if !command && config[:invoked_via_subcommand]
# We're a subcommand and our first argument didn't match any of our
# commands. So we put it back and call our default command.
given_args.unshift(meth)
command = all_commands[normalize_command_name(default_command)]
end
if command
args, opts = Bundler::Thor::Options.split(given_args)
if stop_on_unknown_option?(command) && !args.empty?
# given_args starts with a non-option, so we treat everything as
# ordinary arguments
args.concat opts
opts.clear
end
else
args = given_args
opts = nil
command = dynamic_command_class.new(meth)
end
opts = given_opts || opts || []
config[:current_command] = command
config[:command_options] = command.options
instance = new(args, opts, config)
yield instance if block_given?
args = instance.args
trailing = args[Range.new(arguments.size, -1)]
instance.invoke_command(command, trailing || [])
end
# The banner for this class. You can customize it if you are invoking the
# thor class by another ways which is not the Bundler::Thor::Runner. It receives
# the command that is going to be invoked and a boolean which indicates if
# the namespace should be displayed as arguments.
#
def banner(command, namespace = nil, subcommand = false)
command.formatted_usage(self, $thor_runner, subcommand).split("\n").map do |formatted_usage|
"#{basename} #{formatted_usage}"
end.join("\n")
end
def baseclass #:nodoc:
Bundler::Thor
end
def dynamic_command_class #:nodoc:
Bundler::Thor::DynamicCommand
end
def create_command(meth) #:nodoc:
@usage ||= nil
@desc ||= nil
@long_desc ||= nil
@hide ||= nil
if @usage && @desc
base_class = @hide ? Bundler::Thor::HiddenCommand : Bundler::Thor::Command
commands[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options)
@usage, @desc, @long_desc, @method_options, @hide = nil
true
elsif all_commands[meth] || meth == "method_missing"
true
else
puts "[WARNING] Attempted to create command #{meth.inspect} without usage or description. " \
"Call desc if you want this method to be available as command or declare it inside a " \
"no_commands{} block. Invoked from #{caller[1].inspect}."
false
end
end
alias_method :create_task, :create_command
def initialize_added #:nodoc:
class_options.merge!(method_options)
@method_options = nil
end
# Retrieve the command name from given args.
def retrieve_command_name(args) #:nodoc:
meth = args.first.to_s unless args.empty?
args.shift if meth && (map[meth] || meth !~ /^\-/)
end
alias_method :retrieve_task_name, :retrieve_command_name
# receives a (possibly nil) command name and returns a name that is in
# the commands hash. In addition to normalizing aliases, this logic
# will determine if a shortened command is an unambiguous substring of
# a command or alias.
#
# +normalize_command_name+ also converts names like +animal-prison+
# into +animal_prison+.
def normalize_command_name(meth) #:nodoc:
return default_command.to_s.tr("-", "_") unless meth
possibilities = find_command_possibilities(meth)
raise AmbiguousTaskError, "Ambiguous command #{meth} matches [#{possibilities.join(', ')}]" if possibilities.size > 1
if possibilities.empty?
meth ||= default_command
elsif map[meth]
meth = map[meth]
else
meth = possibilities.first
end
meth.to_s.tr("-", "_") # treat foo-bar as foo_bar
end
alias_method :normalize_task_name, :normalize_command_name
# this is the logic that takes the command name passed in by the user
# and determines whether it is an unambiguous substrings of a command or
# alias name.
def find_command_possibilities(meth)
len = meth.to_s.length
possibilities = all_commands.merge(map).keys.select { |n| meth == n[0, len] }.sort
unique_possibilities = possibilities.map { |k| map[k] || k }.uniq
if possibilities.include?(meth)
[meth]
elsif unique_possibilities.size == 1
unique_possibilities
else
possibilities
end
end
alias_method :find_task_possibilities, :find_command_possibilities
def subcommand_help(cmd)
desc "help [COMMAND]", "Describe subcommands or one specific subcommand"
class_eval "
def help(command = nil, subcommand = true); super; end
"
end
alias_method :subtask_help, :subcommand_help
end
include Bundler::Thor::Base
map HELP_MAPPINGS => :help
desc "help [COMMAND]", "Describe available commands or one specific command"
def help(command = nil, subcommand = false)
if command
if self.class.subcommands.include? command
self.class.subcommand_classes[command].help(shell, true)
else
self.class.command_help(shell, command)
end
else
self.class.help(shell, subcommand)
end
end
end
PK ! Dx, , lib/thor/version.rbnu [ class Bundler::Thor
VERSION = "1.2.1"
end
PK ! U7gR * * lib/thor/actions.rbnu [ require_relative "actions/create_file"
require_relative "actions/create_link"
require_relative "actions/directory"
require_relative "actions/empty_directory"
require_relative "actions/file_manipulation"
require_relative "actions/inject_into_file"
class Bundler::Thor
module Actions
attr_accessor :behavior
def self.included(base) #:nodoc:
super(base)
base.extend ClassMethods
end
module ClassMethods
# Hold source paths for one Bundler::Thor instance. source_paths_for_search is the
# method responsible to gather source_paths from this current class,
# inherited paths and the source root.
#
def source_paths
@_source_paths ||= []
end
# Stores and return the source root for this class
def source_root(path = nil)
@_source_root = path if path
@_source_root ||= nil
end
# Returns the source paths in the following order:
#
# 1) This class source paths
# 2) Source root
# 3) Parents source paths
#
def source_paths_for_search
paths = []
paths += source_paths
paths << source_root if source_root
paths += from_superclass(:source_paths, [])
paths
end
# Add runtime options that help actions execution.
#
def add_runtime_options!
class_option :force, :type => :boolean, :aliases => "-f", :group => :runtime,
:desc => "Overwrite files that already exist"
class_option :pretend, :type => :boolean, :aliases => "-p", :group => :runtime,
:desc => "Run but do not make any changes"
class_option :quiet, :type => :boolean, :aliases => "-q", :group => :runtime,
:desc => "Suppress status output"
class_option :skip, :type => :boolean, :aliases => "-s", :group => :runtime,
:desc => "Skip files that already exist"
end
end
# Extends initializer to add more configuration options.
#
# ==== Configuration
# behavior:: The actions default behavior. Can be :invoke or :revoke.
# It also accepts :force, :skip and :pretend to set the behavior
# and the respective option.
#
# destination_root:: The root directory needed for some actions.
#
def initialize(args = [], options = {}, config = {})
self.behavior = case config[:behavior].to_s
when "force", "skip"
_cleanup_options_and_set(options, config[:behavior])
:invoke
when "revoke"
:revoke
else
:invoke
end
super
self.destination_root = config[:destination_root]
end
# Wraps an action object and call it accordingly to the thor class behavior.
#
def action(instance) #:nodoc:
if behavior == :revoke
instance.revoke!
else
instance.invoke!
end
end
# Returns the root for this thor class (also aliased as destination root).
#
def destination_root
@destination_stack.last
end
# Sets the root for this thor class. Relatives path are added to the
# directory where the script was invoked and expanded.
#
def destination_root=(root)
@destination_stack ||= []
@destination_stack[0] = File.expand_path(root || "")
end
# Returns the given path relative to the absolute root (ie, root where
# the script started).
#
def relative_to_original_destination_root(path, remove_dot = true)
root = @destination_stack[0]
if path.start_with?(root) && [File::SEPARATOR, File::ALT_SEPARATOR, nil, ''].include?(path[root.size..root.size])
path = path.dup
path[0...root.size] = '.'
remove_dot ? (path[2..-1] || "") : path
else
path
end
end
# Holds source paths in instance so they can be manipulated.
#
def source_paths
@source_paths ||= self.class.source_paths_for_search
end
# Receives a file or directory and search for it in the source paths.
#
def find_in_source_paths(file)
possible_files = [file, file + TEMPLATE_EXTNAME]
relative_root = relative_to_original_destination_root(destination_root, false)
source_paths.each do |source|
possible_files.each do |f|
source_file = File.expand_path(f, File.join(source, relative_root))
return source_file if File.exist?(source_file)
end
end
message = "Could not find #{file.inspect} in any of your source paths. ".dup
unless self.class.source_root
message << "Please invoke #{self.class.name}.source_root(PATH) with the PATH containing your templates. "
end
message << if source_paths.empty?
"Currently you have no source paths."
else
"Your current source paths are: \n#{source_paths.join("\n")}"
end
raise Error, message
end
# Do something in the root or on a provided subfolder. If a relative path
# is given it's referenced from the current root. The full path is yielded
# to the block you provide. The path is set back to the previous path when
# the method exits.
#
# Returns the value yielded by the block.
#
# ==== Parameters
# dir:: the directory to move to.
# config:: give :verbose => true to log and use padding.
#
def inside(dir = "", config = {}, &block)
verbose = config.fetch(:verbose, false)
pretend = options[:pretend]
say_status :inside, dir, verbose
shell.padding += 1 if verbose
@destination_stack.push File.expand_path(dir, destination_root)
# If the directory doesnt exist and we're not pretending
if !File.exist?(destination_root) && !pretend
require "fileutils"
FileUtils.mkdir_p(destination_root)
end
result = nil
if pretend
# In pretend mode, just yield down to the block
result = block.arity == 1 ? yield(destination_root) : yield
else
require "fileutils"
FileUtils.cd(destination_root) { result = block.arity == 1 ? yield(destination_root) : yield }
end
@destination_stack.pop
shell.padding -= 1 if verbose
result
end
# Goes to the root and execute the given block.
#
def in_root
inside(@destination_stack.first) { yield }
end
# Loads an external file and execute it in the instance binding.
#
# ==== Parameters
# path:: The path to the file to execute. Can be a web address or
# a relative path from the source root.
#
# ==== Examples
#
# apply "http://gist.github.com/103208"
#
# apply "recipes/jquery.rb"
#
def apply(path, config = {})
verbose = config.fetch(:verbose, true)
is_uri = path =~ %r{^https?\://}
path = find_in_source_paths(path) unless is_uri
say_status :apply, path, verbose
shell.padding += 1 if verbose
contents = if is_uri
require "open-uri"
URI.open(path, "Accept" => "application/x-thor-template", &:read)
else
open(path, &:read)
end
instance_eval(contents, path)
shell.padding -= 1 if verbose
end
# Executes a command returning the contents of the command.
#
# ==== Parameters
# command:: the command to be executed.
# config:: give :verbose => false to not log the status, :capture => true to hide to output. Specify :with
# to append an executable to command execution.
#
# ==== Example
#
# inside('vendor') do
# run('ln -s ~/edge rails')
# end
#
def run(command, config = {})
return unless behavior == :invoke
destination = relative_to_original_destination_root(destination_root, false)
desc = "#{command} from #{destination.inspect}"
if config[:with]
desc = "#{File.basename(config[:with].to_s)} #{desc}"
command = "#{config[:with]} #{command}"
end
say_status :run, desc, config.fetch(:verbose, true)
return if options[:pretend]
env_splat = [config[:env]] if config[:env]
if config[:capture]
require "open3"
result, status = Open3.capture2e(*env_splat, command.to_s)
success = status.success?
else
result = system(*env_splat, command.to_s)
success = result
end
abort if !success && config.fetch(:abort_on_failure, self.class.exit_on_failure?)
result
end
# Executes a ruby script (taking into account WIN32 platform quirks).
#
# ==== Parameters
# command:: the command to be executed.
# config:: give :verbose => false to not log the status.
#
def run_ruby_script(command, config = {})
return unless behavior == :invoke
run command, config.merge(:with => Bundler::Thor::Util.ruby_command)
end
# Run a thor command. A hash of options can be given and it's converted to
# switches.
#
# ==== Parameters
# command:: the command to be invoked
# args:: arguments to the command
# config:: give :verbose => false to not log the status, :capture => true to hide to output.
# Other options are given as parameter to Bundler::Thor.
#
#
# ==== Examples
#
# thor :install, "http://gist.github.com/103208"
# #=> thor install http://gist.github.com/103208
#
# thor :list, :all => true, :substring => 'rails'
# #=> thor list --all --substring=rails
#
def thor(command, *args)
config = args.last.is_a?(Hash) ? args.pop : {}
verbose = config.key?(:verbose) ? config.delete(:verbose) : true
pretend = config.key?(:pretend) ? config.delete(:pretend) : false
capture = config.key?(:capture) ? config.delete(:capture) : false
args.unshift(command)
args.push Bundler::Thor::Options.to_switches(config)
command = args.join(" ").strip
run command, :with => :thor, :verbose => verbose, :pretend => pretend, :capture => capture
end
protected
# Allow current root to be shared between invocations.
#
def _shared_configuration #:nodoc:
super.merge!(:destination_root => destination_root)
end
def _cleanup_options_and_set(options, key) #:nodoc:
case options
when Array
%w(--force -f --skip -s).each { |i| options.delete(i) }
options << "--#{key}"
when Hash
[:force, :skip, "force", "skip"].each { |i| options.delete(i) }
options.merge!(key => true)
end
end
end
end
PK ! ~3 3 % lib/thor/actions/file_manipulation.rbnu [ require "erb"
class Bundler::Thor
module Actions
# Copies the file from the relative source to the relative destination. If
# the destination is not given it's assumed to be equal to the source.
#
# ==== Parameters
# source:: the relative path to the source root.
# destination:: the relative path to the destination root.
# config:: give :verbose => false to not log the status, and
# :mode => :preserve, to preserve the file mode from the source.
#
# ==== Examples
#
# copy_file "README", "doc/README"
#
# copy_file "doc/README"
#
def copy_file(source, *args, &block)
config = args.last.is_a?(Hash) ? args.pop : {}
destination = args.first || source
source = File.expand_path(find_in_source_paths(source.to_s))
resulting_destination = create_file destination, nil, config do
content = File.binread(source)
content = yield(content) if block
content
end
if config[:mode] == :preserve
mode = File.stat(source).mode
chmod(resulting_destination, mode, config)
end
end
# Links the file from the relative source to the relative destination. If
# the destination is not given it's assumed to be equal to the source.
#
# ==== Parameters
# source:: the relative path to the source root.
# destination:: the relative path to the destination root.
# config:: give :verbose => false to not log the status.
#
# ==== Examples
#
# link_file "README", "doc/README"
#
# link_file "doc/README"
#
def link_file(source, *args)
config = args.last.is_a?(Hash) ? args.pop : {}
destination = args.first || source
source = File.expand_path(find_in_source_paths(source.to_s))
create_link destination, source, config
end
# Gets the content at the given address and places it at the given relative
# destination. If a block is given instead of destination, the content of
# the url is yielded and used as location.
#
# +get+ relies on open-uri, so passing application user input would provide
# a command injection attack vector.
#
# ==== Parameters
# source:: the address of the given content.
# destination:: the relative path to the destination root.
# config:: give :verbose => false to not log the status.
#
# ==== Examples
#
# get "http://gist.github.com/103208", "doc/README"
#
# get "http://gist.github.com/103208" do |content|
# content.split("\n").first
# end
#
def get(source, *args, &block)
config = args.last.is_a?(Hash) ? args.pop : {}
destination = args.first
render = if source =~ %r{^https?\://}
require "open-uri"
URI.send(:open, source) { |input| input.binmode.read }
else
source = File.expand_path(find_in_source_paths(source.to_s))
open(source) { |input| input.binmode.read }
end
destination ||= if block_given?
block.arity == 1 ? yield(render) : yield
else
File.basename(source)
end
create_file destination, render, config
end
# Gets an ERB template at the relative source, executes it and makes a copy
# at the relative destination. If the destination is not given it's assumed
# to be equal to the source removing .tt from the filename.
#
# ==== Parameters
# source:: the relative path to the source root.
# destination:: the relative path to the destination root.
# config:: give :verbose => false to not log the status.
#
# ==== Examples
#
# template "README", "doc/README"
#
# template "doc/README"
#
def template(source, *args, &block)
config = args.last.is_a?(Hash) ? args.pop : {}
destination = args.first || source.sub(/#{TEMPLATE_EXTNAME}$/, "")
source = File.expand_path(find_in_source_paths(source.to_s))
context = config.delete(:context) || instance_eval("binding")
create_file destination, nil, config do
match = ERB.version.match(/(\d+\.\d+\.\d+)/)
capturable_erb = if match && match[1] >= "2.2.0" # Ruby 2.6+
CapturableERB.new(::File.binread(source), :trim_mode => "-", :eoutvar => "@output_buffer")
else
CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer")
end
content = capturable_erb.tap do |erb|
erb.filename = source
end.result(context)
content = yield(content) if block
content
end
end
# Changes the mode of the given file or directory.
#
# ==== Parameters
# mode:: the file mode
# path:: the name of the file to change mode
# config:: give :verbose => false to not log the status.
#
# ==== Example
#
# chmod "script/server", 0755
#
def chmod(path, mode, config = {})
return unless behavior == :invoke
path = File.expand_path(path, destination_root)
say_status :chmod, relative_to_original_destination_root(path), config.fetch(:verbose, true)
unless options[:pretend]
require "fileutils"
FileUtils.chmod_R(mode, path)
end
end
# Prepend text to a file. Since it depends on insert_into_file, it's reversible.
#
# ==== Parameters
# path:: path of the file to be changed
# data:: the data to prepend to the file, can be also given as a block.
# config:: give :verbose => false to not log the status.
#
# ==== Example
#
# prepend_to_file 'config/environments/test.rb', 'config.gem "rspec"'
#
# prepend_to_file 'config/environments/test.rb' do
# 'config.gem "rspec"'
# end
#
def prepend_to_file(path, *args, &block)
config = args.last.is_a?(Hash) ? args.pop : {}
config[:after] = /\A/
insert_into_file(path, *(args << config), &block)
end
alias_method :prepend_file, :prepend_to_file
# Append text to a file. Since it depends on insert_into_file, it's reversible.
#
# ==== Parameters
# path:: path of the file to be changed
# data:: the data to append to the file, can be also given as a block.
# config:: give :verbose => false to not log the status.
#
# ==== Example
#
# append_to_file 'config/environments/test.rb', 'config.gem "rspec"'
#
# append_to_file 'config/environments/test.rb' do
# 'config.gem "rspec"'
# end
#
def append_to_file(path, *args, &block)
config = args.last.is_a?(Hash) ? args.pop : {}
config[:before] = /\z/
insert_into_file(path, *(args << config), &block)
end
alias_method :append_file, :append_to_file
# Injects text right after the class definition. Since it depends on
# insert_into_file, it's reversible.
#
# ==== Parameters
# path:: path of the file to be changed
# klass:: the class to be manipulated
# data:: the data to append to the class, can be also given as a block.
# config:: give :verbose => false to not log the status.
#
# ==== Examples
#
# inject_into_class "app/controllers/application_controller.rb", "ApplicationController", " filter_parameter :password\n"
#
# inject_into_class "app/controllers/application_controller.rb", "ApplicationController" do
# " filter_parameter :password\n"
# end
#
def inject_into_class(path, klass, *args, &block)
config = args.last.is_a?(Hash) ? args.pop : {}
config[:after] = /class #{klass}\n|class #{klass} .*\n/
insert_into_file(path, *(args << config), &block)
end
# Injects text right after the module definition. Since it depends on
# insert_into_file, it's reversible.
#
# ==== Parameters
# path:: path of the file to be changed
# module_name:: the module to be manipulated
# data:: the data to append to the class, can be also given as a block.
# config:: give :verbose => false to not log the status.
#
# ==== Examples
#
# inject_into_module "app/helpers/application_helper.rb", "ApplicationHelper", " def help; 'help'; end\n"
#
# inject_into_module "app/helpers/application_helper.rb", "ApplicationHelper" do
# " def help; 'help'; end\n"
# end
#
def inject_into_module(path, module_name, *args, &block)
config = args.last.is_a?(Hash) ? args.pop : {}
config[:after] = /module #{module_name}\n|module #{module_name} .*\n/
insert_into_file(path, *(args << config), &block)
end
# Run a regular expression replacement on a file.
#
# ==== Parameters
# path:: path of the file to be changed
# flag:: the regexp or string to be replaced
# replacement:: the replacement, can be also given as a block
# config:: give :verbose => false to not log the status, and
# :force => true, to force the replacement regardles of runner behavior.
#
# ==== Example
#
# gsub_file 'app/controllers/application_controller.rb', /#\s*(filter_parameter_logging :password)/, '\1'
#
# gsub_file 'README', /rake/, :green do |match|
# match << " no more. Use thor!"
# end
#
def gsub_file(path, flag, *args, &block)
config = args.last.is_a?(Hash) ? args.pop : {}
return unless behavior == :invoke || config.fetch(:force, false)
path = File.expand_path(path, destination_root)
say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true)
unless options[:pretend]
content = File.binread(path)
content.gsub!(flag, *args, &block)
File.open(path, "wb") { |file| file.write(content) }
end
end
# Uncomment all lines matching a given regex. It will leave the space
# which existed before the comment hash in tact but will remove any spacing
# between the comment hash and the beginning of the line.
#
# ==== Parameters
# path:: path of the file to be changed
# flag:: the regexp or string used to decide which lines to uncomment
# config:: give :verbose => false to not log the status.
#
# ==== Example
#
# uncomment_lines 'config/initializers/session_store.rb', /active_record/
#
def uncomment_lines(path, flag, *args)
flag = flag.respond_to?(:source) ? flag.source : flag
gsub_file(path, /^(\s*)#[[:blank:]]*(.*#{flag})/, '\1\2', *args)
end
# Comment all lines matching a given regex. It will leave the space
# which existed before the beginning of the line in tact and will insert
# a single space after the comment hash.
#
# ==== Parameters
# path:: path of the file to be changed
# flag:: the regexp or string used to decide which lines to comment
# config:: give :verbose => false to not log the status.
#
# ==== Example
#
# comment_lines 'config/initializers/session_store.rb', /cookie_store/
#
def comment_lines(path, flag, *args)
flag = flag.respond_to?(:source) ? flag.source : flag
gsub_file(path, /^(\s*)([^#\n]*#{flag})/, '\1# \2', *args)
end
# Removes a file at the given location.
#
# ==== Parameters
# path:: path of the file to be changed
# config:: give :verbose => false to not log the status.
#
# ==== Example
#
# remove_file 'README'
# remove_file 'app/controllers/application_controller.rb'
#
def remove_file(path, config = {})
return unless behavior == :invoke
path = File.expand_path(path, destination_root)
say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true)
if !options[:pretend] && (File.exist?(path) || File.symlink?(path))
require "fileutils"
::FileUtils.rm_rf(path)
end
end
alias_method :remove_dir, :remove_file
attr_accessor :output_buffer
private :output_buffer, :output_buffer=
private
def concat(string)
@output_buffer.concat(string)
end
def capture(*args)
with_output_buffer { yield(*args) }
end
def with_output_buffer(buf = "".dup) #:nodoc:
raise ArgumentError, "Buffer can not be a frozen object" if buf.frozen?
old_buffer = output_buffer
self.output_buffer = buf
yield
output_buffer
ensure
self.output_buffer = old_buffer
end
# Bundler::Thor::Actions#capture depends on what kind of buffer is used in ERB.
# Thus CapturableERB fixes ERB to use String buffer.
class CapturableERB < ERB
def set_eoutvar(compiler, eoutvar = "_erbout")
compiler.put_cmd = "#{eoutvar}.concat"
compiler.insert_cmd = "#{eoutvar}.concat"
compiler.pre_cmd = ["#{eoutvar} = ''.dup"]
compiler.post_cmd = [eoutvar]
end
end
end
end
PK ! mX
$ lib/thor/actions/inject_into_file.rbnu [ require_relative "empty_directory"
class Bundler::Thor
module Actions
# Injects the given content into a file. Different from gsub_file, this
# method is reversible.
#
# ==== Parameters
# destination:: Relative path to the destination root
# data:: Data to add to the file. Can be given as a block.
# config:: give :verbose => false to not log the status and the flag
# for injection (:after or :before) or :force => true for
# insert two or more times the same content.
#
# ==== Examples
#
# insert_into_file "config/environment.rb", "config.gem :thor", :after => "Rails::Initializer.run do |config|\n"
#
# insert_into_file "config/environment.rb", :after => "Rails::Initializer.run do |config|\n" do
# gems = ask "Which gems would you like to add?"
# gems.split(" ").map{ |gem| " config.gem :#{gem}" }.join("\n")
# end
#
WARNINGS = { unchanged_no_flag: 'File unchanged! The supplied flag value not found!' }
def insert_into_file(destination, *args, &block)
data = block_given? ? block : args.shift
config = args.shift || {}
config[:after] = /\z/ unless config.key?(:before) || config.key?(:after)
action InjectIntoFile.new(self, destination, data, config)
end
alias_method :inject_into_file, :insert_into_file
class InjectIntoFile < EmptyDirectory #:nodoc:
attr_reader :replacement, :flag, :behavior
def initialize(base, destination, data, config)
super(base, destination, {:verbose => true}.merge(config))
@behavior, @flag = if @config.key?(:after)
[:after, @config.delete(:after)]
else
[:before, @config.delete(:before)]
end
@replacement = data.is_a?(Proc) ? data.call : data
@flag = Regexp.escape(@flag) unless @flag.is_a?(Regexp)
end
def invoke!
content = if @behavior == :after
'\0' + replacement
else
replacement + '\0'
end
if exists?
if replace!(/#{flag}/, content, config[:force])
say_status(:invoke)
else
say_status(:unchanged, warning: WARNINGS[:unchanged_no_flag], color: :red)
end
else
unless pretend?
raise Bundler::Thor::Error, "The file #{ destination } does not appear to exist"
end
end
end
def revoke!
say_status :revoke
regexp = if @behavior == :after
content = '\1\2'
/(#{flag})(.*)(#{Regexp.escape(replacement)})/m
else
content = '\2\3'
/(#{Regexp.escape(replacement)})(.*)(#{flag})/m
end
replace!(regexp, content, true)
end
protected
def say_status(behavior, warning: nil, color: nil)
status = if behavior == :invoke
if flag == /\A/
:prepend
elsif flag == /\z/
:append
else
:insert
end
elsif warning
warning
else
:subtract
end
super(status, (color || config[:verbose]))
end
# Adds the content to the file.
#
def replace!(regexp, string, force)
content = File.read(destination)
if force || !content.include?(replacement)
success = content.gsub!(regexp, string)
File.open(destination, "wb") { |file| file.write(content) } unless pretend?
success
end
end
end
end
end
PK ! te) ) lib/thor/actions/create_file.rbnu [ require_relative "empty_directory"
class Bundler::Thor
module Actions
# Create a new file relative to the destination root with the given data,
# which is the return value of a block or a data string.
#
# ==== Parameters
# destination:: the relative path to the destination root.
# data:: the data to append to the file.
# config:: give :verbose => false to not log the status.
#
# ==== Examples
#
# create_file "lib/fun_party.rb" do
# hostname = ask("What is the virtual hostname I should use?")
# "vhost.name = #{hostname}"
# end
#
# create_file "config/apache.conf", "your apache config"
#
def create_file(destination, *args, &block)
config = args.last.is_a?(Hash) ? args.pop : {}
data = args.first
action CreateFile.new(self, destination, block || data.to_s, config)
end
alias_method :add_file, :create_file
# CreateFile is a subset of Template, which instead of rendering a file with
# ERB, it gets the content from the user.
#
class CreateFile < EmptyDirectory #:nodoc:
attr_reader :data
def initialize(base, destination, data, config = {})
@data = data
super(base, destination, config)
end
# Checks if the content of the file at the destination is identical to the rendered result.
#
# ==== Returns
# Boolean:: true if it is identical, false otherwise.
#
def identical?
exists? && File.binread(destination) == render
end
# Holds the content to be added to the file.
#
def render
@render ||= if data.is_a?(Proc)
data.call
else
data
end
end
def invoke!
invoke_with_conflict_check do
require "fileutils"
FileUtils.mkdir_p(File.dirname(destination))
File.open(destination, "wb") { |f| f.write render }
end
given_destination
end
protected
# Now on conflict we check if the file is identical or not.
#
def on_conflict_behavior(&block)
if identical?
say_status :identical, :blue
else
options = base.options.merge(config)
force_or_skip_or_conflict(options[:force], options[:skip], &block)
end
end
# If force is true, run the action, otherwise check if it's not being
# skipped. If both are false, show the file_collision menu, if the menu
# returns true, force it, otherwise skip.
#
def force_or_skip_or_conflict(force, skip, &block)
if force
say_status :force, :yellow
yield unless pretend?
elsif skip
say_status :skip, :yellow
else
say_status :conflict, :red
force_or_skip_or_conflict(force_on_collision?, true, &block)
end
end
# Shows the file collision menu to the user and gets the result.
#
def force_on_collision?
base.shell.file_collision(destination) { render }
end
end
end
end
PK ! ,; lib/thor/actions/directory.rbnu [ require_relative "empty_directory"
class Bundler::Thor
module Actions
# Copies recursively the files from source directory to root directory.
# If any of the files finishes with .tt, it's considered to be a template
# and is placed in the destination without the extension .tt. If any
# empty directory is found, it's copied and all .empty_directory files are
# ignored. If any file name is wrapped within % signs, the text within
# the % signs will be executed as a method and replaced with the returned
# value. Let's suppose a doc directory with the following files:
#
# doc/
# components/.empty_directory
# README
# rdoc.rb.tt
# %app_name%.rb
#
# When invoked as:
#
# directory "doc"
#
# It will create a doc directory in the destination with the following
# files (assuming that the `app_name` method returns the value "blog"):
#
# doc/
# components/
# README
# rdoc.rb
# blog.rb
#
# Encoded path note: Since Bundler::Thor internals use Object#respond_to? to check if it can
# expand %something%, this `something` should be a public method in the class calling
# #directory. If a method is private, Bundler::Thor stack raises PrivateMethodEncodedError.
#
# ==== Parameters
# source:: the relative path to the source root.
# destination:: the relative path to the destination root.
# config:: give :verbose => false to not log the status.
# If :recursive => false, does not look for paths recursively.
# If :mode => :preserve, preserve the file mode from the source.
# If :exclude_pattern => /regexp/, prevents copying files that match that regexp.
#
# ==== Examples
#
# directory "doc"
# directory "doc", "docs", :recursive => false
#
def directory(source, *args, &block)
config = args.last.is_a?(Hash) ? args.pop : {}
destination = args.first || source
action Directory.new(self, source, destination || source, config, &block)
end
class Directory < EmptyDirectory #:nodoc:
attr_reader :source
def initialize(base, source, destination = nil, config = {}, &block)
@source = File.expand_path(Dir[Util.escape_globs(base.find_in_source_paths(source.to_s))].first)
@block = block
super(base, destination, {:recursive => true}.merge(config))
end
def invoke!
base.empty_directory given_destination, config
execute!
end
def revoke!
execute!
end
protected
def execute!
lookup = Util.escape_globs(source)
lookup = config[:recursive] ? File.join(lookup, "**") : lookup
lookup = file_level_lookup(lookup)
files(lookup).sort.each do |file_source|
next if File.directory?(file_source)
next if config[:exclude_pattern] && file_source.match(config[:exclude_pattern])
file_destination = File.join(given_destination, file_source.gsub(source, "."))
file_destination.gsub!("/./", "/")
case file_source
when /\.empty_directory$/
dirname = File.dirname(file_destination).gsub(%r{/\.$}, "")
next if dirname == given_destination
base.empty_directory(dirname, config)
when /#{TEMPLATE_EXTNAME}$/
base.template(file_source, file_destination[0..-4], config, &@block)
else
base.copy_file(file_source, file_destination, config, &@block)
end
end
end
def file_level_lookup(previous_lookup)
File.join(previous_lookup, "*")
end
def files(lookup)
Dir.glob(lookup, File::FNM_DOTMATCH)
end
end
end
end
PK ! O& # lib/thor/actions/empty_directory.rbnu [ class Bundler::Thor
module Actions
# Creates an empty directory.
#
# ==== Parameters
# destination:: the relative path to the destination root.
# config:: give :verbose => false to not log the status.
#
# ==== Examples
#
# empty_directory "doc"
#
def empty_directory(destination, config = {})
action EmptyDirectory.new(self, destination, config)
end
# Class which holds create directory logic. This is the base class for
# other actions like create_file and directory.
#
# This implementation is based in Templater actions, created by Jonas Nicklas
# and Michael S. Klishin under MIT LICENSE.
#
class EmptyDirectory #:nodoc:
attr_reader :base, :destination, :given_destination, :relative_destination, :config
# Initializes given the source and destination.
#
# ==== Parameters
# base:: A Bundler::Thor::Base instance
# source:: Relative path to the source of this file
# destination:: Relative path to the destination of this file
# config:: give :verbose => false to not log the status.
#
def initialize(base, destination, config = {})
@base = base
@config = {:verbose => true}.merge(config)
self.destination = destination
end
# Checks if the destination file already exists.
#
# ==== Returns
# Boolean:: true if the file exists, false otherwise.
#
def exists?
::File.exist?(destination)
end
def invoke!
invoke_with_conflict_check do
require "fileutils"
::FileUtils.mkdir_p(destination)
end
end
def revoke!
say_status :remove, :red
require "fileutils"
::FileUtils.rm_rf(destination) if !pretend? && exists?
given_destination
end
protected
# Shortcut for pretend.
#
def pretend?
base.options[:pretend]
end
# Sets the absolute destination value from a relative destination value.
# It also stores the given and relative destination. Let's suppose our
# script is being executed on "dest", it sets the destination root to
# "dest". The destination, given_destination and relative_destination
# are related in the following way:
#
# inside "bar" do
# empty_directory "baz"
# end
#
# destination #=> dest/bar/baz
# relative_destination #=> bar/baz
# given_destination #=> baz
#
def destination=(destination)
return unless destination
@given_destination = convert_encoded_instructions(destination.to_s)
@destination = ::File.expand_path(@given_destination, base.destination_root)
@relative_destination = base.relative_to_original_destination_root(@destination)
end
# Filenames in the encoded form are converted. If you have a file:
#
# %file_name%.rb
#
# It calls #file_name from the base and replaces %-string with the
# return value (should be String) of #file_name:
#
# user.rb
#
# The method referenced can be either public or private.
#
def convert_encoded_instructions(filename)
filename.gsub(/%(.*?)%/) do |initial_string|
method = $1.strip
base.respond_to?(method, true) ? base.send(method) : initial_string
end
end
# Receives a hash of options and just execute the block if some
# conditions are met.
#
def invoke_with_conflict_check(&block)
if exists?
on_conflict_behavior(&block)
else
yield unless pretend?
say_status :create, :green
end
destination
rescue Errno::EISDIR, Errno::EEXIST
on_file_clash_behavior
end
def on_file_clash_behavior
say_status :file_clash, :red
end
# What to do when the destination file already exists.
#
def on_conflict_behavior
say_status :exist, :blue
end
# Shortcut to say_status shell method.
#
def say_status(status, color)
base.shell.say_status status, relative_destination, color if config[:verbose]
end
end
end
end
PK ! s m m lib/thor/actions/create_link.rbnu [ require_relative "create_file"
class Bundler::Thor
module Actions
# Create a new file relative to the destination root from the given source.
#
# ==== Parameters
# destination:: the relative path to the destination root.
# source:: the relative path to the source root.
# config:: give :verbose => false to not log the status.
# :: give :symbolic => false for hard link.
#
# ==== Examples
#
# create_link "config/apache.conf", "/etc/apache.conf"
#
def create_link(destination, *args)
config = args.last.is_a?(Hash) ? args.pop : {}
source = args.first
action CreateLink.new(self, destination, source, config)
end
alias_method :add_link, :create_link
# CreateLink is a subset of CreateFile, which instead of taking a block of
# data, just takes a source string from the user.
#
class CreateLink < CreateFile #:nodoc:
attr_reader :data
# Checks if the content of the file at the destination is identical to the rendered result.
#
# ==== Returns
# Boolean:: true if it is identical, false otherwise.
#
def identical?
source = File.expand_path(render, File.dirname(destination))
exists? && File.identical?(source, destination)
end
def invoke!
invoke_with_conflict_check do
require "fileutils"
FileUtils.mkdir_p(File.dirname(destination))
# Create a symlink by default
config[:symbolic] = true if config[:symbolic].nil?
File.unlink(destination) if exists?
if config[:symbolic]
File.symlink(render, destination)
else
File.link(render, destination)
end
end
given_destination
end
def exists?
super || File.symlink?(destination)
end
end
end
end
PK ! }e
lib/thor/error.rbnu [ class Bundler::Thor
Correctable = if defined?(DidYouMean::SpellChecker) && defined?(DidYouMean::Correctable) # rubocop:disable Naming/ConstantName
# In order to support versions of Ruby that don't have keyword
# arguments, we need our own spell checker class that doesn't take key
# words. Even though this code wouldn't be hit because of the check
# above, it's still necessary because the interpreter would otherwise be
# unable to parse the file.
class NoKwargSpellChecker < DidYouMean::SpellChecker # :nodoc:
def initialize(dictionary)
@dictionary = dictionary
end
end
DidYouMean::Correctable
end
# Bundler::Thor::Error is raised when it's caused by wrong usage of thor classes. Those
# errors have their backtrace suppressed and are nicely shown to the user.
#
# Errors that are caused by the developer, like declaring a method which
# overwrites a thor keyword, SHOULD NOT raise a Bundler::Thor::Error. This way, we
# ensure that developer errors are shown with full backtrace.
class Error < StandardError
end
# Raised when a command was not found.
class UndefinedCommandError < Error
class SpellChecker
attr_reader :error
def initialize(error)
@error = error
end
def corrections
@corrections ||= spell_checker.correct(error.command).map(&:inspect)
end
def spell_checker
NoKwargSpellChecker.new(error.all_commands)
end
end
attr_reader :command, :all_commands
def initialize(command, all_commands, namespace)
@command = command
@all_commands = all_commands
message = "Could not find command #{command.inspect}"
message = namespace ? "#{message} in #{namespace.inspect} namespace." : "#{message}."
super(message)
end
prepend Correctable if Correctable
end
UndefinedTaskError = UndefinedCommandError
class AmbiguousCommandError < Error
end
AmbiguousTaskError = AmbiguousCommandError
# Raised when a command was found, but not invoked properly.
class InvocationError < Error
end
class UnknownArgumentError < Error
class SpellChecker
attr_reader :error
def initialize(error)
@error = error
end
def corrections
@corrections ||=
error.unknown.flat_map { |unknown| spell_checker.correct(unknown) }.uniq.map(&:inspect)
end
def spell_checker
@spell_checker ||= NoKwargSpellChecker.new(error.switches)
end
end
attr_reader :switches, :unknown
def initialize(switches, unknown)
@switches = switches
@unknown = unknown
super("Unknown switches #{unknown.map(&:inspect).join(', ')}")
end
prepend Correctable if Correctable
end
class RequiredArgumentMissingError < InvocationError
end
class MalformattedArgumentError < InvocationError
end
if Correctable
if DidYouMean.respond_to?(:correct_error)
DidYouMean.correct_error(Bundler::Thor::UndefinedCommandError, UndefinedCommandError::SpellChecker)
DidYouMean.correct_error(Bundler::Thor::UnknownArgumentError, UnknownArgumentError::SpellChecker)
else
DidYouMean::SPELL_CHECKERS.merge!(
'Bundler::Thor::UndefinedCommandError' => UndefinedCommandError::SpellChecker,
'Bundler::Thor::UnknownArgumentError' => UnknownArgumentError::SpellChecker
)
end
end
end
PK ! Yt} } lib/thor/line_editor/basic.rbnu [ class Bundler::Thor
module LineEditor
class Basic
attr_reader :prompt, :options
def self.available?
true
end
def initialize(prompt, options)
@prompt = prompt
@options = options
end
def readline
$stdout.print(prompt)
get_input
end
private
def get_input
if echo?
$stdin.gets
else
# Lazy-load io/console since it is gem-ified as of 2.3
require "io/console"
$stdin.noecho(&:gets)
end
end
def echo?
options.fetch(:echo, true)
end
end
end
end
PK ! dq=7 7 lib/thor/line_editor/readline.rbnu [ class Bundler::Thor
module LineEditor
class Readline < Basic
def self.available?
begin
require "readline"
rescue LoadError
end
Object.const_defined?(:Readline)
end
def readline
if echo?
::Readline.completion_append_character = nil
# rb-readline does not allow Readline.completion_proc= to receive nil.
if complete = completion_proc
::Readline.completion_proc = complete
end
::Readline.readline(prompt, add_to_history?)
else
super
end
end
private
def add_to_history?
options.fetch(:add_to_history, true)
end
def completion_proc
if use_path_completion?
proc { |text| PathCompletion.new(text).matches }
elsif completion_options.any?
proc do |text|
completion_options.select { |option| option.start_with?(text) }
end
end
end
def completion_options
options.fetch(:limited_to, [])
end
def use_path_completion?
options.fetch(:path, false)
end
class PathCompletion
attr_reader :text
private :text
def initialize(text)
@text = text
end
def matches
relative_matches
end
private
def relative_matches
absolute_matches.map { |path| path.sub(base_path, "") }
end
def absolute_matches
Dir[glob_pattern].map do |path|
if File.directory?(path)
"#{path}/"
else
path
end
end
end
def glob_pattern
"#{base_path}#{text}*"
end
def base_path
"#{Dir.pwd}/"
end
end
end
end
end
PK ! L WX# X# lib/thor/util.rbnu [ require "rbconfig"
class Bundler::Thor
module Sandbox #:nodoc:
end
# This module holds several utilities:
#
# 1) Methods to convert thor namespaces to constants and vice-versa.
#
# Bundler::Thor::Util.namespace_from_thor_class(Foo::Bar::Baz) #=> "foo:bar:baz"
#
# 2) Loading thor files and sandboxing:
#
# Bundler::Thor::Util.load_thorfile("~/.thor/foo")
#
module Util
class << self
# Receives a namespace and search for it in the Bundler::Thor::Base subclasses.
#
# ==== Parameters
# namespace:: The namespace to search for.
#
def find_by_namespace(namespace)
namespace = "default#{namespace}" if namespace.empty? || namespace =~ /^:/
Bundler::Thor::Base.subclasses.detect { |klass| klass.namespace == namespace }
end
# Receives a constant and converts it to a Bundler::Thor namespace. Since Bundler::Thor
# commands can be added to a sandbox, this method is also responsible for
# removing the sandbox namespace.
#
# This method should not be used in general because it's used to deal with
# older versions of Bundler::Thor. On current versions, if you need to get the
# namespace from a class, just call namespace on it.
#
# ==== Parameters
# constant