rails-annotate-solargraph 0.2.3 → 0.5.0

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: 0f1d0f284eac106e51e1abc19eec0d7b8790aab9ee188e1cabea5defb04417da
4
- data.tar.gz: 392519ce6da6313e8a3308dee6f54b66629ee108120b8abcb94e1d838dc86470
3
+ metadata.gz: 641aad34ff5a1a7f98a1eca52baf74c311308b2e9e062cf8c5ac3c0186d1f1ec
4
+ data.tar.gz: 70657a49775862f8b50dc2e04f7b489b04f124cbfb4893f777f5a11f69b0ba51
5
5
  SHA512:
6
- metadata.gz: 23e25ae122d969be4f5d4081638592e3db7d6ab46adf60cdaf82057953441576d842bc2db79af664371637e332b25c5fee091fe930e53ffd88f97d78a04533c9
7
- data.tar.gz: 43d0752100b231426877a84665ba8030d5121b8f0d7b07549f2312c7e30cb7f1c0f9c9807b99bc085394fd369cb81a95ec63c15366e92a9eb96116fdb91b8fee
6
+ metadata.gz: 8a2c58e2d0dbb0dd0df66d1f2f04242095081c4159059c8830021cc16f9ece5222dc9fee73392757b88cf1798f5e53256a09fc2291585b8474c36db8777d64f2
7
+ data.tar.gz: 6335dab053b82ff232fdcc69c3453eea68ae44432bd6f4032f29ab812072e9053795955556f14578479bd47ebd37a3bfc6ac592254de63801d38369834dcc358
@@ -1,6 +1,11 @@
1
1
  {
2
2
  "cSpell.words": [
3
3
  "activerecord",
4
+ "citext",
5
+ "datetime",
6
+ "gsub",
7
+ "inet",
8
+ "klass",
4
9
  "rakefile",
5
10
  "solargraph",
6
11
  "yieldparam"
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.5.0] - 2022-04-19
4
+
5
+ - Add some static comments to the schema file to improve general Rails intellisense
6
+ - Rename schema file from `app/models/annotate_solargraph_schema.rb` to `.annotate-solargraph-schema`
7
+ - Generate schema file as a regular ruby file
8
+ - Add `yard` and `solargraph` as dependencies
9
+ - Add `.solargraph.yml` to the installation generator
10
+
11
+ ## [0.4.0] - 2022-04-17
12
+
13
+ - Annotations get saved to a schema file by default `app/models/annotate_solargraph_schema.rb`
14
+
15
+ ## [0.3.0] - 2022-04-17
16
+
17
+ - `has_many :through` and `has_one :through` relations get documented
18
+
3
19
  ## [0.2.3] - 2022-04-16
4
20
 
5
21
  - A nicer fix for the previous problem
@@ -15,6 +31,7 @@
15
31
  ## [0.2.0] - 2022-04-16
16
32
 
17
33
  - Associations get fully documented
34
+ - `has_many`, `has_one` and `belongs_to` relations get documented
18
35
 
19
36
  ## [0.1.1] - 2022-04-15
20
37
 
@@ -24,4 +41,5 @@
24
41
 
25
42
  - Initial release
26
43
  - Automatic generation of annotations after migrations
44
+ - Database fields get documented
27
45
  - Manual rake tasks `annotate:solargraph:generate`, `annotate:solargraph:remove`
data/Gemfile.lock CHANGED
@@ -1,8 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rails-annotate-solargraph (0.2.3)
4
+ rails-annotate-solargraph (0.5.0)
5
5
  rails (>= 5.0, < 8.0)
6
+ solargraph
7
+ yard
6
8
 
7
9
  GEM
8
10
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -63,11 +63,31 @@ You can change the gem's default configuration like so:
63
63
  ```ruby
64
64
  # config/initializers/rails_annotate_solargraph.rb
65
65
 
66
- Rails::Annotate::Solargraph.configure do |conf|
67
- conf.annotation_position = :top # `:bottom` by default
66
+ if ::Rails.env.development?
67
+ ::Rails::Annotate::Solargraph.configure do |conf|
68
+ conf.annotation_position = :top # `:schema_file` by default
69
+ end
68
70
  end
69
71
  ```
70
72
 
73
+ #### annotation_position
74
+
75
+ There are a few values for this option:
76
+
77
+ - `:schema_file` -- default value, annotations get saved to a special file `app/models/annotate_solargraph_schema.rb`
78
+ - `:bottom` -- annotations are appended to the model files
79
+ - `:top` -- annotations are prepended to the model files
80
+
81
+ ### Update
82
+
83
+ To update this gem you should generate the rakefiles once again. Overwrite them.
84
+
85
+ ```sh
86
+ $ rails g annotate:solargraph:install
87
+ $ rake annotate:solargraph:remove
88
+ $ rake annotate:solargraph:generate
89
+ ```
90
+
71
91
  ## Development
72
92
 
73
93
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -1,3 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'set'
5
+
1
6
  module Annotate
2
7
  module Solargraph
3
8
  module Generators
@@ -8,6 +13,17 @@ module Annotate
8
13
  # copy rake tasks
9
14
  def copy_tasks
10
15
  template ::Rails::Annotate::Solargraph::RAKEFILE_NAME, ::File.join('lib', 'tasks', ::Rails::Annotate::Solargraph::RAKEFILE_NAME)
16
+ template ::Rails::Annotate::Solargraph::SCHEMA_FILE_NAME, ::Rails::Annotate::Solargraph::SCHEMA_RAILS_PATH
17
+
18
+ solargraph_config_file = ::File.join(::Rails.root, ::Rails::Annotate::Solargraph::SOLARGRAPH_FILE_NAME)
19
+ system 'solargraph config' unless ::File.exist? solargraph_config_file
20
+ solargraph_config = ::YAML.load_file solargraph_config_file
21
+ solargraph_config['include'] = solargraph_config['include'] || []
22
+ solargraph_config['include'].unshift ::Rails::Annotate::Solargraph::SCHEMA_RAILS_PATH
23
+ # make sure there are no duplicated entries
24
+ solargraph_config['include'] = solargraph_config['include'].to_set.to_a
25
+
26
+ ::File.write(solargraph_config_file, solargraph_config.to_yaml)
11
27
  end
12
28
  end
13
29
  end
@@ -0,0 +1,69 @@
1
+ # This is a dummy file generated by `rails-annotate-solargraph`
2
+ # to extend solargraph's understanding of your Rails app.
3
+ # You should probably add it to `.gitignore`
4
+
5
+ # Some static comments to fill a few gaps
6
+ # in Rails comprehension.
7
+
8
+ class ActionController::Base
9
+ include ActionController::MimeResponds
10
+ include ActionController::Redirecting
11
+ include ActionController::Cookies
12
+ include AbstractController::Rendering
13
+ extend ActiveSupport::Callbacks::ClassMethods
14
+ extend ActiveSupport::Rescuable::ClassMethods
15
+ extend AbstractController::Callbacks::ClassMethods
16
+ extend ActionController::RequestForgeryProtection::ClassMethods
17
+ end
18
+ class ActiveRecord::Base
19
+ extend ActiveRecord::Reflection::ClassMethods
20
+ extend ActiveModel::SecurePassword::ClassMethods
21
+ extend ActiveModel::Attributes::ClassMethods
22
+ include ActiveModel::Attributes
23
+ include ActiveModel::Dirty
24
+ extend ActiveRecord::Validations::ClassMethods
25
+ include ActiveRecord::Validations
26
+ extend ActiveModel::Validations::ClassMethods
27
+ include ActiveModel::Validations
28
+ extend ActiveRecord::Calculations
29
+ extend ActiveRecord::Batches
30
+ extend ActiveRecord::QueryMethods
31
+ extend ActiveRecord::FinderMethods
32
+ extend ActiveRecord::Associations::ClassMethods
33
+ extend ActiveRecord::Inheritance::ClassMethods
34
+ extend ActiveRecord::ModelSchema::ClassMethods
35
+ extend ActiveRecord::Transactions::ClassMethods
36
+ extend ActiveRecord::Scoping::Named::ClassMethods
37
+ include ActiveRecord::Persistence
38
+
39
+ <% (ActiveRecord::Callbacks::CALLBACKS rescue []).each do |callback| -%>
40
+ # Registers a callback to be called <%= callback.to_s.gsub('_', ' ') %>.
41
+ # See `ActiveRecord::Callbacks` for more information.
42
+ # @return [void]
43
+ def self.<%= callback %>(*args, &block); end
44
+ <% end -%>
45
+
46
+ end
47
+ class Rails
48
+ # @return [Rails::Application]
49
+ def self.application; end
50
+ end
51
+ class Rails::Application
52
+ # @return [ActionDispatch::Routing::RouteSet]
53
+ def routes; end
54
+ end
55
+ class ActionDispatch::Routing::Mapper
56
+ include ActionDispatch::Routing::Mapper::Base
57
+ include ActionDispatch::Routing::Mapper::HttpHelpers
58
+ include ActionDispatch::Routing::Mapper::Redirection
59
+ include ActionDispatch::Routing::Mapper::Scoping
60
+ include ActionDispatch::Routing::Mapper::Concerns
61
+ include ActionDispatch::Routing::Mapper::Resources
62
+ include ActionDispatch::Routing::Mapper::CustomUrls
63
+ end
64
+ class ActionDispatch::Routing::RouteSet
65
+ # @yieldself [ActionDispatch::Routing::Mapper]
66
+ def draw; end
67
+ end
68
+
69
+ # Dynamically generated documentation
@@ -19,6 +19,7 @@ if ::Rails.env.development?
19
19
  next unless ::Rake::Task.task_defined?(task)
20
20
 
21
21
  ::Rake::Task[task].enhance do
22
+ system 'yard gems' unless ENV['TEST']
22
23
  ::Rake::Task['annotate:solargraph:generate'].invoke
23
24
  end
24
25
  end
@@ -9,10 +9,10 @@ module Rails
9
9
  # @return [Symbol]
10
10
  attr_reader :annotation_position
11
11
 
12
- ANNOTATION_POSITIONS = ::Set[:bottom, :top].freeze
12
+ ANNOTATION_POSITIONS = ::Set[:bottom, :top, :schema_file].freeze
13
13
 
14
14
  def initialize
15
- @annotation_position = :bottom
15
+ @annotation_position = :schema_file
16
16
  end
17
17
 
18
18
  # @param val [Symbol]
@@ -22,6 +22,10 @@ module Rails
22
22
 
23
23
  @annotation_position = val
24
24
  end
25
+
26
+ def schema_file?
27
+ @annotation_position == :schema_file
28
+ end
25
29
  end
26
30
  end
27
31
  end
@@ -1,44 +1,55 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'fileutils'
4
+
3
5
  module Rails
4
6
  module Annotate
5
7
  module Solargraph
6
8
  class Model
7
9
  using TerminalColors::Refinement
8
10
 
9
- # @return [String]
10
- ANNOTATION_START = "\n# %%<RailsAnnotateSolargraph:Start>%%"
11
- # @return [String]
12
- ANNOTATION_END = "%%<RailsAnnotateSolargraph:End>%%\n\n"
13
- # @return [Regexp]
14
- ANNOTATION_REGEXP = /#{ANNOTATION_START}.*#{ANNOTATION_END}/m.freeze
15
11
  # @return [Regexp]
16
12
  MAGIC_COMMENT_REGEXP = /(^#\s*encoding:.*(?:\n|r\n))|(^# coding:.*(?:\n|\r\n))|(^# -\*- coding:.*(?:\n|\r\n))|(^# -\*- encoding\s?:.*(?:\n|\r\n))|(^#\s*frozen_string_literal:.+(?:\n|\r\n))|(^# -\*- frozen_string_literal\s*:.+-\*-(?:\n|\r\n))/.freeze
17
13
 
14
+ # @return [Hash{Symbol => String}]
15
+ TYPE_MAP = {
16
+ float: 'BigDecimal',
17
+ decimal: 'BigDecimal',
18
+ integer: 'Integer',
19
+ datetime: 'ActiveSupport::TimeWithZone',
20
+ date: 'Date',
21
+ string: 'String',
22
+ boolean: 'Boolean',
23
+ text: 'String',
24
+ jsonb: 'Hash',
25
+ citext: 'String',
26
+ json: 'Hash',
27
+ bigint: 'Integer',
28
+ uuid: 'String',
29
+ inet: 'IPAddr'
30
+ }
31
+ TYPE_MAP.default = 'Object'
32
+ TYPE_MAP.freeze
33
+
18
34
  class << self
19
- # @param type [Symbol, String, nil]
35
+ # @param klass [Class]
20
36
  # @return [String]
21
- def active_record_type_to_yard(type)
22
- case type&.to_sym
23
- when :float
24
- ::Float.to_s
25
- when :integer
26
- ::Integer.to_s
27
- when :decimal
28
- ::BigDecimal.to_s
29
- when :datetime, :timestamp, :time
30
- ::Time.to_s
31
- when :json, :jsonb
32
- ::Hash.to_s
33
- when :date
34
- ::Date.to_s
35
- when :text, :string, :binary, :inet, :uuid
36
- ::String.to_s
37
- when :boolean
38
- 'Boolean'
39
- else
40
- ::Object.to_s
41
- end
37
+ def annotation_start(klass = nil)
38
+ table_name = klass && CONFIG.schema_file? ? ":#{klass.table_name}" : ''
39
+ "\n# %%<RailsAnnotateSolargraph:Start#{table_name}>%%"
40
+ end
41
+
42
+ # @param klass [Class]
43
+ # @return [String]
44
+ def annotation_end(klass = nil)
45
+ table_name = klass && CONFIG.schema_file? ? ":#{klass.table_name}" : ''
46
+ "%%<RailsAnnotateSolargraph:End#{table_name}>%%\n\n"
47
+ end
48
+
49
+ # @param klass [Class]
50
+ # @return [Regexp]
51
+ def annotation_regexp(klass = nil)
52
+ /#{annotation_start(klass)}.*#{annotation_end(klass)}/m
42
53
  end
43
54
  end
44
55
 
@@ -51,7 +62,22 @@ module Rails
51
62
  # @param klass [Class]
52
63
  def initialize(klass)
53
64
  @klass = klass
54
- @file_name = ::File.join(::Rails.root, MODEL_DIR, "#{klass.to_s.underscore}.rb")
65
+ @file_name = CONFIG.schema_file? ? SCHEMA_RAILS_PATH : ::File.join(::Rails.root, MODEL_DIR, "#{klass.to_s.underscore}.rb")
66
+ end
67
+
68
+ # @return [String]
69
+ def annotation_start
70
+ self.class.annotation_start(@klass)
71
+ end
72
+
73
+ # @return [String]
74
+ def annotation_end
75
+ self.class.annotation_end(@klass)
76
+ end
77
+
78
+ # @return [Regexp]
79
+ def annotation_regexp
80
+ self.class.annotation_regexp(@klass)
55
81
  end
56
82
 
57
83
  # @param :write [Boolean]
@@ -79,8 +105,10 @@ module Rails
79
105
  # @param :write [Boolean]
80
106
  # @return [Array<String>] Old file content followed by new content.
81
107
  def remove_annotation(write: true)
108
+ return ['', ''] unless ::File.exist?(@file_name)
109
+
82
110
  file_content = ::File.read(@file_name)
83
- new_file_content = file_content.sub(ANNOTATION_REGEXP, '')
111
+ new_file_content = file_content.sub(annotation_regexp, '')
84
112
  result = [file_content, new_file_content]
85
113
  return result unless write
86
114
  return result if file_content == new_file_content
@@ -93,8 +121,8 @@ module Rails
93
121
  def annotation
94
122
  doc_string = ::String.new
95
123
  doc_string << <<~DOC
96
- #{ANNOTATION_START}
97
- # @!parse
124
+ #{annotation_start}
125
+ ##{parse_clause}
98
126
  # class #{@klass} < #{@klass.superclass}
99
127
  DOC
100
128
 
@@ -117,12 +145,23 @@ module Rails
117
145
 
118
146
  doc_string << <<~DOC.chomp
119
147
  # end
120
- # #{ANNOTATION_END}
148
+ # #{annotation_end}
121
149
  DOC
150
+
151
+ # uncomment the generated annotations if they're saved in the schema file
152
+ return doc_string.gsub(/^#\ {3}/, '').gsub(/^#\n/, "\n") if CONFIG.schema_file?
153
+
154
+ doc_string
122
155
  end
123
156
 
124
157
  private
125
158
 
159
+ def parse_clause
160
+ return if CONFIG.schema_file?
161
+
162
+ " @!parse\n#"
163
+ end
164
+
126
165
  # @param file_name [String]
127
166
  # @return [String]
128
167
  def relative_file_name(file_name)
@@ -133,6 +172,7 @@ module Rails
133
172
  # @param content [String]
134
173
  # @return [void]
135
174
  def write_file(file_name, content)
175
+ ::FileUtils.touch(file_name) unless ::File.exists?(file_name)
136
176
  ::File.write(file_name, content)
137
177
  puts "modify".rjust(12).with_styles(:bold, :green) + " #{relative_file_name(file_name)}"
138
178
  end
@@ -142,37 +182,57 @@ module Rails
142
182
  @klass.table_name[..-2]
143
183
  end
144
184
 
185
+ # @param reflection [ActiveRecord::Reflection::AbstractReflection]
186
+ # @return [Class]
187
+ def reflection_class(reflection)
188
+ reflection.klass
189
+ rescue ::NameError
190
+ Object
191
+ end
192
+
193
+ # @param reflection [ActiveRecord::Reflection::AbstractReflection]
194
+ # @return [String]
195
+ def reflection_foreign_key(reflection)
196
+ reflection.try(:foreign_key) || '<unknown>'
197
+ end
198
+
199
+ # @param klass [Class]
200
+ # @return [String]
201
+ def class_table_name(klass)
202
+ klass.try(:table_name) || '<unknown>'
203
+ end
204
+
145
205
  # @param doc_string [String]
146
206
  # @param attr_name [String]
147
207
  # @param reflection [ActiveRecord::Reflection::AbstractReflection]
148
208
  # @return [void]
149
209
  def document_relation(doc_string, attr_name, reflection)
150
- reflection_class = begin
151
- reflection.klass
152
- rescue ::NameError
153
- Object
154
- end
155
-
156
- associated_table_name = reflection_class.try(:table_name) || '<unknown>'
157
- foreign_key = reflection.try(:foreign_key) || '<unknown>'
158
- db_description = \
210
+ reflection_klass = reflection_class(reflection)
211
+ type_docstring, db_description = \
159
212
  case reflection
160
213
  when ::ActiveRecord::Reflection::BelongsToReflection
161
- type_docstring = reflection_class
162
- "`belongs_to` relation with `#{reflection_class}`. Database column `#{@klass.table_name}.#{foreign_key}`."
214
+ belongs_to_description(reflection_klass,
215
+ class_table_name(@klass),
216
+ reflection_foreign_key(reflection))
163
217
  when ::ActiveRecord::Reflection::HasOneReflection
164
- type_docstring = reflection_class
165
- "`has_one` relation with `#{reflection_class}`. Database column `#{associated_table_name}.#{foreign_key}`."
218
+ has_one_description(reflection_klass,
219
+ class_table_name(reflection_klass),
220
+ reflection_foreign_key(reflection))
166
221
  when ::ActiveRecord::Reflection::HasManyReflection
167
- type_docstring = "Array<#{reflection_class}>"
168
- "`has_many` relation with `#{reflection_class}`. Database column `#{associated_table_name}.#{foreign_key}`."
222
+ has_many_description(reflection_klass,
223
+ class_table_name(reflection_klass),
224
+ reflection_foreign_key(reflection))
225
+ when ::ActiveRecord::Reflection::ThroughReflection
226
+ through_description(reflection)
227
+ else
228
+ [::Object.to_s, '']
169
229
  end
170
230
 
171
231
  doc_string << <<~DOC
172
- # # #{db_description}
232
+ # ##{db_description}
173
233
  # # @param val [#{type_docstring}, nil]
174
234
  # def #{attr_name}=(val); end
175
- # # #{db_description}
235
+ # ##{db_description}
176
236
  # # @return [#{type_docstring}, nil]
177
237
  # def #{attr_name}; end
178
238
  DOC
@@ -187,7 +247,7 @@ module Rails
187
247
  model_class.reflections[klass_relation_name]&.options&.[](:as)&.to_sym == attr_name.to_sym
188
248
  end
189
249
 
190
- classes_string = classes.join(', ')
250
+ classes_string = classes.empty? ? ::Object.to_s : classes.join(', ')
191
251
  doc_string << <<~DOC
192
252
  # # Polymorphic relation. Database columns `#{@klass.table_name}.#{attr_name}_id` and `#{@klass.table_name}.#{attr_name}_type`.
193
253
  # # @param val [#{classes_string}, nil]
@@ -198,13 +258,98 @@ module Rails
198
258
  DOC
199
259
  end
200
260
 
261
+ # @param reflection [ActiveRecord::Reflection::AbstractReflection]
262
+ # @return [Array<String>]
263
+ def through_description(reflection)
264
+ through_klass = reflection_class(reflection.through_reflection)
265
+
266
+ case (reflection.__send__(:delegate_reflection) rescue nil)
267
+ when ::ActiveRecord::Reflection::HasOneReflection
268
+ has_one_description(reflection_class(reflection.source_reflection),
269
+ class_table_name(through_klass),
270
+ reflection_foreign_key(reflection.source_reflection),
271
+ through: through_klass)
272
+ when ::ActiveRecord::Reflection::HasManyReflection
273
+ has_many_description(reflection_class(reflection.source_reflection),
274
+ class_table_name(through_klass),
275
+ reflection_foreign_key(reflection.source_reflection),
276
+ through: through_klass)
277
+ else
278
+ [::Object.to_s, '']
279
+ end
280
+ end
281
+
282
+ # @param through [Class, nil]
283
+ # @return [String]
284
+ def through_sentence(through = nil)
285
+ return '' unless through
286
+
287
+ " through `#{through}`"
288
+ end
289
+
290
+ # @param table_name [String]
291
+ # @param foreign_key [String]
292
+ # @param through [Class, nil]
293
+ # @return [String]
294
+ def column_description(table_name, foreign_key, through = nil)
295
+ return '' if through
296
+
297
+ " Database column `#{table_name}.#{foreign_key}`."
298
+ end
299
+
300
+ # @param relation [Symbol, String]
301
+ # @param klass [Class]
302
+ # @param table_name [String]
303
+ # @param foreign_key [String]
304
+ # @param through [Class, nil]
305
+ # @return [String]
306
+ def relation_description(relation, klass, table_name, foreign_key, through = nil)
307
+ " `#{relation}` relation with `#{klass}`#{through_sentence(through)}.#{column_description(table_name, foreign_key, through)}"
308
+ end
309
+
310
+
311
+ # @param klass [Class]
312
+ # @param table_name [String]
313
+ # @param foreign_key [String]
314
+ # @param :through [Class, nil]
315
+ # @return [Array<String>] Type docstring followed by the description of the method.
316
+ def has_many_description(klass, table_name, foreign_key, through: nil)
317
+ type_docstring = "Array<#{klass}>"
318
+ desc = relation_description(:has_many, klass, table_name, foreign_key, through)
319
+
320
+ [type_docstring, desc]
321
+ end
322
+
323
+ # @param klass [Class]
324
+ # @param table_name [String]
325
+ # @param foreign_key [String]
326
+ # @param :through [Class, nil]
327
+ # @return [Array<String>] Type docstring followed by the description of the method.
328
+ def has_one_description(klass, table_name, foreign_key, through: nil)
329
+ type_docstring = klass
330
+ desc = relation_description(:has_one, klass, table_name, foreign_key, through)
331
+
332
+ [type_docstring, desc]
333
+ end
334
+
335
+ # @param klass [Class]
336
+ # @param table_name [String]
337
+ # @param foreign_key [String]
338
+ # @return [Array<String>] Type docstring followed by the description of the method.
339
+ def belongs_to_description(klass, table_name, foreign_key)
340
+ type_docstring = klass
341
+ desc = relation_description(:belongs_to, klass, table_name, foreign_key)
342
+
343
+ [type_docstring, desc]
344
+ end
345
+
201
346
  # @param attr_type [ActiveModel::Type::Value]
202
347
  # @return [String]
203
348
  def yard_type(attr_type)
204
349
  return attr_type.coder.object_class.to_s if attr_type.respond_to?(:coder) && attr_type.coder.respond_to?(:object_class)
205
350
  return 'Object' if attr_type.respond_to?(:coder) && attr_type.coder.is_a?(::ActiveRecord::Coders::JSON)
206
351
 
207
- self.class.active_record_type_to_yard(attr_type.type)
352
+ TYPE_MAP[attr_type.type]
208
353
  end
209
354
  end
210
355
  end
@@ -3,7 +3,7 @@
3
3
  module Rails
4
4
  module Annotate
5
5
  module Solargraph
6
- VERSION = '0.2.3'
6
+ VERSION = '0.5.0'
7
7
  end
8
8
  end
9
9
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'set'
4
+ require 'fileutils'
4
5
 
5
6
  require_relative "solargraph/version"
6
7
  require_relative "solargraph/configuration"
@@ -19,11 +20,20 @@ module Rails
19
20
  CONFIG = Configuration.new
20
21
  # @return [Set<Symbol>]
21
22
  VALID_MODIFICATION_METHODS = ::Set[:annotate, :remove_annotation].freeze
23
+ # @return [String]
24
+ SCHEMA_CLASS_NAME = 'AnnotateSolargraphSchema'
25
+ # @return [String]
26
+ SOLARGRAPH_FILE_NAME = '.solargraph.yml'
27
+ # @return [String]
28
+ SCHEMA_FILE_NAME = '.annotate_solargraph_schema'
29
+ # @return [String]
30
+ SCHEMA_RAILS_PATH = SCHEMA_FILE_NAME
22
31
 
23
32
  class << self
24
33
  # @return [Array<String>] Array of changed files.
25
34
  def generate
26
35
  title 'Generating model schema annotations'
36
+ create_schema_file
27
37
  modify_models :annotate
28
38
  end
29
39
 
@@ -49,6 +59,13 @@ module Rails
49
59
 
50
60
  include TerminalColors
51
61
 
62
+ def create_schema_file
63
+ schema_file = ::File.join ::Rails.root, SCHEMA_RAILS_PATH
64
+ return if ::File.exist?(schema_file)
65
+
66
+ system 'rails g annotate:solargraph:install'
67
+ end
68
+
52
69
  # @param method [Symbol] Name of the method that will be called on every loaded Model
53
70
  # @return [Array<String>] Array of changed files.
54
71
  def modify_models(method)
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
16
16
 
17
17
  spec.metadata["homepage_uri"] = spec.homepage
18
18
  spec.metadata["source_code_uri"] = "https://gitlab.com/mateuszdrewniak/rails-annotate-solargraph"
19
- # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
19
+ spec.metadata["changelog_uri"] = "https://gitlab.com/mateuszdrewniak/rails-annotate-solargraph/-/raw/main/CHANGELOG.md"
20
20
 
21
21
  # Specify which files should be added to the gem when it is released.
22
22
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -31,6 +31,8 @@ Gem::Specification.new do |spec|
31
31
 
32
32
  # Uncomment to register a new dependency of your gem
33
33
  spec.add_dependency 'rails', ">= 5.0", '< 8.0'
34
+ spec.add_dependency 'solargraph'
35
+ spec.add_dependency 'yard'
34
36
 
35
37
  # For more information and examples about making a new gem, check out our
36
38
  # guide at: https://bundler.io/guides/creating_gem.html
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-annotate-solargraph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mateusz Drewniak
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-04-16 00:00:00.000000000 Z
11
+ date: 2022-04-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -30,6 +30,34 @@ dependencies:
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: '8.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: solargraph
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: yard
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
33
61
  description: Annotate ActiveRecord models with schema comments formatted in YARD that
34
62
  are compatible with Solargraph.
35
63
  email:
@@ -53,6 +81,7 @@ files:
53
81
  - bin/console
54
82
  - bin/setup
55
83
  - lib/generators/annotate/solargraph/install_generator.rb
84
+ - lib/generators/annotate/solargraph/templates/.annotate_solargraph_schema
56
85
  - lib/generators/annotate/solargraph/templates/rails_annotate_solargraph.rake
57
86
  - lib/rails/annotate/solargraph.rb
58
87
  - lib/rails/annotate/solargraph/configuration.rb
@@ -67,6 +96,7 @@ licenses:
67
96
  metadata:
68
97
  homepage_uri: https://gitlab.com/mateuszdrewniak/rails-annotate-solargraph
69
98
  source_code_uri: https://gitlab.com/mateuszdrewniak/rails-annotate-solargraph
99
+ changelog_uri: https://gitlab.com/mateuszdrewniak/rails-annotate-solargraph/-/raw/main/CHANGELOG.md
70
100
  post_install_message:
71
101
  rdoc_options: []
72
102
  require_paths: