rails-annotate-solargraph 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: '0841b81a947cf88befe6531d7b4c8aabc0f3d1708b12543bf88e56f39835aea0'
4
+ data.tar.gz: 32e2be64e71eb09976f8babea38ec7fc0f8dc0373970ade0a09c65e36f56cb62
5
+ SHA512:
6
+ metadata.gz: a485c9e9acb53bd7dec92be97e9f57386ddebe913ead221e7fa00ad8e0f7ec697968dde5195514fef12af9a0d9d674cfd91e6db7a1f8e0c32297d61555892bd9
7
+ data.tar.gz: 4603a5ff8d88b3e732afa1f2dfb5aa76a2ef01b7b32cde7105d5881bcf60c3db9e2345c43780ef623ef8f0b4e25d71489ee9c5e04a3b24bccd4e886a99a9cfba
data/.rubocop.yml ADDED
@@ -0,0 +1,12 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.7
3
+
4
+ Style/StringLiterals:
5
+ Enabled: false
6
+
7
+ Style/StringLiteralsInInterpolation:
8
+ Enabled: true
9
+ EnforcedStyle: double_quotes
10
+
11
+ Layout/LineLength:
12
+ Max: 120
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ rails-annotate-solargraph
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.7.6
@@ -0,0 +1,8 @@
1
+ {
2
+ "cSpell.words": [
3
+ "activerecord",
4
+ "rakefile",
5
+ "solargraph",
6
+ "yieldparam"
7
+ ]
8
+ }
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2022-04-15
4
+
5
+ - Initial release
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in rails-annotate-solargraph.gemspec
6
+ gemspec
7
+
8
+ gem 'debug'
9
+ gem 'git'
10
+ gem "minitest", "~> 5.0"
11
+ gem "rake", "~> 13.0"
12
+ gem "rubocop", "~> 1.21"
13
+ gem "solargraph"
14
+ gem "sqlite3", "~> 1.4"
data/Gemfile.lock ADDED
@@ -0,0 +1,232 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rails-annotate-solargraph (0.1.0)
5
+ rails (>= 5.0, < 8.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actioncable (7.0.2.3)
11
+ actionpack (= 7.0.2.3)
12
+ activesupport (= 7.0.2.3)
13
+ nio4r (~> 2.0)
14
+ websocket-driver (>= 0.6.1)
15
+ actionmailbox (7.0.2.3)
16
+ actionpack (= 7.0.2.3)
17
+ activejob (= 7.0.2.3)
18
+ activerecord (= 7.0.2.3)
19
+ activestorage (= 7.0.2.3)
20
+ activesupport (= 7.0.2.3)
21
+ mail (>= 2.7.1)
22
+ net-imap
23
+ net-pop
24
+ net-smtp
25
+ actionmailer (7.0.2.3)
26
+ actionpack (= 7.0.2.3)
27
+ actionview (= 7.0.2.3)
28
+ activejob (= 7.0.2.3)
29
+ activesupport (= 7.0.2.3)
30
+ mail (~> 2.5, >= 2.5.4)
31
+ net-imap
32
+ net-pop
33
+ net-smtp
34
+ rails-dom-testing (~> 2.0)
35
+ actionpack (7.0.2.3)
36
+ actionview (= 7.0.2.3)
37
+ activesupport (= 7.0.2.3)
38
+ rack (~> 2.0, >= 2.2.0)
39
+ rack-test (>= 0.6.3)
40
+ rails-dom-testing (~> 2.0)
41
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
42
+ actiontext (7.0.2.3)
43
+ actionpack (= 7.0.2.3)
44
+ activerecord (= 7.0.2.3)
45
+ activestorage (= 7.0.2.3)
46
+ activesupport (= 7.0.2.3)
47
+ globalid (>= 0.6.0)
48
+ nokogiri (>= 1.8.5)
49
+ actionview (7.0.2.3)
50
+ activesupport (= 7.0.2.3)
51
+ builder (~> 3.1)
52
+ erubi (~> 1.4)
53
+ rails-dom-testing (~> 2.0)
54
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
55
+ activejob (7.0.2.3)
56
+ activesupport (= 7.0.2.3)
57
+ globalid (>= 0.3.6)
58
+ activemodel (7.0.2.3)
59
+ activesupport (= 7.0.2.3)
60
+ activerecord (7.0.2.3)
61
+ activemodel (= 7.0.2.3)
62
+ activesupport (= 7.0.2.3)
63
+ activestorage (7.0.2.3)
64
+ actionpack (= 7.0.2.3)
65
+ activejob (= 7.0.2.3)
66
+ activerecord (= 7.0.2.3)
67
+ activesupport (= 7.0.2.3)
68
+ marcel (~> 1.0)
69
+ mini_mime (>= 1.1.0)
70
+ activesupport (7.0.2.3)
71
+ concurrent-ruby (~> 1.0, >= 1.0.2)
72
+ i18n (>= 1.6, < 2)
73
+ minitest (>= 5.1)
74
+ tzinfo (~> 2.0)
75
+ ast (2.4.2)
76
+ backport (1.2.0)
77
+ benchmark (0.2.0)
78
+ builder (3.2.4)
79
+ concurrent-ruby (1.1.10)
80
+ crass (1.0.6)
81
+ debug (1.5.0)
82
+ irb (>= 1.3.6)
83
+ reline (>= 0.2.7)
84
+ diff-lcs (1.5.0)
85
+ digest (3.1.0)
86
+ e2mmap (0.1.0)
87
+ erubi (1.10.0)
88
+ git (1.10.2)
89
+ rchardet (~> 1.8)
90
+ globalid (1.0.0)
91
+ activesupport (>= 5.0)
92
+ i18n (1.10.0)
93
+ concurrent-ruby (~> 1.0)
94
+ io-console (0.5.11)
95
+ irb (1.4.1)
96
+ reline (>= 0.3.0)
97
+ jaro_winkler (1.5.4)
98
+ kramdown (2.3.2)
99
+ rexml
100
+ kramdown-parser-gfm (1.1.0)
101
+ kramdown (~> 2.0)
102
+ loofah (2.16.0)
103
+ crass (~> 1.0.2)
104
+ nokogiri (>= 1.5.9)
105
+ mail (2.7.1)
106
+ mini_mime (>= 0.1.1)
107
+ marcel (1.0.2)
108
+ method_source (1.0.0)
109
+ mini_mime (1.1.2)
110
+ mini_portile2 (2.8.0)
111
+ minitest (5.15.0)
112
+ net-imap (0.2.3)
113
+ digest
114
+ net-protocol
115
+ strscan
116
+ net-pop (0.1.1)
117
+ digest
118
+ net-protocol
119
+ timeout
120
+ net-protocol (0.1.3)
121
+ timeout
122
+ net-smtp (0.3.1)
123
+ digest
124
+ net-protocol
125
+ timeout
126
+ nio4r (2.5.8)
127
+ nokogiri (1.13.4)
128
+ mini_portile2 (~> 2.8.0)
129
+ racc (~> 1.4)
130
+ nokogiri (1.13.4-arm64-darwin)
131
+ racc (~> 1.4)
132
+ parallel (1.22.1)
133
+ parser (3.1.1.0)
134
+ ast (~> 2.4.1)
135
+ racc (1.6.0)
136
+ rack (2.2.3)
137
+ rack-test (1.1.0)
138
+ rack (>= 1.0, < 3)
139
+ rails (7.0.2.3)
140
+ actioncable (= 7.0.2.3)
141
+ actionmailbox (= 7.0.2.3)
142
+ actionmailer (= 7.0.2.3)
143
+ actionpack (= 7.0.2.3)
144
+ actiontext (= 7.0.2.3)
145
+ actionview (= 7.0.2.3)
146
+ activejob (= 7.0.2.3)
147
+ activemodel (= 7.0.2.3)
148
+ activerecord (= 7.0.2.3)
149
+ activestorage (= 7.0.2.3)
150
+ activesupport (= 7.0.2.3)
151
+ bundler (>= 1.15.0)
152
+ railties (= 7.0.2.3)
153
+ rails-dom-testing (2.0.3)
154
+ activesupport (>= 4.2.0)
155
+ nokogiri (>= 1.6)
156
+ rails-html-sanitizer (1.4.2)
157
+ loofah (~> 2.3)
158
+ railties (7.0.2.3)
159
+ actionpack (= 7.0.2.3)
160
+ activesupport (= 7.0.2.3)
161
+ method_source
162
+ rake (>= 12.2)
163
+ thor (~> 1.0)
164
+ zeitwerk (~> 2.5)
165
+ rainbow (3.1.1)
166
+ rake (13.0.6)
167
+ rchardet (1.8.0)
168
+ regexp_parser (2.2.1)
169
+ reline (0.3.1)
170
+ io-console (~> 0.5)
171
+ reverse_markdown (2.1.1)
172
+ nokogiri
173
+ rexml (3.2.5)
174
+ rubocop (1.26.1)
175
+ parallel (~> 1.10)
176
+ parser (>= 3.1.0.0)
177
+ rainbow (>= 2.2.2, < 4.0)
178
+ regexp_parser (>= 1.8, < 3.0)
179
+ rexml
180
+ rubocop-ast (>= 1.16.0, < 2.0)
181
+ ruby-progressbar (~> 1.7)
182
+ unicode-display_width (>= 1.4.0, < 3.0)
183
+ rubocop-ast (1.16.0)
184
+ parser (>= 3.1.1.0)
185
+ ruby-progressbar (1.11.0)
186
+ solargraph (0.44.3)
187
+ backport (~> 1.2)
188
+ benchmark
189
+ bundler (>= 1.17.2)
190
+ diff-lcs (~> 1.4)
191
+ e2mmap
192
+ jaro_winkler (~> 1.5)
193
+ kramdown (~> 2.3)
194
+ kramdown-parser-gfm (~> 1.1)
195
+ parser (~> 3.0)
196
+ reverse_markdown (>= 1.0.5, < 3)
197
+ rubocop (>= 0.52)
198
+ thor (~> 1.0)
199
+ tilt (~> 2.0)
200
+ yard (~> 0.9, >= 0.9.24)
201
+ sqlite3 (1.4.2)
202
+ strscan (3.0.1)
203
+ thor (1.2.1)
204
+ tilt (2.0.10)
205
+ timeout (0.2.0)
206
+ tzinfo (2.0.4)
207
+ concurrent-ruby (~> 1.0)
208
+ unicode-display_width (2.1.0)
209
+ webrick (1.7.0)
210
+ websocket-driver (0.7.5)
211
+ websocket-extensions (>= 0.1.0)
212
+ websocket-extensions (0.1.5)
213
+ yard (0.9.27)
214
+ webrick (~> 1.7.0)
215
+ zeitwerk (2.5.4)
216
+
217
+ PLATFORMS
218
+ arm64-darwin-20
219
+ ruby
220
+
221
+ DEPENDENCIES
222
+ debug
223
+ git
224
+ minitest (~> 5.0)
225
+ rails-annotate-solargraph!
226
+ rake (~> 13.0)
227
+ rubocop (~> 1.21)
228
+ solargraph
229
+ sqlite3 (~> 1.4)
230
+
231
+ BUNDLED WITH
232
+ 2.3.3
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 Mateusz Drewniak
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # Rails::Annotate::Solargraph
2
+
3
+ ![pipeline status](https://gitlab.com/mateuszdrewniak/rails-annotate-solargraph/badges/main/pipeline.svg)
4
+
5
+ This gem is inspired by [ctran/annotate_models](https://github.com/ctran/annotate_models).
6
+
7
+ It automatically generates YARD comments for every model
8
+ in your Rails application. They're formatted in a way to make them easy
9
+ to parse for [Solargraph](https://solargraph.org/) (a great gem that serves
10
+ as a Ruby language server for your IDE).
11
+
12
+ Here's how you can generate and use these annotations.
13
+
14
+ ![Annotation Generation Gif](readme_assets/annotation_generation_demo.gif)
15
+
16
+ They're automatically updated and generated when you execute migrations
17
+ in the development environment.
18
+
19
+ ![Automatic Annotations Gif](readme_assets/automatic_annotations_demo.gif)
20
+
21
+ ## Installation
22
+
23
+ Add this line to your application's Gemfile:
24
+
25
+ ```ruby
26
+ gem 'rails-annotate-solargraph'
27
+ ```
28
+
29
+ And then execute:
30
+
31
+ $ bundle install
32
+
33
+ Or install it yourself as:
34
+
35
+ $ gem install rails-annotate-solargraph
36
+
37
+ Then use this command to generate appropriate Rakefiles
38
+
39
+ $ rails g annotate:solargraph:install
40
+
41
+
42
+ And you're ready to go!
43
+
44
+ Comments should be automatically added and
45
+ updated once you execute a migration.
46
+
47
+ ## Usage
48
+
49
+ You can also manually generate or remove annotations.
50
+
51
+ ### Annotate all models
52
+
53
+ $ rake annotate:solargraph:generate
54
+
55
+ ### Remove all annotations
56
+
57
+ $ rake annotate:solargraph:remove
58
+
59
+ ### Configure
60
+
61
+ You can change the gem's default configuration like so:
62
+
63
+ ```ruby
64
+ # config/initializers/rails_annotate_solargraph.rb
65
+
66
+ Rails::Annotate::Solargraph.configure do |conf|
67
+ conf.annotation_position = :top # `:bottom` by default
68
+ end
69
+ ```
70
+
71
+ ## Development
72
+
73
+ 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.
74
+
75
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
76
+
77
+ ## Contributing
78
+
79
+ Bug reports and pull requests are welcome on Gitlab at https://gitlab.com/mateuszdrewniak/rails-annotate-solargraph.
80
+
81
+ ## License
82
+
83
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/testtask"
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << "test"
8
+ t.libs << "lib"
9
+ t.test_files = FileList["test/rails/**/*_test.rb"]
10
+ end
11
+
12
+ require "rubocop/rake_task"
13
+
14
+ RuboCop::RakeTask.new
15
+
16
+ task default: %i[test rubocop]
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "rails/annotate/solargraph"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+ cd test/rails/annotate/solargraph/rails_7_0
8
+ bundle install
@@ -0,0 +1,15 @@
1
+ module Annotate
2
+ module Solargraph
3
+ module Generators
4
+ class InstallGenerator < ::Rails::Generators::Base
5
+ desc 'Generate rails-annotate-solargraph rakefiles.'
6
+ source_root ::File.expand_path('templates', __dir__)
7
+
8
+ # copy rake tasks
9
+ def copy_tasks
10
+ template ::Rails::Annotate::Solargraph::RAKEFILE_NAME, ::File.join('lib', 'tasks', ::Rails::Annotate::Solargraph::RAKEFILE_NAME)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ if ::Rails.env.development?
4
+ namespace :annotate do
5
+ namespace :solargraph do
6
+ desc "Add YARD comments documenting the models' schemas"
7
+ task generate: :environment do
8
+ system 'rails runner "p ::Rails::Annotate::Solargraph.generate"'
9
+ end
10
+
11
+ desc "Remove YARD comments documenting the models' schemas"
12
+ task remove: :environment do
13
+ system 'rails runner "p ::Rails::Annotate::Solargraph.remove"'
14
+ end
15
+ end
16
+
17
+ migration_tasks = %w[db:migrate db:migrate:up db:migrate:down db:migrate:reset db:migrate:redo db:rollback]
18
+ migration_tasks.each do |task|
19
+ next unless ::Rake::Task.task_defined?(task)
20
+
21
+ ::Rake::Task[task].enhance do
22
+ ::Rake::Task['annotate:solargraph:generate'].invoke
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'set'
4
+
5
+ module Rails
6
+ module Annotate
7
+ module Solargraph
8
+ class Configuration
9
+ # @return [Symbol]
10
+ attr_reader :annotation_position
11
+
12
+ ANNOTATION_POSITIONS = ::Set[:bottom, :top].freeze
13
+
14
+ def initialize
15
+ @annotation_position = :bottom
16
+ end
17
+
18
+ # @param val [Symbol]
19
+ def annotation_position=(val)
20
+ raise Error, "`annotation_position` is incorrect! Got `#{val.inspect}`, expected a member of `#{ANNOTATION_POSITIONS.inspect}`" \
21
+ unless ANNOTATION_POSITIONS.include?(val)
22
+
23
+ @annotation_position = val
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails
4
+ module Annotate
5
+ module Solargraph
6
+ class Model
7
+ ANNOTATION_START = "\n# %%<RailsAnnotateSolargraph:Start>%%"
8
+ ANNOTATION_END = "%%<RailsAnnotateSolargraph:End>%%\n\n"
9
+ ANNOTATION_REGEXP = /#{ANNOTATION_START}.*#{ANNOTATION_END}/m.freeze
10
+ 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
11
+
12
+ class << self
13
+ # @param type [Symbol, String, nil]
14
+ # @return [String]
15
+ def active_record_type_to_yard(type)
16
+ case type&.to_sym
17
+ when :float
18
+ ::Float.to_s
19
+ when :integer
20
+ ::Integer.to_s
21
+ when :decimal
22
+ ::BigDecimal.to_s
23
+ when :datetime, :timestamp, :time
24
+ ::Time.to_s
25
+ when :json, :jsonb
26
+ ::Hash.to_s
27
+ when :date
28
+ ::Date.to_s
29
+ when :text, :string, :binary, :inet, :uuid
30
+ ::String.to_s
31
+ when :boolean
32
+ 'Boolean'
33
+ else
34
+ ::Object.to_s
35
+ end
36
+ end
37
+ end
38
+
39
+ # @return [String]
40
+ attr_reader :file_name
41
+
42
+ # @return [Class]
43
+ attr_reader :klass
44
+
45
+ # @param klass [Class]
46
+ def initialize(klass)
47
+ @klass = klass
48
+ @file_name = ::File.join(::Rails.root, MODEL_DIR, "#{klass.to_s.underscore}.rb")
49
+ end
50
+
51
+ # @param :write [Boolean]
52
+ # @return [String] New file content.
53
+ def annotate(write: true)
54
+ file_content = remove_annotation write: false
55
+
56
+ if CONFIG.annotation_position == :top
57
+ magic_comments = file_content.scan(MAGIC_COMMENT_REGEXP).flatten.compact.join
58
+ file_content.sub!(MAGIC_COMMENT_REGEXP, '')
59
+
60
+ new_file_content = magic_comments + annotation + file_content
61
+ else
62
+ new_file_content = file_content + annotation
63
+ end
64
+
65
+ return new_file_content unless write
66
+ return new_file_content if file_content == new_file_content
67
+
68
+ ::File.write @file_name, new_file_content
69
+ new_file_content
70
+ end
71
+
72
+ # @param :write [Boolean]
73
+ # @return [String] New file content.
74
+ def remove_annotation(write: true)
75
+ file_content = ::File.read(@file_name)
76
+ new_file_content = file_content.sub(ANNOTATION_REGEXP, '')
77
+ return new_file_content unless write
78
+ return new_file_content if file_content == new_file_content
79
+
80
+ ::File.write @file_name, new_file_content
81
+ new_file_content
82
+ end
83
+
84
+ # @return [String]
85
+ def annotation
86
+ result = ::String.new
87
+ result << <<~DOC
88
+ #{ANNOTATION_START}
89
+ # @!parse
90
+ # class #{@klass} < #{@klass.superclass}
91
+ DOC
92
+
93
+ @klass.attribute_types.each do |name, attr_type|
94
+ result << <<~DOC
95
+ # # Database column `#{@klass.table_name}.#{name}`, type: `#{attr_type.type}`.
96
+ # # @param val [#{yard_type attr_type}, nil]
97
+ # def #{name}=(val); end
98
+ # # Database column `#{@klass.table_name}.#{name}`, type: `#{attr_type.type}`.
99
+ # # @return [#{yard_type attr_type}, nil]
100
+ # def #{name}; end
101
+ DOC
102
+ end
103
+
104
+ result << <<~DOC.chomp
105
+ # end
106
+ # #{ANNOTATION_END}
107
+ DOC
108
+ end
109
+
110
+ private
111
+
112
+ # @param attr_type [ActiveModel::Type::Value]
113
+ # @return [String]
114
+ def yard_type(attr_type)
115
+ return attr_type.coder.object_class.to_s if attr_type.respond_to?(:coder) && attr_type.coder.respond_to?(:object_class)
116
+ return 'Object' if attr_type.respond_to?(:coder) && attr_type.coder.is_a?(::ActiveRecord::Coders::JSON)
117
+
118
+ self.class.active_record_type_to_yard(attr_type.type)
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Rails
4
+ module Annotate
5
+ module Solargraph
6
+ VERSION = '0.1.0'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'set'
4
+
5
+ require_relative "solargraph/version"
6
+ require_relative "solargraph/configuration"
7
+ require_relative "solargraph/model"
8
+
9
+ module Rails
10
+ module Annotate
11
+ module Solargraph
12
+ class Error < ::StandardError; end
13
+ # @return [String]
14
+ MODEL_DIR = 'app/models'
15
+ # @return [String]
16
+ RAKEFILE_NAME = 'rails_annotate_solargraph.rake'
17
+ # @return [Configuration]
18
+ CONFIG = Configuration.new
19
+
20
+ class << self
21
+ # @return [Array<String>] Array of changed files.
22
+ def generate
23
+ modify_models :annotate
24
+ end
25
+
26
+ # @return [Array<String>] Array of changed files.
27
+ def remove
28
+ modify_models :remove_annotation
29
+ end
30
+
31
+ # @yieldparam [Configuration]
32
+ def configure
33
+ yield(CONFIG)
34
+ end
35
+
36
+ alias call generate
37
+
38
+ VALID_MODIFICATION_METHODS = ::Set[:annotate, :remove_annotation]
39
+
40
+ private
41
+
42
+ # @param method [Symbol] Name of the method that will be called on every loaded Model
43
+ # @return [Array<String>] Array of changed files.
44
+ def modify_models(method)
45
+ raise Error, "Invalid method. Got `#{method.inspect}`, but expected a member of `#{VALID_MODIFICATION_METHODS}`" \
46
+ unless VALID_MODIFICATION_METHODS.include? method
47
+
48
+ changed_files = []
49
+ model_files = ::Dir[::File.join(::Rails.root, MODEL_DIR, '**/*.rb')].map { |file| file.sub("#{::Rails.root}/", '') }.to_set
50
+
51
+ ::Rails.application.eager_load!
52
+ (::ApplicationRecord rescue ::ActiveRecord::Base).subclasses.each do |subclass|
53
+ subclass_file = ::File.join MODEL_DIR, "#{subclass.to_s.underscore}.rb"
54
+ next unless model_files.include? subclass_file
55
+
56
+ Model.new(subclass).public_send(method)
57
+ changed_files << subclass_file
58
+ end
59
+
60
+ changed_files
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/rails/annotate/solargraph/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "rails-annotate-solargraph"
7
+ spec.version = Rails::Annotate::Solargraph::VERSION
8
+ spec.authors = ["Mateusz Drewniak"]
9
+ spec.email = ["matmg24@gmail.com"]
10
+
11
+ spec.summary = "Annotate ActiveRecord models with schema comments formatted in YARD that are compatible with Solargraph."
12
+ spec.description = "Annotate ActiveRecord models with schema comments formatted in YARD that are compatible with Solargraph."
13
+ spec.homepage = "https://gitlab.com/mateuszdrewniak/rails-annotate-solargraph"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = ">= 2.7.0"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
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."
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
+ `git ls-files -z`.split("\x0").reject do |f|
25
+ (f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
26
+ end
27
+ end
28
+ spec.bindir = "exe"
29
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ["lib"]
31
+
32
+ # Uncomment to register a new dependency of your gem
33
+ spec.add_dependency 'rails', ">= 5.0", '< 8.0'
34
+
35
+ # For more information and examples about making a new gem, check out our
36
+ # guide at: https://bundler.io/guides/creating_gem.html
37
+ end
@@ -0,0 +1,8 @@
1
+ module Rails
2
+ module Annotate
3
+ module Solargraph
4
+ VERSION: String
5
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
6
+ end
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails-annotate-solargraph
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mateusz Drewniak
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-04-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '5.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '8.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '5.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '8.0'
33
+ description: Annotate ActiveRecord models with schema comments formatted in YARD that
34
+ are compatible with Solargraph.
35
+ email:
36
+ - matmg24@gmail.com
37
+ executables: []
38
+ extensions: []
39
+ extra_rdoc_files: []
40
+ files:
41
+ - ".rubocop.yml"
42
+ - ".ruby-gemset"
43
+ - ".ruby-version"
44
+ - ".vscode/settings.json"
45
+ - CHANGELOG.md
46
+ - Gemfile
47
+ - Gemfile.lock
48
+ - LICENSE.txt
49
+ - README.md
50
+ - Rakefile
51
+ - bin/console
52
+ - bin/setup
53
+ - lib/generators/annotate/solargraph/install_generator.rb
54
+ - lib/generators/annotate/solargraph/templates/rails_annotate_solargraph.rake
55
+ - lib/rails/annotate/solargraph.rb
56
+ - lib/rails/annotate/solargraph/configuration.rb
57
+ - lib/rails/annotate/solargraph/model.rb
58
+ - lib/rails/annotate/solargraph/version.rb
59
+ - rails-annotate-solargraph.gemspec
60
+ - readme_assets/annotation_generation_demo.gif
61
+ - readme_assets/automatic_annotations_demo.gif
62
+ - sig/rails/annotate/solargraph.rbs
63
+ homepage: https://gitlab.com/mateuszdrewniak/rails-annotate-solargraph
64
+ licenses:
65
+ - MIT
66
+ metadata:
67
+ homepage_uri: https://gitlab.com/mateuszdrewniak/rails-annotate-solargraph
68
+ source_code_uri: https://gitlab.com/mateuszdrewniak/rails-annotate-solargraph
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: 2.7.0
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubygems_version: 3.1.6
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: Annotate ActiveRecord models with schema comments formatted in YARD that
88
+ are compatible with Solargraph.
89
+ test_files: []