uff_db_loader 1.3.0 → 2.0.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: 5f807430f4dff47a2a9a98b6f360720a51a7f96c9af2554e0784383adaf0fe63
4
- data.tar.gz: dfaf6dad64eea0e267872426f1426534703e52257c8e29a6440c174a94a94f72
3
+ metadata.gz: 28a567bb65dcdcc545605a5b8b921abe6fb6b4b666d97928e659bf535a1675ed
4
+ data.tar.gz: 4deffc2f8bad009cd16d04f08280765be75042da0f6e6e97d488addd22a51065
5
5
  SHA512:
6
- metadata.gz: c1bed481bd67cc2d5dc3000b6d8b67d17ae0e3f7631302b717c436827862538ab679b52edea76777e8a6f2e1d103caca6c5b75796f64dcf457c7bec7e5a6b226
7
- data.tar.gz: 05defe18ffd2c6719180c26fcab48c85de42cba697834162c9ca81a15e8394760afe8e5daf60e287bc7611b2d257d3a58cbe98778ea2c119275a0a692673bbb3
6
+ metadata.gz: 22b2e2a27364e1afccda77edf18218c9c0862ee0ef389126e745848fceb08fb9fb73b042e07a71a9bddacc2818262d36c9ba109cadc5840c1c3b6175190ccfb5
7
+ data.tar.gz: d8ddddf06be94aa6d2799e7beaeff371c2897cbb7cf6e83855ed112325cc2796732c23082214aa9aa938be023f881e354d2607197dd01a9923777962068c555f
data/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## Installation
8
8
 
9
- Add this line to your application's Gemfile:
9
+ Add this line to your application's `Gemfile`:
10
10
 
11
11
  ```ruby
12
12
  gem 'uff_db_loader'
@@ -20,14 +20,16 @@ Or install it yourself as:
20
20
 
21
21
  $ gem install uff_db_loader
22
22
 
23
+ Run the installation script:
24
+
25
+ $ bin/rails uff_db_loader:install
26
+
23
27
  ## Configuration
24
28
 
25
29
  You can configure the gem by running the following during the initialization of the Rails app:
26
30
  ```ruby
27
- # frozen_string_literal: true
28
-
29
31
  UffDbLoader.configure do |config|
30
- config.environments = ['sandbox', 'production'] # default is "['staging', 'production']"
32
+ config.environments = ['staging', 'production']
31
33
  config.ssh_user = 'Francina'
32
34
  config.ssh_host = 'host.of.yoursite'
33
35
  config.db_name = 'twotter'
@@ -43,10 +45,13 @@ Make sure the app's database user has the superuser role. Otherwise the app will
43
45
 
44
46
  ## Usage
45
47
 
46
- `uff_db_loader` provides `rails uff_db_loader:dump` and `rails uff_db_loader:load` which will prompt for a configured environment.
47
- `dump` will only create and download a current database dump, while `load`, will do the same and restore the database content into a new database and gives instructions on how to use it in development.
48
-
48
+ `uff_db_loader` can be called like `bin/rails uff_db_loader:<task>` where `<task>` is one of the following:
49
49
 
50
+ - `dump`: Dumps a remote database from a selected environment and downloads it
51
+ - `restore`: Restores a downloaded dump into a local database
52
+ - `switch`: Selects a restored local database to use
53
+ - `load`: Dumps a remote database from a selected environment and downloads it then restores and selects the database
54
+ - `prune`: Delete all downloaded db dumps and removes all databases created by UffDbLoader
50
55
 
51
56
  ## Development
52
57
 
data/lib/configuration.rb CHANGED
@@ -8,7 +8,7 @@ module UffDbLoader
8
8
  attr_accessor :environments, :ssh_host, :ssh_user, :db_name, :db_system, :app_name, :dumps_directory, :database_config_file
9
9
 
10
10
  def initialize
11
- @environments = %w[staging production]
11
+ @environments = nil
12
12
  @ssh_host = nil
13
13
  @ssh_user = nil
14
14
  @db_name = nil
@@ -3,7 +3,21 @@
3
3
  require "tty-prompt"
4
4
 
5
5
  namespace :uff_db_loader do
6
- desc "Dumps a remote database to #{UffDbLoader.config.dumps_directory}"
6
+ desc "Set up UffDbLoader"
7
+ task install: :environment do
8
+ UffDbLoader.create_initializer
9
+
10
+ puts "👶 Created a Rails initializer file at #{UffDbLoader.initializer_path}."
11
+
12
+ if UffDbLoader.setup_dynamic_database_name_in_config
13
+ puts "🤖 Updated #{UffDbLoader.config.database_config_file}. Happy hacking, beep boop!"
14
+ else
15
+ puts "💩 Because YAML is a wonderful format, you need to adapt your config file by hand."
16
+ puts "🆗 Go to #{UffDbLoader.config.database_config_file} and change the development database value to: #{UffDbLoader.database_name_template("default_database_name")}"
17
+ end
18
+ end
19
+
20
+ desc "Dumps a remote database from a selected environment to #{UffDbLoader.config.dumps_directory}"
7
21
  task dump: :environment do
8
22
  prompt = TTY::Prompt.new
9
23
  environment = prompt.select("Which environment should we get the dump from?", UffDbLoader.config.environments)
@@ -11,8 +25,35 @@ namespace :uff_db_loader do
11
25
  UffDbLoader.dump_from(environment)
12
26
  end
13
27
 
14
- desc "Gets a dump from remote and loads it into the local database"
28
+ desc "Restores a downloaded dump into a local database"
29
+ task restore: :environment do
30
+ UffDbLoader.ensure_installation!
31
+
32
+ prompt = TTY::Prompt.new
33
+ existing_dumps = Dir.glob("#{UffDbLoader.config.dumps_directory}/#{UffDbLoader.config.app_name}*").map { |f| File.basename(f, ".*") }
34
+ database_name = prompt.select("Which dump should be restored?", existing_dumps)
35
+
36
+ UffDbLoader.load_dump_into_database(database_name)
37
+ end
38
+
39
+ desc "Selects a restored local database to use"
40
+ task switch: :environment do
41
+ UffDbLoader.ensure_installation!
42
+
43
+ prompt = TTY::Prompt.new
44
+ databases = UffDbLoader.databases
45
+ new_database = prompt.select("Which database do you want to switch to?", databases)
46
+
47
+ UffDbLoader.remember_database_name(new_database)
48
+ UffDbLoader.restart_rails_server
49
+
50
+ puts "♻️ Restarted rails server with new database."
51
+ end
52
+
53
+ desc "Dumps a remote database from a selected environment to #{UffDbLoader.config.dumps_directory}, then restores and selects the database"
15
54
  task load: :environment do
55
+ UffDbLoader.ensure_installation!
56
+
16
57
  prompt = TTY::Prompt.new
17
58
  environment = prompt.select("Which environment should we get the dump from?", UffDbLoader.config.environments)
18
59
  UffDbLoader.ensure_valid_environment!(environment)
@@ -21,27 +62,15 @@ namespace :uff_db_loader do
21
62
  puts "🤓 Reading from to #{result_file_path}"
22
63
 
23
64
  database_name = File.basename(result_file_path, ".*")
24
- UffDbLoader.create_database(database_name)
25
-
26
- puts "🗂 Created database #{database_name}"
27
-
28
- command_successful = system(UffDbLoader.restore_command(database_name, result_file_path))
29
- raise "Command did not run succesful: #{UffDbLoader.restore_command(database_name, result_file_path)}" unless command_successful
30
-
31
- puts "✅ Succesfully loaded #{result_file_path} into #{database_name}"
32
-
33
- if UffDbLoader.replace_database_name_in_config(database_name)
34
- system("bin/rails restart")
35
- puts "🤖 Updated #{UffDbLoader.config.database_config_file} and restarted the rails server. Happy hacking, beep boop!"
36
- else
37
- puts "💩 Because YAML is a wonderful format, you need to adapt your config file by hand."
38
- puts "🆗 Go to #{UffDbLoader.config.database_config_file} and change the development database value to: #{database_name}"
39
- puts "🧑🏾‍🏫 Don't forgot to restart the Rails server after changing the database config (`rails restart`)"
40
- end
65
+ UffDbLoader.load_dump_into_database(database_name)
41
66
  end
42
67
 
43
- desc "Delete all downloaded db dumps and emove all databases created by UffDbLoader"
68
+ desc "Delete all downloaded db dumps and removes all databases created by UffDbLoader"
44
69
  task prune: :environment do
70
+ # switch to default db so we can also drop the currently connected database
71
+ UffDbLoader.remember_database_name("")
72
+ ActiveRecord::Base.connection.reconnect!
73
+
45
74
  UffDbLoader.databases.each do |database_name|
46
75
  puts "Dropping #{database_name}"
47
76
  UffDbLoader.drop_database(database_name)
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Check out our README: https://github.com/rmehner/uff_db_loader/blob/main/README.md
4
+
5
+ if defined?(UffDbLoader)
6
+ UffDbLoader.configure do |config|
7
+ config.ssh_user = 'SSH_USER'
8
+ config.ssh_host = 'HOST_OF_YOUR_SITE'
9
+ config.db_name = 'YOUR_DATABASE_NAME'
10
+ config.db_system = <%= used_database_system %> # Possible values are :postgresql and :mysql
11
+ config.environments = <%= environments %>
12
+
13
+ # Optional settings:
14
+ # config.app_name = 'my_app' # Defaults to the Rails app name
15
+ # config.dumps_directory = '/path/to/dumps' # Defaults to Rails.root.join('dumps')
16
+ # config.database_config_file = 'path/to/database.yml' # Defaults to Rails.root.join('config', 'database.yml')
17
+ end
18
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module UffDbLoader
4
- VERSION = "1.3.0"
4
+ VERSION = "2.0.0"
5
5
  end
data/lib/uff_db_loader.rb CHANGED
@@ -6,91 +6,183 @@ require "configuration"
6
6
  module UffDbLoader
7
7
  require "railtie"
8
8
 
9
- def self.config
10
- @configuration ||= Configuration.new
11
- end
9
+ class << self
10
+ def config
11
+ @configuration ||= Configuration.new
12
+ end
12
13
 
13
- def self.reset
14
- @configuration = Configuration.new
15
- end
14
+ def reset
15
+ @configuration = Configuration.new
16
+ end
16
17
 
17
- def self.configure
18
- yield(config)
19
- end
18
+ def configure
19
+ yield(config)
20
+ end
20
21
 
21
- def self.dump_filename(environment)
22
- File.join(
23
- config.dumps_directory,
24
- Time.now.strftime("#{config.app_name}_#{environment}_%Y_%m_%d_%H_%M_%S.#{config.database_system.dump_extension}")
25
- )
26
- end
22
+ def restart_rails_server
23
+ system("bin/rails restart")
24
+ end
27
25
 
28
- def self.dump_from(environment)
29
- FileUtils.mkdir_p(config.dumps_directory)
26
+ def dump_from(environment)
27
+ FileUtils.mkdir_p(config.dumps_directory)
30
28
 
31
- puts "⬇️ Creating dump ..."
29
+ puts "⬇️ Creating dump ..."
32
30
 
33
- target = dump_filename(environment)
31
+ target = dump_file_path(Time.now.strftime("#{config.app_name}_#{environment}_%Y_%m_%d_%H_%M_%S)"))
34
32
 
35
- command_successful = system(dump_command(environment, target))
36
- raise "Command did not run succesful: #{dump_command(environment, target)}" unless command_successful
33
+ command_successful = system(dump_command(environment, target))
34
+ raise "Command did not run succesful: #{dump_command(environment, target)}" unless command_successful
37
35
 
38
- puts "✅ Succesfully dumped to #{target}"
36
+ puts "✅ Succesfully dumped to #{target}"
39
37
 
40
- target
41
- end
38
+ target
39
+ end
42
40
 
43
- def self.create_database(database_name)
44
- config.database_system.create_database(database_name)
45
- end
41
+ def ensure_valid_environment!(environment)
42
+ unless config.environments.include?(environment)
43
+ raise ForbiddenEnvironmentError, "Invalid environment: #{environment}."
44
+ end
45
+ end
46
46
 
47
- def self.dump_command(environment, target)
48
- config
49
- .database_system
50
- .dump_command_template
51
- .gsub("%environment%", environment)
52
- .gsub("%host%", config.ssh_host)
53
- .gsub("%user%", config.ssh_user)
54
- .gsub("%database%", config.database)
55
- .gsub("%target%", target)
56
- .gsub("%app_name%", config.app_name)
57
- end
47
+ def prune_dump_directory
48
+ FileUtils.rm_rf("#{config.dumps_directory}/.", secure: true)
49
+ end
58
50
 
59
- def self.ensure_valid_environment!(environment)
60
- unless config.environments.include?(environment)
61
- raise ForbiddenEnvironmentError, "Invalid environment: #{environment}."
51
+ def create_database(database_name)
52
+ config.database_system.create_database(database_name)
62
53
  end
63
- end
64
54
 
65
- def self.restore_command(database_name, result_file_path)
66
- config.database_system.restore_command(database_name, result_file_path)
67
- end
55
+ def drop_database(database_name)
56
+ config.database_system.drop_database(database_name)
57
+ end
68
58
 
69
- def self.prune_dump_directory
70
- FileUtils.rm_rf("#{config.dumps_directory}/.", secure: true)
71
- end
59
+ def databases
60
+ config.database_system.list_databases.select do |line|
61
+ line =~ /#{config.app_name}_(#{config.environments.join("|")})_(\d|_)+/
62
+ end
63
+ end
72
64
 
73
- def self.drop_database(database_name)
74
- config.database_system.drop_database(database_name)
75
- end
65
+ def setup_dynamic_database_name_in_config
66
+ old_database_name = Rails.configuration.database_configuration["development"]["database"]
67
+
68
+ return false if old_database_name.nil?
76
69
 
77
- def self.databases
78
- config.database_system.list_databases.select do |line|
79
- line =~ /#{config.app_name}_(#{config.environments.join("|")})_(\d|_)+/
70
+ old_config = File.read(UffDbLoader.config.database_config_file)
71
+ new_config = old_config.sub(old_database_name, database_name_template(old_database_name))
72
+ File.write(UffDbLoader.config.database_config_file, new_config)
80
73
  end
81
- end
82
74
 
83
- def self.replace_database_name_in_config(new_database_name)
84
- old_database_name = Rails.configuration.database_configuration["development"]["database"]
75
+ def current_database_name
76
+ File.read(database_name_file).strip.presence
77
+ rescue IOError, Errno::ENOENT => e
78
+ puts "Could not read #{database_name_file}. #{e.message} – Falling back to default database. 🥱"
79
+ end
85
80
 
86
- return false if old_database_name.nil?
81
+ def remember_database_name(database_name)
82
+ File.write(database_name_file, database_name)
83
+ end
87
84
 
88
- old_config = File.read(UffDbLoader.config.database_config_file)
89
- new_config = old_config.sub(old_database_name, new_database_name)
90
- File.write(UffDbLoader.config.database_config_file, new_config)
91
- end
85
+ def ensure_installation!
86
+ unless File.read(UffDbLoader.config.database_config_file).include?("UffDbLoader.current_database_name")
87
+ raise InstallationDidNotRunError, "Please run bin/rails uff_db_loader:install"
88
+ end
89
+ end
90
+
91
+ def load_dump_into_database(database_name)
92
+ UffDbLoader.drop_database(database_name)
93
+ UffDbLoader.create_database(database_name)
94
+
95
+ puts "🗂 Created database #{database_name}"
96
+
97
+ dump_file_path = dump_file_path(database_name)
92
98
 
93
- class ForbiddenEnvironmentError < StandardError; end
99
+ command_successful = system(restore_command(database_name, dump_file_path))
100
+ raise "Command did not run succesful: #{restore_command(database_name, dump_file_path)}" unless command_successful
94
101
 
95
- class UnknownDatabaseSystem < StandardError; end
102
+ puts "✅ Succesfully loaded #{dump_file_path} into #{database_name}"
103
+
104
+ remember_database_name(database_name)
105
+ restart_rails_server
106
+
107
+ puts "♻️ Restarted rails server with new database."
108
+ end
109
+
110
+ def initializer_path
111
+ File.join(__dir__, "uff_db_loader", "templates", "uff_db_loader_initializer.erb")
112
+ end
113
+
114
+ def create_initializer
115
+ template = ERB.new(File.read(initializer_path))
116
+
117
+ File.write(
118
+ Rails.root.join("config", "initializers", "uff_db_loader.rb"),
119
+ template.result_with_hash(
120
+ used_database_system: used_database_system,
121
+ environments: environments
122
+ )
123
+ )
124
+ end
125
+
126
+ private
127
+
128
+ def database_name_file
129
+ Rails.root.join("tmp", "uff_db_loader_database_name")
130
+ end
131
+
132
+ def dump_filename(environment)
133
+ File.join(
134
+ config.dumps_directory,
135
+ Time.now.strftime("#{config.app_name}_#{environment}_%Y_%m_%d_%H_%M_%S.#{config.database_system.dump_extension}")
136
+ )
137
+ end
138
+
139
+ def dump_command(environment, target)
140
+ config
141
+ .database_system
142
+ .dump_command_template
143
+ .gsub("%environment%", environment)
144
+ .gsub("%host%", config.ssh_host)
145
+ .gsub("%user%", config.ssh_user)
146
+ .gsub("%database%", config.database)
147
+ .gsub("%target%", target)
148
+ .gsub("%app_name%", config.app_name)
149
+ end
150
+
151
+ def restore_command(database_name, result_file_path)
152
+ config.database_system.restore_command(database_name, result_file_path)
153
+ end
154
+
155
+ def database_name_template(old_database_name)
156
+ "<%= defined?(UffDbLoader) && UffDbLoader.current_database_name || '#{old_database_name}' %>"
157
+ end
158
+
159
+ def dump_file_path(database_name)
160
+ File.join(
161
+ config.dumps_directory,
162
+ "#{database_name}.#{config.database_system.dump_extension}"
163
+ )
164
+ end
165
+
166
+ def used_database_system
167
+ case Rails.configuration.database_configuration["development"]["adapter"]
168
+ when "mysql", "mysql2", "trilogy"
169
+ ":mysql"
170
+ when "postgresql"
171
+ ":postgresql"
172
+ else
173
+ puts "🙃 Could not automatically determine your used database system. Please adapt in the initializer."
174
+ ":unknown"
175
+ end
176
+ end
177
+
178
+ def environments
179
+ ActiveRecord::Base.configurations.configurations.to_a.map(&:env_name) - ["test", "development"]
180
+ end
181
+
182
+ class ForbiddenEnvironmentError < StandardError; end
183
+
184
+ class UnknownDatabaseSystem < StandardError; end
185
+
186
+ class InstallationDidNotRunError < StandardError; end
187
+ end
96
188
  end
@@ -8,6 +8,7 @@ Gem::Specification.new do |spec|
8
8
 
9
9
  spec.summary = "Allows to dump, download and restore databases from docker servers."
10
10
  spec.description = "Allows to dump, download and restore databases from servers with a specific docker setup, that UFF uses commonly."
11
+ spec.post_install_message = "Please run `bin/rails uff_db_loader:install` to complete the installation."
11
12
  spec.homepage = "https://github.com/rmehner/uff_db_loader"
12
13
  spec.license = "MIT"
13
14
  spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0")
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uff_db_loader
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andreas Hellwig
8
8
  - Fynn Heintz
9
9
  - Robin Mehner
10
- autorequire:
10
+ autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2022-08-25 00:00:00.000000000 Z
13
+ date: 2022-09-29 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: tty-prompt
@@ -79,8 +79,8 @@ files:
79
79
  - lib/uff_db_loader.rb
80
80
  - lib/uff_db_loader/mysql.rb
81
81
  - lib/uff_db_loader/postgresql.rb
82
- - lib/uff_db_loader/tasks/remote_database.rake
83
82
  - lib/uff_db_loader/tasks/uff_db_loader.rake
83
+ - lib/uff_db_loader/templates/uff_db_loader_initializer.erb
84
84
  - lib/uff_db_loader/version.rb
85
85
  - uff_db_loader.gemspec
86
86
  homepage: https://github.com/rmehner/uff_db_loader
@@ -88,10 +88,11 @@ licenses:
88
88
  - MIT
89
89
  metadata:
90
90
  bug_tracker_uri: https://github.com/rmehner/uff_db_loader/issues
91
- changelog_uri: https://github.com/rmehner/uff_db_loader/releases/tag/1.3.0
91
+ changelog_uri: https://github.com/rmehner/uff_db_loader/releases/tag/2.0.0
92
92
  homepage_uri: https://github.com/rmehner/uff_db_loader
93
- source_code_uri: https://github.com/rmehner/uff_db_loader/tree/1.3.0
94
- post_install_message:
93
+ source_code_uri: https://github.com/rmehner/uff_db_loader/tree/2.0.0
94
+ post_install_message: Please run `bin/rails uff_db_loader:install` to complete the
95
+ installation.
95
96
  rdoc_options: []
96
97
  require_paths:
97
98
  - lib
@@ -106,8 +107,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
107
  - !ruby/object:Gem::Version
107
108
  version: '0'
108
109
  requirements: []
109
- rubygems_version: 3.0.3
110
- signing_key:
110
+ rubygems_version: 3.3.8
111
+ signing_key:
111
112
  specification_version: 4
112
113
  summary: Allows to dump, download and restore databases from docker servers.
113
114
  test_files: []
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "tty-prompt"
4
-
5
- namespace :remote_database do
6
- desc "Dumps a remote database to #{UffDbLoader.config.dumps_directory}"
7
- task dump: :environment do
8
- puts "🧐 Please note this task is called 'uff_db_loader:dump' now."
9
- Rake::Task["uff_db_loader:dump"].invoke
10
- end
11
-
12
- desc "Gets a dump from remote and loads it into the local database"
13
- task load: :environment do
14
- puts "🧐 Please note this task is called 'uff_db_loader:load' now."
15
- Rake::Task["uff_db_loader:load"].invoke
16
- end
17
-
18
- desc "Delete all downloaded db dumps and emove all databases created by UffDbLoader"
19
- task prune: :environment do
20
- puts "🧐 Please note this task is called 'uff_db_loader:prune' now."
21
- Rake::Task["uff_db_loader:prune"].invoke
22
- end
23
- end