module R10K::Util::Purgeable

Mixin for purging stale directory contents.

@abstract Classes using this mixin need to implement {#managed_directory} and

{#desired_contents}

Public Instance Methods

current_contents(recurse) click to toggle source

@return [Array<String>] The present directory entries in `self.managed_directories`

# File lib/r10k/util/purgeable.rb, line 27
def current_contents(recurse)
  dirs = self.managed_directories

  dirs.flat_map do |dir|
    if recurse
      glob_exp = File.join(dir, '**', '{*,.[^.]*}')
    else
      glob_exp = File.join(dir, '*')
    end

    Dir.glob(glob_exp)
  end
end
pending_contents(recurse) click to toggle source

@return [Array<String>] Directory contents that are expected but not present

# File lib/r10k/util/purgeable.rb, line 42
def pending_contents(recurse)
  desired_contents - current_contents(recurse)
end
purge!(opts={}) click to toggle source

Forcibly remove all unmanaged content in `self.managed_directories`

# File lib/r10k/util/purgeable.rb, line 60
def purge!(opts={})
  recurse = opts[:recurse] || false
  whitelist = opts[:whitelist] || []

  exclusions = self.respond_to?(:purge_exclusions) ? purge_exclusions : []

  stale = stale_contents(recurse, exclusions, whitelist)

  if stale.empty?
    logger.debug1 _("No unmanaged contents in %{managed_dirs}, nothing to purge") % {managed_dirs: managed_directories.join(', ')}
  else
    stale.each do |fpath|
      begin
        FileUtils.rm_r(fpath, :secure => true)
        logger.info _("Removing unmanaged path %{path}") % {path: fpath}
      rescue Errno::ENOENT
        # Don't log on ENOENT since we may encounter that from recursively deleting
        # this item's parent earlier in the purge.
      rescue
        logger.debug1 _("Unable to remove unmanaged path: %{path}") % {path: fpath}
      end
    end
  end
end
stale_contents(recurse, exclusions, whitelist) click to toggle source

@return [Array<String>] Directory contents that are present but not expected

# File lib/r10k/util/purgeable.rb, line 47
def stale_contents(recurse, exclusions, whitelist)
  (current_contents(recurse) - desired_contents).reject do |item|
    if exclusion_match = exclusions.find { |ex_item| File.fnmatch?(ex_item, item, File::FNM_PATHNAME | File::FNM_DOTMATCH) }
      logger.debug2 _("Not purging %{item} due to internal exclusion match: %{exclusion_match}") % {item: item, exclusion_match: exclusion_match}
    elsif whitelist_match = whitelist.find { |wl_item| File.fnmatch?(wl_item, item, File::FNM_PATHNAME | File::FNM_DOTMATCH) }
      logger.debug _("Not purging %{item} due to whitelist match: %{whitelist_match}") % {item: item, whitelist_match: whitelist_match}
    end

    !!exclusion_match || !!whitelist_match
  end
end