Extends initializer to add more configuration options.
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. |
# File lib/thor/actions.rb, line 74 74: def initialize(args=[], options={}, config={}) 75: self.behavior = case config[:behavior].to_s 76: when "force", "skip" 77: _cleanup_options_and_set(options, config[:behavior]) 78: :invoke 79: when "revoke" 80: :revoke 81: else 82: :invoke 83: end 84: 85: super 86: self.destination_root = config[:destination_root] 87: end
Append text to a file. Since it depends on insert_into_file, it’s reversible.
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. |
append_to_file 'config/environments/test.rb', 'config.gem "rspec"' append_to_file 'config/environments/test.rb' do 'config.gem "rspec"' end
# File lib/thor/actions/file_manipulation.rb, line 172 172: def append_to_file(path, *args, &block) 173: config = args.last.is_a?(Hash) ? args.pop : {} 174: config.merge!(:before => /\z/) 175: insert_into_file(path, *(args << config), &block) 176: end
Loads an external file and execute it in the instance binding.
path | The path to the file to execute. Can be a web address or a relative path from the source root. |
apply "http://gist.github.com/103208" apply "recipes/jquery.rb"
# File lib/thor/actions.rb, line 203 203: def apply(path, config={}) 204: verbose = config.fetch(:verbose, true) 205: is_uri = path =~ /^https?\:\/\// 206: path = find_in_source_paths(path) unless is_uri 207: 208: say_status :apply, path, verbose 209: shell.padding += 1 if verbose 210: 211: if is_uri 212: contents = open(path, "Accept" => "application/x-thor-template") {|io| io.read } 213: else 214: contents = open(path) {|io| io.read } 215: end 216: 217: instance_eval(contents, path) 218: shell.padding -= 1 if verbose 219: end
Changes the mode of the given file or directory.
mode | the file mode |
path | the name of the file to change mode |
config | give :verbose => false to not log the status. |
chmod "script/*", 0755
# File lib/thor/actions/file_manipulation.rb, line 128 128: def chmod(path, mode, config={}) 129: return unless behavior == :invoke 130: path = File.expand_path(path, destination_root) 131: say_status :chmod, relative_to_original_destination_root(path), config.fetch(:verbose, true) 132: FileUtils.chmod_R(mode, path) unless options[:pretend] 133: end
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.
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. |
copy_file "README", "doc/README" copy_file "doc/README"
# File lib/thor/actions/file_manipulation.rb, line 21 21: def copy_file(source, *args, &block) 22: config = args.last.is_a?(Hash) ? args.pop : {} 23: destination = args.first || source 24: source = File.expand_path(find_in_source_paths(source.to_s)) 25: 26: create_file destination, nil, config do 27: content = File.binread(source) 28: content = block.call(content) if block 29: content 30: end 31: 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.
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. |
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/thor/actions/create_file.rb, line 23 23: def create_file(destination, *args, &block) 24: config = args.last.is_a?(Hash) ? args.pop : {} 25: data = args.first 26: action CreateFile.new(self, destination, block || data.to_s, config) 27: end
Create a new file relative to the destination root from the given source.
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.
create_link "config/apache.conf", "/etc/apache.conf"
# File lib/thor/actions/create_link.rb, line 18 18: def create_link(destination, *args, &block) 19: config = args.last.is_a?(Hash) ? args.pop : {} 20: source = args.first 21: action CreateLink.new(self, destination, source, config) 22: end
Returns the root for this thor class (also aliased as destination root).
# File lib/thor/actions.rb, line 101 101: def destination_root 102: @destination_stack.last 103: end
Sets the root for this thor class. Relatives path are added to the directory where the script was invoked and expanded.
# File lib/thor/actions.rb, line 108 108: def destination_root=(root) 109: @destination_stack ||= [] 110: @destination_stack[0] = File.expand_path(root || '') 111: 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. 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` method returns the value “blog”):
doc/ components/ README rdoc.rb blog.rb
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. |
directory "doc" directory "doc", "docs", :recursive => false
# File lib/thor/actions/directory.rb, line 43 43: def directory(source, *args, &block) 44: config = args.last.is_a?(Hash) ? args.pop : {} 45: destination = args.first || source 46: action Directory.new(self, source, destination || source, config, &block) 47: end
Creates an empty directory.
destination | the relative path to the destination root. |
config | give :verbose => false to not log the status. |
empty_directory "doc"
# File lib/thor/actions/empty_directory.rb, line 14 14: def empty_directory(destination, config={}) 15: action EmptyDirectory.new(self, destination, config) 16: end
Receives a file or directory and search for it in the source paths.
# File lib/thor/actions.rb, line 129 129: def find_in_source_paths(file) 130: relative_root = relative_to_original_destination_root(destination_root, false) 131: 132: source_paths.each do |source| 133: source_file = File.expand_path(file, File.join(source, relative_root)) 134: return source_file if File.exists?(source_file) 135: end 136: 137: message = "Could not find #{file.inspect} in any of your source paths. " 138: 139: unless self.class.source_root 140: message << "Please invoke #{self.class.name}.source_root(PATH) with the PATH containing your templates. " 141: end 142: 143: if source_paths.empty? 144: message << "Currently you have no source paths." 145: else 146: message << "Your current source paths are: \n#{source_paths.join("\n")}" 147: end 148: 149: raise Error, message 150: 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.
source | the address of the given content. |
destination | the relative path to the destination root. |
config | give :verbose => false to not log the status. |
get "http://gist.github.com/103208", "doc/README" get "http://gist.github.com/103208" do |content| content.split("\n").first end
# File lib/thor/actions/file_manipulation.rb, line 72 72: def get(source, *args, &block) 73: config = args.last.is_a?(Hash) ? args.pop : {} 74: destination = args.first 75: 76: source = File.expand_path(find_in_source_paths(source.to_s)) unless source =~ /^https?\:\/\// 77: render = open(source) {|input| input.binmode.read } 78: 79: destination ||= if block_given? 80: block.arity == 1 ? block.call(render) : block.call 81: else 82: File.basename(source) 83: end 84: 85: create_file destination, render, config 86: end
Run a regular expression replacement on a file.
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. |
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/thor/actions/file_manipulation.rb, line 218 218: def gsub_file(path, flag, *args, &block) 219: return unless behavior == :invoke 220: config = args.last.is_a?(Hash) ? args.pop : {} 221: 222: path = File.expand_path(path, destination_root) 223: say_status :gsub, relative_to_original_destination_root(path), config.fetch(:verbose, true) 224: 225: unless options[:pretend] 226: content = File.binread(path) 227: content.gsub!(flag, *args, &block) 228: File.open(path, 'wb') { |file| file.write(content) } 229: end 230: end
Goes to the root and execute the given block.
# File lib/thor/actions.rb, line 187 187: def in_root 188: inside(@destination_stack.first) { yield } 189: end
Injects text right after the class definition. Since it depends on insert_into_file, it’s reversible.
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. |
inject_into_class "app/controllers/application_controller.rb", " filter_parameter :password\n" inject_into_class "app/controllers/application_controller.rb", ApplicationController do " filter_parameter :password\n" end
# File lib/thor/actions/file_manipulation.rb, line 196 196: def inject_into_class(path, klass, *args, &block) 197: config = args.last.is_a?(Hash) ? args.pop : {} 198: config.merge!(:after => /class #{klass}\n|class #{klass} .*\n/) 199: insert_into_file(path, *(args << config), &block) 200: end
Injects the given content into a file. Different from gsub_file, this method is reversible.
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. |
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/thor/actions/inject_into_file.rb, line 25 25: def insert_into_file(destination, *args, &block) 26: if block_given? 27: data, config = block, args.shift 28: else 29: data, config = args.shift, args.shift 30: end 31: action InjectIntoFile.new(self, destination, data, config) 32: 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.
dir | the directory to move to. |
config | give :verbose => true to log and use padding. |
# File lib/thor/actions.rb, line 161 161: def inside(dir='', config={}, &block) 162: verbose = config.fetch(:verbose, false) 163: pretend = options[:pretend] 164: 165: say_status :inside, dir, verbose 166: shell.padding += 1 if verbose 167: @destination_stack.push File.expand_path(dir, destination_root) 168: 169: # If the directory doesnt exist and we're not pretending 170: if !File.exist?(destination_root) && !pretend 171: FileUtils.mkdir_p(destination_root) 172: end 173: 174: if pretend 175: # In pretend mode, just yield down to the block 176: block.arity == 1 ? yield(destination_root) : yield 177: else 178: FileUtils.cd(destination_root) { block.arity == 1 ? yield(destination_root) : yield } 179: end 180: 181: @destination_stack.pop 182: shell.padding -= 1 if verbose 183: 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.
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. |
link_file "README", "doc/README" link_file "doc/README"
# File lib/thor/actions/file_manipulation.rb, line 47 47: def link_file(source, *args, &block) 48: config = args.last.is_a?(Hash) ? args.pop : {} 49: destination = args.first || source 50: source = File.expand_path(find_in_source_paths(source.to_s)) 51: 52: create_link destination, source, config 53: end
Prepend text to a file. Since it depends on insert_into_file, it’s reversible.
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. |
prepend_to_file 'config/environments/test.rb', 'config.gem "rspec"' prepend_to_file 'config/environments/test.rb' do 'config.gem "rspec"' end
# File lib/thor/actions/file_manipulation.rb, line 150 150: def prepend_to_file(path, *args, &block) 151: config = args.last.is_a?(Hash) ? args.pop : {} 152: config.merge!(:after => /\A/) 153: insert_into_file(path, *(args << config), &block) 154: end
Returns the given path relative to the absolute root (ie, root where the script started).
# File lib/thor/actions.rb, line 116 116: def relative_to_original_destination_root(path, remove_dot=true) 117: path = path.gsub(@destination_stack[0], '.') 118: remove_dot ? (path[2..1] || '') : path 119: end
Removes a file at the given location.
path | path of the file to be changed |
config | give :verbose => false to not log the status. |
remove_file 'README' remove_file 'app/controllers/application_controller.rb'
# File lib/thor/actions/file_manipulation.rb, line 243 243: def remove_file(path, config={}) 244: return unless behavior == :invoke 245: path = File.expand_path(path, destination_root) 246: 247: say_status :remove, relative_to_original_destination_root(path), config.fetch(:verbose, true) 248: ::FileUtils.rm_rf(path) if !options[:pretend] && File.exists?(path) 249: end
Executes a command returning the contents of the command.
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 executation. |
inside('vendor') do run('ln -s ~/edge rails') end
# File lib/thor/actions.rb, line 234 234: def run(command, config={}) 235: return unless behavior == :invoke 236: 237: destination = relative_to_original_destination_root(destination_root, false) 238: desc = "#{command} from #{destination.inspect}" 239: 240: if config[:with] 241: desc = "#{File.basename(config[:with].to_s)} #{desc}" 242: command = "#{config[:with]} #{command}" 243: end 244: 245: say_status :run, desc, config.fetch(:verbose, true) 246: 247: unless options[:pretend] 248: config[:capture] ? `#{command}` : system("#{command}") 249: end 250: end
Executes a ruby script (taking into account WIN32 platform quirks).
command | the command to be executed. |
config | give :verbose => false to not log the status. |
# File lib/thor/actions.rb, line 258 258: def run_ruby_script(command, config={}) 259: return unless behavior == :invoke 260: run command, config.merge(:with => Thor::Util.ruby_command) 261: end
Holds source paths in instance so they can be manipulated.
# File lib/thor/actions.rb, line 123 123: def source_paths 124: @source_paths ||= self.class.source_paths_for_search 125: 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.
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. |
template "README", "doc/README" template "doc/README"
# File lib/thor/actions/file_manipulation.rb, line 103 103: def template(source, *args, &block) 104: config = args.last.is_a?(Hash) ? args.pop : {} 105: destination = args.first || source 106: 107: source = File.expand_path(find_in_source_paths(source.to_s)) 108: context = instance_eval('binding') 109: 110: create_file destination, nil, config do 111: content = ERB.new(::File.binread(source), nil, '-', '@output_buffer').result(context) 112: content = block.call(content) if block 113: content 114: end 115: end
Run a thor command. A hash of options can be given and it’s converted to switches.
task | the task to be invoked |
args | arguments to the task |
config | give :verbose => false to not log the status, :capture => true to hide to output. Other options are given as parameter to 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/thor/actions.rb, line 281 281: def thor(task, *args) 282: config = args.last.is_a?(Hash) ? args.pop : {} 283: verbose = config.key?(:verbose) ? config.delete(:verbose) : true 284: pretend = config.key?(:pretend) ? config.delete(:pretend) : false 285: capture = config.key?(:capture) ? config.delete(:capture) : false 286: 287: args.unshift task 288: args.push Thor::Options.to_switches(config) 289: command = args.join(' ').strip 290: 291: run command, :with => :thor, :verbose => verbose, :pretend => pretend, :capture => capture 292: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.