On this page
module Bundler::Thor::Actions
Attributes
Public Class Methods
# 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
Extends initializer to add more configuration options.
Configuration
- behavior<Symbol>
-
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
<String>-
The root directory needed for some actions.
Public Instance Methods
# 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
Append text to a file. Since it depends on insert_into_file
, it's reversible.
Parameters
- path<String>
-
path of the file to be changed
- data<String>
-
the data to append to the file, can be also given as a block.
- config<Hash>
-
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
# 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
Loads an external file and execute it in the instance binding.
Parameters
- path<String>
-
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"
# 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
Changes the mode of the given file or directory.
Parameters
- mode<Integer>
-
the file mode
- path<String>
-
the name of the file to change mode
- config<Hash>
-
give :verbose => false to not log the status.
Example
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
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<String>
-
path of the file to be changed
- flag<Regexp|String>
-
the regexp or string used to decide which lines to comment
- config<Hash>
-
give :verbose => false to not log the status.
Example
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
Examples
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
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<String>
-
the relative path to the destination root.
- data<String|NilClass>
-
the data to append to the file.
- config<Hash>
-
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"
# 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
Create a new file relative to the destination root from the given source.
Parameters
- destination<String>
-
the relative path to the destination root.
- source<String|NilClass>
-
the relative path to the source root.
- config<Hash>
-
give :verbose => false to not log the status.
-
give :symbolic => false for hard link.
Examples
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
Returns the root for this thor class (also aliased as destination root).
# 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
Sets the root for this thor class. Relatives path are added to the directory where the script was invoked and expanded.
# 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
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<String>
-
the relative path to the source root.
- destination<String>
-
the relative path to the destination root.
- config<Hash>
-
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
# 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
Creates an empty directory.
Parameters
- destination<String>
-
the relative path to the destination root.
- config<Hash>
-
give :verbose => false to not log the status.
Examples
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
Receives a file or directory and search for it in the source paths.
# 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
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.
Parameters
- source<String>
-
the address of the given content.
- destination<String>
-
the relative path to the destination root.
- config<Hash>
-
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
# 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
Run a regular expression replacement on a file.
Parameters
- path<String>
-
path of the file to be changed
- flag<Regexp|String>
-
the regexp or string to be replaced
- replacement<String>
-
the replacement, can be also given as a block
- config<Hash>
-
give :verbose => false to not log the status.
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
# File lib/bundler/vendor/thor/lib/thor/actions.rb, line 195
def in_root
inside(@destination_stack.first) { yield }
end
Goes to the root and execute the given block.
# 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
Injects text right after the class definition. Since it depends on insert_into_file
, it's reversible.
Parameters
- path<String>
-
path of the file to be changed
- klass<String|Class>
-
the class to be manipulated
- data<String>
-
the data to append to the class, can be also given as a block.
- config<Hash>
-
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
# 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
Injects text right after the module definition. Since it depends on insert_into_file
, it's reversible.
Parameters
- path<String>
-
path of the file to be changed
- module_name<String|Class>
-
the module to be manipulated
- data<String>
-
the data to append to the class, can be also given as a block.
- config<Hash>
-
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
# 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
Injects the given content into a file. Different from gsub_file
, this method is reversible.
Parameters
- destination<String>
-
Relative path to the destination root
- data<String>
-
Data
to add to the file. Can be given as a block. - config<Hash>
-
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
# 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
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.
Parameters
- dir<String>
-
the directory to move to.
- config<Hash>
-
give :verbose => true to log and use padding.
# 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
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<String>
-
the relative path to the source root.
- destination<String>
-
the relative path to the destination root.
- config<Hash>
-
give :verbose => false to not log the status.
Examples
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
Prepend text to a file. Since it depends on insert_into_file
, it's reversible.
Parameters
- path<String>
-
path of the file to be changed
- data<String>
-
the data to prepend to the file, can be also given as a block.
- config<Hash>
-
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
# 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
Returns the given path relative to the absolute root (ie, root where the script started).
# 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
Removes a file at the given location.
Parameters
- path<String>
-
path of the file to be changed
- config<Hash>
-
give :verbose => false to not log the status.
Example
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
Executes a command returning the contents of the command.
Parameters
- command<String>
-
the command to be executed.
- config<Hash>
-
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
# 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
Executes a ruby script (taking into account WIN32 platform quirks).
Parameters
- command<String>
-
the command to be executed.
- config<Hash>
-
give :verbose => false to not log the status.
# File lib/bundler/vendor/thor/lib/thor/actions.rb, line 126
def source_paths
@source_paths ||= self.class.source_paths_for_search
end
Holds source paths in instance so they can be manipulated.
# 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
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<String>
-
the relative path to the source root.
- destination<String>
-
the relative path to the destination root.
- config<Hash>
-
give :verbose => false to not log the status.
Examples
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
Run a thor command. A hash of options can be given and it's converted to switches.
Parameters
- command<String>
-
the command to be invoked
- args<Array>
-
arguments to the command
- config<Hash>
-
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
# 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
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<String>
-
path of the file to be changed
- flag<Regexp|String>
-
the regexp or string used to decide which lines to uncomment
- config<Hash>
-
give :verbose => false to not log the status.
Example
uncomment_lines 'config/initializers/session_store.rb', /active_record/
Private Instance Methods
# 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.