solargraph-rails 1.1.2 → 1.2.1

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/linter.yml +94 -0
  3. data/.github/workflows/test.yml +185 -0
  4. data/.github/workflows/typecheck.yml +83 -0
  5. data/.overcommit.yml +51 -0
  6. data/.rubocop.yml +334 -0
  7. data/.rubocop_todo.yml +784 -0
  8. data/.solargraph.yml +8 -2
  9. data/CHANGELOG.md +51 -1
  10. data/DEVELOPMENT.md +8 -19
  11. data/Gemfile +22 -9
  12. data/README.md +39 -25
  13. data/bin/overcommit +27 -0
  14. data/bin/rubocop +27 -0
  15. data/ci/auto_yard/plugins.rb +0 -1
  16. data/lib/solargraph/rails/annotate.rb +10 -0
  17. data/lib/solargraph/rails/annotations/action_controller.rb +57 -5
  18. data/lib/solargraph/rails/annotations/action_text.rb +11 -0
  19. data/lib/solargraph/rails/annotations/active_job.rb +276 -0
  20. data/lib/solargraph/rails/annotations/active_model.rb +18 -0
  21. data/lib/solargraph/rails/annotations/active_record.rb +54 -3
  22. data/lib/solargraph/rails/annotations/active_storage.rb +113 -0
  23. data/lib/solargraph/rails/annotations/active_support.rb +3 -0
  24. data/lib/solargraph/rails/annotations/array.rb +7 -0
  25. data/lib/solargraph/rails/annotations/class.rb +2 -0
  26. data/lib/solargraph/rails/annotations/date.rb +8 -0
  27. data/lib/solargraph/rails/annotations/module.rb +13 -0
  28. data/lib/solargraph/rails/annotations/object.rb +3 -0
  29. data/lib/solargraph/rails/annotations/rails.rb +4 -0
  30. data/lib/solargraph/rails/annotations/time.rb +6 -2
  31. data/lib/solargraph/rails/delegate.rb +44 -10
  32. data/lib/solargraph/rails/model.rb +252 -31
  33. data/lib/solargraph/rails/rails_api.rb +2 -2
  34. data/lib/solargraph/rails/schema.rb +27 -8
  35. data/lib/solargraph/rails/util.rb +45 -4
  36. data/lib/solargraph/rails/version.rb +1 -1
  37. data/lib/solargraph-rails.rb +1 -1
  38. data/script/generate_definitions.rb +49 -24
  39. data/solargraph-rails.gemspec +14 -5
  40. metadata +64 -17
  41. data/.github/workflows/ruby.yml +0 -76
data/.solargraph.yml CHANGED
@@ -1,11 +1,17 @@
1
1
  ---
2
2
  include:
3
3
  - "**/*.rb"
4
+ - "Gemfile"
5
+ - "Rakefile"
6
+ - "*.gemspec"
4
7
  exclude:
5
- - test/**/*
8
+ - spec/**/*
9
+ - lib/solargraph/rails/annotations/**/*
6
10
  - vendor/**/*
7
11
  - ".bundle/**/*"
8
- require: []
12
+ require:
13
+ # we generally assume a solargraph require has been made and don't make it explicitly
14
+ - solargraph
9
15
  domains: []
10
16
  reporters: []
11
17
  formatter:
data/CHANGELOG.md CHANGED
@@ -2,6 +2,57 @@
2
2
 
3
3
  ## Changes
4
4
 
5
+ ### v1.2.1
6
+
7
+ Features / fixes:
8
+ - Add annotation for ActiveRecord::Base#reload
9
+ - Add annotation for Rails::Application.config
10
+ - Add static Rails::Application.config method annotation
11
+ - Retire earlier version expectations
12
+ - Fix changelog typo
13
+
14
+ Internal improvements:
15
+ - CI/testing improvements:
16
+ - Add PR comments, rubocop-yard
17
+ - Update rbs collection in specs
18
+ - Test current Solargraph pre-release PRs
19
+
20
+ ### v1.2
21
+
22
+ Most of these are courtesy of @grncdr, with integration work by
23
+ @iftheshoefritz and @apiology
24
+
25
+ Features / fixes:
26
+ - Unlock support for Solargraph ~>0.56.0, with [major
27
+ improvements](https://github.com/castwide/solargraph/blob/master/CHANGELOG.md)
28
+ across the board
29
+ - Support writers in Rails models
30
+ - Support `gem_rbs_collection` for better quality Rails types
31
+ - Use Solargraph::Pin::DelegatedMethod to define delegate methods
32
+ - Include overloads and parameter types for ActiveRecord methods
33
+ - Improve private relation support for ActiveRecord
34
+ - Add find_by_column methods, clean up spec (Thanks, @ShadiestGoat!)
35
+ - Annotation improvements driven by testing
36
+
37
+
38
+ Internal improvements:
39
+ - Many CI, linting and testing improvements
40
+ - Extract Util.extract_option helper
41
+ - Remove Rails 5 & Rails 6 specs
42
+ - Configure test app to behave like a real app
43
+ - Use ruby/setup-ruby action and test app Gemfile for CI
44
+ - Add a plugin that generates yard docs after bundle install
45
+ - Update test pin definitions and exclusions to be Solargraph and
46
+ Rails version-focused in a single location
47
+ - Working build matrix with heavy caching
48
+ - Add typecheck workflow
49
+ - Use Solargraph::Pin::DelegatedMethod to define delegate methods
50
+ - Update README introduction
51
+ - Update model spec to expect private relation types
52
+ - Fix undefined closure for generated parameter pins
53
+ - Add Rails 7.1, 7.2 and 8.0 to test matrix
54
+ - README.md example bug fix (Thanks, @snuggs!)
55
+
5
56
  ### v1.1.2
6
57
 
7
58
  Features / fixes:
@@ -14,7 +65,6 @@ Internal improvements:
14
65
  - Use normal ruby source for extra YARD annotations (Thanks, @grncdr!)
15
66
  - Speed up CI for recent Solargraph version fresh builds
16
67
  - spec reliability fixes
17
- -
18
68
 
19
69
  ### v1.1.1
20
70
 
data/DEVELOPMENT.md CHANGED
@@ -1,19 +1,5 @@
1
1
  # Solargraph-Rails development guide
2
2
 
3
- ## Contributing
4
-
5
- 1. create fork and clone the repo
6
- 2. install gem deps `bundle install`
7
- 3. install dummy Rails app deps and build its yard cache
8
-
9
- ```
10
- $ cd spec/rails7
11
- $ bundle install && yard gems
12
- $ cd ../../
13
- ```
14
- 4. now tests should pass locally and you can try different changes
15
- 5. submit PR
16
-
17
3
  ## Debugging workflow / test matrix issues locally
18
4
 
19
5
  ```sh
@@ -24,7 +10,7 @@ act pull_request
24
10
  ## Completion coverage tracking
25
11
 
26
12
  Solargraph-Rails uses a [set of yaml files](https://github.com/iftheshoefritz/solargraph-rails/tree/master/spec/definitions) to track coverage of found completions.
27
- Those yaml files are generated at runtime from a dummy [Rails 7 app](https://github.com/iftheshoefritz/solargraph-rails/tree/master/spec/rails7).
13
+ Those yaml files are generated at runtime from a dummy Rails apps in the spec/rails* directories.
28
14
 
29
15
  The main goal is to catch any regressions in case of any change. In case a method completion is marked completed and it is not found in solargraph completions, the tests will fail.
30
16
 
@@ -48,7 +34,7 @@ What you will see in test output is reported coverage for classes that are track
48
34
  In case an improvement is made, and more completions are found then being asserted, tests will throw a warning:
49
35
 
50
36
  ```
51
- ActionDispatch::Routing::Mapper.try! is marked as skipped in spec/definitions/rails5/routes.yml, but is actually present.
37
+ ActionDispatch::Routing::Mapper.try! is marked as skipped in spec/definitions/routes.yml, but is actually present.
52
38
  Consider setting skip=false
53
39
  provides completions for ActionDispatch::Routing::Mapper
54
40
  ```
@@ -76,15 +62,18 @@ In case a new set of assertion files has to be created (for a new Rails version
76
62
  All you have to do is execute the script and pass it a path to rails app:
77
63
 
78
64
  ```
79
- ruby script/generate_definitions.rb spec/rails7
65
+ cd spec/rails8
66
+ rails g model model
67
+ rails db:drop db:create db:migrate
68
+ bundle exec ruby ../../script/generate_definitions.rb .
80
69
  ```
81
70
 
82
- Make sure to review the script and uncomment relevant parts
71
+ Move .yml files into place, then make sure to review the script and uncomment relevant parts
83
72
 
84
73
  ## Preparing a release (maintainers)
85
74
 
86
75
  1. Look up [most recent release](https://rubygems.org/gems/solargraph-rails)
87
- 2. Open up commit list(https://github.com/iftheshoefritz/solargraph-rails/compare/v1.1.1...main)
76
+ 2. Open up [commit list](https://github.com/iftheshoefritz/solargraph-rails/compare/v1.2.0...main)
88
77
  3. Update [CHANGELOG.md](./CHANGELOG.md)
89
78
  4. Flip to 'files changed view' and refine updates
90
79
  5. Bump [version](./lib/solargraph/rails/version.rb) appropriately
data/Gemfile CHANGED
@@ -1,14 +1,14 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
-
4
3
  # Kind of ugly, but works. The setup-ruby action forces gems to be installed to vendor/bundle
5
- # If we use it naively we end up with vendor/bundle and spec/rails7/vendor/bundle, which
4
+ # If we use it naively we end up with vendor/bundle and spec/rails*/vendor/bundle, which
6
5
  # breaks all the tests because docs are generated in two different directories.
7
6
  #
8
7
  # So if we just install the rails deps at the same time, we have a single cache and a single
9
8
  # directory for gems.
10
- rails_version = ENV['MATRIX_RAILS_VERSION'] || '7'
11
- instance_eval File.read(File.expand_path("spec/rails#{rails_version}/Gemfile", __dir__))
9
+ rails_version = (ENV['CI'] && ENV['MATRIX_RAILS_VERSION']) || '7.2'
10
+ rails_major_version = rails_version.split('.').first
11
+ instance_eval File.read(File.expand_path("spec/rails#{rails_major_version}/Gemfile", __dir__))
12
12
 
13
13
  solargraph_version = (ENV['CI'] && ENV['MATRIX_SOLARGRAPH_VERSION'])
14
14
 
@@ -30,7 +30,19 @@ group :development, :test do
30
30
  gem 'byebug'
31
31
  end
32
32
 
33
- if rails_version == '7'
33
+ group :development, :rubocop do
34
+ gem 'rubocop', require: false
35
+ gem 'rubocop-rake', require: false
36
+ gem 'rubocop-rspec', require: false
37
+ gem 'rubocop-performance', require: false
38
+ gem 'rubocop-yard', require: true
39
+ gem 'overcommit'
40
+ gem 'simplecov-lcov',
41
+ github: 'apiology/simplecov-lcov',
42
+ branch: 'avoid_blank_lines'
43
+ end
44
+
45
+ if rails_major_version == '7'
34
46
  # https://stackoverflow.com/questions/79360526/uninitialized-constant-activesupportloggerthreadsafelevellogger-nameerror
35
47
  gem "concurrent-ruby", '<=1.3.5'
36
48
  end
@@ -40,11 +52,12 @@ gemspec
40
52
 
41
53
  solargraph_force_ci_version = (ENV['CI'] && ENV['MATRIX_SOLARGRAPH_VERSION'])
42
54
 
43
- if solargraph_force_ci_version == '0.54.6.alpha'
44
- gem 'solargraph',
55
+ case solargraph_force_ci_version
56
+ when '0.57.alpha'
57
+ gem "solargraph",
45
58
  github: 'apiology/solargraph',
46
- branch: 'v54-alpha'
47
- # path: '../solargraph'
59
+ branch: '2025-07-02'
60
+ # path: '../solargraph'
48
61
  end
49
62
 
50
63
  # Local gemfile for development tools, etc.
data/README.md CHANGED
@@ -1,46 +1,48 @@
1
1
  # Solargraph::Rails - Help solargraph with Rails
2
2
 
3
3
  ## Models
4
- Given a typical Rails model like this:
4
+ Consider pair of typical Rails models like this:
5
+
6
+ ```sh
7
+ rails g model Author lastname:string firstnames:string
8
+ rails g model Book title:string isbn:string author:belongs_to
9
+ ```
5
10
 
6
11
  ```ruby
7
- # == Schema Information
8
- #
9
- # Table name: my_books
10
- #
11
- # id :integer not null, primary key
12
- # author :string
13
- # name :string
14
- # created_at :datetime not null
15
- # updated_at :datetime not null
16
- #
17
- class MyBook < ApplicationRecord
18
- def my_method
19
- "hello"
12
+ class Author < ApplicationRecord
13
+ has_many :books
14
+
15
+ def sortable_name
16
+ "#{lastname}, #{firstnames}"
20
17
  end
18
+ end
21
19
 
22
- ...
20
+ class Book < ApplicationRecord
21
+ belongs_to :author
23
22
 
23
+ def label
24
+ [author.sortable_name, title, isbn].join("\n")
25
+ end
24
26
  end
25
27
  ```
26
28
 
27
- The various Ruby intellisense tools are ok at knowing that there is a `MyBook` constant, and some (including Solargraph) are aware that objects like `MyBook.new` have a method `.my_method`. But what about those magical dynamic attributes that ActiveRecord creates when Rails starts up? You can see these listed at the top of the file under `# == Schema Information`, the comments helpfully added by the Annotate gem.
29
+ The various Ruby intellisense tools are ok at knowing that there are `Book` and `Author` constants, and some (including Solargraph) are aware that objects like `Book.new` have a `.label` method. But what about those "magical" dynamic methods that ActiveRecord creates like `.title`, or `.author`?
28
30
 
29
- Since these attributes are only created at runtime, static analysis alone can't identify them. Your editor has no idea that these attributes exist, but they're amongst the most common things that you will work with in any Rails app.
31
+ Since these attributes are only created at runtime, a simple static analysis of the `Book` class alone can't identify them. Your editor has no idea that these attributes exist, but they're amongst the most common things that you will work with in any Rails app.
30
32
 
31
- That's where this plugin for Solargraph comes in: it parses the database schema and YARD docs of various gems to give Solargraph some extra hints. For instance database attributes:
33
+ That's where this plugin for Solargraph comes in: it understands db/schema.rb and any comments from the annotate\_models gem for models, and also supplies key annotations and Rails-specific context on top of what Solargraph pulls via YARD and RBS. As a result, you have access to database attributes:
32
34
 
33
35
  ![Go to attribute schema definition](assets/sg_rails_1_0_go_to_attribute_definition.gif)
34
36
 
35
- ... or ActiveRecord finders:
37
+ ... and ActiveRecord finders:
36
38
 
37
39
  ![ActiveRecord method support](assets/sg_rails_1_0_activerecord_support.gif)
38
40
 
39
- ... or associations:
41
+ ... and associations:
40
42
 
41
43
  ![Association support](assets/sg_rails_1_0_association_completion.gif)
42
44
 
43
- ... or routes file:
45
+ ... and routes file syntax:
44
46
 
45
47
  ![Routes file support](assets/sg_rails_1_0_routes_support.gif)
46
48
 
@@ -52,6 +54,16 @@ and more!
52
54
 
53
55
  If you add them to your Gemfile, you'll have to tell your IDE plugin to use bundler to load the right version of solargraph.
54
56
 
57
+ ### Import Rails RBS types
58
+
59
+ Use [gem\_rbs\_collection](https://github.com/ruby/gem_rbs_collection)
60
+ to install RBS types for Rails:
61
+
62
+ ```sh
63
+ rbs collection init
64
+ rbs collection install
65
+ ```
66
+
55
67
  ### Add `solargraph-rails` to your `.solargraph.yml`
56
68
 
57
69
  (if you don't have a `.solargraph.yml` in your project root, you can run `solargraph config` to add one)
@@ -62,6 +74,7 @@ plugins:
62
74
  ```
63
75
 
64
76
  ### Build YARD docs
77
+
65
78
  In the project root, run `yard gems`.
66
79
 
67
80
  ## Contributing
@@ -71,18 +84,19 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/ifthes
71
84
 
72
85
  2. install gem deps `bundle install`
73
86
 
74
- 3. install dummy rails app deps and build the yard cache:
87
+ 3. install dummy rails app deps:
75
88
 
76
89
  ```
77
- $ cd spec/rails7
78
- $ bundle install && yard gems
79
- $ cd ../../
90
+ cd spec/rails7 && bundle install && rbs collection init && rbs collection install && cd ../../
91
+ cd spec/rails8 && bundle install && rbs collection init && rbs collection install && cd ../../
80
92
  ```
81
93
 
82
94
  4. now tests should pass locally and you can try different changes
83
95
 
84
96
  5. submit PR
85
97
 
98
+ See [DEVELOPMENT.md](./DEVELOPMENT.md) for more information
99
+
86
100
  ## License
87
101
 
88
102
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/bin/overcommit ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'overcommit' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
+
13
+ bundle_binstub = File.expand_path("bundle", __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
17
+ load(bundle_binstub)
18
+ else
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21
+ end
22
+ end
23
+
24
+ require "rubygems"
25
+ require "bundler/setup"
26
+
27
+ load Gem.bin_path("overcommit", "overcommit")
data/bin/rubocop ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rubocop' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
+
13
+ bundle_binstub = File.expand_path("bundle", __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
17
+ load(bundle_binstub)
18
+ else
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21
+ end
22
+ end
23
+
24
+ require "rubygems"
25
+ require "bundler/setup"
26
+
27
+ load Gem.bin_path("rubocop", "rubocop")
@@ -1,5 +1,4 @@
1
1
  Bundler::Plugin.add_hook('after-install-all') do
2
- system('bundle exec yard gems')
3
2
  cmd = 'bundle exec yard gems --plugin solargraph'
4
3
  STDERR.puts("Installing yard info using #{cmd.inspect}")
5
4
  # Attempt to run yard, and if it fails, try again - sometimes YARD gets indigestion on a given gem
@@ -35,6 +35,16 @@ module Solargraph
35
35
  location:
36
36
  Solargraph::Location.new(source_map.filename, snip.range)
37
37
  )
38
+
39
+ pins <<
40
+ Util.build_public_method(
41
+ ns,
42
+ "#{name}=",
43
+ types: [ruby_type],
44
+ params: { 'value' => [ruby_type] },
45
+ location:
46
+ Solargraph::Location.new(source_map.filename, snip.range)
47
+ )
38
48
  end
39
49
 
40
50
  pins
@@ -1,12 +1,59 @@
1
1
  class ActionController::Base
2
- include ActionController::MimeResponds
3
- include ActionController::Redirecting
4
- include ActionController::Cookies
2
+ #
3
+ # NOTE: keep this list synced with new items from MODULES in action_controller/base.rb
4
+ #
5
+ # @todo pull this as literal array dynamically from
6
+ # ActionController::Base::MODULES and walk through it (and other
7
+ # cases of same pattern) to help future-proof things
8
+ #
5
9
  include AbstractController::Rendering
10
+ extend AbstractController::Rendering::ClassMethods
11
+ include AbstractController::Translation
12
+ include AbstractController::AssetPaths
13
+ include Helpers
14
+ include UrlFor
15
+ include Redirecting
16
+ include ActionView::Layouts
17
+ include Rendering
18
+ include Renderers::All
19
+ include ConditionalGet
20
+ include EtagWithTemplateDigest
21
+ include EtagWithFlash
22
+ include Caching
23
+ include MimeResponds
24
+ include ImplicitRender
25
+ include StrongParameters
26
+ include ParameterEncoding
27
+ include Cookies
28
+ include Flash
29
+ include FormBuilder
30
+ include RequestForgeryProtection
31
+ extend RequestForgeryProtection::ClassMethods
32
+ include ContentSecurityPolicy
33
+ include PermissionsPolicy
34
+ extend PermissionsPolicy::ClassMethods
35
+ include Streaming
36
+ include DataStreaming
37
+ include HttpAuthentication::Basic::ControllerMethods
38
+ extend HttpAuthentication::Basic::ControllerMethods::ClassMethods
39
+ include HttpAuthentication::Digest::ControllerMethods
40
+ include HttpAuthentication::Token::ControllerMethods
41
+ include DefaultHeaders
42
+ include Logging
43
+ extend Logging::ClassMethods
44
+ include AbstractController::Callbacks
45
+ extend AbstractController::Callbacks::ClassMethods
46
+ include Rescue
47
+ include Instrumentation
48
+ include ParamsWrapper
49
+
50
+ #
51
+ # I don't see the thinsg below in action_controller/base.rb, at least in Rails
52
+ # 7.0. Maybe they need to be moved to be under a different class?
53
+ #
6
54
  extend ActiveSupport::Callbacks::ClassMethods
7
55
  extend ActiveSupport::Rescuable::ClassMethods
8
- extend AbstractController::Callbacks::ClassMethods
9
- extend ActionController::RequestForgeryProtection::ClassMethods
56
+ include ActiveSupport::Rescuable
10
57
 
11
58
  # @return [ActionDispatch::Response]
12
59
  def response; end
@@ -27,3 +74,8 @@ class ActionController::Cookies
27
74
  # @return [ActionDispatch::Cookies::CookieJar]
28
75
  def cookies; end
29
76
  end
77
+
78
+ class ActionController::StrongParameters
79
+ # @return [ActionController::Parameters]
80
+ def params; end
81
+ end
@@ -0,0 +1,11 @@
1
+ module ActionText
2
+ module Attribute
3
+ # @param name [String, Symbol]
4
+ # @param encrypted [Boolean]
5
+ # @param strict_loading [Boolean]
6
+ # @return [void]
7
+ def self.has_rich_text(name, encrypted = false, strict_loading = false); end
8
+ # @return [Array<String>]
9
+ def self.rich_text_association_names; end
10
+ end
11
+ end