Class: Dotenv::Merge::SmartMerger

Inherits:
Object
  • Object
show all
Defined in:
lib/dotenv/merge/smart_merger.rb

Overview

Smart merger for dotenv files. Intelligently combines template and destination dotenv files by matching environment variable names and preserving customizations.

Examples:

Basic merge

merger = SmartMerger.new(template_content, dest_content)
result = merger.merge
puts result.to_s

With options

merger = SmartMerger.new(
  template_content,
  dest_content,
  preference: :template,
  add_template_only_nodes: true,
)
result = merger.merge

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(template_content, dest_content, preference: :destination, add_template_only_nodes: false, freeze_token: FileAnalysis::DEFAULT_FREEZE_TOKEN, signature_generator: nil) ⇒ SmartMerger

Initialize a new SmartMerger

Parameters:

  • template_content (String)

    Content of the template dotenv file

  • dest_content (String)

    Content of the destination dotenv file

  • preference (Symbol) (defaults to: :destination)

    Which version to prefer on match (:template or :destination, default: :destination)

  • add_template_only_nodes (Boolean) (defaults to: false)

    Whether to add template-only env vars (default: false)

  • freeze_token (String) (defaults to: FileAnalysis::DEFAULT_FREEZE_TOKEN)

    Token for freeze block markers (default: “dotenv-merge”)

  • signature_generator (Proc, nil) (defaults to: nil)

    Custom signature generator



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/dotenv/merge/smart_merger.rb', line 40

def initialize(
  template_content,
  dest_content,
  preference: :destination,
  add_template_only_nodes: false,
  freeze_token: FileAnalysis::DEFAULT_FREEZE_TOKEN,
  signature_generator: nil
)
  @preference = preference
  @add_template_only_nodes = add_template_only_nodes

  # Parse template
  @template_analysis = FileAnalysis.new(
    template_content,
    freeze_token: freeze_token,
    signature_generator: signature_generator,
  )

  # Parse destination
  @dest_analysis = FileAnalysis.new(
    dest_content,
    freeze_token: freeze_token,
    signature_generator: signature_generator,
  )

  @result = MergeResult.new(@template_analysis, @dest_analysis)
end

Instance Attribute Details

#dest_analysisFileAnalysis (readonly)

Returns Analysis of destination file.

Returns:



27
28
29
# File 'lib/dotenv/merge/smart_merger.rb', line 27

def dest_analysis
  @dest_analysis
end

#template_analysisFileAnalysis (readonly)

Returns Analysis of template file.

Returns:



24
25
26
# File 'lib/dotenv/merge/smart_merger.rb', line 24

def template_analysis
  @template_analysis
end

Instance Method Details

#mergeString

Perform the merge operation

Returns:

  • (String)

    The merged content as a string



71
72
73
# File 'lib/dotenv/merge/smart_merger.rb', line 71

def merge
  merge_result.to_s
end

#merge_resultMergeResult

Perform the merge operation and return the full result object

Returns:

  • (MergeResult)

    The merge result containing merged content



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/dotenv/merge/smart_merger.rb', line 78

def merge_result
  return @merge_result if @merge_result

  @merge_result = DebugLogger.time("SmartMerger#merge") do
    alignment = align_statements

    DebugLogger.debug("Alignment complete", {
      total_entries: alignment.size,
      matches: alignment.count { |e| e[:type] == :match },
      template_only: alignment.count { |e| e[:type] == :template_only },
      dest_only: alignment.count { |e| e[:type] == :dest_only },
    })

    process_alignment(alignment)
    @result
  end
end