From a8b32920cf811e57bb15acf5c4688f8df629ee0d Mon Sep 17 00:00:00 2001 From: Rob Galanakis Date: Mon, 15 Apr 2024 12:45:18 -0700 Subject: [PATCH] Dotenviable: Load env into another hash If `Dotenviable.load(env:)` is passed, load all config into `env`, not just the port and rack_env. Allows loading of alternative environments, usually needed only for testing, but sometimes in other situations (like loading development database urls from a test environment). --- lib/appydays/dotenviable.rb | 17 +++++++++++++++++ spec/appydays/dotenviable_spec.rb | 14 ++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/lib/appydays/dotenviable.rb b/lib/appydays/dotenviable.rb index a30a932..d43f36b 100644 --- a/lib/appydays/dotenviable.rb +++ b/lib/appydays/dotenviable.rb @@ -24,6 +24,13 @@ # it won't get used, because .env files don't stomp what is already in the environment # (we don't want to use `overload`). # So we have some trickery to overwrite only PORT. +# +# @param rack_env [nil,String] Value like 'development' or 'production' to use to load .env files. +# If not given, use +env['RACK_ENV']+ or +default_rack_env+. +# @param default_rack_env [String] If +env['RACK_ENV']+ is not set, use this value. +# @param env [Hash] Hash to read and mutate. +# Pass in a different hash to load environment variables into it instead of ENV. +# Useful for testing, or to get the config for another environment. module Appydays::Dotenviable def self.load(rack_env: nil, default_rack_env: "development", env: ENV) original_port = env.delete("PORT") @@ -33,7 +40,17 @@ def self.load(rack_env: nil, default_rack_env: "development", env: ENV) ".env.#{rack_env}", ".env", ] + orig_env = nil + if env.object_id != ENV.object_id + orig_env = ENV.to_h + ENV.replace(env) + end Dotenv.load(*paths) + if orig_env + env.merge!(ENV) + ENV.replace(orig_env) + end + env["PORT"] ||= original_port env["RACK_ENV"] ||= rack_env end diff --git a/spec/appydays/dotenviable_spec.rb b/spec/appydays/dotenviable_spec.rb index 0b13ea6..48ff063 100644 --- a/spec/appydays/dotenviable_spec.rb +++ b/spec/appydays/dotenviable_spec.rb @@ -46,4 +46,18 @@ described_class.load(env: env) expect(env).to include("PORT" => "456") end + + it "can load into a separate hash" do + ENV["HASHTESTABC"] = "x" + File.write(".env.hashtest", "HASHTESTXYZ=a") + e = {} + described_class.load(rack_env: "hashtest", env: e) + expect(e).to include("HASHTESTXYZ" => "a") + expect(e).to_not include("HASHTESTABC") + expect(ENV.to_h).to_not include("HASHTESTXYZ") + expect(ENV.to_h).to include("HASHTESTABC" => "x") + ensure + File.delete(".env.hashtest") + ENV.delete("HASHTESTABC") + end end