trx_ext 1.0.6 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +1 -1
  3. data/.ruby-version +1 -1
  4. data/CHANGELOG.md +10 -2
  5. data/Gemfile +20 -3
  6. data/README.md +39 -15
  7. data/bin/console +0 -9
  8. data/bin/rails +9 -0
  9. data/bin/test_all_ar_versions +1 -1
  10. data/docker/my.cnf +13 -0
  11. data/docker/mysqld.sh +22 -0
  12. data/docker-compose.yml +14 -2
  13. data/dummy_app/.gitattributes +7 -0
  14. data/dummy_app/.gitignore +38 -0
  15. data/dummy_app/README.md +24 -0
  16. data/dummy_app/Rakefile +6 -0
  17. data/dummy_app/app/controllers/application_controller.rb +2 -0
  18. data/dummy_app/app/models/application_mysql_record.rb +7 -0
  19. data/dummy_app/app/models/application_pg_record.rb +7 -0
  20. data/dummy_app/app/models/application_sqlite_record.rb +7 -0
  21. data/dummy_app/app/models/application_trilogy_record.rb +7 -0
  22. data/dummy_app/app/models/dummy_mysql_record.rb +11 -0
  23. data/dummy_app/app/models/dummy_pg_record.rb +11 -0
  24. data/dummy_app/app/models/dummy_sqlite_record.rb +11 -0
  25. data/dummy_app/app/models/dummy_trilogy_record.rb +11 -0
  26. data/dummy_app/bin/bundle +109 -0
  27. data/dummy_app/bin/rails +4 -0
  28. data/dummy_app/bin/rake +4 -0
  29. data/dummy_app/bin/setup +33 -0
  30. data/dummy_app/config/application.rb +51 -0
  31. data/dummy_app/config/boot.rb +4 -0
  32. data/dummy_app/config/credentials.yml +0 -0
  33. data/dummy_app/config/database.yml +70 -0
  34. data/dummy_app/config/environment.rb +5 -0
  35. data/dummy_app/config/environments/development.rb +66 -0
  36. data/dummy_app/config/environments/test.rb +61 -0
  37. data/dummy_app/config/initializers/.keep +0 -0
  38. data/dummy_app/config/locales/en.yml +2 -0
  39. data/dummy_app/config/locales/fr-CH.yml +2 -0
  40. data/dummy_app/config/puma.rb +43 -0
  41. data/dummy_app/config/routes.rb +5 -0
  42. data/dummy_app/config.ru +6 -0
  43. data/dummy_app/db/migrate/.keep +0 -0
  44. data/dummy_app/db/migrate/20240128111549_create_dummy_record.rb +10 -0
  45. data/dummy_app/db/primary_mysql/20240128111549_create_dummy_mysql_record.rb +10 -0
  46. data/dummy_app/db/primary_sqlite/20240128111549_create_dummy_sqlite_record.rb +10 -0
  47. data/dummy_app/db/primary_trilogy/20240128111549_create_dummy_trilogy_record.rb +10 -0
  48. data/dummy_app/db/seeds.rb +7 -0
  49. data/dummy_app/lib/tasks/.keep +0 -0
  50. data/dummy_app/log/.keep +0 -0
  51. data/dummy_app/public/robots.txt +1 -0
  52. data/dummy_app/storage/.keep +0 -0
  53. data/dummy_app/tmp/.keep +0 -0
  54. data/dummy_app/vendor/.keep +0 -0
  55. data/lib/trx_ext/object_ext.rb +12 -7
  56. data/lib/trx_ext/retry.rb +14 -16
  57. data/lib/trx_ext/transaction.rb +1 -1
  58. data/lib/trx_ext/version.rb +1 -1
  59. data/lib/trx_ext.rb +18 -21
  60. data/trx_ext.gemspec +1 -7
  61. metadata +52 -94
  62. data/Dockerfile +0 -3
  63. data/bin/setup +0 -8
  64. data/lib/trx_ext/railtie.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0215abbca618956a55b181c88c6d1658ae5e12a0133f9797c0171b8b9f93e56e
4
- data.tar.gz: 47c9e6c5158adf4ef735de356de2fa613394546a056dde43c1e252873271b790
3
+ metadata.gz: d86c6295c4d141b3bcf938c95e8856cf390d5bd1a0454f81dfde3a135c35b9ff
4
+ data.tar.gz: d47c2e2425bf29d242824da94551acd8f44cb4489c811935ef5bd16169892544
5
5
  SHA512:
6
- metadata.gz: bd0d01be3aa27dff5752d91317101915db9e58ea1eb89adff6027bf43739328098d4dbd6c849be2f2c095f959fa2ded3c8d8338ee45e31931cc48f0066d641d2
7
- data.tar.gz: f21e6e927d86119a2d08dab98dce1a9acf2ed528e0773a9241c3dde75f429b2f643612efc6d67494e9c3ceb4c5eaa075d78b83ea98fa5c25a6f396e1b461debb
6
+ metadata.gz: 1dd474ef6d21fe8443b14b7d3d12a3af00c030d14ff45924cf5130495cd12e5e37b8890d6af9303100e7acf269564fce405b9f00848661079c4e2627735ccfe7
7
+ data.tar.gz: 98ea0710b3c50b96741511c50ce627b06e8d8a7e8701c53935db1696c7aec2e61db9474bfa4239f11aa15e2243a7754a7de1590d3e2a157a885d8e6f9b4d1d93
data/.rspec CHANGED
@@ -1,3 +1,3 @@
1
1
  --format Fivemat
2
- --require spec_helper
2
+ --require rails_helper
3
3
  --require fivemat
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.2.2
1
+ 3.3.0
data/CHANGELOG.md CHANGED
@@ -1,8 +1,16 @@
1
1
  ## [Unreleased]
2
2
 
3
- Nothing new yet
3
+ ## [2.0.0] - 2024-04-14
4
4
 
5
- ## [1.0.5] - 2022-01-27
5
+ - `trx_ext` now supports any adapter(except `mysql`; `mysql2` is supported though), supported by rails
6
+ - **Requirement is rails v7.1+ now**. This is because rails v7.1 introduced unification of connection adapters which allowed to implement the integration with all of them
7
+ - Support multiple databases configurations
8
+
9
+ ## [1.0.6] - 2023-08-25
10
+
11
+ - Refactoring the retry implementation
12
+
13
+ ## [1.0.5] - 2023-05-11
6
14
 
7
15
  - Load `Object` extension earlier
8
16
 
data/Gemfile CHANGED
@@ -5,12 +5,29 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in trx_ext.gemspec
6
6
  gemspec
7
7
 
8
- gem "rake", "~> 13.0"
9
-
10
8
  if ENV['AR_VERSION']
11
9
  # Given ENV['AR_VERSION'] to equal "6.0" will produce
12
10
  # ```ruby
13
11
  # gem 'activerecord', "~> 6.0", "< 6.1"
14
12
  # ```
15
- gem 'activerecord', "~> #{ENV['AR_VERSION']}", "< #{ENV['AR_VERSION'].next}"
13
+ gem 'rails', "~> #{ENV['AR_VERSION']}", "< #{ENV['AR_VERSION'].next}"
14
+ else
15
+ gem 'rails'
16
16
  end
17
+
18
+ gem "rake", "~> 13.0"
19
+ gem 'rspec', '~> 3.12'
20
+ gem 'timecop', '~> 0.9.8'
21
+ # To support postgresql adapter
22
+ gem 'pg', '~> 1.5', '>= 1.5.4'
23
+ # To support sqlite3 adapter
24
+ gem 'sqlite3', '~> 1.7', '>= 1.7.1'
25
+ # To support mysql2 adapter
26
+ gem 'mysql2', '~> 0.5.5'
27
+ # To support trilogy adapter
28
+ gem 'trilogy', '~> 2.8'
29
+ gem 'factory_bot_rails', '~> 6.4', '>= 6.4.3'
30
+ gem 'fivemat', '~> 1.3', '>= 1.3.7'
31
+ gem 'rspec-its', '~> 1.3'
32
+ gem "bootsnap", require: false
33
+ gem 'rspec-rails', '~> 6.0'
data/README.md CHANGED
@@ -1,20 +1,22 @@
1
1
  # TrxExt
2
2
 
3
- Extends functionality of ActiveRecord's transaction to auto-retry failed SQL transaction in case of deadlock, serialization error or unique constraint error. It also allows you to define `on_complete` callback that is being executed after SQL transaction is finished(either COMMIT-ed or ROLLBACK-ed).
3
+ Extends functionality of ActiveRecord's transaction to auto-retry failed SQL transaction in case of deadlock, serialization error or unique constraint error. It also allows you to define `on_complete` callback that is being executed after SQL transaction is finished(either COMMIT-ed or ROLLBACK-ed). The implementation is not bound to any database, but relies on the rails connection adapters instead. Thus, if your database is supported by rails out of the box, then the gem's features will just work. Currently supported adapters:
4
4
 
5
- Currently, the implementation only works for ActiveRecord PostgreSQL adapter. Feel free to improve it.
5
+ - `postgresql`
6
+ - `mysql2`
7
+ - `sqlite3`
8
+ - `trilogy`
6
9
 
7
10
  **WARNING!**
8
11
 
9
- Because the implementation of this gem is a patch for `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter` - carefully test its integration into your project. For example, if your project patches ActiveRecord or if some of your gems patches ActiveRecord - there might be conflicts in the implementation which could potentially lead to the data loss.
12
+ Because the implementation of this gem patches ActiveRecord - carefully test its integration into your project. For example, if your application patches ActiveRecord or if some of your gems patches ActiveRecord - there might be conflicts in the implementation which could potentially lead to the data loss.
10
13
 
11
- Currently, the implementation is tested for rails v6+.
14
+ Currently, the implementation is tested for rails v7.1+. **If you need the support of rails v6.0, v6.1, v7.0 - please use v1.x of this gem, but it works with PostgreSQL only.**
12
15
 
13
16
  ## Requirements
14
17
 
15
- - ActiveRecord 6+
18
+ - ActiveRecord 7.1+
16
19
  - Ruby 3
17
- - PostgreSQL 9.1+
18
20
 
19
21
  ## Installation
20
22
 
@@ -36,7 +38,6 @@ Or install it yourself as:
36
38
 
37
39
  ```ruby
38
40
  require 'trx_ext'
39
- require 'active_record'
40
41
 
41
42
  # Object#trx is a shorthand of ActiveRecord::Base.transaction
42
43
  trx do
@@ -66,6 +67,27 @@ class DummyRecord
66
67
  end
67
68
  ```
68
69
 
70
+ If you are using non-primary connection for your model - you have to explicitly call `trx` method over that class:
71
+
72
+ ```ruby
73
+ DummyRecord.trx do
74
+ DummyRecord.first || DummyRecord.create
75
+ end
76
+ ```
77
+ In general, you should know about this if you are using multi-databases configuration.
78
+
79
+ If you want to wrap some method into a transaction using `wrap_in_trx` outside the ActiveRecord model context, you can pass a model name as a second argument explicitly:
80
+
81
+ ```ruby
82
+ class MyAwesomeLib
83
+ # Wrap method in transaction
84
+ def some_method_with_quieries
85
+ DummyRecord.first || DummyRecord.create
86
+ end
87
+ wrap_in_trx :some_method_with_quieries, 'DummyRecord'
88
+ end
89
+ ```
90
+
69
91
  ## Configuration
70
92
 
71
93
  ```ruby
@@ -77,15 +99,11 @@ end
77
99
 
78
100
  ## How it works?
79
101
 
80
- Your either every single AR SQL query or whole AR transaction is retried whenever it throws deadlock error, serialization error or unique constraint error. In case of AR transaction - the block of code that the AR transaction belongs to is re-executed, thus the transaction is retried.
102
+ When an ActiveRecord SQL query fails due to deadlock error, serialization error or unique constraint error - it is automatically retried. In case of ActiveRecord transaction - the block of code the AR transaction belongs to is re-executed, thus the transaction query is retried.
81
103
 
82
104
  ## Rules you have to stick when using this gem
83
105
 
84
- > "Don't put more into a single transaction than needed for integrity purposes."
85
- >
86
- > — [PostgreSQL documentation]
87
-
88
- Since `ActiveRecord::ConnectionAdapters::PostgreSQLAdapter` is now patched with `TrxExt::Retry.with_retry_until_serialized`, there's no need to wrap every AR query in a `trx` block to ensure integrity. Wrap code in an explicit `trx` block if and only if it can or does produce two or more SQL queries *and* it is important to run those queries together atomically.
106
+ **Don't put into a single transaction more than needed for integrity purposes.**
89
107
 
90
108
  There is "On complete" feature that allows you to define callbacks(blocks of code) that will be executed after transaction is complete. See `On complete callbacks` section bellow for the docs. See `On complete callbacks integrity` section bellow to be aware about different situations with them.
91
109
 
@@ -583,8 +601,14 @@ end
583
601
 
584
602
  ### Setup
585
603
 
586
- - After checking out the repo, run `bin/setup` to install dependencies.
587
- - run docker-compose using `docker-compose up` command - it starts necessary services
604
+ - After checking out the repo, run `bundle install` to install dependencies.
605
+ - Run docker-compose using `docker-compose up` command - it starts necessary services
606
+ - Run next command to create dev and test databases:
607
+
608
+ ```shell
609
+ bundle exec rails db:create db:migrate
610
+ RAILS_ENV=test bundle exec rails db:migrate
611
+ ```
588
612
 
589
613
  Now you can run `bin/console` for an interactive prompt that will allow you to experiment.
590
614
 
data/bin/console CHANGED
@@ -13,14 +13,5 @@ require "trx_ext"
13
13
  # Pry.start
14
14
 
15
15
  require "irb"
16
- require "logger"
17
- require 'active_record'
18
- require_relative '../spec/support/config'
19
- require_relative '../spec/support/dummy_record'
20
-
21
- ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT)
22
- TrxExt.logger = ActiveSupport::Logger.new(STDOUT)
23
-
24
- DummyRecord.setup
25
16
 
26
17
  IRB.start(__FILE__)
data/bin/rails ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ Dir.chdir(File.expand_path("../dummy_app", __dir__))
4
+ ENV['BUNDLE_GEMFILE'] = "#{__dir__}/Gemfile"
5
+
6
+ APP_PATH = File.expand_path("../dummy_app/config/application", __dir__)
7
+ require_relative "../dummy_app/config/boot"
8
+
9
+ require "rails/commands"
@@ -2,7 +2,7 @@
2
2
 
3
3
  # frozen_string_literal: true
4
4
 
5
- %w[6.0 6.1 7.0].each do |ar_version|
5
+ %w[7.1].each do |ar_version|
6
6
  `rm Gemfile.lock`
7
7
  Process.waitpid(Kernel.spawn({ 'AR_VERSION' => ar_version }, "bundle install --quiet", close_others: true))
8
8
  Process.waitpid(Kernel.spawn({ 'AR_VERSION' => ar_version }, "rspec", close_others: true))
data/docker/my.cnf ADDED
@@ -0,0 +1,13 @@
1
+ [mysqld]
2
+ # Log General
3
+ general_log = 1
4
+ general_log_file = /var/log/mysql_general.log
5
+
6
+ # Log Error
7
+ log_error = /var/log/mysql_error.log
8
+
9
+ # Log Slow
10
+ slow_query_log = 1
11
+ slow_query_log_file = /var/log/mysql_slow_query.log
12
+ long_query_time = 0 # 0 has the effect of logging all queries
13
+ log_queries_not_using_indexes = 1
data/docker/mysqld.sh ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ##
5
+ # This script exists to work-around the fact that
6
+ # mysql does not support logging to stdout
7
+ #
8
+ # This will tail the file logs configured in ./my.cnf
9
+ ##
10
+
11
+ LOG_PATHS=(
12
+ '/var/log/mysql_general.log'
13
+ '/var/log/mysql_error.log'
14
+ '/var/log/mysql_slow_query.log'
15
+ )
16
+ for LOG_PATH in "${LOG_PATHS[@]}"; do
17
+ # https://serverfault.com/a/599209
18
+ ( umask 0 && truncate -s0 "$LOG_PATH" )
19
+ tail --pid $$ -n0 -F "$LOG_PATH" &
20
+ done
21
+
22
+ docker-entrypoint.sh mysqld
data/docker-compose.yml CHANGED
@@ -2,9 +2,21 @@ version: "3.5"
2
2
 
3
3
  services:
4
4
  postgres:
5
- image: trx_ext/postgres
6
- build: .
5
+ image: postgres:16
6
+ command: ["postgres", "-c", "log_statement=all", "-c", "default_transaction_isolation=serializable"]
7
7
  ports:
8
8
  - 5532:5432
9
9
  environment:
10
10
  - POSTGRES_PASSWORD=postgres
11
+ mysql:
12
+ image: mysql:8.3
13
+ command:
14
+ - /usr/local/bin/mysqld.sh
15
+ volumes:
16
+ - ./docker/my.cnf:/etc/mysql/conf.d/my.cnf
17
+ - ./docker/mysqld.sh:/usr/local/bin/mysqld.sh
18
+ ports:
19
+ - 3406:3306
20
+ - 34060:33060
21
+ environment:
22
+ - MYSQL_ALLOW_EMPTY_PASSWORD=true
@@ -0,0 +1,7 @@
1
+ # See https://git-scm.com/docs/gitattributes for more about git attribute files.
2
+
3
+ # Mark the database schema as having been generated.
4
+ db/schema.rb linguist-generated
5
+
6
+ # Mark any vendored files as having been vendored.
7
+ vendor/* linguist-vendored
@@ -0,0 +1,38 @@
1
+ # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile '~/.gitignore_global'
6
+
7
+ # Ignore bundler config.
8
+ /.bundle
9
+
10
+ # Ignore the default SQLite database.
11
+ /db/*.sqlite3
12
+ /db/*.sqlite3-*
13
+
14
+ # Ignore all logfiles and tempfiles.
15
+ /log/*
16
+ /tmp/*
17
+ !/log/.keep
18
+ !/tmp/.keep
19
+
20
+ # Ignore pidfiles, but keep the directory.
21
+ /tmp/pids/*
22
+ !/tmp/pids/
23
+ !/tmp/pids/.keep
24
+
25
+ # Ignore uploaded files in development.
26
+ /storage/*
27
+ !/storage/.keep
28
+ /tmp/storage/*
29
+ !/tmp/storage/
30
+ !/tmp/storage/.keep
31
+
32
+ # Ignore master key for decrypting credentials and more.
33
+ /config/master.key
34
+ Gemfile.lock
35
+ db/schema.rb
36
+ db/primary_sqlite_schema.rb
37
+ db/primary_mysql_schema.rb
38
+ db/primary_trilogy_schema.rb
@@ -0,0 +1,24 @@
1
+ # README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require_relative "config/application"
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,2 @@
1
+ class ApplicationController < ActionController::API
2
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationMysqlRecord < ActiveRecord::Base
4
+ self.abstract_class = true
5
+
6
+ connects_to database: { writing: :primary_mysql, reading: :primary_mysql }
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationPgRecord < ActiveRecord::Base
4
+ self.abstract_class = true
5
+
6
+ connects_to database: { writing: :primary_pg, reading: :primary_pg }
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationSqliteRecord < ActiveRecord::Base
4
+ self.abstract_class = true
5
+
6
+ connects_to database: { writing: :primary_sqlite, reading: :primary_sqlite }
7
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationTrilogyRecord < ActiveRecord::Base
4
+ self.abstract_class = true
5
+
6
+ connects_to database: { writing: :primary_trilogy, reading: :primary_trilogy }
7
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Dummy record. It is used to test transaction integration.
4
+ class DummyMysqlRecord < ApplicationMysqlRecord
5
+ class << self
6
+ def find_or_create_by(attributes, &block)
7
+ find_by(attributes) || create(attributes, &block)
8
+ end
9
+ wrap_in_trx :find_or_create_by
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Dummy record. It is used to test transaction integration.
4
+ class DummyPgRecord < ApplicationPgRecord
5
+ class << self
6
+ def find_or_create_by(attributes, &block)
7
+ find_by(attributes) || create(attributes, &block)
8
+ end
9
+ wrap_in_trx :find_or_create_by
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Dummy record. It is used to test transaction integration.
4
+ class DummySqliteRecord < ApplicationSqliteRecord
5
+ class << self
6
+ def find_or_create_by(attributes, &block)
7
+ find_by(attributes) || create(attributes, &block)
8
+ end
9
+ wrap_in_trx :find_or_create_by
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Dummy record. It is used to test transaction integration.
4
+ class DummyTrilogyRecord < ApplicationTrilogyRecord
5
+ class << self
6
+ def find_or_create_by(attributes, &block)
7
+ find_by(attributes) || create(attributes, &block)
8
+ end
9
+ wrap_in_trx :find_or_create_by
10
+ end
11
+ end
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'bundle' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "rubygems"
12
+
13
+ m = Module.new do
14
+ module_function
15
+
16
+ def invoked_as_script?
17
+ File.expand_path($0) == File.expand_path(__FILE__)
18
+ end
19
+
20
+ def env_var_version
21
+ ENV["BUNDLER_VERSION"]
22
+ end
23
+
24
+ def cli_arg_version
25
+ return unless invoked_as_script? # don't want to hijack other binstubs
26
+ return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
27
+ bundler_version = nil
28
+ update_index = nil
29
+ ARGV.each_with_index do |a, i|
30
+ if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
31
+ bundler_version = a
32
+ end
33
+ next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
34
+ bundler_version = $1
35
+ update_index = i
36
+ end
37
+ bundler_version
38
+ end
39
+
40
+ def gemfile
41
+ gemfile = ENV["BUNDLE_GEMFILE"]
42
+ return gemfile if gemfile && !gemfile.empty?
43
+
44
+ File.expand_path("../Gemfile", __dir__)
45
+ end
46
+
47
+ def lockfile
48
+ lockfile =
49
+ case File.basename(gemfile)
50
+ when "gems.rb" then gemfile.sub(/\.rb$/, ".locked")
51
+ else "#{gemfile}.lock"
52
+ end
53
+ File.expand_path(lockfile)
54
+ end
55
+
56
+ def lockfile_version
57
+ return unless File.file?(lockfile)
58
+ lockfile_contents = File.read(lockfile)
59
+ return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
60
+ Regexp.last_match(1)
61
+ end
62
+
63
+ def bundler_requirement
64
+ @bundler_requirement ||=
65
+ env_var_version ||
66
+ cli_arg_version ||
67
+ bundler_requirement_for(lockfile_version)
68
+ end
69
+
70
+ def bundler_requirement_for(version)
71
+ return "#{Gem::Requirement.default}.a" unless version
72
+
73
+ bundler_gem_version = Gem::Version.new(version)
74
+
75
+ bundler_gem_version.approximate_recommendation
76
+ end
77
+
78
+ def load_bundler!
79
+ ENV["BUNDLE_GEMFILE"] ||= gemfile
80
+
81
+ activate_bundler
82
+ end
83
+
84
+ def activate_bundler
85
+ gem_error = activation_error_handling do
86
+ gem "bundler", bundler_requirement
87
+ end
88
+ return if gem_error.nil?
89
+ require_error = activation_error_handling do
90
+ require "bundler/version"
91
+ end
92
+ return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
93
+ warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
94
+ exit 42
95
+ end
96
+
97
+ def activation_error_handling
98
+ yield
99
+ nil
100
+ rescue StandardError, LoadError => e
101
+ e
102
+ end
103
+ end
104
+
105
+ m.load_bundler!
106
+
107
+ if m.invoked_as_script?
108
+ load Gem.bin_path("bundler", "bundle")
109
+ end
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ APP_PATH = File.expand_path("../config/application", __dir__)
3
+ require_relative "../config/boot"
4
+ require "rails/commands"
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative "../config/boot"
3
+ require "rake"
4
+ Rake.application.run
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ require "fileutils"
3
+
4
+ # path to your application root.
5
+ APP_ROOT = File.expand_path("..", __dir__)
6
+
7
+ def system!(*args)
8
+ system(*args) || abort("\n== Command #{args} failed ==")
9
+ end
10
+
11
+ FileUtils.chdir APP_ROOT do
12
+ # This script is a way to set up or update your development environment automatically.
13
+ # This script is idempotent, so that you can run it at any time and get an expectable outcome.
14
+ # Add necessary setup steps to this file.
15
+
16
+ puts "== Installing dependencies =="
17
+ system! "gem install bundler --conservative"
18
+ system("bundle check") || system!("bundle install")
19
+
20
+ # puts "\n== Copying sample files =="
21
+ # unless File.exist?("config/database.yml")
22
+ # FileUtils.cp "config/database.yml.sample", "config/database.yml"
23
+ # end
24
+
25
+ puts "\n== Preparing database =="
26
+ system! "bin/rails db:prepare"
27
+
28
+ puts "\n== Removing old logs and tempfiles =="
29
+ system! "bin/rails log:clear tmp:clear"
30
+
31
+ puts "\n== Restarting application server =="
32
+ system! "bin/rails restart"
33
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "boot"
4
+
5
+ require "rails"
6
+
7
+ %w(
8
+ active_record/railtie
9
+ action_controller/railtie
10
+ action_view/railtie
11
+ ).each do |railtie|
12
+ begin
13
+ require railtie
14
+ rescue LoadError
15
+ end
16
+ end
17
+
18
+
19
+ # Require the gems listed in Gemfile, including any gems
20
+ # you've limited to :test, :development, or :production.
21
+ Bundler.require(*Rails.groups)
22
+
23
+ module DummyApp
24
+ class Application < Rails::Application
25
+ rails_version = Gem::Specification.find_by_name('rails').version
26
+ # Initialize configuration defaults for originally generated Rails version.
27
+ config.load_defaults rails_version.segments[0..1].join('.')
28
+
29
+ # Configuration for the application, engines, and railties goes here.
30
+ #
31
+ # These settings can be overridden in specific environments using the files
32
+ # in config/environments, which are processed later.
33
+ #
34
+ # config.time_zone = "Central Time (US & Canada)"
35
+ # config.eager_load_paths << Rails.root.join("extras")
36
+
37
+ # Only loads a smaller set of middleware suitable for API only apps.
38
+ # Middleware like session, flash, cookies can be added back manually.
39
+ # Skip views, helpers and assets when generating a new resource.
40
+ config.api_only = true
41
+ if rails_version < Gem::Version.new('7.0.0')
42
+ config.active_record.legacy_connection_handling = false
43
+ end
44
+ # config.active_job.queue_adapter = :async
45
+
46
+
47
+ if defined?(FactoryBotRails)
48
+ config.factory_bot.definition_file_paths += [File.expand_path('../../spec/factories', __dir__)]
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,4 @@
1
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
2
+
3
+ require "bundler/setup" # Set up gems listed in the Gemfile.
4
+ require "bootsnap/setup" # Speed up boot time by caching expensive operations.
File without changes