Module: Philiprehberger::EnvDiff

Defined in:
lib/philiprehberger/env_diff.rb,
lib/philiprehberger/env_diff/diff.rb,
lib/philiprehberger/env_diff/parser.rb,
lib/philiprehberger/env_diff/version.rb

Defined Under Namespace

Modules: Parser Classes: Diff, Error

Constant Summary collapse

VERSION =
'0.3.0'

Class Method Summary collapse

Class Method Details

.compare(source, target, case_sensitive: true) ⇒ Diff

Compare two environment hashes and return a Diff.

Parameters:

  • source (Hash)

    the baseline environment hash

  • target (Hash)

    the environment hash to compare against

  • case_sensitive (Boolean) (defaults to: true)

    whether key comparison is case-sensitive (default: true)

Returns:

  • (Diff)

    the computed differences



17
18
19
20
21
22
23
24
25
# File 'lib/philiprehberger/env_diff.rb', line 17

def self.compare(source, target, case_sensitive: true)
  if case_sensitive
    Diff.new(source, target)
  else
    normalized_source = source.transform_keys(&:upcase)
    normalized_target = target.transform_keys(&:upcase)
    Diff.new(normalized_source, normalized_target)
  end
end

.from_env_file(path_a, path_b, case_sensitive: true) ⇒ Diff

Parse two .env files and compare them.

Parameters:

  • path_a (String)

    path to the source .env file

  • path_b (String)

    path to the target .env file

  • case_sensitive (Boolean) (defaults to: true)

    whether key comparison is case-sensitive (default: true)

Returns:

  • (Diff)

    the computed differences



112
113
114
# File 'lib/philiprehberger/env_diff.rb', line 112

def self.from_env_file(path_a, path_b, case_sensitive: true)
  compare(Parser.parse_file(path: path_a), Parser.parse_file(path: path_b), case_sensitive: case_sensitive)
end

.from_hash(hash_a, hash_b, case_sensitive: true) ⇒ Diff

Alias for compare — compare two hashes.

Parameters:

  • hash_a (Hash)

    the baseline environment hash

  • hash_b (Hash)

    the environment hash to compare against

  • case_sensitive (Boolean) (defaults to: true)

    whether key comparison is case-sensitive (default: true)

Returns:

  • (Diff)

    the computed differences



102
103
104
# File 'lib/philiprehberger/env_diff.rb', line 102

def self.from_hash(hash_a, hash_b, case_sensitive: true)
  compare(hash_a, hash_b, case_sensitive: case_sensitive)
end

.from_system(target, case_sensitive: true) ⇒ Diff

Compare the current system ENV against a target hash or .env file path.

Parameters:

  • target (Hash, String)

    a hash of target variables or a path to a .env file

  • case_sensitive (Boolean) (defaults to: true)

    whether key comparison is case-sensitive (default: true)

Returns:

  • (Diff)

    the computed differences between ENV and target



121
122
123
124
# File 'lib/philiprehberger/env_diff.rb', line 121

def self.from_system(target, case_sensitive: true)
  target_hash = target.is_a?(String) ? Parser.parse_file(path: target) : target
  compare(ENV.to_h, target_hash, case_sensitive: case_sensitive)
end

.to_html(diff) ⇒ String

Format a diff result as an HTML table string.

Parameters:

  • diff (Diff)

    the diff to format

Returns:

  • (String)

    HTML table



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/philiprehberger/env_diff.rb', line 70

def self.to_html(diff)
  rows = diff.added.map do |key|
    "  <tr><td>#{key}</td><td>added</td><td></td><td>#{diff.to_h[:added][key]}</td></tr>"
  end

  diff.removed.each do |key|
    rows << "  <tr><td>#{key}</td><td>removed</td><td>#{diff.to_h[:removed][key]}</td><td></td></tr>"
  end

  diff.changed.each do |key, vals|
    rows << "  <tr><td>#{key}</td><td>changed</td><td>#{vals[:source]}</td><td>#{vals[:target]}</td></tr>"
  end

  diff.unchanged.each do |key|
    val = diff.to_h[:unchanged][key]
    rows << "  <tr><td>#{key}</td><td>unchanged</td><td>#{val}</td><td>#{val}</td></tr>"
  end

  lines = []
  lines << '<table>'
  lines << '  <tr><th>Key</th><th>Status</th><th>Source</th><th>Target</th></tr>'
  lines.concat(rows)
  lines << '</table>'
  lines.join("\n")
end

.to_markdown(diff) ⇒ String

Format a diff result as a Markdown table string.

Parameters:

  • diff (Diff)

    the diff to format

Returns:

  • (String)

    Markdown table



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/philiprehberger/env_diff.rb', line 42

def self.to_markdown(diff)
  lines = []
  lines << '| Key | Status | Source | Target |'
  lines << '| --- | ------ | ------ | ------ |'

  diff.added.each do |key|
    lines << "| #{key} | added | | #{diff.to_h[:added][key]} |"
  end

  diff.removed.each do |key|
    lines << "| #{key} | removed | #{diff.to_h[:removed][key]} | |"
  end

  diff.changed.each do |key, vals|
    lines << "| #{key} | changed | #{vals[:source]} | #{vals[:target]} |"
  end

  diff.unchanged.each do |key|
    lines << "| #{key} | unchanged | #{diff.to_h[:unchanged][key]} | #{diff.to_h[:unchanged][key]} |"
  end

  lines.join("\n")
end

.validate(target, required:) ⇒ Hash

Validate that all required keys exist in target.

Parameters:

  • target (Hash, String)

    a hash of target variables or a path to a .env file

  • required (Array<String>)

    list of required key names

Returns:

  • (Hash)

    with :valid (Boolean) and :missing (Array<String>)



32
33
34
35
36
# File 'lib/philiprehberger/env_diff.rb', line 32

def self.validate(target, required:)
  target_hash = target.is_a?(String) ? Parser.parse_file(path: target) : target
  missing = required.reject { |key| target_hash.key?(key) }
  { valid: missing.empty?, missing: missing }
end