From a8837d453cfaf3bbf18e386fbf4c3dc895a05db8 Mon Sep 17 00:00:00 2001 From: Donal McBreen Date: Tue, 30 Jul 2024 12:29:44 +0100 Subject: [PATCH] Read from .kamal/.env To avoid conflicts with other tools that use .env files, read the files from .kamal/ instead. If there are no matching env files in .kamal/, we'll read from the project root for now and emit a warning. --- lib/kamal/cli/base.rb | 18 ++++++++++++++++-- lib/kamal/cli/main.rb | 10 +++++----- test/cli/main_test.rb | 19 +++++++++++-------- .../docker/deployer/app/{ => .kamal}/.env.erb | 0 .../app_with_roles/{ => .kamal}/.env.erb | 0 test/integration/main_test.rb | 4 ++-- 6 files changed, 34 insertions(+), 17 deletions(-) rename test/integration/docker/deployer/app/{ => .kamal}/.env.erb (100%) rename test/integration/docker/deployer/app_with_roles/{ => .kamal}/.env.erb (100%) diff --git a/lib/kamal/cli/base.rb b/lib/kamal/cli/base.rb index 0710c088..2463f585 100644 --- a/lib/kamal/cli/base.rb +++ b/lib/kamal/cli/base.rb @@ -37,9 +37,23 @@ module Kamal::Cli def load_env if destination = options[:destination] - Dotenv.load(".env.#{destination}", ".env") + if File.exist?(".kamal/.env.#{destination}") || File.exist?(".kamal/.env") + Dotenv.load(".kamal/.env.#{destination}", ".kamal/.env") + else + loading_files = [ (".env" if File.exist?(".env")), (".env.#{destination}" if File.exist?(".env.#{destination}")) ].compact + if loading_files.any? + warn "Loading #{loading_files.join(" and ")} from the project root, in future they will be loaded from .kamal/" + Dotenv.load(".env.#{destination}", ".env") + end + end else - Dotenv.load(".env") + if File.exist?(".kamal/.env") + Dotenv.load(".kamal/.env") + elsif File.exist?(".env") + $stderr.puts caller + warn "Loading .env from the project root, in future it will be loaded then from .kamal/.env" + Dotenv.load(".env") + end end end diff --git a/lib/kamal/cli/main.rb b/lib/kamal/cli/main.rb index 598d6c42..a65e7b8d 100644 --- a/lib/kamal/cli/main.rb +++ b/lib/kamal/cli/main.rb @@ -179,15 +179,15 @@ class Kamal::Cli::Main < Kamal::Cli::Base end end - desc "envify", "Create .env by evaluating .env.erb (or .env.staging.erb -> .env.staging when using -d staging)" + desc "envify", "Create .kamal/.env by evaluating .kamal/.env.erb (or .kamal/.env.staging.erb -> .kamal/.env.staging when using -d staging)" option :skip_push, aliases: "-P", type: :boolean, default: false, desc: "Skip .env file push" def envify if destination = options[:destination] - env_template_path = ".env.#{destination}.erb" - env_path = ".env.#{destination}" + env_template_path = ".kamal/.env.#{destination}.erb" + env_path = ".kamal/.env.#{destination}" else - env_template_path = ".env.erb" - env_path = ".env" + env_template_path = ".kamal/.env.erb" + env_path = ".kamal/.env" end if Pathname.new(File.expand_path(env_template_path)).exist? diff --git a/test/cli/main_test.rb b/test/cli/main_test.rb index e562499b..82d4e2ba 100644 --- a/test/cli/main_test.rb +++ b/test/cli/main_test.rb @@ -449,7 +449,7 @@ class CliMainTest < CliTestCase test "envify" do with_test_dotenv(".env.erb": "HELLO=<%= 'world' %>") do run_command("envify") - assert_equal("HELLO=world", File.read(".env")) + assert_equal("HELLO=world", File.read(".kamal/.env")) end end @@ -463,21 +463,21 @@ class CliMainTest < CliTestCase with_test_dotenv(".env.erb": file) do run_command("envify") - assert_equal("HELLO=world\nKEY=value\n", File.read(".env")) + assert_equal("HELLO=world\nKEY=value\n", File.read(".kamal/.env")) end end test "envify with destination" do with_test_dotenv(".env.world.erb": "HELLO=<%= 'world' %>") do run_command("envify", "-d", "world", config_file: "deploy_for_dest") - assert_equal "HELLO=world", File.read(".env.world") + assert_equal "HELLO=world", File.read(".kamal/.env.world") end end test "envify with skip_push" do Pathname.any_instance.expects(:exist?).returns(true).times(1) - File.expects(:read).with(".env.erb").returns("HELLO=<%= 'world' %>") - File.expects(:write).with(".env", "HELLO=world", perm: 0600) + File.expects(:read).with(".kamal/.env.erb").returns("HELLO=<%= 'world' %>") + File.expects(:write).with(".kamal/.env", "HELLO=world", perm: 0600) Kamal::Cli::Main.any_instance.expects(:invoke).with("kamal:cli:env:push").never run_command("envify", "--skip-push") @@ -486,7 +486,7 @@ class CliMainTest < CliTestCase test "envify with clean env" do with_test_dotenv(".env": "HELLO=already", ".env.erb": "HELLO=<%= ENV.fetch 'HELLO', 'never' %>") do run_command("envify", "--skip-push") - assert_equal "HELLO=never", File.read(".env") + assert_equal "HELLO=never", File.read(".kamal/.env") end end @@ -549,8 +549,11 @@ class CliMainTest < CliTestCase FileUtils.cp_r("test/fixtures/", fixtures_dup) Dir.chdir(dir) do - files.each do |filename, contents| - File.binwrite(filename.to_s, contents) + FileUtils.mkdir_p(".kamal") + Dir.chdir(".kamal") do + files.each do |filename, contents| + File.binwrite(filename.to_s, contents) + end end yield end diff --git a/test/integration/docker/deployer/app/.env.erb b/test/integration/docker/deployer/app/.kamal/.env.erb similarity index 100% rename from test/integration/docker/deployer/app/.env.erb rename to test/integration/docker/deployer/app/.kamal/.env.erb diff --git a/test/integration/docker/deployer/app_with_roles/.env.erb b/test/integration/docker/deployer/app_with_roles/.kamal/.env.erb similarity index 100% rename from test/integration/docker/deployer/app_with_roles/.env.erb rename to test/integration/docker/deployer/app_with_roles/.kamal/.env.erb diff --git a/test/integration/main_test.rb b/test/integration/main_test.rb index c4558c1d..4d4513ad 100644 --- a/test/integration/main_test.rb +++ b/test/integration/main_test.rb @@ -97,7 +97,7 @@ class MainTest < IntegrationTest private def assert_local_env_file(contents) - assert_equal contents, deployer_exec("cat .env", capture: true) + assert_equal contents, deployer_exec("cat .kamal/.env", capture: true) end def assert_envs(version:) @@ -127,7 +127,7 @@ class MainTest < IntegrationTest end def remove_local_env_file - deployer_exec("rm .env") + deployer_exec("rm .kamal/.env") end def assert_remote_env_file(contents, vm:)