sorbet-rails 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +77 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +176 -0
- data/README.md +68 -45
- data/Rakefile +6 -0
- data/SECURITY.md +5 -0
- data/lib/sorbet-rails/model_rbi_formatter.rb +1 -1
- data/lib/sorbet-rails/tasks/rails_rbi.rake +60 -0
- data/rbis/activerecord.rbi +133 -0
- data/sorbet-rails.gemspec +31 -0
- data/spec/model_rbi_formatter_spec.rb +54 -0
- data/spec/rails_helper.rb +14 -0
- data/spec/routes_rbi_formatter_spec.rb +21 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/support/rails_app/.ruby-version +1 -0
- data/spec/support/rails_app/Gemfile +45 -0
- data/spec/support/rails_app/Gemfile.lock +139 -0
- data/spec/support/rails_app/README.md +24 -0
- data/spec/support/rails_app/Rakefile +6 -0
- data/spec/support/rails_app/app/channels/application_cable/channel.rb +4 -0
- data/spec/support/rails_app/app/channels/application_cable/connection.rb +4 -0
- data/spec/support/rails_app/app/controllers/application_controller.rb +2 -0
- data/spec/support/rails_app/app/controllers/concerns/.keep +0 -0
- data/spec/support/rails_app/app/controllers/test_controller.rb +5 -0
- data/spec/support/rails_app/app/jobs/application_job.rb +2 -0
- data/spec/support/rails_app/app/mailers/application_mailer.rb +4 -0
- data/spec/support/rails_app/app/models/application_record.rb +3 -0
- data/spec/support/rails_app/app/models/concerns/.keep +0 -0
- data/spec/support/rails_app/app/models/spell_book.rb +6 -0
- data/spec/support/rails_app/app/models/wand.rb +15 -0
- data/spec/support/rails_app/app/models/wizard.rb +14 -0
- data/spec/support/rails_app/app/views/layouts/mailer.html.erb +13 -0
- data/spec/support/rails_app/app/views/layouts/mailer.text.erb +1 -0
- data/spec/support/rails_app/bin/bundle +3 -0
- data/spec/support/rails_app/bin/rails +9 -0
- data/spec/support/rails_app/bin/rake +9 -0
- data/spec/support/rails_app/bin/setup +33 -0
- data/spec/support/rails_app/bin/spring +17 -0
- data/spec/support/rails_app/bin/update +28 -0
- data/spec/support/rails_app/config.ru +5 -0
- data/spec/support/rails_app/config/application.rb +35 -0
- data/spec/support/rails_app/config/boot.rb +3 -0
- data/spec/support/rails_app/config/cable.yml +10 -0
- data/spec/support/rails_app/config/credentials.yml.enc +1 -0
- data/spec/support/rails_app/config/database.yml +25 -0
- data/spec/support/rails_app/config/environment.rb +5 -0
- data/spec/support/rails_app/config/environments/development.rb +54 -0
- data/spec/support/rails_app/config/environments/production.rb +85 -0
- data/spec/support/rails_app/config/environments/test.rb +46 -0
- data/spec/support/rails_app/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/support/rails_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/support/rails_app/config/initializers/cors.rb +16 -0
- data/spec/support/rails_app/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/support/rails_app/config/initializers/inflections.rb +16 -0
- data/spec/support/rails_app/config/initializers/mime_types.rb +4 -0
- data/spec/support/rails_app/config/initializers/wrap_parameters.rb +14 -0
- data/spec/support/rails_app/config/locales/en.yml +33 -0
- data/spec/support/rails_app/config/puma.rb +34 -0
- data/spec/support/rails_app/config/routes.rb +5 -0
- data/spec/support/rails_app/config/spring.rb +6 -0
- data/spec/support/rails_app/config/storage.yml +34 -0
- data/spec/support/rails_app/db/migrate/20190620001234_create_wizards.rb +12 -0
- data/spec/support/rails_app/db/migrate/20190620003037_create_wands.rb +11 -0
- data/spec/support/rails_app/db/migrate/20190620003739_create_spell_books.rb +8 -0
- data/spec/support/rails_app/db/schema.rb +39 -0
- data/spec/support/rails_app/db/seeds.rb +7 -0
- data/spec/support/rails_app/lib/tasks/.keep +0 -0
- data/spec/support/rails_app/log/.keep +0 -0
- data/spec/support/rails_app/public/robots.txt +1 -0
- data/spec/support/rails_app/storage/.keep +0 -0
- data/spec/support/rails_app/test/controllers/.keep +0 -0
- data/spec/support/rails_app/test/fixtures/.keep +0 -0
- data/spec/support/rails_app/test/fixtures/files/.keep +0 -0
- data/spec/support/rails_app/test/integration/.keep +0 -0
- data/spec/support/rails_app/test/mailers/.keep +0 -0
- data/spec/support/rails_app/test/models/.keep +0 -0
- data/spec/support/rails_app/test/test_helper.rb +10 -0
- data/spec/support/rails_app/tmp/.keep +0 -0
- data/spec/support/rails_app/vendor/.keep +0 -0
- data/spec/test_data/expected_routes.rbi +43 -0
- data/spec/test_data/expected_wizard_no_book.rbi +0 -0
- data/spec/test_data/models/expected_wand.rbi +174 -0
- data/spec/test_data/models/expected_wizard.rbi +189 -0
- data/spec/test_data/models/expected_wizard_wo_spellbook.rbi +189 -0
- metadata +338 -3
@@ -286,7 +286,7 @@ class ModelRbiFormatter
|
|
286
286
|
|
287
287
|
def type_for_column_def(column_def)
|
288
288
|
strict_type = RUBY_TO_SORBET_TYPE_MAPPING[column_def.type] || 'T.untyped'
|
289
|
-
if column_def.array?
|
289
|
+
if column_def.respond_to?(:array?) && column_def.array?
|
290
290
|
strict_type = "T::Array[#{strict_type}]"
|
291
291
|
end
|
292
292
|
column_def.null ? "T.nilable(#{strict_type})" : strict_type
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require("sorbet-rails/model_rbi_formatter")
|
2
|
+
require("sorbet-rails/routes_rbi_formatter")
|
3
|
+
|
4
|
+
namespace :rails_rbi do
|
5
|
+
|
6
|
+
desc "Generate rbi for rails routes"
|
7
|
+
task :routes, [:root_dir] => :environment do |t, args|
|
8
|
+
all_routes = Rails.application.routes.routes
|
9
|
+
require "action_dispatch/routing/inspector"
|
10
|
+
inspector = ActionDispatch::Routing::RoutesInspector.new(all_routes)
|
11
|
+
root_dir = args[:root_dir] || Rails.root
|
12
|
+
file_path = Rails.root.join("sorbet", "rails-rbi", "routes.rbi")
|
13
|
+
FileUtils.mkdir_p(File.dirname(file_path))
|
14
|
+
File.write(file_path, inspector.format(RoutesRbiFormatter.new))
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Generate rbi for rails models. Pass models name to regenrate rbi for only the given models."
|
18
|
+
task models: :environment do |t, args|
|
19
|
+
# need to eager load to see all models
|
20
|
+
Rails.application.eager_load!
|
21
|
+
|
22
|
+
blacklisted_models = []
|
23
|
+
blacklisted_models << ActiveRecord::SchemaMigration if defined?(ActiveRecord::SchemaMigration)
|
24
|
+
|
25
|
+
all_models = ActiveRecord::Base.descendants - blacklisted_models
|
26
|
+
|
27
|
+
models_to_generate = args.extras.size > 0 ?
|
28
|
+
args.extras.map { |m| Object.const_get(m) } :
|
29
|
+
all_models
|
30
|
+
|
31
|
+
generated_rbis = generate_rbis_for_models(models_to_generate, all_models)
|
32
|
+
generated_rbis.each do |model_name, contents|
|
33
|
+
file_path = Rails.root.join("sorbet", "rails-rbi", "models", "#{model_name.underscore}.rbi")
|
34
|
+
FileUtils.mkdir_p(File.dirname(file_path))
|
35
|
+
File.write(file_path, contents)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def generate_rbis_for_models(model_classes, available_classes)
|
40
|
+
available_class_names = Set.new(available_classes.map { |c| c.name })
|
41
|
+
formatted = model_classes.map do |model_class|
|
42
|
+
begin
|
43
|
+
formatter = ModelRbiFormatter.new(model_class, available_class_names)
|
44
|
+
[model_class.name, formatter.generate_rbi]
|
45
|
+
rescue StandardError => ex
|
46
|
+
puts "---"
|
47
|
+
puts "Error when handling model #{model_class.name}: #{ex}"
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
Hash[formatted.compact] # remove models with errors
|
52
|
+
end
|
53
|
+
|
54
|
+
def blacklisted_models
|
55
|
+
blacklisted_models = []
|
56
|
+
blacklisted_models << ActiveRecord::SchemaMigration if defined?(ActiveRecord::SchemaMigration)
|
57
|
+
blacklisted_models << ApplicationRecord if defined?(ApplicationRecord)
|
58
|
+
blacklisted_models
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
# typed: strong
|
2
|
+
class ActiveRecord::Relation
|
3
|
+
extend T::Sig
|
4
|
+
extend T::Generic
|
5
|
+
include Enumerable
|
6
|
+
include ActiveRecord::Querying::Typed
|
7
|
+
|
8
|
+
Elem = type_member
|
9
|
+
|
10
|
+
sig { params(block: T.proc.params(e: Elem).void).void }
|
11
|
+
def each(&block); end
|
12
|
+
|
13
|
+
sig { params(level: T.nilable(Integer)).returns(T::Array[Elem]) }
|
14
|
+
def flatten(level); end
|
15
|
+
|
16
|
+
sig { returns(T::Array[Elem]) }
|
17
|
+
def to_a; end
|
18
|
+
|
19
|
+
# This is part of both FinderMethods & Enumerable module.
|
20
|
+
# We need to define here to override the typedef in Enumerable module.
|
21
|
+
# TODO normally this method could return Elem or Array[Elem]
|
22
|
+
# however, we think it's better to limit the interface to returning Elem only
|
23
|
+
# Use `find_n` as a replacement if you want to get an array from `find`
|
24
|
+
sig { params(args: T.untyped).returns(Elem).soft }
|
25
|
+
def find(*args); end
|
26
|
+
end
|
27
|
+
|
28
|
+
module ActiveRecord::Querying::Typed
|
29
|
+
extend T::Sig
|
30
|
+
extend T::Generic
|
31
|
+
Elem = type_member
|
32
|
+
|
33
|
+
# -- Booleans
|
34
|
+
sig { params(args: T.untyped, block: T.nilable(T.proc.void)).returns(T::Boolean) }
|
35
|
+
def exists?(*args, &block); end
|
36
|
+
sig { params(args: T.untyped, block: T.nilable(T.proc.void)).returns(T::Boolean) }
|
37
|
+
def any?(*args, &block); end
|
38
|
+
sig { params(args: T.untyped, block: T.nilable(T.proc.void)).returns(T::Boolean) }
|
39
|
+
def many?(*args, &block); end
|
40
|
+
sig { params(args: T.untyped, block: T.nilable(T.proc.void)).returns(T::Boolean) }
|
41
|
+
def none?(*args, &block); end
|
42
|
+
sig { params(args: T.untyped, block: T.nilable(T.proc.void)).returns(T::Boolean) }
|
43
|
+
def one?(*args, &block); end
|
44
|
+
|
45
|
+
# -- finder methods
|
46
|
+
sig { returns(Elem) }
|
47
|
+
def first!; end
|
48
|
+
sig { returns(Elem) }
|
49
|
+
def second!; end
|
50
|
+
sig { returns(T.nilable(Elem)) }
|
51
|
+
def second; end
|
52
|
+
sig { returns(Elem) }
|
53
|
+
def third!; end
|
54
|
+
sig { returns(T.nilable(Elem)) }
|
55
|
+
def third; end
|
56
|
+
sig { returns(Elem) }
|
57
|
+
def fourth!; end
|
58
|
+
sig { returns(T.nilable(Elem)) }
|
59
|
+
def fourth; end
|
60
|
+
sig { returns(Elem) }
|
61
|
+
def fifth!; end
|
62
|
+
sig { returns(T.nilable(Elem)) }
|
63
|
+
def fifth; end
|
64
|
+
|
65
|
+
sig { returns(Elem) }
|
66
|
+
def last!; end
|
67
|
+
sig { returns(Elem) }
|
68
|
+
def third_to_last!; end
|
69
|
+
sig { returns(T.nilable(Elem)) }
|
70
|
+
def third_to_last; end
|
71
|
+
sig { returns(Elem) }
|
72
|
+
def second_to_last!; end
|
73
|
+
sig { returns(T.nilable(Elem)) }
|
74
|
+
def second_to_last; end
|
75
|
+
|
76
|
+
# These methods would return 1 single element when there is no limit, and return an
|
77
|
+
# array of element when there is a limit passed in.
|
78
|
+
# The more common use case is to find 1 object. We use that as the default sig
|
79
|
+
# and add custom first_n, last_n method for the cases that return an array
|
80
|
+
sig { params(limit: T.nilable(Integer)).returns(T.nilable(Elem)).soft }
|
81
|
+
def first(limit = nil); end
|
82
|
+
sig { params(limit: T.nilable(Integer)).returns(T.nilable(Elem)).soft }
|
83
|
+
def last(limit = nil); end
|
84
|
+
# Similar to first & last, normally this method could return Elem or Array[Elem]
|
85
|
+
# But we enforce that `find` return Elem by default and provide find_n as an alternative
|
86
|
+
sig { params(args: T.any(Integer, String)).returns(Elem).soft }
|
87
|
+
def find(*args); end
|
88
|
+
# These are custom finder methods to provide strong type for secondary use case of first, last & find
|
89
|
+
# See sorbet_rails/custom_finder_methods
|
90
|
+
sig { params(limit: Integer).returns(T::Array[Elem]) }
|
91
|
+
def first_n(limit); end
|
92
|
+
sig { params(limit: Integer).returns(T::Array[Elem]) }
|
93
|
+
def last_n(limit); end
|
94
|
+
sig { params(args: T::Array[T.any(Integer, String)]).returns(T::Array[Elem]) }
|
95
|
+
def find_n(*args); end
|
96
|
+
|
97
|
+
sig { params(args: T.untyped, block: T.nilable(T.proc.void)).returns(T.nilable(Elem)) }
|
98
|
+
def find_by(*args, &block); end
|
99
|
+
|
100
|
+
sig { params(args: T.untyped, block: T.nilable(T.proc.void)).returns(Elem) }
|
101
|
+
def find_by!(*args, &block); end
|
102
|
+
|
103
|
+
sig { params(id: Integer).returns(T.nilable(Elem)) }
|
104
|
+
def find_by_id(id); end
|
105
|
+
|
106
|
+
sig { params(id: Integer).returns(Elem) }
|
107
|
+
def find_by_id!(id); end
|
108
|
+
|
109
|
+
# -- Calculation
|
110
|
+
# There can be a complication of using count with .group
|
111
|
+
# https://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-count
|
112
|
+
# sig { params(args: T.untyped, block: T.nilable(T.proc.void)).returns(Integer) }
|
113
|
+
# def count(*args, &block); end
|
114
|
+
end
|
115
|
+
|
116
|
+
module ActiveRecord::QueryMethods
|
117
|
+
# TODO: where.not is a special case that we replace it with a `where_not` method
|
118
|
+
# `where` when not given parameters will return a `ActiveRecord::QueryMethods::WhereChain`
|
119
|
+
# instance that has a method `not` on it
|
120
|
+
sig { params(opts: T.untyped, rest: T.untyped).returns(T.self_type) }
|
121
|
+
def not(opts = nil, *rest); end
|
122
|
+
end
|
123
|
+
|
124
|
+
class ActiveRecord::Base
|
125
|
+
extend ActiveRecord::Querying::Typed
|
126
|
+
extend T::Generic
|
127
|
+
Elem = type_template(fixed: ActiveRecord::Base)
|
128
|
+
end
|
129
|
+
|
130
|
+
class ApplicationRecord
|
131
|
+
extend T::Generic
|
132
|
+
Elem = type_template(fixed: ApplicationRecord)
|
133
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = %q{sorbet-rails}
|
3
|
+
s.version = "0.1.3"
|
4
|
+
s.date = %q{2019-04-18}
|
5
|
+
s.summary = %q{Set of tools to make Sorbet work with Rails seamlessly.}
|
6
|
+
s.authors = ["Chan Zuckerberg Initiative"]
|
7
|
+
s.email = "opensource@chanzuckerberg.com"
|
8
|
+
s.homepage = "https://github.com/chanzuckerberg/sorbet-rails"
|
9
|
+
s.license = 'MIT'
|
10
|
+
s.require_paths = ["lib"]
|
11
|
+
s.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
12
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
13
|
+
end
|
14
|
+
s.test_files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
15
|
+
`git ls-files -z`.split("\x0").select { |f| f.match(%r{^(test|spec|features)/}) }
|
16
|
+
end
|
17
|
+
|
18
|
+
# Development
|
19
|
+
s.add_development_dependency 'rspec', '~> 3.8', '>= 3.8'
|
20
|
+
# Debugging
|
21
|
+
s.add_development_dependency 'awesome_print', '~>1.8.0', '>=1.8.0'
|
22
|
+
s.add_development_dependency 'byebug', '~>11.0.1', '>=11.0.1'
|
23
|
+
|
24
|
+
# for testing a gem with a rails app (controller specs)
|
25
|
+
s.add_development_dependency 'bundler', '~>1.3.0', '>=1.3.0'
|
26
|
+
s.add_development_dependency 'rails', '~>5.2.3', '>=5.2.3'
|
27
|
+
s.add_development_dependency 'rspec-rails', '~>3.8.2', '>=3.8.2'
|
28
|
+
s.add_development_dependency 'sqlite3', '~>1.4.1', '>=1.4.1'
|
29
|
+
s.add_development_dependency 'puma', '~>3.12.1', '>=3.12.1'
|
30
|
+
s.add_development_dependency 'listen', '~>3.1.5', '>=3.1.5'
|
31
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
require 'sorbet-rails/model_rbi_formatter'
|
3
|
+
|
4
|
+
RSpec.describe ModelRbiFormatter do
|
5
|
+
|
6
|
+
def expect_match_file(content, file_path, save_to_file: false)
|
7
|
+
# TODO make this a custom matcher that can be shared in multiple files
|
8
|
+
if save_to_file
|
9
|
+
FileUtils.mkdir_p(File.dirname(file_path))
|
10
|
+
File.write(file_path, content)
|
11
|
+
end
|
12
|
+
expected_value = File.read(file_path)
|
13
|
+
expect(content).to eql(expected_value)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'loads all the models in the app' do
|
17
|
+
Rails.application.eager_load!
|
18
|
+
all_models = ActiveRecord::Base.descendants.sort_by(&:name)
|
19
|
+
expect(all_models).to eql([
|
20
|
+
ActiveRecord::SchemaMigration,
|
21
|
+
ApplicationRecord,
|
22
|
+
SpellBook,
|
23
|
+
Wand,
|
24
|
+
Wizard,
|
25
|
+
])
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'generates correct rbi file for Wizard' do
|
29
|
+
formatter = ModelRbiFormatter.new(Wizard, ['Wizard', 'Wand', 'SpellBook'])
|
30
|
+
expect_match_file(
|
31
|
+
formatter.generate_rbi,
|
32
|
+
'spec/test_data/models/expected_wizard.rbi',
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'generates strict belongs_to and do not generate overridden methods' do
|
37
|
+
formatter = ModelRbiFormatter.new(Wand, ['Wizard', 'Wand', 'SpellBook'])
|
38
|
+
expect_match_file(
|
39
|
+
formatter.generate_rbi,
|
40
|
+
'spec/test_data/models/expected_wand.rbi',
|
41
|
+
save_to_file: true,
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'there is a hidden model' do
|
46
|
+
it 'fallbacks to use ActiveRecord::Relation' do
|
47
|
+
formatter = ModelRbiFormatter.new(Wizard, ['Wizard', 'Wand'])
|
48
|
+
expect_match_file(
|
49
|
+
formatter.generate_rbi,
|
50
|
+
'spec/test_data/models/expected_wizard_wo_spellbook.rbi',
|
51
|
+
)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
ENV['RAILS_ENV'] = 'test'
|
4
|
+
|
5
|
+
require 'rails/all'
|
6
|
+
require 'rake'
|
7
|
+
require 'rspec/rails'
|
8
|
+
require 'sorbet-rails/railtie'
|
9
|
+
|
10
|
+
load 'sorbet-rails/tasks/rails_rbi.rake'
|
11
|
+
|
12
|
+
require 'support/rails_app/config/environment'
|
13
|
+
|
14
|
+
ActiveRecord::Migration.maintain_test_schema!
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
require 'sorbet-rails/routes_rbi_formatter'
|
3
|
+
|
4
|
+
RSpec.describe RoutesRbiFormatter do
|
5
|
+
it 'sets up Rails Application' do
|
6
|
+
expect(Rails.application.routes).to_not be_empty
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'generates _path and _url of a named route' do
|
10
|
+
all_routes = Rails.application.routes.routes
|
11
|
+
require "action_dispatch/routing/inspector"
|
12
|
+
inspector = ActionDispatch::Routing::RoutesInspector.new(all_routes)
|
13
|
+
formatted = inspector.format(RoutesRbiFormatter.new)
|
14
|
+
# Write the res to a file
|
15
|
+
# file_path = '/tmp/expected_routes.rbi'
|
16
|
+
# FileUtils.mkdir_p(File.dirname(file_path))
|
17
|
+
# File.write(file_path, res)
|
18
|
+
expected_value = File.read('spec/test_data/expected_routes.rbi')
|
19
|
+
expect(formatted).to eql(expected_value)
|
20
|
+
end
|
21
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.4.3
|
@@ -0,0 +1,45 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
3
|
+
|
4
|
+
ruby '2.4.3'
|
5
|
+
|
6
|
+
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
7
|
+
gem 'rails', '~> 5.2.3'
|
8
|
+
# Use sqlite3 as the database for Active Record
|
9
|
+
gem 'sqlite3'
|
10
|
+
# Use Puma as the app server
|
11
|
+
gem 'puma', '~> 3.11'
|
12
|
+
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
|
13
|
+
# gem 'jbuilder', '~> 2.5'
|
14
|
+
# Use Redis adapter to run Action Cable in production
|
15
|
+
# gem 'redis', '~> 4.0'
|
16
|
+
# Use ActiveModel has_secure_password
|
17
|
+
# gem 'bcrypt', '~> 3.1.7'
|
18
|
+
|
19
|
+
# Use ActiveStorage variant
|
20
|
+
# gem 'mini_magick', '~> 4.8'
|
21
|
+
|
22
|
+
# Use Capistrano for deployment
|
23
|
+
# gem 'capistrano-rails', group: :development
|
24
|
+
|
25
|
+
# Reduces boot times through caching; required in config/boot.rb
|
26
|
+
# gem 'bootsnap', '>= 1.1.0', require: false
|
27
|
+
|
28
|
+
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
|
29
|
+
# gem 'rack-cors'
|
30
|
+
|
31
|
+
group :development, :test do
|
32
|
+
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
|
33
|
+
gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
|
34
|
+
end
|
35
|
+
|
36
|
+
group :development do
|
37
|
+
gem 'listen', '>= 3.0.5', '< 3.2'
|
38
|
+
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
|
39
|
+
# gem 'spring'
|
40
|
+
# gem 'spring-watcher-listen', '~> 2.0.0'
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
45
|
+
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
@@ -0,0 +1,139 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
actioncable (5.2.3)
|
5
|
+
actionpack (= 5.2.3)
|
6
|
+
nio4r (~> 2.0)
|
7
|
+
websocket-driver (>= 0.6.1)
|
8
|
+
actionmailer (5.2.3)
|
9
|
+
actionpack (= 5.2.3)
|
10
|
+
actionview (= 5.2.3)
|
11
|
+
activejob (= 5.2.3)
|
12
|
+
mail (~> 2.5, >= 2.5.4)
|
13
|
+
rails-dom-testing (~> 2.0)
|
14
|
+
actionpack (5.2.3)
|
15
|
+
actionview (= 5.2.3)
|
16
|
+
activesupport (= 5.2.3)
|
17
|
+
rack (~> 2.0)
|
18
|
+
rack-test (>= 0.6.3)
|
19
|
+
rails-dom-testing (~> 2.0)
|
20
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
21
|
+
actionview (5.2.3)
|
22
|
+
activesupport (= 5.2.3)
|
23
|
+
builder (~> 3.1)
|
24
|
+
erubi (~> 1.4)
|
25
|
+
rails-dom-testing (~> 2.0)
|
26
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
27
|
+
activejob (5.2.3)
|
28
|
+
activesupport (= 5.2.3)
|
29
|
+
globalid (>= 0.3.6)
|
30
|
+
activemodel (5.2.3)
|
31
|
+
activesupport (= 5.2.3)
|
32
|
+
activerecord (5.2.3)
|
33
|
+
activemodel (= 5.2.3)
|
34
|
+
activesupport (= 5.2.3)
|
35
|
+
arel (>= 9.0)
|
36
|
+
activestorage (5.2.3)
|
37
|
+
actionpack (= 5.2.3)
|
38
|
+
activerecord (= 5.2.3)
|
39
|
+
marcel (~> 0.3.1)
|
40
|
+
activesupport (5.2.3)
|
41
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
42
|
+
i18n (>= 0.7, < 2)
|
43
|
+
minitest (~> 5.1)
|
44
|
+
tzinfo (~> 1.1)
|
45
|
+
arel (9.0.0)
|
46
|
+
builder (3.2.3)
|
47
|
+
byebug (11.0.1)
|
48
|
+
concurrent-ruby (1.1.5)
|
49
|
+
crass (1.0.4)
|
50
|
+
erubi (1.8.0)
|
51
|
+
ffi (1.11.1)
|
52
|
+
globalid (0.4.2)
|
53
|
+
activesupport (>= 4.2.0)
|
54
|
+
i18n (1.6.0)
|
55
|
+
concurrent-ruby (~> 1.0)
|
56
|
+
listen (3.1.5)
|
57
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
58
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
59
|
+
ruby_dep (~> 1.2)
|
60
|
+
loofah (2.2.3)
|
61
|
+
crass (~> 1.0.2)
|
62
|
+
nokogiri (>= 1.5.9)
|
63
|
+
mail (2.7.1)
|
64
|
+
mini_mime (>= 0.1.1)
|
65
|
+
marcel (0.3.3)
|
66
|
+
mimemagic (~> 0.3.2)
|
67
|
+
method_source (0.9.2)
|
68
|
+
mimemagic (0.3.3)
|
69
|
+
mini_mime (1.0.1)
|
70
|
+
mini_portile2 (2.4.0)
|
71
|
+
minitest (5.11.3)
|
72
|
+
nio4r (2.3.1)
|
73
|
+
nokogiri (1.10.3)
|
74
|
+
mini_portile2 (~> 2.4.0)
|
75
|
+
puma (3.12.1)
|
76
|
+
rack (2.0.7)
|
77
|
+
rack-test (1.1.0)
|
78
|
+
rack (>= 1.0, < 3)
|
79
|
+
rails (5.2.3)
|
80
|
+
actioncable (= 5.2.3)
|
81
|
+
actionmailer (= 5.2.3)
|
82
|
+
actionpack (= 5.2.3)
|
83
|
+
actionview (= 5.2.3)
|
84
|
+
activejob (= 5.2.3)
|
85
|
+
activemodel (= 5.2.3)
|
86
|
+
activerecord (= 5.2.3)
|
87
|
+
activestorage (= 5.2.3)
|
88
|
+
activesupport (= 5.2.3)
|
89
|
+
bundler (>= 1.3.0)
|
90
|
+
railties (= 5.2.3)
|
91
|
+
sprockets-rails (>= 2.0.0)
|
92
|
+
rails-dom-testing (2.0.3)
|
93
|
+
activesupport (>= 4.2.0)
|
94
|
+
nokogiri (>= 1.6)
|
95
|
+
rails-html-sanitizer (1.0.4)
|
96
|
+
loofah (~> 2.2, >= 2.2.2)
|
97
|
+
railties (5.2.3)
|
98
|
+
actionpack (= 5.2.3)
|
99
|
+
activesupport (= 5.2.3)
|
100
|
+
method_source
|
101
|
+
rake (>= 0.8.7)
|
102
|
+
thor (>= 0.19.0, < 2.0)
|
103
|
+
rake (12.3.2)
|
104
|
+
rb-fsevent (0.10.3)
|
105
|
+
rb-inotify (0.10.0)
|
106
|
+
ffi (~> 1.0)
|
107
|
+
ruby_dep (1.5.0)
|
108
|
+
sprockets (3.7.2)
|
109
|
+
concurrent-ruby (~> 1.0)
|
110
|
+
rack (> 1, < 3)
|
111
|
+
sprockets-rails (3.2.1)
|
112
|
+
actionpack (>= 4.0)
|
113
|
+
activesupport (>= 4.0)
|
114
|
+
sprockets (>= 3.0.0)
|
115
|
+
sqlite3 (1.4.1)
|
116
|
+
thor (0.20.3)
|
117
|
+
thread_safe (0.3.6)
|
118
|
+
tzinfo (1.2.5)
|
119
|
+
thread_safe (~> 0.1)
|
120
|
+
websocket-driver (0.7.1)
|
121
|
+
websocket-extensions (>= 0.1.0)
|
122
|
+
websocket-extensions (0.1.4)
|
123
|
+
|
124
|
+
PLATFORMS
|
125
|
+
ruby
|
126
|
+
|
127
|
+
DEPENDENCIES
|
128
|
+
byebug
|
129
|
+
listen (>= 3.0.5, < 3.2)
|
130
|
+
puma (~> 3.11)
|
131
|
+
rails (~> 5.2.3)
|
132
|
+
sqlite3
|
133
|
+
tzinfo-data
|
134
|
+
|
135
|
+
RUBY VERSION
|
136
|
+
ruby 2.4.3p205
|
137
|
+
|
138
|
+
BUNDLED WITH
|
139
|
+
2.0.1
|