From 1982e3c18d19dc12047d12ae3b57ebcf3c6fbf17 Mon Sep 17 00:00:00 2001 From: Max Jacobson Date: Fri, 19 Apr 2024 17:03:15 -0400 Subject: [PATCH] Fix template (-t) handling of multi-line variables I'm noticing that multi-line variables aren't properly templated. This input: ``` FOO=BAR FOO2="BAR2 BAR2 BAR2 BAR2" FOO3=BAR3 ``` produces this output: ``` FOO=FOO FOO2=FOO2 BAR2 BAR2 BAR2" FOO3=FOO3 ``` My expectation is that it would instead produce this output: ``` FOO=FOO FOO2=FOO2 FOO3=FOO3 ``` --- lib/dotenv/template.rb | 30 ++++++++++++++++++++++++------ spec/dotenv/cli_spec.rb | 14 ++++++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/lib/dotenv/template.rb b/lib/dotenv/template.rb index ce42e36c..2e79376d 100644 --- a/lib/dotenv/template.rb +++ b/lib/dotenv/template.rb @@ -10,17 +10,35 @@ def create_template File.open(@env_file, "r") do |env_file| File.open("#{@env_file}.template", "w") do |env_template| env_file.each do |line| - env_template.puts template_line(line) + if is_comment?(line) + env_template.puts line + elsif (var = var_defined?(line)) + if line.match(EXPORT_COMMAND) + env_template.puts "export #{var}=#{var}" + else + env_template.puts "#{var}=#{var}" + end + elsif line_blank?(line) + env_template.puts + end end end end end - def template_line(line) - var, value = line.split("=") - template = var.gsub(EXPORT_COMMAND, "") - is_a_comment = var.strip[0].eql?("#") - (value.nil? || is_a_comment) ? line : "#{var}=#{template}" + private + + def is_comment?(line) + line.strip.start_with?("#") + end + + def var_defined?(line) + match = Dotenv::Parser::LINE.match(line) + match && match[1] + end + + def line_blank?(line) + line.strip.length.zero? end end end diff --git a/spec/dotenv/cli_spec.rb b/spec/dotenv/cli_spec.rb index afcb1431..1da6426f 100644 --- a/spec/dotenv/cli_spec.rb +++ b/spec/dotenv/cli_spec.rb @@ -89,6 +89,20 @@ def run(*args) expect(@buffer.string).to eq("export FOO=FOO\nexport FOO2=FOO2\n") end + it "templates multi-line variables" do + @input = StringIO.new(<<~TEXT) + FOO=BAR + FOO2="BAR2 + BAR2" + TEXT + allow(File).to receive(:open).with(@origin_filename, "r").and_yield(@input) + allow(File).to receive(:open).with(@template_filename, "w").and_yield(@buffer) + # call the function that writes to the file + Dotenv::CLI.new(["-t", @origin_filename]) + # reading the buffer and checking its content. + expect(@buffer.string).to eq("FOO=FOO\nFOO2=FOO2\n") + end + it "ignores blank lines" do @input = StringIO.new("\nFOO=BAR\nFOO2=BAR2") allow(File).to receive(:open).with(@origin_filename, "r").and_yield(@input)