testmycode/tmc-server

View on GitHub
lib/file_tree_hasher.rb

Summary

Maintainability
A
55 mins
Test Coverage
# frozen_string_literal: true

require 'find'
require 'digest/sha2'

# Produces a combined hash of all the files and directories in a directory.
#
# This is currently used to cache part of the work done by CourseRefresher.
#
# The has depends on the files' paths as well as contents.
class FileTreeHasher
  def self.hash_file_tree(root_path)
    paths = []
    root_path = File.expand_path(root_path)
    Find.find(root_path) do |path|
      paths << path unless File.directory?(path)
    end

    paths.sort!

    digest = Digest::SHA2.new
    paths.each do |path|
      raise "Find didn't work as expected." unless path.start_with?(root_path)
      relative_path = path[(root_path.length + 1)...path.length]
      digest << relative_path << File.read(path)
    rescue StandardError
      raise "Failed to hash file #{path}: #{$!.message}"
    end
    digest.hexdigest
  end
end