branch_db 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8a44bc87f28c22ce64d6203b277410bca8c1b5d700d6985023cda0f759057b83
4
- data.tar.gz: f801399f3ba42bd476428c96f64412fc51d2705c05ab2762dbb5d219cc96babc
3
+ metadata.gz: b89c858576fe083b0a57357468a32253f332a639ca96386ecfe5e740fdbb5359
4
+ data.tar.gz: e454deaba31ed922ecef875a625c5d17c72c2428e90efb214981efde90196c07
5
5
  SHA512:
6
- metadata.gz: 0e0f292f72bb117d603377611f6f09d0849a01b2a14658b1113331c0646c22323775dafacd437727f3136fa5e13a6536043e7b03cce3c4061ebec76f1f9b01c1
7
- data.tar.gz: ac74c3bd8eee25af6139b29cec4ed0071621c04f02dbb4c94316bfe855053272fd6ec820da281249cdc36aee5327268d3e56eddd3f7be5324926552c824ff623
6
+ metadata.gz: 21a0fcd375d2fdba1b9f3c2ce6829b6b539f8615cd292bf443eabd515cea4908b3b6df3c535578939e87acee063fd9905097e74a217745d006722fa23dc1577c
7
+ data.tar.gz: eb0a1722a367714346d82886c695bfbb734b195a8062c4bf5d97b207e635227dd0378488c4c2a1a88b23b01f2d3f2ff3372b960b7e0f2e94cfdccdb9459fdfaf
data/Appraisals ADDED
@@ -0,0 +1,24 @@
1
+ appraise "rails-7-0" do
2
+ gem "railties", "~> 7.0.0"
3
+ gem "activerecord", "~> 7.0.0"
4
+ end
5
+
6
+ appraise "rails-7-1" do
7
+ gem "railties", "~> 7.1.0"
8
+ gem "activerecord", "~> 7.1.0"
9
+ end
10
+
11
+ appraise "rails-7-2" do
12
+ gem "railties", "~> 7.2.0"
13
+ gem "activerecord", "~> 7.2.0"
14
+ end
15
+
16
+ appraise "rails-8-0" do
17
+ gem "railties", "~> 8.0.0"
18
+ gem "activerecord", "~> 8.0.0"
19
+ end
20
+
21
+ appraise "rails-8-1" do
22
+ gem "railties", "~> 8.1.0"
23
+ gem "activerecord", "~> 8.1.0"
24
+ end
data/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.2] - 2026-01-26
4
+
5
+ ### Fixed
6
+
7
+ - Fixed `main_database_name` to truncate the branch name to the configured length
8
+ - Fixed parent branch detection to find the original parent instead of the most recent checkout
9
+
10
+ ### Changed
11
+
12
+ - Refactored internal modules for improved code quality
13
+
3
14
  ## [0.1.1] - 2026-01-18
4
15
 
5
16
  ### Fixed
data/README.md CHANGED
@@ -43,6 +43,8 @@ git status
43
43
  # Run db:migrate? Schema.rb still shows the foreign column
44
44
  ```
45
45
 
46
+ More complex migrations could cause the code to stop working like renaming tables, adding foreign keys, or removing columns!
47
+
46
48
  ## The Solution
47
49
 
48
50
  BranchDb automatically manages separate databases for each branch:
@@ -78,14 +80,14 @@ Update your `config/database.yml`:
78
80
  ```yaml
79
81
  development:
80
82
  <<: *default
81
- database: <%= defined?(BranchDb) ? BranchDb.database_name('myapp_development') : 'myapp_development' %>
83
+ database: <%= BranchDb.database_name('myapp_development') rescue 'myapp_development' %>
82
84
 
83
85
  test:
84
86
  <<: *default
85
- database: <%= defined?(BranchDb) ? BranchDb.database_name('myapp_test') : 'myapp_test' %>
87
+ database: <%= BranchDb.database_name('myapp_test') rescue 'myapp_test' %>
86
88
  ```
87
89
 
88
- > **Note:** The `defined?(BranchDb)` guard ensures production/staging environments work correctly since the gem is only loaded in development/test. Replace `myapp` with your application name.
90
+ > **Note:** The `rescue` fallback ensures production/staging environments work correctly since the gem is only loaded in development/test. Replace `myapp` with your application name.
89
91
 
90
92
  Initialize your first branch database:
91
93
 
@@ -0,0 +1,16 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 7.0.0"
6
+ gem "irb"
7
+ gem "rake", "~> 13.0"
8
+ gem "rspec", "~> 3.0"
9
+ gem "rubocop", "~> 1.21"
10
+ gem "rubocop-rake", "~> 0.7.1"
11
+ gem "rubocop-rspec", "~> 3.9"
12
+ gem "simplecov", "~> 0.22", require: false
13
+ gem "appraisal", "~> 2.5"
14
+ gem "railties", "~> 7.0.0"
15
+
16
+ gemspec path: "../"
@@ -0,0 +1,16 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 7.1.0"
6
+ gem "irb"
7
+ gem "rake", "~> 13.0"
8
+ gem "rspec", "~> 3.0"
9
+ gem "rubocop", "~> 1.21"
10
+ gem "rubocop-rake", "~> 0.7.1"
11
+ gem "rubocop-rspec", "~> 3.9"
12
+ gem "simplecov", "~> 0.22", require: false
13
+ gem "appraisal", "~> 2.5"
14
+ gem "railties", "~> 7.1.0"
15
+
16
+ gemspec path: "../"
@@ -0,0 +1,16 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 7.2.0"
6
+ gem "irb"
7
+ gem "rake", "~> 13.0"
8
+ gem "rspec", "~> 3.0"
9
+ gem "rubocop", "~> 1.21"
10
+ gem "rubocop-rake", "~> 0.7.1"
11
+ gem "rubocop-rspec", "~> 3.9"
12
+ gem "simplecov", "~> 0.22", require: false
13
+ gem "appraisal", "~> 2.5"
14
+ gem "railties", "~> 7.2.0"
15
+
16
+ gemspec path: "../"
@@ -0,0 +1,16 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 8.0.0"
6
+ gem "irb"
7
+ gem "rake", "~> 13.0"
8
+ gem "rspec", "~> 3.0"
9
+ gem "rubocop", "~> 1.21"
10
+ gem "rubocop-rake", "~> 0.7.1"
11
+ gem "rubocop-rspec", "~> 3.9"
12
+ gem "simplecov", "~> 0.22", require: false
13
+ gem "appraisal", "~> 2.5"
14
+ gem "railties", "~> 8.0.0"
15
+
16
+ gemspec path: "../"
@@ -0,0 +1,16 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 8.1.0"
6
+ gem "irb"
7
+ gem "rake", "~> 13.0"
8
+ gem "rspec", "~> 3.0"
9
+ gem "rubocop", "~> 1.21"
10
+ gem "rubocop-rake", "~> 0.7.1"
11
+ gem "rubocop-rspec", "~> 3.9"
12
+ gem "simplecov", "~> 0.22", require: false
13
+ gem "appraisal", "~> 2.5"
14
+ gem "railties", "~> 8.1.0"
15
+
16
+ gemspec path: "../"
@@ -16,15 +16,13 @@ module BranchDb
16
16
  end
17
17
 
18
18
  def list_branch_databases
19
- dev_dbs = find_databases(dev_prefix)
20
- test_dbs = find_databases(test_prefix)
19
+ all_dbs = all_branch_databases
21
20
 
22
- if dev_dbs.empty? && test_dbs.empty?
21
+ if all_dbs.empty?
23
22
  log "No branch databases found#{db_label}."
24
23
  return []
25
24
  end
26
25
 
27
- all_dbs = dev_dbs + test_dbs
28
26
  log "Found #{all_dbs.size} branch database(s)#{db_label}:"
29
27
  all_dbs.each { |db| log " - #{db}" }
30
28
  all_dbs
@@ -40,6 +38,17 @@ module BranchDb
40
38
  done_msg: "Prune complete#{db_label}!", confirm:)
41
39
  end
42
40
 
41
+ private
42
+
43
+ def deletable_databases = all_branch_databases.reject { |db| protected_databases.include?(db) }
44
+
45
+ def prunable_databases
46
+ existing = BranchDb::Naming.git_branches.map { BranchDb::Naming.sanitize_branch(_1) }
47
+ all_branch_databases.reject { |db| protected_databases.include?(db) || branch_exists?(db, existing) }
48
+ end
49
+
50
+ def all_branch_databases = find_databases(dev_prefix) + find_databases(test_prefix)
51
+
43
52
  def protected_databases
44
53
  current_dev = config[:database]
45
54
  current_test = current_dev.sub(dev_prefix, test_prefix)
@@ -52,19 +61,6 @@ module BranchDb
52
61
  ]
53
62
  end
54
63
 
55
- private
56
-
57
- def deletable_databases
58
- all_branch_databases.reject { |db| protected_databases.include?(db) }
59
- end
60
-
61
- def prunable_databases
62
- existing = BranchDb::Naming.git_branches.map { BranchDb::Naming.sanitize_branch(_1) }
63
- all_branch_databases.reject { |db| protected_databases.include?(db) || branch_exists?(db, existing) }
64
- end
65
-
66
- def all_branch_databases = find_databases(dev_prefix) + find_databases(test_prefix)
67
-
68
64
  def branch_exists?(db, existing_branches)
69
65
  prefix = db.start_with?(test_prefix) ? test_prefix : dev_prefix
70
66
  existing_branches.include?(db.sub(prefix, ""))
@@ -21,20 +21,9 @@ module BranchDb
21
21
  database_exists?(source_db)
22
22
  end
23
23
 
24
- def source_db
25
- @source_db ||= determine_source_db
26
- end
27
-
28
- def target_db
29
- config[:database]
30
- end
31
-
32
- def base_name
33
- suffix = BranchDb::Naming.branch_suffix
34
- return target_db if suffix.empty?
24
+ def source_db = @source_db ||= determine_source_db
35
25
 
36
- target_db.sub(/#{Regexp.escape(suffix)}\z/, "")
37
- end
26
+ def target_db = config[:database]
38
27
 
39
28
  private
40
29
 
@@ -48,6 +37,13 @@ module BranchDb
48
37
  database_exists?(parent_db) ? parent_db : main_db
49
38
  end
50
39
 
40
+ def base_name
41
+ suffix = BranchDb::Naming.branch_suffix
42
+ return target_db if suffix.empty?
43
+
44
+ target_db.sub(/#{Regexp.escape(suffix)}\z/, "")
45
+ end
46
+
51
47
  def database_exists?(db_name)
52
48
  check_cmd = "#{list_databases_cmd} | grep -qx #{db_name.shellescape}"
53
49
  system(pg_env, "bash", "-c", check_cmd)
@@ -1,21 +1,15 @@
1
1
  module BranchDb
2
2
  module GitUtils
3
- def current_branch
4
- `git symbolic-ref HEAD 2>/dev/null`.chomp.sub("refs/heads/", "")
5
- end
3
+ def current_branch = `git symbolic-ref HEAD 2>/dev/null`.chomp.sub("refs/heads/", "")
6
4
 
7
5
  def git_branches
8
6
  output = `git branch --format='%(refname:short)' 2>/dev/null`
9
7
  output.split("\n").map(&:strip).reject(&:empty?)
10
8
  end
11
9
 
12
- def parent_branch
13
- @parent_branch ||= detect_parent_branch
14
- end
10
+ def parent_branch = @parent_branch ||= detect_parent_branch
15
11
 
16
- def reset_parent_cache!
17
- @parent_branch = nil
18
- end
12
+ def reset_parent_cache! = @parent_branch = nil
19
13
 
20
14
  private
21
15
 
@@ -29,11 +23,9 @@ module BranchDb
29
23
  current = current_branch
30
24
  return nil if current.empty?
31
25
 
32
- `git reflog show --format='%gs' -n 100 2>/dev/null`.each_line do |line|
33
- parent = extract_parent_from_reflog_line(line.chomp, current)
34
- return parent if parent
35
- end
36
- nil
26
+ `git reflog show --format='%gs' -n 1000 2>/dev/null`.each_line.filter_map do |line|
27
+ extract_parent_from_reflog_line(line.chomp, current)
28
+ end.last
37
29
  end
38
30
 
39
31
  def extract_parent_from_reflog_line(line, current)
@@ -4,13 +4,9 @@ module BranchDb
4
4
 
5
5
  private
6
6
 
7
- def log(message)
8
- output.puts prefix? ? "#{PREFIX} #{message}" : message
9
- end
7
+ def log(message) = output.puts prefix? ? "#{PREFIX} #{message}" : message
10
8
 
11
- def log_indented(message)
12
- output.puts prefix? ? "#{PREFIX} #{message}" : " #{message}"
13
- end
9
+ def log_indented(message) = output.puts prefix? ? "#{PREFIX} #{message}" : " #{message}"
14
10
 
15
11
  def prefix? = @prefix != false
16
12
  end
@@ -3,22 +3,22 @@ module BranchDb
3
3
  extend GitUtils
4
4
 
5
5
  class << self
6
- def sanitize_branch(branch)
7
- branch.gsub(/[^a-zA-Z0-9_]/, "_")
8
- end
6
+ def main_database_name(base_name) = "#{base_name}#{suffix_for(BranchDb.configuration.main_branch)}"
7
+
8
+ def database_name(base_name) = "#{base_name}#{branch_suffix}"
9
+
10
+ def branch_suffix = suffix_for(current_branch)
9
11
 
10
- def branch_suffix
11
- branch = sanitize_branch(current_branch)
12
+ def suffix_for(branch)
13
+ branch = sanitize_branch(branch)
12
14
  max_length = BranchDb.configuration.max_branch_length
13
15
  truncated = branch[0, max_length]
14
16
  truncated.empty? ? "" : "_#{truncated}"
15
17
  end
16
18
 
17
- def database_name(base_name) = "#{base_name}#{branch_suffix}"
18
-
19
- def main_database_name(base_name) = "#{base_name}_#{BranchDb.configuration.main_branch}"
20
-
21
19
  def parent_database_name(base_name) = "#{base_name}_#{sanitize_branch(parent_branch)}"
20
+
21
+ def sanitize_branch(branch) = branch.gsub(/[^a-zA-Z0-9_]/, "_")
22
22
  end
23
23
  end
24
24
  end
@@ -14,13 +14,9 @@ module BranchDb
14
14
  "-h #{host} -p #{port} -U #{username}"
15
15
  end
16
16
 
17
- def pg_env
18
- { "PGPASSWORD" => config[:password].to_s }
19
- end
17
+ def pg_env = { "PGPASSWORD" => config[:password].to_s }
20
18
 
21
- def list_databases_cmd
22
- "psql #{psql_flags} -lqt | cut -d \\| -f 1 | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'"
23
- end
19
+ def list_databases_cmd = "psql #{psql_flags} -lqt | cut -d \\| -f 1 | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'"
24
20
 
25
21
  def check_pg_tools!(*tools)
26
22
  tools = PG_TOOLS if tools.empty?
@@ -24,13 +24,9 @@ module BranchDb
24
24
 
25
25
  private
26
26
 
27
- def config
28
- db_config.configuration_hash
29
- end
27
+ def config = db_config.configuration_hash
30
28
 
31
- def db_label
32
- db_config.name == "primary" ? "" : " (#{db_config.name})"
33
- end
29
+ def db_label = db_config.name == "primary" ? "" : " (#{db_config.name})"
34
30
 
35
31
  def needs_cloning?
36
32
  establish_connection
@@ -39,9 +35,7 @@ module BranchDb
39
35
  true
40
36
  end
41
37
 
42
- def establish_connection
43
- ActiveRecord::Base.establish_connection(db_config)
44
- end
38
+ def establish_connection = ActiveRecord::Base.establish_connection(db_config)
45
39
 
46
40
  def attempt_clone
47
41
  cloner = Cloner.new(config, output:)
@@ -1,3 +1,3 @@
1
1
  module BranchDb
2
- VERSION = "0.1.1".freeze
2
+ VERSION = "0.1.2".freeze
3
3
  end
data/lib/branch_db.rb CHANGED
@@ -13,20 +13,12 @@ module BranchDb
13
13
  class Error < StandardError; end
14
14
 
15
15
  class << self
16
- def configuration
17
- @configuration ||= Configuration.new
18
- end
16
+ def configuration = @configuration ||= Configuration.new
19
17
 
20
- def configure
21
- yield(configuration)
22
- end
18
+ def configure = yield(configuration)
23
19
 
24
- def database_name(base_name)
25
- Naming.database_name(base_name)
26
- end
20
+ def database_name(base_name) = Naming.database_name(base_name)
27
21
 
28
- def main_database_name(base_name)
29
- Naming.main_database_name(base_name)
30
- end
22
+ def main_database_name(base_name) = Naming.main_database_name(base_name)
31
23
  end
32
24
  end
@@ -19,10 +19,10 @@ module BranchDb
19
19
  say "1. Update your config/database.yml to use dynamic database names:"
20
20
  say ""
21
21
  say " development:"
22
- say " database: <%= BranchDb.database_name('#{app_name}_development') %>"
22
+ say " database: <%= BranchDb.database_name('#{app_name}_development') rescue '#{app_name}_development' %>"
23
23
  say ""
24
24
  say " test:"
25
- say " database: <%= BranchDb.database_name('#{app_name}_test') %>"
25
+ say " database: <%= BranchDb.database_name('#{app_name}_test') rescue '#{app_name}_test' %>"
26
26
  say ""
27
27
  say "2. Initialize your database:"
28
28
  say " rails db:prepare # Creates and clones from main"
@@ -36,8 +36,6 @@ module BranchDb
36
36
 
37
37
  private
38
38
 
39
- def app_name
40
- Rails.application.class.module_parent_name.underscore
41
- end
39
+ def app_name = Rails.application.class.module_parent_name.underscore
42
40
  end
43
41
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: branch_db
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ali Hamdi Ali Fadel
@@ -31,10 +31,16 @@ executables: []
31
31
  extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
+ - Appraisals
34
35
  - CHANGELOG.md
35
36
  - LICENSE.txt
36
37
  - README.md
37
38
  - Rakefile
39
+ - gemfiles/rails_7_0.gemfile
40
+ - gemfiles/rails_7_1.gemfile
41
+ - gemfiles/rails_7_2.gemfile
42
+ - gemfiles/rails_8_0.gemfile
43
+ - gemfiles/rails_8_1.gemfile
38
44
  - lib/branch_db.rb
39
45
  - lib/branch_db/cleaner.rb
40
46
  - lib/branch_db/cloner.rb