Commit 44e73fc8 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Clean up unused files from .cache directory.

We remember each cache entry that was read or written during the
current jsduck run.  All others get deleted.  This ensures the .cache
directory doesn't grow over time.

Refs #446
parent 9a0f2263
Loading
Loading
Loading
Loading
+12 −2
Original line number Diff line number Diff line
@@ -14,21 +14,31 @@ module JsDuck
    def self.parse(opts)
      cache = Cache.create(opts)

      Util::Parallel.map(opts.input_files) do |fname|
      results = Util::Parallel.map(opts.input_files) do |fname|
        Logger.log("Parsing", fname)

        begin
          source = Util::IO.read(fname)
          docs = nil

          unless docs = cache.read(source)
            docs = Parser.new.parse(source, fname, opts)
            cache.write(source, docs)
          end
          Source::File.new(source, docs, fname)

          {
            :file => Source::File.new(source, docs, fname),
            :cache => cache.previous_entry,
          }
        rescue
          Logger.fatal_backtrace("Error while parsing #{fname}", $!)
          exit(1)
        end
      end

      cache.cleanup( results.map {|r| r[:cache] }.compact )

      return results.map {|r| r[:file] }
    end

  end
+27 −1
Original line number Diff line number Diff line
require 'digest/md5'
require 'fileutils'
require 'jsduck/util/null_object'
require 'set'

module JsDuck

@@ -15,12 +16,23 @@ module JsDuck
      if opts.cache && opts.cache_dir
        Cache.new(opts.cache_dir)
      else
        Util::NullObject.new(:read => nil, :write => nil)
        Util::NullObject.new(
          :read => nil,
          :write => nil,
          :previous_entry => nil,
          :cleanup => nil
          )
      end
    end

    # The name of the cache file that was previously read or written.
    # When the #read call failed to find the file, it will be nil.
    # But it will always be available after the #write call.
    attr_reader :previous_entry

    def initialize(cache_dir)
      @cache_dir = cache_dir
      @previous_entry = nil
      FileUtils.mkdir_p(cache_dir) unless File.exists?(cache_dir)
    end

@@ -29,8 +41,10 @@ module JsDuck
    def read(file_contents)
      fname = file_name(file_contents)
      if File.exists?(fname)
        @previous_entry = fname
        File.open(fname, "rb") {|file| Marshal::load(file) }
      else
        @previous_entry = nil
        nil
      end
    end
@@ -39,9 +53,21 @@ module JsDuck
    # contents of a source file.
    def write(file_contents, data)
      fname = file_name(file_contents)
      @previous_entry = fname
      File.open(fname, "wb") {|file| Marshal::dump(data, file) }
    end

    # Given listing of used cache files (those that were either read
    # or written during this jsduck run) removes rest of the files
    # from cache directory that were unused.
    def cleanup(used_cache_entries)
      used = Set.new(used_cache_entries)

      Dir[@cache_dir + "/*.dat"].each do |file|
        FileUtils.rm_rf(file) unless used.include?(file)
      end
    end

    private

    def file_name(file_contents)