dotenv_rails_db_tasks_fix 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d126642ad8ea8ec2a15861353fa3b48efd0133e22df45b63f4f25d2e9499a0ca
4
- data.tar.gz: b59c95dcecb6f997799d32d04f259a70fba3673d053fe898854c2dab1a135b25
3
+ metadata.gz: ab842233cb330350cc2a4fa074cc42a313cc9520427768d6033c2bbf2aab67ba
4
+ data.tar.gz: 53aa623b5c8e2f2e930c62377ec7206bbef0166009802934342b07afde348340
5
5
  SHA512:
6
- metadata.gz: 6a34646ddce10d1d8c7e47ecd19d35e75695dad9becf03aee0315dbdda70a79cfd92a297dd12808f05f81beac98e34e94f5604f1bdc0935c5caa4062392e2fdd
7
- data.tar.gz: f46d7d44344ac35610780e488d937907ee11a9607c44c03d85e84be368645ce11328a0923f5ea130a9300bac11b7d4ad4ba497f79c8e512c4c7826bc0d392049
6
+ metadata.gz: fd703d7e2bbc0c48c57bc5d40b95976c420e2f0c276c8865570d03f4708aa9dac2f5de8bec39ba62a27425b67f598b56b63f6c2db72a697023051c54c5c0bc39
7
+ data.tar.gz: 2381d0d03e5036c10574068d80c8eb1796a910a6a446ac0d94e8a3379dae1ee5c3ffd78485f7615cba5925ef1d5ad57d8913cfc87ad5cb3d216fdcbe093edccd
@@ -3,3 +3,5 @@ language: ruby
3
3
  rvm:
4
4
  - 2.3.1
5
5
  before_install: gem install bundler -v 1.16.0
6
+ env:
7
+ - RAILS_ENV=development
data/README.md CHANGED
@@ -2,13 +2,14 @@
2
2
 
3
3
  #### Fix for the issue when ActiveRecord `rake db:*` tasks are magically executed in both developement and test environments, but environment variables loaded via `dotenv` are not picking up the change.
4
4
 
5
- *You are viewing the README of version [v0.1.0](https://github.com/thisismydesign/dotenv_rails_db_tasks_fix/releases/tag/v0.1.0).*
5
+ *You are viewing the README of version [v0.2.0](https://github.com/thisismydesign/dotenv_rails_db_tasks_fix/releases/tag/v0.2.0). You can find other releases [here](https://github.com/thisismydesign/dotenv_rails_db_tasks_fix/releases).*
6
6
 
7
7
  | Branch | Status |
8
8
  | ------ | ------ |
9
+ | Release | [![Build Status](https://travis-ci.org/thisismydesign/dotenv_rails_db_tasks_fix.svg?branch=release)](https://travis-ci.org/thisismydesign/dotenv_rails_db_tasks_fix) [![Coverage Status](https://coveralls.io/repos/github/thisismydesign/dotenv_rails_db_tasks_fix/badge.svg?branch=release)](https://coveralls.io/github/thisismydesign/dotenv_rails_db_tasks_fix?branch=release) [![Gem Version](https://badge.fury.io/rb/dotenv_rails_db_tasks_fix.svg)](https://badge.fury.io/rb/dotenv_rails_db_tasks_fix) [![Total Downloads](http://ruby-gem-downloads-badge.herokuapp.com/dotenv_rails_db_tasks_fix?type=total)](https://rubygems.org/gems/dotenv_rails_db_tasks_fix) |
9
10
  | Development | [![Build Status](https://travis-ci.org/thisismydesign/dotenv_rails_db_tasks_fix.svg?branch=master)](https://travis-ci.org/thisismydesign/dotenv_rails_db_tasks_fix) [![Coverage Status](https://coveralls.io/repos/github/thisismydesign/dotenv_rails_db_tasks_fix/badge.svg?branch=master)](https://coveralls.io/github/thisismydesign/dotenv_rails_db_tasks_fix?branch=master) |
10
11
 
11
- If you're using environment variables in your `database.yml` and load them via `Dotenv` chances are you also ran into this annoying issue in your development environment:
12
+ If you rely on environment variables loaded via `Dotenv` chances are you also ran into this issue. E.g.:
12
13
 
13
14
  `database.yml`
14
15
  ```
@@ -32,6 +33,8 @@ DB_NAME=test
32
33
  # ...
33
34
  ```
34
35
 
36
+ In your development environment:
37
+
35
38
  ```
36
39
  $ rails db:setup
37
40
  =>
@@ -39,6 +42,8 @@ Created database 'app_development'
39
42
  Database 'app_development' already exists
40
43
  ```
41
44
 
45
+ It seems like the task is executed twice for the development environment (more on that later..) and you also often encounter an `EnvironmentMismatchError`:
46
+
42
47
  ```
43
48
  $ rails db:setup
44
49
  =>
@@ -51,13 +56,12 @@ You are running in `development` environment. If you are sure you want to contin
51
56
  bin/rails db:environment:set RAILS_ENV=development
52
57
  ```
53
58
 
54
- Using this gem you can do:
59
+ #### Using this gem you can do:
55
60
 
56
61
  `Rakefile`
57
- ```
62
+ ```ruby
58
63
  # ...
59
- require "dotenv_rails_db_tasks_fix"
60
- DotenvRailsDbTasksFix.activate
64
+ DotenvRailsDbTasksFix.activate if ActiveRecord::Tasks::DatabaseTasks.env.eql?("development") # or Rails.env
61
65
  ```
62
66
 
63
67
  ```
@@ -69,25 +73,27 @@ Created database 'app_test'
69
73
 
70
74
  ## Explanation
71
75
 
72
- ActiveRecord has this feature that it executes DB tasks in `test` env as well if the current env is `development`. ([see](https://github.com/rails/rails/blob/v5.1.5/activerecord/lib/active_record/tasks/database_tasks.rb#L300):
73
- `environments << "test" if environment == "development"`). This happens in the middle of execution so there's no way for `dotenv` to nicely intervene and even if they did there are things already loaded at this point (e.g. env vars are interpolated to configs). Dotenv's recommendation is to use different env var names (e.g. `TEST_DB_NAME`, `DEVELOPMENT_DB_NAME`) but that would be counter-intuitive. Instead here we monkey patch `ActiveRecord::Tasks::DatabaseTasks` to explicitly reload env vars and the DB config when it switches to test env.
76
+ ActiveRecord has this feature that it executes DB tasks in `test` env as well if the current env is `development` ([see](https://github.com/rails/rails/blob/v5.1.5/activerecord/lib/active_record/tasks/database_tasks.rb#L300):
77
+ `environments << "test" if environment == "development"`). So ActiveRecord actually executes for different environments but not via a fresh start. This makes it impossible for `dotenv` to pick this change up in a clean way. But even if it did there are things already loaded at this point which dotenv should not touch. E.g. reinitializing the database config after an environment change should rather be the responsibility of ActiveRecord.
74
78
 
75
- *It's invasive and ugly but it only affects the development environment (so it's low-risk) and restores the expected behaviour of this widely used feature therefore sparing the annoyance and possible effort of investigation.*
79
+ Dotenv's recommendation is to use different env var names (e.g. `TEST_DB_NAME`, `DEVELOPMENT_DB_NAME`) but that would be counter-intuitive. Instead via this gem `ActiveRecord::Tasks::DatabaseTasks` is monkey patched to explicitly reload env vars and the DB config when it switches to test env. *This approach undoubtedly has its cons but in this case it only affects the development environment and restores the expected behaviour of this widely used feature therefore sparing the annoyance and possible effort of investigation.*
76
80
 
77
- See [this issue](https://github.com/thisismydesign/dotenv_rails_db_tasks_fix) and [this article](http://www.zhuwu.me/blog/posts/rake-db-tasks-always-runs-twice-in-development-environment).
81
+ See also [this issue](https://github.com/thisismydesign/dotenv_rails_db_tasks_fix) and [this article](http://www.zhuwu.me/blog/posts/rake-db-tasks-always-runs-twice-in-development-environment).
78
82
 
79
83
  ## Caveats
80
84
 
85
+ - Outside of `development` environment `DotenvRailsDbTasksFix.activate` will `raise` and will _not_ monkey patch
81
86
  - Database config is expected to reside in Rails default `#{DatabaseTasks.root}/config/database.yml` (if you're using Rails `DatabaseTasks.root == Rails.root`)
82
87
  - Requires ActiveRecord >= 5.1.5, ~> 5.1.6 (because there're slight differences in the private API, althoguh following this solution it would be easy to extend support for other versions)
83
88
  - There's some weirdness with `Rails.env` vs `DatabaseTasks.env`. From trial-and-error it seems changing `DatabaseTasks.env` to reflect the current execution env will result in issues (with e.g. `db:setup` and `db:reset`), while changing `Rails.env` is actually required for `db:setup` to work correctly. [This fix](https://github.com/thisismydesign/dotenv_rails_db_tasks_fix/blob/be83ad6f97e4c1eb4bcfb5a2860eb3b53d7ff063/lib/dotenv_rails_db_tasks_fix.rb#L24-L28) seems to work for the use cases I tried but it's good to keep this in mind in case any similar issue presents.
89
+ - If you introduce this to a project currently in use a final `db:environment:set` might be needed if prompted
84
90
 
85
91
  ## Installation
86
92
 
87
93
  Add this line to your application's Gemfile:
88
94
 
89
95
  ```ruby
90
- gem 'dotenv_rails_db_tasks_fix'
96
+ gem 'dotenv_rails_db_tasks_fix', group: :development
91
97
  ```
92
98
 
93
99
  And then execute:
data/Rakefile CHANGED
@@ -1,37 +1,19 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
+ require 'dotenv'
4
+
3
5
  require_relative "lib/dotenv_rails_db_tasks_fix"
6
+ require_relative "spec/support/active_record_tasks"
4
7
 
5
8
  RSpec::Core::RakeTask.new(:spec)
6
9
 
7
10
  task :default => :spec
8
11
 
9
- require "erb"
10
- require 'yaml'
11
- require 'dotenv'
12
- require 'active_record'
13
-
14
12
  RSPEC_ROOT = Pathname.new(File.dirname(__FILE__)).join("spec")
15
13
  environment = ENV["RAILS_ENV"] || "development"
16
- db_config = Pathname.new(RSPEC_ROOT).join("example_project", "config", "database.yml")
14
+ project_path = Pathname.new(RSPEC_ROOT).join("example_project")
17
15
 
18
16
  Dotenv.overload(".env", ".env.#{environment}", ".env.local", ".env.#{environment}.local")
19
-
20
- class Seeder; def load_seed; end; end
21
-
22
- include ActiveRecord::Tasks
23
- DatabaseTasks.database_configuration = YAML::load(ERB.new(File.read(db_config)).result)
24
- DatabaseTasks.root = Pathname.new(RSPEC_ROOT).join("example_project")
25
- DatabaseTasks.db_dir = Pathname.new(DatabaseTasks.root).join("db")
26
- DatabaseTasks.migrations_paths = [File.join(DatabaseTasks.root, 'db/migrate')]
27
- DatabaseTasks.env = environment
28
- DatabaseTasks.seed_loader = Seeder.new
29
-
30
- task :environment do
31
- ActiveRecord::Base.configurations = DatabaseTasks.database_configuration
32
- ActiveRecord::Base.establish_connection DatabaseTasks.env.to_sym
33
- end
34
-
35
- load 'active_record/railties/databases.rake'
17
+ load_active_record_tasks(project_path: project_path, env: environment)
36
18
 
37
19
  DotenvRailsDbTasksFix.activate
@@ -4,9 +4,10 @@ require "active_record"
4
4
 
5
5
  module DotenvRailsDbTasksFix
6
6
  def self.activate
7
- ActiveRecord::Tasks::DatabaseTasks.instance_eval do
8
- return unless env.eql?("development")
7
+ target_env = "development".freeze
8
+ raise "`DotenvRailsDbTasksFix` activated outside of #{target_env} environment" unless ActiveRecord::Tasks::DatabaseTasks.env.eql?(target_env)
9
9
 
10
+ ActiveRecord::Tasks::DatabaseTasks.instance_eval do
10
11
  private
11
12
 
12
13
  def each_current_configuration(environment)
@@ -1,3 +1,3 @@
1
1
  module DotenvRailsDbTasksFix
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dotenv_rails_db_tasks_fix
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - thisismydesign