From 6ed39f396991a55b38a65fea089651b2665a7e17 Mon Sep 17 00:00:00 2001 From: Brandon Keepers Date: Sat, 20 Jan 2024 12:34:51 -0500 Subject: [PATCH] Refactor Rails integration --- lib/dotenv/rails.rb | 35 +++++++++++++++++------------------ spec/dotenv/rails_spec.rb | 31 +++++++++---------------------- 2 files changed, 26 insertions(+), 40 deletions(-) diff --git a/lib/dotenv/rails.rb b/lib/dotenv/rails.rb index d8a33552..4b4569e5 100644 --- a/lib/dotenv/rails.rb +++ b/lib/dotenv/rails.rb @@ -12,23 +12,18 @@ end module Dotenv - # Dotenv Railtie for using Dotenv to load environment from a file into - # Rails applications + # Rails integration for using Dotenv to load ENV variables from a file class Rails < ::Rails::Railtie - def self.deprecator # :nodoc: - @deprecator ||= ActiveSupport::Deprecation.new - end + attr_accessor :mode, :files def initialize - config.dotenv = ActiveSupport::OrderedOptions.new.merge!( - mode: :load, - files: [ - root.join(".env.#{env}.local"), - (root.join(".env.local") unless env.test?), - root.join(".env.#{env}"), - root.join(".env") - ].compact - ) + @mode = :load + @files = [ + root.join(".env.#{env}.local"), + (root.join(".env.local") unless env.test?), + root.join(".env.#{env}"), + root.join(".env") + ].compact end # Public: Load dotenv @@ -36,14 +31,14 @@ def initialize # This will get called during the `before_configuration` callback, but you # can manually call `Dotenv::Railtie.load` if you needed it sooner. def load - Dotenv.load(*config.dotenv.files) + Dotenv.load(*files) end # Public: Reload dotenv # # Same as `load`, but will override existing values in `ENV` def overload - Dotenv.overload(*config.dotenv.files) + Dotenv.overload(*files) end # Internal: `Rails.root` is nil in Rails 4.1 before the application is @@ -72,6 +67,10 @@ def env env end + def deprecator # :nodoc: + @deprecator ||= ActiveSupport::Deprecation.new + end + # Rails uses `#method_missing` to delegate all class methods to the # instance, which means `Kernel#load` gets called here. We don't want that. def self.load @@ -79,12 +78,12 @@ def self.load end initializer "dotenv.deprecator" do |app| - app.deprecators[:dotenv] = Dotenv::Railtie.deprecator + app.deprecators[:dotenv] = deprecator end config.before_configuration do Dotenv.instrumenter = ActiveSupport::Notifications - config.dotenv.mode == :load ? load : overload + mode == :load ? load : overload end end diff --git a/spec/dotenv/rails_spec.rb b/spec/dotenv/rails_spec.rb index 30f99eb7..46176432 100644 --- a/spec/dotenv/rails_spec.rb +++ b/spec/dotenv/rails_spec.rb @@ -2,19 +2,6 @@ require "rails" require "dotenv/rails" -# Fake watcher for Spring -class SpecWatcher - attr_reader :items - - def initialize - @items = [] - end - - def add(*items) - @items |= items - end -end - describe Dotenv::Rails do before do # Remove the singleton instance if it exists @@ -23,7 +10,7 @@ def add(*items) Rails.env = "test" allow(Rails).to receive(:root).and_return Pathname.new(__dir__).join('../fixtures') Rails.application = double(:application) - Spring.watcher = SpecWatcher.new + Spring.watcher = Set.new # Responds to #add end after do @@ -32,11 +19,11 @@ def add(*items) Rails.application = nil end - describe "config.dotenv.files" do + describe "files" do it "loads files for development environment" do Rails.env = "development" - expect(Dotenv::Rails.config.dotenv.files).to eql( + expect(Dotenv::Rails.files).to eql( [ Rails.root.join(".env.development.local"), Rails.root.join(".env.local"), @@ -48,7 +35,7 @@ def add(*items) it "does not load .env.local in test rails environment" do Rails.env = "test" - expect(Dotenv::Rails.config.dotenv.files).to eql( + expect(Dotenv::Rails.files).to eql( [ Rails.root.join(".env.test.local"), Rails.root.join(".env.test"), @@ -67,7 +54,7 @@ def add(*items) end context "with mode = :overload" do - before { Dotenv::Rails.config.dotenv.mode = :overload } + before { Dotenv::Rails.mode = :overload } it "calls #overload" do expect(Dotenv::Rails.instance).to receive(:overload) @@ -80,13 +67,13 @@ def add(*items) before { Dotenv::Rails.load } it "watches .env with Spring" do - expect(Spring.watcher.items).to include(Rails.root.join(".env").to_s) + expect(Spring.watcher).to include(Rails.root.join(".env").to_s) end it "watches other loaded files with Spring" do path = fixture_path("plain.env") Dotenv.load(path) - expect(Spring.watcher.items).to include(path) + expect(Spring.watcher).to include(path) end it "loads .env.test before .env" do @@ -95,7 +82,7 @@ def add(*items) it "loads configured files" do expect(Dotenv).to receive(:load).with("custom.env") - Dotenv::Rails.config.dotenv.files = ["custom.env"] + Dotenv::Rails.files = ["custom.env"] Dotenv::Rails.load end @@ -120,7 +107,7 @@ def add(*items) it "loads configured files" do expect(Dotenv).to receive(:overload).with("custom.env") - Dotenv::Rails.config.dotenv.files = ["custom.env"] + Dotenv::Rails.files = ["custom.env"] Dotenv::Rails.overload end