require 'rake' namespace :scm do desc "Adds missing files into SCM, interactively" task :add do scm_processor(:add) end desc "Reverts and Removes deleted files from SCM, interactively" task :remove do scm_processor(:remove) end desc "Looks for added files, then removed ones" task :all do scm_processor(:add, "No files to add") scm_processor(:remove, "No files to remove") end end SVN = ENV['SCM'] || 'svk' def propset(prop, value, *targets) sh %(#{SVN} propset #{prop} "#{value}" #{targets.join(' ')}) end def add(dir) sh %(#{SVN} add #{dir}) end def remove(file) sh %(#{SVN} revert #{file}) sh %(#{SVN} delete #{file}) end def stat `#{SVN} stat` end def project_name File.basename(File.expand_path(RAILS_ROOT)) end def scm_processor(mode, no_targets_msg="Nothing to do") raise "Requires mode :add or :remove" if mode.nil? or ![:add,:remove].include?(mode) re = (mode == :add) ? [ /^\?/, /^\?\s*/ ] : [ /^\!/, /^\!\s*/ ] files = stat.select{ |e| re[0] =~ e}.collect{|e| e.sub(re[1], '').chomp } puts if files.length == 0 puts no_targets_msg else files.map {|f| puts " #{f}"} print "\n#{mode.to_s.capitalize} all of these? (y/n/i) : " affected_files = 0 if STDIN.gets =~ /^(y|i)/i case $1.downcase when 'y' (mode == :add) ? add(files.join(' ')) : files.map { |f| remove(f) } affected_files = files.length when 'i' puts "\n[Interactive Mode]\n" files.each do |file| print "#{mode.to_s.capitalize} '#{file}'? (y/n) : " if /^y/i =~ STDIN.gets (mode == :add) ? add(file) : remove(file) affected_files += 1 else puts "Ignored" end end end end puts "\n#{affected_files} file(s) affected, #{files.length - affected_files} ignored" end puts end