class Prune::Pruner

The co-ordinating class of Prune, Pruner works with the retention policy, archiver, grouper to get everything done. This is the central hub through which almost all other activity passes.

Constants

FILTERS

Attributes

categories[R]
options[R]

Public Class Methods

new( options ) click to toggle source
# File lib/prune/pruner.rb, line 15
def initialize( options )
  @options = options
  @categories = Hash.new { |h,k| h[k] = [] } # initialize new keys with an empty array
  @analyzed_count = 0
end

Public Instance Methods

actions_require_prompt( policy ) click to toggle source
# File lib/prune/pruner.rb, line 59
def actions_require_prompt( policy )
  @categories.keys.any? { |category| category.requires_prompt? }
end
analyze( folder_name, policy ) click to toggle source
# File lib/prune/pruner.rb, line 31
def analyze( folder_name, policy )
  print "Analyzing '#{folder_name}':\n"
  files = Dir.entries( folder_name ).sort_by { |f| test(?M, File.join( folder_name, f ) ) }
  files.each do |file|
    analyze_file( policy, file ) unless filter?(file)
  end
  print "\n" if @options[:verbose]

  display_categories( @categories )
  print "\t#{@analyzed_count} file(s) analyzed\n"
end
analyze_file( policy, file ) click to toggle source
# File lib/prune/pruner.rb, line 148
def analyze_file( policy, file )
  category = policy.categorize( file )
  @categories[ category ] << file unless category.nil?
  @analyzed_count += 1
end
display_categories( categories ) click to toggle source
# File lib/prune/pruner.rb, line 131
def display_categories( categories )
  categories.each_pair do |category,files|
    if should_display?( category, files ) then 
      print "\t#{category.description}:\n\t\t"
      if files.empty? then
        puts "none"
      else
        puts files.join( "\n\t\t" )
      end
    end
  end
end
execute_prune( folder_name, policy ) click to toggle source
# File lib/prune/pruner.rb, line 43
def execute_prune( folder_name, policy )
  begin
    if should_prompt?( policy ) && !prompt then
      puts "Not proceeding; no actions taken."
    else
      take_all_actions( folder_name, policy )
    end
  rescue IOError
    $stderr.print "ERROR: #{$!}\n"
  end
end
filter?( file ) click to toggle source
# File lib/prune/pruner.rb, line 154
def filter?( file )
  return file =~ /\.prune/
end
prompt() click to toggle source
# File lib/prune/pruner.rb, line 63
def prompt
  print "Proceed? [y/N]: "
  response = STDIN.gets.chomp.strip.downcase
  ['y','yes','true'].include? response
end
prune( folder_name ) click to toggle source
# File lib/prune/pruner.rb, line 21
def prune( folder_name )
  return print( "ERROR: Cannot find folder: #{folder_name}\n" ) unless File.exists? folder_name
  return puts( "ERROR: #{folder_name} is not a folder" ) unless File.directory? folder_name
  policy = RetentionPolicy.new folder_name
  return puts( "ERROR: Retention policy contains no categories." ) if policy.categories.empty?
  policy.categories.each { |cat| @categories[cat] = Array.new } # retain category order
  analyze folder_name, policy
  execute_prune( folder_name, policy ) unless @options[:dry_run]
end
should_display?( category, files ) click to toggle source
# File lib/prune/pruner.rb, line 144
def should_display?( category, files )
  @options[:verbose] || !( category.quiet? || files.empty? )
end
should_prompt?( policy ) click to toggle source
# File lib/prune/pruner.rb, line 55
def should_prompt?( policy )
  @options[:prompt] && actions_require_prompt( policy )
end
take_action( action, folder_name, files ) click to toggle source
# File lib/prune/pruner.rb, line 82
def take_action( action, folder_name, files )
  case action
  when :remove
    take_remove_action folder_name, files
  when :archive
    take_archive_action folder_name, files
  end
end
take_all_actions( folder_name, policy ) click to toggle source
# File lib/prune/pruner.rb, line 69
def take_all_actions( folder_name, policy )
  actions = 0
  @categories.each_pair do |category,files|
    action = category.action
    result = take_action( action, folder_name, files )
    if !result.nil? then
      puts result
      actions += files.size
    end
  end
  print "No actions necessary.\n" if actions == 0
end
take_archive_action( folder_name, files ) click to toggle source
# File lib/prune/pruner.rb, line 116
def take_archive_action( folder_name, files )
  if @options[:archive] then
    if files.empty? then
      "No files categorized for archival, so no archives created."
    else
      archiver = Archiver.new( @options[:archive_path], folder_name, @options[:verbose] )
      grouper = Grouper.new( archiver )
      grouper.group( folder_name, files );
      grouper.archive
    end
  else
    "Archive option disabled. Archive(s) not created."
  end
end
take_remove_action( folder_name, files ) click to toggle source
# File lib/prune/pruner.rb, line 91
def take_remove_action( folder_name, files )
  if files.empty? then
    "No files categorized to be removed."
  else
    paths = files.map { |file| File.join folder_name, file }

    begin
      failed_paths = []
      paths.each do |path|
        if FileUtils.remove_entry( path, true ) == 0
          failed_paths << path
        end
      end

      if failed_paths.empty?
        "#{files.size} file(s) deleted"
      else
        "#{files.size-failed_paths.size} file(s) deleted, #{failed_paths.size} file(s) could not be deleted."
      end
    rescue
      raise IOError, "Could not remove file(s): #{$!}"
    end
  end
end