Skip to content

Commit

Permalink
More actions.
Browse files Browse the repository at this point in the history
  • Loading branch information
josevalim committed Jun 14, 2009
1 parent 0e8108f commit a87e6ac
Show file tree
Hide file tree
Showing 20 changed files with 373 additions and 232 deletions.
108 changes: 14 additions & 94 deletions lib/thor/actions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ def initialize(args=[], options={}, config={})
end

self.root = config[:root]

if config[:in_root]
FileUtils.mkdir_p(root) unless File.exist?(root)
FileUtils.cd(root)
Expand All @@ -58,6 +57,13 @@ def action(instance)
end
end

# Returns the root for this thor class (also aliased as destination root).
#
def root
@root_stack.last
end
alias :destination_root :root

# Sets the root for this thor class. Relatives path are added to the
# directory where the script was invoked and expanded.
#
Expand All @@ -66,12 +72,13 @@ def root=(root)
@root_stack[0] = File.expand_path(root || '')
end

# Returns the root for this thor class (also aliased as destination root).
# Returns the given path relative to the absolute root (ie, root where
# the script started).
#
def root
@root_stack.last
def relative_to_absolute_root(path, remove_dot=true)
path = path.gsub(@root_stack[0], '.')
remove_dot ? path[2..-1] : path
end
alias :destination_root :root

# Get the source root in the class. Raises an error if a source root is
# not specified in the thor class.
Expand All @@ -92,104 +99,17 @@ def source_root
# log_status<Boolean>:: if false, does not log the status. True by default.
# If a symbol is given, uses it as the output color.
#
def inside(dir='', log_status=true, &block)
def inside(dir='', &block)
@root_stack.push File.expand_path(dir, root)

say_status_if_log :inside, root, log_status

FileUtils.mkdir_p(root) unless File.exist?(root)
FileUtils.cd(root) { block.arity == 1 ? yield(root) : yield }

@root_stack.pop
end

# Goes to the root and execute the given block.
#
def in_root
inside(@root_stack.first, false) { yield }
end

# Executes a command.
#
# ==== Parameters
# command<String>:: the command to be executed.
# log_status<Boolean>:: if false, does not log the status. True by default.
# If a symbol is given, uses it as the output color.
#
# ==== Example
#
# inside('vendor') do
# run('ln -s ~/edge rails')
# end
#
def run(command, log_status=true)
say_status_if_log :run, "#{command} from #{Dir.pwd}", log_status
`#{command}` unless options[:pretend]
end

# Executes a ruby script (taking into account WIN32 platform quirks).
#
# ==== Parameters
# command<String>:: the command to be executed.
# log_status<Boolean>:: if false, does not log the status. True by default.
# If a symbol is given, uses it as the output color.
#
def run_ruby_script(command, log_status=true)
run("ruby #{command}", log_status)
end

# Run a command in git.
#
# ==== Parameters
# command<String>:: the command to be executed.
# log_status<Boolean>:: if false, does not log the status. True by default.
# If a symbol is given, uses it as the output color.
#
# ==== Examples
#
# git :init
# git :add => "this.file that.rb"
# git :add => "onefile.rb", :rm => "badfile.cxx"
#
def git(command, log_status=true)
in_root do
if command.is_a?(Symbol)
run "git #{command}", log_status
else
command.each do |command, options|
run "git #{command} #{options}", log_status
end
end
end
end

# Run a thor command. A hash of options can be given and it's converted to
# switches.
#
# ==== Parameters
# task<String>:: the task to be invoked
# args<Array>:: arguments to the task
# options<Hash>:: a hash with options used on invocation
# log_status<Boolean>:: if false, does not log the status. True by default.
# If a symbol is given, uses it as the output color.
#
# ==== 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
#
def thor(task, *args)
log_status = [true, false].include?(args.last) ? args.pop : true
options = args.last.is_a?(Hash) ? args.pop : {}

in_root do
args.unshift "thor #{task}"
args.push Thor::Options.to_switches(options)
run args.join(' ').strip, log_status
end
inside(@root_stack.first) { yield }
end

protected
Expand Down
86 changes: 86 additions & 0 deletions lib/thor/actions/commands.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
class Thor
module Actions
# Executes a command.
#
# ==== Parameters
# command<String>:: the command to be executed.
# log_status<Boolean>:: if false, does not log the status. True by default.
# If a symbol is given, uses it as the output color.
#
# ==== Example
#
# inside('vendor') do
# run('ln -s ~/edge rails')
# end
#
def run(command, log_status=true)
say_status_if_log :run, "#{command} from #{relative_to_absolute_root(root, false)}", log_status
`#{command}` unless options[:pretend]
end

# Executes a ruby script (taking into account WIN32 platform quirks).
#
# ==== Parameters
# command<String>:: the command to be executed.
# log_status<Boolean>:: if false, does not log the status. True by default.
# If a symbol is given, uses it as the output color.
#
def run_ruby_script(command, log_status=true)
run("ruby #{command}", log_status)
end

# Run a command in git.
#
# ==== Parameters
# command<String>:: the command to be executed.
# log_status<Boolean>:: if false, does not log the status. True by default.
# If a symbol is given, uses it as the output color.
#
# ==== Examples
#
# git :init
# git :add => "this.file that.rb"
# git :add => "onefile.rb", :rm => "badfile.cxx"
#
def git(command, log_status=true)
in_root do
if command.is_a?(Symbol)
run "git #{command}", log_status
else
command.each do |command, options|
run "git #{command} #{options}", log_status
end
end
end
end

# Run a thor command. A hash of options can be given and it's converted to
# switches.
#
# ==== Parameters
# task<String>:: the task to be invoked
# args<Array>:: arguments to the task
# options<Hash>:: a hash with options used on invocation
# log_status<Boolean>:: if false, does not log the status. True by default.
# If a symbol is given, uses it as the output color.
#
# ==== 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
#
def thor(task, *args)
log_status = [true, false].include?(args.last) ? args.pop : true
options = args.last.is_a?(Hash) ? args.pop : {}

in_root do
args.unshift "thor #{task}"
args.push Thor::Options.to_switches(options)
run args.join(' ').strip, log_status
end
end
end
end
6 changes: 4 additions & 2 deletions lib/thor/actions/copy_file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ module Actions
# log_status<Boolean>:: if false, does not log the status. True by default.
#
# ==== Examples
# copy_file "README", "doc/README"
# copy_file "doc/README"
#
# copy_file "README", "doc/README"
#
# copy_file "doc/README"
#
def copy_file(source, destination=nil, log_status=true)
action CopyFile.new(self, source, destination || source, log_status)
Expand Down
3 changes: 2 additions & 1 deletion lib/thor/actions/directory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ module Actions
# log_status<Boolean>:: if false, does not log the status. True by default.
#
# ==== Examples
# directory "doc"
#
# directory "doc"
#
def directory(source, destination=nil, log_status=true)
action Directory.new(self, source, destination || source, log_status)
Expand Down
3 changes: 2 additions & 1 deletion lib/thor/actions/empty_directory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ module Actions
# log_status<Boolean>:: if false, does not log the status. True by default.
#
# ==== Examples
# empty_directory "doc"
#
# empty_directory "doc"
#
def empty_directory(destination, log_status=true)
action EmptyDirectory.new(self, nil, destination, log_status)
Expand Down
73 changes: 73 additions & 0 deletions lib/thor/actions/gsub_file.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
class Thor
module Actions

# 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
# log_status<Boolean>:: if false, does not log the status. True by default.
# If a symbol is given, uses it as the output color.
#
# ==== 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
#
def gsub_file(path, flag, *args, &block)
log_status = args.last.is_a?(Symbol) || [ true, false ].include?(args.last) ? args.pop : true

path = File.expand_path(path, root)
say_status_if_log :gsub, relative_to_absolute_root(path), log_status

unless options[:pretend]
content = File.read(path)
content.gsub!(flag, *args, &block)
File.open(path, 'wb') { |file| file.write(content) }
end
end

# Append text to a file.
#
# ==== Parameters
# path<String>:: path of the file to be changed
# data<String>:: the data to append to the file
# log_status<Boolean>:: if false, does not log the status. True by default.
# If a symbol is given, uses it as the output color.
#
# ==== Example
#
# append_file 'config/environments/test.rb', 'config.gem "rspec"'
#
def append_file(path, data, log_status=true)
path = File.expand_path(path, root)
say_status_if_log :append, relative_to_absolute_root(path), log_status

File.open(path, 'ab') { |file| file.write(data) } unless options[:pretend]
end

# Prepend text to a file.
#
# ==== Parameters
# path<String>:: path of the file to be changed
# data<String>:: the data to prepend to the file
# log_status<Boolean>:: if false, does not log the status. True by default.
# If a symbol is given, uses it as the output color.
#
# ==== Example
#
# prepend_file 'config/environments/test.rb', 'config.gem "rspec"'
#
def prepend_file(path, data, log_status=true)
path = File.expand_path(path, root)
say_status_if_log :prepend, relative_to_absolute_root(path), log_status

File.open(path, 'r+b') { |file| file.write(data) } unless options[:pretend]
end

end
end
6 changes: 3 additions & 3 deletions lib/thor/actions/inject_into_file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ module Actions
#
def inject_into_file(destination, *args, &block)
if block_given?
data, flag = block, args.pop
data, flag = block, args.shift
else
data, flag = args.pop, args.pop
data, flag = args.shift, args.shift
end

log_status = args.empty? || args.pop
Expand Down Expand Up @@ -67,8 +67,8 @@ def revoke!
#
def destination=(destination)
if destination
@relative_destination = destination.to_s
@destination = ::File.expand_path(destination.to_s, base.destination_root)
@relative_destination = base.relative_to_absolute_root(@destination)
end
end

Expand Down
6 changes: 4 additions & 2 deletions lib/thor/actions/template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ module Actions
# log_status<Boolean>:: if false, does not log the status. True by default.
#
# ==== Examples
# template "README", "doc/README"
# template "doc/README"
#
# template "README", "doc/README"
#
# template "doc/README"
#
def template(source, destination=nil, log_status=true)
action Template.new(self, source, destination || source, log_status)
Expand Down
2 changes: 1 addition & 1 deletion lib/thor/actions/templater.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ def source=(source)
#
def destination=(destination)
if destination
@relative_destination = destination.to_s
@destination = ::File.expand_path(destination.to_s, base.destination_root)
@relative_destination = base.relative_to_absolute_root(@destination)
end
end

Expand Down
1 change: 1 addition & 0 deletions spec/actions/add_file_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ def add_file(destination, data=nil, options={}, &block)
@base = begin
base = Object.new
stub(base).destination_root{ destination_root }
stub(base).relative_to_absolute_root{ |p| p.gsub(destination_root, '.')[2..-1] }
stub(base).options{ options }
stub(base).shell{ @shell = Thor::Shell::Basic.new }
base
Expand Down
Loading

0 comments on commit a87e6ac

Please sign in to comment.