lib/bundler/vendor/thor/actions/empty_directory.rb
class Thor module Actions # 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" # 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<Thor::Base>:: A Thor::Base instance # source<String>:: Relative path to the source of this file # destination<String>:: Relative path to the destination of this file # config<Hash>:: give :verbose => false to not log the status. # def initialize(base, destination, config={}) @base, @config = base, { :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.exists?(destination) end def invoke! invoke_with_conflict_check do ::FileUtils.mkdir_p(destination) end end def revoke! say_status :remove, :red ::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) if 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 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 by %-string SHOULD be public. Otherwise you # get the exception with the corresponding error message. # def convert_encoded_instructions(filename) filename.gsub(/%(.*?)%/) do |initial_string| call_public_method($1.strip) or initial_string end end # Calls `base`'s public method `sym`. # Returns:: result of `base.sym` or `nil` if `sym` wasn't found in # `base` # Raises:: Thor::PrivateMethodEncodedError if `sym` references # a private method. def call_public_method(sym) if base.respond_to?(sym) base.send(sym) elsif base.respond_to?(sym, true) raise Thor::PrivateMethodEncodedError, "Method #{base.class}##{sym} should be public, not private" else nil 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 say_status :create, :green block.call unless pretend? end destination end # What to do when the destination file already exists. # def on_conflict_behavior(&block) 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