Module: Thor::Actions
- Defined in:
- lib/thor/actions.rb,
lib/thor/actions/directory.rb,
lib/thor/actions/create_file.rb,
lib/thor/actions/empty_directory.rb,
lib/thor/actions/inject_into_file.rb,
lib/thor/actions/file_manipulation.rb
Defined Under Namespace
Modules: ClassMethods Classes: CreateFile, Directory, EmptyDirectory, InjectIntoFile
Instance Attribute Summary collapse
-
#behavior ⇒ Object
Returns the value of attribute behavior.
Class Method Summary collapse
-
.included(base) ⇒ Object
On inclusion, add some options to base.
Instance Method Summary collapse
-
#action(instance) ⇒ Object
Wraps an action object and call it accordingly to the thor class behavior.
-
#append_file(path, data = nil, config = {}, &block) ⇒ Object
Append text to a file.
-
#apply(path, config = {}) ⇒ Object
Loads an external file and execute it in the instance binding.
-
#chmod(path, mode, config = {}) ⇒ Object
Changes the mode of the given file or directory.
-
#copy_file(source, destination = nil, config = {}) ⇒ Object
Copies the file from the relative source to the relative destination.
-
#create_file(destination, data = nil, config = {}, &block) ⇒ Object
(also: #add_file)
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.
-
#destination_root ⇒ Object
Returns the root for this thor class (also aliased as destination root).
-
#destination_root=(root) ⇒ Object
Sets the root for this thor class.
-
#directory(source, destination = nil, config = {}) ⇒ Object
Copies recursively the files from source directory to root directory.
-
#empty_directory(destination, config = {}) ⇒ Object
Creates an empty directory.
-
#find_in_source_paths(file) ⇒ Object
Receives a file or directory and search for it in the source paths.
-
#get(source, destination = nil, config = {}, &block) ⇒ Object
Gets the content at the given address and places it at the given relative destination.
-
#gsub_file(path, flag, *args, &block) ⇒ Object
Run a regular expression replacement on a file.
-
#in_root ⇒ Object
Goes to the root and execute the given block.
-
#initialize(args = [], options = {}, config = {}) ⇒ Object
Extends initializer to add more configuration options.
-
#inject_into_file(destination, *args, &block) ⇒ Object
Injects the given content into a file.
-
#inside(dir = '', config = {}, &block) ⇒ Object
Do something in the root or on a provided subfolder.
-
#prepend_file(path, data = nil, config = {}, &block) ⇒ Object
Prepend text to a file.
-
#relative_to_original_destination_root(path, remove_dot = true) ⇒ Object
Returns the given path relative to the absolute root (ie, root where the script started).
-
#remove_file(path, config = {}) ⇒ Object
(also: #remove_dir)
Removes a file at the given location.
-
#run(command, config = {}) ⇒ Object
Executes a command.
-
#run_ruby_script(command, config = {}) ⇒ Object
Executes a ruby script (taking into account WIN32 platform quirks).
-
#source_paths ⇒ Object
Holds source paths in instance so they can be manipulated.
-
#template(source, destination = nil, config = {}) ⇒ Object
Gets an ERB template at the relative source, executes it and makes a copy at the relative destination.
-
#thor(task, *args) ⇒ Object
Run a thor command.
Instance Attribute Details
#behavior ⇒ Object
Returns the value of attribute behavior.
9 10 11 |
# File 'lib/thor/actions.rb', line 9 def behavior @behavior end |
Class Method Details
.included(base) ⇒ Object
On inclusion, add some options to base.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/thor/actions.rb', line 13 def self.included(base) #:nodoc: base.extend ClassMethods return unless base.respond_to?(:class_option) base.class_option :pretend, :type => :boolean, :aliases => "-p", :group => :runtime, :desc => "Run but do not make any changes" base.class_option :force, :type => :boolean, :aliases => "-f", :group => :runtime, :desc => "Overwrite files that already exist" base.class_option :skip, :type => :boolean, :aliases => "-s", :group => :runtime, :desc => "Skip files that already exist" base.class_option :quiet, :type => :boolean, :aliases => "-q", :group => :runtime, :desc => "Supress status output" end |
Instance Method Details
#action(instance) ⇒ Object
Wraps an action object and call it accordingly to the thor class behavior.
80 81 82 83 84 85 86 |
# File 'lib/thor/actions.rb', line 80 def action(instance) #:nodoc: if behavior == :revoke instance.revoke! else instance.invoke! end end |
#append_file(path, data = nil, config = {}, &block) ⇒ Object
Append text to a file.
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_file 'config/environments/test.rb', 'config.gem "rspec"'
137 138 139 140 141 142 |
# File 'lib/thor/actions/file_manipulation.rb', line 137 def append_file(path, data=nil, config={}, &block) return unless behavior == :invoke path = File.(path, destination_root) say_status :append, relative_to_original_destination_root(path), config.fetch(:verbose, true) File.open(path, 'ab') { |file| file.write(data || block.call) } unless [:pretend] end |
#apply(path, config = {}) ⇒ Object
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"
175 176 177 178 179 180 181 182 183 |
# File 'lib/thor/actions.rb', line 175 def apply(path, config={}) verbose = config.fetch(:verbose, true) path = find_in_source_paths(path) unless path =~ /^http\:\/\// say_status :apply, path, verbose shell.padding += 1 if verbose instance_eval(open(path).read) shell.padding -= 1 if verbose end |
#chmod(path, mode, config = {}) ⇒ Object
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/*", 0755
96 97 98 99 100 101 |
# File 'lib/thor/actions/file_manipulation.rb', line 96 def chmod(path, mode, config={}) return unless behavior == :invoke path = File.(path, destination_root) say_status :chmod, relative_to_original_destination_root(path), config.fetch(:verbose, true) FileUtils.chmod_R(mode, path) unless [:pretend] end |
#copy_file(source, destination = nil, config = {}) ⇒ Object
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.
Examples
copy_file "README", "doc/README"
copy_file "doc/README"
21 22 23 24 25 26 27 28 |
# File 'lib/thor/actions/file_manipulation.rb', line 21 def copy_file(source, destination=nil, config={}) destination ||= source source = File.(find_in_source_paths(source.to_s)) create_file destination, nil, config do File.read(source) end end |
#create_file(destination, data = nil, config = {}, &block) ⇒ Object Also known as: add_file
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<String|NilClass>
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/apach.conf", "your apache config"
23 24 25 |
# File 'lib/thor/actions/create_file.rb', line 23 def create_file(destination, data=nil, config={}, &block) action CreateFile.new(self, destination, block || data.to_s, config) end |
#destination_root ⇒ Object
Returns the root for this thor class (also aliased as destination root).
90 91 92 |
# File 'lib/thor/actions.rb', line 90 def destination_root @destination_stack.last end |
#destination_root=(root) ⇒ Object
Sets the root for this thor class. Relatives path are added to the directory where the script was invoked and expanded.
97 98 99 100 |
# File 'lib/thor/actions.rb', line 97 def destination_root=(root) @destination_stack ||= [] @destination_stack[0] = File.(root || '') end |
#directory(source, destination = nil, config = {}) ⇒ Object
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. Remember that file paths can also be encoded, 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 is "blog"):
doc/
components/
README
rdoc.rb
blog.rb
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.
Examples
directory "doc"
directory "doc", "docs", :recursive => false
43 44 45 |
# File 'lib/thor/actions/directory.rb', line 43 def directory(source, destination=nil, config={}) action Directory.new(self, source, destination || source, config) end |
#empty_directory(destination, config = {}) ⇒ Object
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"
14 15 16 |
# File 'lib/thor/actions/empty_directory.rb', line 14 def empty_directory(destination, config={}) action EmptyDirectory.new(self, destination, config) end |
#find_in_source_paths(file) ⇒ Object
Receives a file or directory and search for it in the source paths.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/thor/actions.rb', line 118 def find_in_source_paths(file) relative_root = relative_to_original_destination_root(destination_root, false) source_paths.each do |source| source_file = File.(file, File.join(source, relative_root)) return source_file if File.exists?(source_file) end if source_paths.empty? raise Error, "You don't have any source path defined for class #{self.class.name}. To fix this, " << "you can define a source_root in your class." else raise Error, "Could not find #{file.inspect} in source paths." end end |
#get(source, destination = nil, config = {}, &block) ⇒ Object
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
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
47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/thor/actions/file_manipulation.rb', line 47 def get(source, destination=nil, config={}, &block) source = File.(find_in_source_paths(source.to_s)) unless source =~ /^http\:\/\// render = open(source).read destination ||= if block_given? block.arity == 1 ? block.call(render) : block.call else File.basename(source) end create_file destination, render, config end |
#gsub_file(path, flag, *args, &block) ⇒ Object
Run a regular expression replacement on a file.
Parameters
- path
path of the file to be changed
- flag<Regexp|String>
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.
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
160 161 162 163 164 165 166 167 168 169 170 171 172 |
# File 'lib/thor/actions/file_manipulation.rb', line 160 def gsub_file(path, flag, *args, &block) return unless behavior == :invoke config = args.last.is_a?(Hash) ? args.pop : {} path = File.(path, destination_root) say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true) unless [:pretend] content = File.read(path) content.gsub!(flag, *args, &block) File.open(path, 'wb') { |file| file.write(content) } end end |
#in_root ⇒ Object
Goes to the root and execute the given block.
159 160 161 |
# File 'lib/thor/actions.rb', line 159 def in_root inside(@destination_stack.first) { yield } end |
#initialize(args = [], options = {}, config = {}) ⇒ Object
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.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/thor/actions.rb', line 63 def initialize(args=[], ={}, config={}) self.behavior = case config[:behavior].to_s when "force", "skip" (, config[:behavior]) :invoke when "revoke" :revoke else :invoke end super self.destination_root = config[:destination_root] end |
#inject_into_file(destination, *args, &block) ⇒ Object
Injects the given content into a file. Different from append_file, prepend_file and gsub_file, this method is reversible. By this reason, the flag can only be strings. gsub_file is your friend if you need to deal with more complex cases.
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).
Examples
inject_into_file "config/environment.rb", "config.gem thor", :after => "Rails::Initializer.run do |config|\n"
inject_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
26 27 28 29 30 31 32 33 34 35 |
# File 'lib/thor/actions/inject_into_file.rb', line 26 def inject_into_file(destination, *args, &block) if block_given? data, config = block, args.shift else data, config = args.shift, args.shift end log_status = args.empty? || args.pop action InjectIntoFile.new(self, destination, data, config) end |
#inside(dir = '', config = {}, &block) ⇒ Object
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
the directory to move to.
- config
give :verbose => true to log and use padding.
143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/thor/actions.rb', line 143 def inside(dir='', config={}, &block) verbose = config.fetch(:verbose, false) say_status :inside, dir, verbose shell.padding += 1 if verbose @destination_stack.push File.(dir, destination_root) FileUtils.mkdir_p(destination_root) unless File.exist?(destination_root) FileUtils.cd(destination_root) { block.arity == 1 ? yield(destination_root) : yield } @destination_stack.pop shell.padding -= 1 if verbose end |
#prepend_file(path, data = nil, config = {}, &block) ⇒ Object
Prepend text to a file.
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_file 'config/environments/test.rb', 'config.gem "rspec"'
114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/thor/actions/file_manipulation.rb', line 114 def prepend_file(path, data=nil, config={}, &block) return unless behavior == :invoke path = File.(path, destination_root) say_status :prepend, relative_to_original_destination_root(path), config.fetch(:verbose, true) unless [:pretend] content = data || block.call content << File.read(path) File.open(path, 'wb') { |file| file.write(content) } end end |
#relative_to_original_destination_root(path, remove_dot = true) ⇒ Object
Returns the given path relative to the absolute root (ie, root where the script started).
105 106 107 108 |
# File 'lib/thor/actions.rb', line 105 def relative_to_original_destination_root(path, remove_dot=true) path = path.gsub(@destination_stack[0], '.') remove_dot ? (path[2..-1] || '') : path end |
#remove_file(path, config = {}) ⇒ Object Also known as: remove_dir
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'
185 186 187 188 189 190 191 |
# File 'lib/thor/actions/file_manipulation.rb', line 185 def remove_file(path, config={}) return unless behavior == :invoke path = File.(path, destination_root) say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true) ::FileUtils.rm_rf(path) if ![:pretend] && File.exists?(path) end |
#run(command, config = {}) ⇒ Object
Executes a command.
Parameters
- command
the command to be executed.
- config
give :verbose => false to not log the status. Specify :with to append an executable to command executation.
Example
inside('vendor') do
run('ln -s ~/edge rails')
end
198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/thor/actions.rb', line 198 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) system(command) unless [:pretend] end |
#run_ruby_script(command, config = {}) ⇒ Object
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.
219 220 221 222 |
# File 'lib/thor/actions.rb', line 219 def run_ruby_script(command, config={}) return unless behavior == :invoke run "#{command}", config.merge(:with => Thor::Util.ruby_command) end |
#source_paths ⇒ Object
Holds source paths in instance so they can be manipulated.
112 113 114 |
# File 'lib/thor/actions.rb', line 112 def source_paths @source_paths ||= self.class.source_paths_for_search end |
#template(source, destination = nil, config = {}) ⇒ Object
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"
75 76 77 78 79 80 81 82 83 |
# File 'lib/thor/actions/file_manipulation.rb', line 75 def template(source, destination=nil, config={}) destination ||= source source = File.(find_in_source_paths(source.to_s)) context = instance_eval('binding') create_file destination, nil, config do ERB.new(::File.read(source), nil, '-').result(context) end end |
#thor(task, *args) ⇒ Object
Run a thor command. A hash of options can be given and it's converted to switches.
Parameters
- task
the task to be invoked
- args
arguments to the task
- config
give :verbose => false to not log the status. Other options are given as parameter to 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
241 242 243 244 245 246 247 248 249 250 |
# File 'lib/thor/actions.rb', line 241 def thor(task, *args) config = args.last.is_a?(Hash) ? args.pop : {} verbose = config.key?(:verbose) ? config.delete(:verbose) : true args.unshift task args.push Thor::Options.to_switches(config) command = args.join(' ').strip run command, :with => :thor, :verbose => verbose end |