1
0

diff.rb 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. module Dotenv
  2. # A diff between multiple states of ENV.
  3. class Diff
  4. # The initial state
  5. attr_reader :a
  6. # The final or current state
  7. attr_reader :b
  8. # Create a new diff. If given a block, the state of ENV after the block will be preserved as
  9. # the final state for comparison. Otherwise, the current ENV will be the final state.
  10. #
  11. # @param a [Hash] the initial state, defaults to a snapshot of current ENV
  12. # @param b [Hash] the final state, defaults to the current ENV
  13. # @yield [diff] a block to execute before recording the final state
  14. def initialize(a: snapshot, b: ENV, &block)
  15. @a, @b = a, b
  16. block&.call self
  17. ensure
  18. @b = snapshot if block
  19. end
  20. # Return a Hash of keys added with their new values
  21. def added
  22. b.slice(*(b.keys - a.keys))
  23. end
  24. # Returns a Hash of keys removed with their previous values
  25. def removed
  26. a.slice(*(a.keys - b.keys))
  27. end
  28. # Returns of Hash of keys changed with an array of their previous and new values
  29. def changed
  30. (b.slice(*a.keys).to_a - a.to_a).map do |(k, v)|
  31. [k, [a[k], v]]
  32. end.to_h
  33. end
  34. # Returns a Hash of all added, changed, and removed keys and their new values
  35. def env
  36. b.slice(*(added.keys + changed.keys)).merge(removed.transform_values { |v| nil })
  37. end
  38. # Returns true if any keys were added, removed, or changed
  39. def any?
  40. [added, removed, changed].any?(&:any?)
  41. end
  42. private
  43. def snapshot
  44. ENV.to_h.freeze
  45. end
  46. end
  47. end