модуль Bundler::Thor::Actions
Атрибуты
Публичные методы класса
# File lib/bundler/vendor/thor/lib/thor/actions.rb, line 73
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 Расширяет инициализатор, добавляя дополнительные параметры конфигурации.
Конфигурация
- behavior<Symbol>
-
Поведение по умолчанию для действий. Может быть :invoke или :revoke. Также принимает :force, :skip и :pretend для установки поведения и соответствующего параметра.
-
destination_root<String> -
Корневой каталог, необходимый для некоторых действий.
Общедоступные методы экземпляра
# File lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb, line 186
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 Добавляет текст в файл. Поскольку это зависит от insert_into_file, операция обратима.
Параметры
- path<String>
-
путь к файлу, который необходимо изменить
- data<String>
-
данные для добавления в файл, также могут быть переданы как блок.
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать статус.
Пример
append_to_file 'config/environments/test.rb', 'config.gem "rspec"' append_to_file 'config/environments/test.rb' do 'config.gem "rspec"' end
# File lib/bundler/vendor/thor/lib/thor/actions.rb, line 211
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
open(path, "Accept" => "application/x-thor-template", &:read)
else
open(path, &:read)
end
instance_eval(contents, path)
shell.padding -= 1 if verbose
end Загружает внешний файл и выполняет его в контексте текущего экземпляра.
Параметры
- path<String>
-
Путь к файлу для выполнения. Может быть веб-адресом или относительным путем от корня исходного файла.
Примеры
apply "http://gist.github.com/103208" apply "recipes/jquery.rb"
# File lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb, line 139
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 Изменяет режим указанного файла или каталога.
Параметры
- mode<Integer>
-
режим файла
- path<String>
-
имя файла, режим которого необходимо изменить
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать статус.
Пример
chmod "script/server", 0755
# File lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb, line 301
def comment_lines(path, flag, *args)
flag = flag.respond_to?(:source) ? flag.source : flag
gsub_file(path, /^(\s*)([^#|\n]*#{flag})/, '\1# \2', *args)
end Комментирует все строки, соответствующие заданному регулярному выражению. Пробелы в начале строки сохраняются, а после символа # добавляется пробел.
Параметры
- path<String>
-
путь к файлу, который необходимо изменить
- flag<Regexp|String>
-
регулярное выражение или строка, используемая для определения строк, которые необходимо закомментировать
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать статус.
Пример
comment_lines 'config/initializers/session_store.rb', /cookie_store/
# File lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb, line 21
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))
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(destination, mode, config)
end
end Примеры
copy_file "README", "doc/README" copy_file "doc/README"
# File lib/bundler/vendor/thor/lib/thor/actions/create_file.rb, line 22
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 Создаёт новый файл по относительному пути от корня назначения с заданными данными, которые являются результатом блока или строкой данных.
Параметры
- destination<String>
-
относительный путь к корню назначения.
- data<String|NilClass>
-
данные для добавления в файл.
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать статус.
Примеры
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"
# File lib/bundler/vendor/thor/lib/thor/actions/create_link.rb, line 17
def create_link(destination, *args)
config = args.last.is_a?(Hash) ? args.pop : {}
source = args.first
action CreateLink.new(self, destination, source, config)
end Создаёт новый файл по относительному пути от корня назначения из заданного источника.
Параметры
- destination<String>
-
относительный путь к корню назначения.
- source<String|NilClass>
-
относительный путь к корню источника.
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать статус.
-
установите :symbolic => false для жёсткой ссылки.
Примеры
create_link "config/apache.conf", "/etc/apache.conf"
# File lib/bundler/vendor/thor/lib/thor/actions.rb, line 100 def destination_root @destination_stack.last end
Возвращает корень для данного класса thor (также известен как корень назначения).
# File lib/bundler/vendor/thor/lib/thor/actions.rb, line 107 def destination_root=(root) @destination_stack ||= [] @destination_stack[0] = File.expand_path(root || "") end
Устанавливает корень для данного класса thor. Относительные пути добавляются к каталогу, в котором был вызван скрипт и расширен.
# File lib/bundler/vendor/thor/lib/thor/actions/directory.rb, line 49
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 Рекурсивно копирует файлы из каталога source в корневой каталог. Файлы, заканчивающиеся на .tt, считаются шаблонами и помещаются в каталог назначения без расширения .tt. Пустые каталоги копируются, а файлы .empty_directory игнорируются. Имена файлов, заключённые в знаки %, обрабатываются как вызовы методов, а возвращаемое значение подставляет содержимое.
Предположим, есть каталог doc со следующими файлами:
doc/ components/.empty_directory README rdoc.rb.tt %app_name%.rb
При вызове:
directory "doc"
Будет создан каталог doc в каталоге назначения со следующими файлами (предполагая, что метод `app_name` возвращает «blog»):
doc/ components/ README rdoc.rb blog.rb
Примечание по кодированию путей: Поскольку внутренности Bundler::Thor используют Object#respond_to? для проверки возможности расширения %something%, это `something` должно быть общедоступным методом в классе, вызывающем directory. Если метод приватный, стек Bundler::Thor генерирует исключение PrivateMethodEncodedError.
Параметры
- source<String>
-
относительный путь к корню источника.
- destination<String>
-
относительный путь к корню назначения.
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать статус. Если :recursive => false, не ищет пути рекурсивно. Если :mode => :preserve, сохраняет режим файла из источника. Если :exclude_pattern => /regexp/, предотвращает копирование файлов, соответствующих данному регулярному выражению.
Примеры
directory "doc" directory "doc", "docs", :recursive => false
# File lib/bundler/vendor/thor/lib/thor/actions/empty_directory.rb, line 13
def empty_directory(destination, config = {})
action EmptyDirectory.new(self, destination, config)
end Создаёт пустой каталог.
Параметры
- destination<String>
-
относительный путь к корню назначения.
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать статус.
Примеры
empty_directory "doc"
# File lib/bundler/vendor/thor/lib/thor/actions.rb, line 132
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 Принимает файл или каталог и ищет его в путях источника.
# File lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb, line 76
def get(source, *args, &block)
config = args.last.is_a?(Hash) ? args.pop : {}
destination = args.first
if source =~ %r{^https?\://}
require "open-uri"
else
source = File.expand_path(find_in_source_paths(source.to_s))
end
render = open(source) { |input| input.binmode.read }
destination ||= if block_given?
block.arity == 1 ? yield(render) : yield
else
File.basename(source)
end
create_file destination, render, config
end Получает содержимое по заданному адресу и помещает его в указанное относительное место назначения. Если вместо местоположения задан блок, содержимое URL передается и используется в качестве расположения.
Параметры
- source<String>
-
адрес заданного содержимого.
- destination<String>
-
относительный путь к корню назначения.
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать статус.
Примеры
get "http://gist.github.com/103208", "doc/README"
get "http://gist.github.com/103208" do |content|
content.split("\n").first
end
# File lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb, line 255
def gsub_file(path, flag, *args, &block)
return unless behavior == :invoke
config = args.last.is_a?(Hash) ? args.pop : {}
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 Выполняет замену по регулярному выражению в файле.
Параметры
- path<String>
-
путь к файлу, который нужно изменить
- flag<Regexp|String>
-
регулярное выражение или строка, которую нужно заменить
- replacement<String>
-
замена, также может быть задана в виде блока
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать статус.
Пример
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
# File lib/bundler/vendor/thor/lib/thor/actions.rb, line 195
def in_root
inside(@destination_stack.first) { yield }
end Переходит в корень и выполняет заданный блок.
# File lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb, line 210
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 Вставляет текст сразу после определения класса. Поскольку это зависит от insert_into_file, оно обратимо.
Параметры
- path<String>
-
путь к файлу, который нужно изменить
- klass<String|Class>
-
класс, который нужно изменить
- data<String>
-
данные, которые нужно добавить к классу, также могут быть заданы в виде блока.
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать статус.
Примеры
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
# File lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb, line 233
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 Вставляет текст сразу после определения модуля. Поскольку это зависит от insert_into_file, оно обратимо.
Параметры
- path<String>
-
путь к файлу, который нужно изменить
- module_name<String|Class>
-
модуль, который нужно изменить
- data<String>
-
данные, которые нужно добавить к классу, также могут быть заданы в виде блока.
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать статус.
Примеры
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
# File lib/bundler/vendor/thor/lib/thor/actions/inject_into_file.rb, line 24 def insert_into_file(destination, *args, &block) data = block_given? ? block : args.shift config = args.shift action InjectIntoFile.new(self, destination, data, config) end
Вставляет заданное содержимое в файл. Отличается от gsub_file, этот метод обратим.
Параметры
- destination<String>
-
Относительный путь к корню назначения
- data<String>
-
Dataдля добавления в файл. Может быть задан как блок. - config<Hash>
-
установите :verbose => false, чтобы не регистрировать статус и флаг для вставки (:after или :before) или :force => true для вставки два или более раз одного и того же содержимого.
Примеры
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
# File lib/bundler/vendor/thor/lib/thor/actions.rb, line 167
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
if pretend
# In pretend mode, just yield down to the block
block.arity == 1 ? yield(destination_root) : yield
else
require "fileutils"
FileUtils.cd(destination_root) { block.arity == 1 ? yield(destination_root) : yield }
end
@destination_stack.pop
shell.padding -= 1 if verbose
end Выполняет действие в корне или в указанной подпапке. Если задан относительный путь, он относится к текущему корню. Полный путь передается в блок, который вы предоставляете. Путь восстанавливается до предыдущего значения при выходе из метода.
Параметры
- dir<String>
-
директория, в которую нужно перейти.
- config<Hash>
-
установите :verbose => true, чтобы регистрировать и использовать отступы.
# File lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb, line 51
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 Создает ссылку на файл из относительного источника в относительное место назначения. Если место назначения не указано, предполагается, что оно равно источнику.
Параметры
- source<String>
-
относительный путь к источнику.
- destination<String>
-
относительный путь к корню назначения.
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать статус.
Примеры
link_file "README", "doc/README" link_file "doc/README"
# File lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb, line 164
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 Добавляет текст в начало файла. Поскольку это зависит от insert_into_file, оно обратимо.
Параметры
- path<String>
-
путь к файлу, который нужно изменить
- data<String>
-
данные, которые нужно добавить в начало файла, также могут быть заданы в виде блока.
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать статус.
Пример
prepend_to_file 'config/environments/test.rb', 'config.gem "rspec"' prepend_to_file 'config/environments/test.rb' do 'config.gem "rspec"' end
# File lib/bundler/vendor/thor/lib/thor/actions.rb, line 115
def relative_to_original_destination_root(path, remove_dot = true)
path = path.dup
if path.gsub!(@destination_stack[0], ".")
remove_dot ? (path[2..-1] || "") : path
else
path
end
end Возвращает заданный путь относительно абсолютного корня (т. е. корня, с которого начался сценарий).
# File lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb, line 318
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)
require "fileutils"
::FileUtils.rm_rf(path)
end
end Удаляет файл в заданном месте.
Параметры
- path<String>
-
путь к файлу, который нужно изменить
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать статус.
Пример
remove_file 'README' remove_file 'app/controllers/application_controller.rb'
# File lib/bundler/vendor/thor/lib/thor/actions.rb, line 242
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)
unless options[:pretend]
config[:capture] ? `#{command}` : system(command.to_s)
end
end Выполняет команду и возвращает её содержимое.
Параметры
- command<String>
-
команда, подлежащая выполнению.
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать состояние; :capture => true, чтобы скрыть вывод. Укажите :with, чтобы добавить исполняемый файл к выполнению команды.
Пример
inside('vendor') do
run('ln -s ~/edge rails')
end
# File lib/bundler/vendor/thor/lib/thor/actions.rb, line 266
def run_ruby_script(command, config = {})
return unless behavior == :invoke
run command, config.merge(:with => Bundler::Thor::Util.ruby_command)
end Выполняет скрипт Ruby (принимая во внимание особенности платформы WIN32).
Параметры
- command<String>
-
команда, подлежащая выполнению.
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать состояние.
# File lib/bundler/vendor/thor/lib/thor/actions.rb, line 126 def source_paths @source_paths ||= self.class.source_paths_for_search end
Хранит пути к исходным файлам в экземпляре, чтобы их можно было обрабатывать.
# File lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb, line 112
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
content = CapturableERB.new(::File.binread(source), nil, "-", "@output_buffer").tap do |erb|
erb.filename = source
end.result(context)
content = yield(content) if block
content
end
end Получает шаблон ERB по относительному пути к источнику, выполняет его и создаёт копию по относительному пути к целевому каталогу. Если целевой каталог не указан, предполагается, что он равен источнику, удаляя .tt из имени файла.
Параметры
- source<String>
-
относительный путь к корню источника.
- destination<String>
-
относительный путь к корню назначения.
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать состояние.
Примеры
template "README", "doc/README" template "doc/README"
# File lib/bundler/vendor/thor/lib/thor/actions.rb, line 289
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 Выполняет команду thor. Хэш опций может быть передан, и он преобразуется в переключатели.
Параметры
- command<String>
-
команда, которая должна быть вызвана
- args<Array>
-
аргументы для команды
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать состояние; :capture => true, чтобы скрыть вывод. Другие параметры передаются в Bundler::Thor.
Примеры
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
# File lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb, line 282
def uncomment_lines(path, flag, *args)
flag = flag.respond_to?(:source) ? flag.source : flag
gsub_file(path, /^(\s*)#[[:blank:]]*(.*#{flag})/, '\1\2', *args)
end Разкомментирует все строки, соответствующие заданному регулярному выражению. Пробел, существовавший перед символом комментария, будет сохранен, но любые пробелы между символом комментария и началом строки будут удалены.
Параметры
- path<String>
-
путь к файлу, который нужно изменить
- flag<Regexp|String>
-
регулярное выражение или строка, используемые для определения строк, которые нужно разкомментировать
- config<Hash>
-
установите :verbose => false, чтобы не регистрировать состояние.
Пример
uncomment_lines 'config/initializers/session_store.rb', /active_record/
Закрытые методы экземпляра
# File lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb, line 339
def capture(*args)
with_output_buffer { yield(*args) }
end # File lib/bundler/vendor/thor/lib/thor/actions/file_manipulation.rb, line 335 def concat(string) @output_buffer.concat(string) end
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.