rbs_draper 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: 2e6df474118e1aa1523fc02aa5fd55e15d4c329ce9503147e2f252b69dc3656e
4
+ data.tar.gz: 78da07e88141b84609208766a4b270548da02964b313d2d462529c5afae9441a
5
+ SHA512:
6
+ metadata.gz: e1774f4eebbc89a4092d0c3b1e38e53886a1740d5bb6ac275f31ed48db0c28e1847746ce22080844d18c96b6173d2355dc87a60267abef9020d25d29c1346d0f
7
+ data.tar.gz: 68837472313ad5112d16741a02048dd8484d38b7a10c0aaabcdf437289f521a9834bbe4b207d67021b6a7884b9d9fd1e841d449565e51a7390c4912a49c391b4
data/.rubocop.yml ADDED
@@ -0,0 +1,20 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.0
3
+
4
+ Style/Documentation:
5
+ Enabled: false
6
+
7
+ Style/StringLiterals:
8
+ Enabled: true
9
+ EnforcedStyle: double_quotes
10
+
11
+ Style/StringLiteralsInInterpolation:
12
+ Enabled: true
13
+ EnforcedStyle: double_quotes
14
+
15
+ Layout/LineLength:
16
+ Max: 120
17
+
18
+ Metrics/BlockLength:
19
+ Exclude:
20
+ - spec/**/*.rb
@@ -0,0 +1,7 @@
1
+ {
2
+ "recommendations": [
3
+ "shopify.ruby-lsp",
4
+ "soutaro.steep-vscode",
5
+ "tk0miya.rspec-daemon"
6
+ ]
7
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "[ruby]": {
3
+ "editor.defaultFormatter": "Shopify.ruby-lsp"
4
+ }
5
+ }
@@ -0,0 +1,84 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
6
+
7
+ We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
8
+
9
+ ## Our Standards
10
+
11
+ Examples of behavior that contributes to a positive environment for our community include:
12
+
13
+ * Demonstrating empathy and kindness toward other people
14
+ * Being respectful of differing opinions, viewpoints, and experiences
15
+ * Giving and gracefully accepting constructive feedback
16
+ * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
17
+ * Focusing on what is best not just for us as individuals, but for the overall community
18
+
19
+ Examples of unacceptable behavior include:
20
+
21
+ * The use of sexualized language or imagery, and sexual attention or
22
+ advances of any kind
23
+ * Trolling, insulting or derogatory comments, and personal or political attacks
24
+ * Public or private harassment
25
+ * Publishing others' private information, such as a physical or email
26
+ address, without their explicit permission
27
+ * Other conduct which could reasonably be considered inappropriate in a
28
+ professional setting
29
+
30
+ ## Enforcement Responsibilities
31
+
32
+ Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
33
+
34
+ Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate.
35
+
36
+ ## Scope
37
+
38
+ This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event.
39
+
40
+ ## Enforcement
41
+
42
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at i.tkomiya@gmail.com. All complaints will be reviewed and investigated promptly and fairly.
43
+
44
+ All community leaders are obligated to respect the privacy and security of the reporter of any incident.
45
+
46
+ ## Enforcement Guidelines
47
+
48
+ Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct:
49
+
50
+ ### 1. Correction
51
+
52
+ **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
53
+
54
+ **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
55
+
56
+ ### 2. Warning
57
+
58
+ **Community Impact**: A violation through a single incident or series of actions.
59
+
60
+ **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
61
+
62
+ ### 3. Temporary Ban
63
+
64
+ **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior.
65
+
66
+ **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
67
+
68
+ ### 4. Permanent Ban
69
+
70
+ **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
71
+
72
+ **Consequence**: A permanent ban from any sort of public interaction within the community.
73
+
74
+ ## Attribution
75
+
76
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0,
77
+ available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
78
+
79
+ Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity).
80
+
81
+ [homepage]: https://www.contributor-covenant.org
82
+
83
+ For answers to common questions about this code of conduct, see the FAQ at
84
+ https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
data/Gemfile ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in rbs_draper.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
9
+
10
+ gem "rubocop", "~> 1.21"
11
+
12
+ group :development do
13
+ gem "rspec", require: false
14
+ gem "rspec-daemon", require: false
15
+
16
+ gem "steep"
17
+ end
18
+
19
+ # dependencies only for signature
20
+ group :signature do
21
+ gem "activerecord"
22
+ gem "railties"
23
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,179 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rbs_draper (0.1.0)
5
+ draper
6
+ rbs_rails
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actionpack (7.0.5)
12
+ actionview (= 7.0.5)
13
+ activesupport (= 7.0.5)
14
+ rack (~> 2.0, >= 2.2.4)
15
+ rack-test (>= 0.6.3)
16
+ rails-dom-testing (~> 2.0)
17
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
18
+ actionview (7.0.5)
19
+ activesupport (= 7.0.5)
20
+ builder (~> 3.1)
21
+ erubi (~> 1.4)
22
+ rails-dom-testing (~> 2.0)
23
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
24
+ activemodel (7.0.5)
25
+ activesupport (= 7.0.5)
26
+ activemodel-serializers-xml (1.0.2)
27
+ activemodel (> 5.x)
28
+ activesupport (> 5.x)
29
+ builder (~> 3.1)
30
+ activerecord (7.0.5)
31
+ activemodel (= 7.0.5)
32
+ activesupport (= 7.0.5)
33
+ activesupport (7.0.5)
34
+ concurrent-ruby (~> 1.0, >= 1.0.2)
35
+ i18n (>= 1.6, < 2)
36
+ minitest (>= 5.1)
37
+ tzinfo (~> 2.0)
38
+ ast (2.4.2)
39
+ builder (3.2.4)
40
+ coderay (1.1.3)
41
+ concurrent-ruby (1.2.2)
42
+ crass (1.0.6)
43
+ csv (3.2.6)
44
+ diff-lcs (1.5.0)
45
+ draper (4.0.2)
46
+ actionpack (>= 5.0)
47
+ activemodel (>= 5.0)
48
+ activemodel-serializers-xml (>= 1.0)
49
+ activesupport (>= 5.0)
50
+ request_store (>= 1.0)
51
+ ruby2_keywords
52
+ erubi (1.12.0)
53
+ ffi (1.15.5)
54
+ fileutils (1.7.1)
55
+ i18n (1.14.1)
56
+ concurrent-ruby (~> 1.0)
57
+ json (2.6.3)
58
+ language_server-protocol (3.17.0.3)
59
+ listen (3.8.0)
60
+ rb-fsevent (~> 0.10, >= 0.10.3)
61
+ rb-inotify (~> 0.9, >= 0.9.10)
62
+ logger (1.5.3)
63
+ loofah (2.21.3)
64
+ crass (~> 1.0.2)
65
+ nokogiri (>= 1.12.0)
66
+ method_source (1.0.0)
67
+ minitest (5.18.0)
68
+ nokogiri (1.15.2-x86_64-darwin)
69
+ racc (~> 1.4)
70
+ nokogiri (1.15.2-x86_64-linux)
71
+ racc (~> 1.4)
72
+ parallel (1.23.0)
73
+ parser (3.2.2.3)
74
+ ast (~> 2.4.1)
75
+ racc
76
+ pry (0.14.2)
77
+ coderay (~> 1.1)
78
+ method_source (~> 1.0)
79
+ racc (1.7.0)
80
+ rack (2.2.7)
81
+ rack-test (2.1.0)
82
+ rack (>= 1.3)
83
+ rails-dom-testing (2.0.3)
84
+ activesupport (>= 4.2.0)
85
+ nokogiri (>= 1.6)
86
+ rails-html-sanitizer (1.6.0)
87
+ loofah (~> 2.21)
88
+ nokogiri (~> 1.14)
89
+ railties (7.0.5)
90
+ actionpack (= 7.0.5)
91
+ activesupport (= 7.0.5)
92
+ method_source
93
+ rake (>= 12.2)
94
+ thor (~> 1.0)
95
+ zeitwerk (~> 2.5)
96
+ rainbow (3.1.1)
97
+ rake (13.0.6)
98
+ rb-fsevent (0.11.2)
99
+ rb-inotify (0.10.1)
100
+ ffi (~> 1.0)
101
+ rbs (3.1.0)
102
+ rbs_rails (0.12.0)
103
+ parser
104
+ rbs (>= 1)
105
+ regexp_parser (2.8.1)
106
+ request_store (1.5.1)
107
+ rack (>= 1.4)
108
+ rexml (3.2.5)
109
+ rspec (3.12.0)
110
+ rspec-core (~> 3.12.0)
111
+ rspec-expectations (~> 3.12.0)
112
+ rspec-mocks (~> 3.12.0)
113
+ rspec-core (3.12.2)
114
+ rspec-support (~> 3.12.0)
115
+ rspec-daemon (0.1.5)
116
+ pry
117
+ rspec
118
+ rspec-expectations (3.12.3)
119
+ diff-lcs (>= 1.2.0, < 2.0)
120
+ rspec-support (~> 3.12.0)
121
+ rspec-mocks (3.12.5)
122
+ diff-lcs (>= 1.2.0, < 2.0)
123
+ rspec-support (~> 3.12.0)
124
+ rspec-support (3.12.0)
125
+ rubocop (1.52.0)
126
+ json (~> 2.3)
127
+ parallel (~> 1.10)
128
+ parser (>= 3.2.0.0)
129
+ rainbow (>= 2.2.2, < 4.0)
130
+ regexp_parser (>= 1.8, < 3.0)
131
+ rexml (>= 3.2.5, < 4.0)
132
+ rubocop-ast (>= 1.28.0, < 2.0)
133
+ ruby-progressbar (~> 1.7)
134
+ unicode-display_width (>= 2.4.0, < 3.0)
135
+ rubocop-ast (1.29.0)
136
+ parser (>= 3.2.1.0)
137
+ ruby-progressbar (1.13.0)
138
+ ruby2_keywords (0.0.5)
139
+ securerandom (0.2.2)
140
+ steep (1.4.0)
141
+ activesupport (>= 5.1)
142
+ concurrent-ruby (>= 1.2.2)
143
+ csv (>= 3.0.9)
144
+ fileutils (>= 1.1.0)
145
+ json (>= 2.1.0)
146
+ language_server-protocol (>= 3.15, < 4.0)
147
+ listen (~> 3.0)
148
+ logger (>= 1.3.0)
149
+ parser (>= 3.1)
150
+ rainbow (>= 2.2.2, < 4.0)
151
+ rbs (>= 2.8.0)
152
+ securerandom (>= 0.1)
153
+ strscan (>= 1.0.0)
154
+ terminal-table (>= 2, < 4)
155
+ strscan (3.0.6)
156
+ terminal-table (3.0.2)
157
+ unicode-display_width (>= 1.1.1, < 3)
158
+ thor (1.2.2)
159
+ tzinfo (2.0.6)
160
+ concurrent-ruby (~> 1.0)
161
+ unicode-display_width (2.4.2)
162
+ zeitwerk (2.6.8)
163
+
164
+ PLATFORMS
165
+ x86_64-darwin-21
166
+ x86_64-linux
167
+
168
+ DEPENDENCIES
169
+ activerecord
170
+ railties
171
+ rake (~> 13.0)
172
+ rbs_draper!
173
+ rspec
174
+ rspec-daemon
175
+ rubocop (~> 1.21)
176
+ steep
177
+
178
+ BUNDLED WITH
179
+ 2.4.13
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 Takeshi KOMIYA
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,61 @@
1
+ # rbs_draper
2
+
3
+ rbs_draper is a generator for decorators using [Draper](https://github.com/drapergem/draper).
4
+
5
+ ## Installation
6
+
7
+ Add a new entry to your Gemfile and run `bundle install`:
8
+
9
+ group :development do
10
+ gem 'rbs_draper'
11
+ end
12
+
13
+ After the installation, please run rake task generator:
14
+
15
+ bundle exec rails g rbs_draper:install
16
+
17
+ Additionally, it would be better to add the following entry to your `rbs_collection.yml`:
18
+
19
+ gems:
20
+ - name: rbs_draper
21
+ ignore: true
22
+
23
+ ## Usage
24
+
25
+ 1. Run `rbs:draper:clean` at first
26
+ 2. Run other RBS generators (ex. `rbs prototype`, `rbs_rails` and so on)
27
+ 3. Run `rbs:draper:setup` task finally.
28
+
29
+ bundle exec rake rbs:draper:setup
30
+
31
+ Then rbs_draper will scan your source code and type signatures, and will generate
32
+ RBS files into `sig/draper` directory.
33
+
34
+ Note: rbs_draper uses other type signatures to generate decorators' signature.
35
+ So it should be run after other tasks.
36
+
37
+ ## Development
38
+
39
+ After checking out the repo, run `bin/setup` to install dependencies. You can also
40
+ run `bin/console` for an interactive prompt that will allow you to experiment.
41
+
42
+ To install this gem onto your local machine, run `bundle exec rake install`.
43
+
44
+ To release a new version, update the version number in `version.rb`, and then put
45
+ a git tag (ex. `git tag v1.0.0`) and push it to the GitHub. Then GitHub Actions
46
+ will release a new package to [rubygems.org](https://rubygems.org) automatically.
47
+
48
+ ## Contributing
49
+
50
+ Bug reports and pull requests are welcome on GitHub at https://github.com/tk0miya/rbs_draper.
51
+ This project is intended to be a safe, welcoming space for collaboration, and contributors are
52
+ expected to adhere to the [code of conduct](https://github.com/tk0miya/rbs_draper/blob/main/CODE_OF_CONDUCT.md).
53
+
54
+ ## License
55
+
56
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
57
+
58
+ ## Code of Conduct
59
+
60
+ Everyone interacting in the RbsDraper project's codebases, issue trackers is expected to
61
+ follow the [code of conduct](https://github.com/tk0miya/rbs_draper/blob/main/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rubocop/rake_task"
5
+
6
+ RuboCop::RakeTask.new
7
+
8
+ task default: :rubocop
data/Steepfile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ D = Steep::Diagnostic
4
+
5
+ target :lib do
6
+ signature "sig"
7
+
8
+ check "lib" # Directory name
9
+ check "Gemfile" # File name
10
+
11
+ configure_code_diagnostics(D::Ruby.lenient) # `lenient` diagnostics setting
12
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails"
4
+
5
+ module RbsDraper
6
+ class InstallGenerator < Rails::Generators::Base
7
+ def create_raketask
8
+ create_file "lib/tasks/rbs_draper.rake", <<~RUBY
9
+ begin
10
+ require 'rbs_draper/rake_task'
11
+ RbsDraper::RakeTask.new
12
+ rescue LoadError
13
+ # failed to load rbs_draper. Skip to load rbs_draper tasks.
14
+ end
15
+ RUBY
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "draper"
4
+ require "rbs_rails"
5
+
6
+ module RbsDraper
7
+ module Decoratable
8
+ def self.all
9
+ ObjectSpace.each_object.select do |obj|
10
+ obj.is_a?(Class) && obj.ancestors.include?(::Draper::Decoratable) && obj.decorator_class
11
+ rescue StandardError
12
+ nil
13
+ end
14
+ end
15
+
16
+ def self.class_to_rbs(klass)
17
+ Generator.new(klass).generate
18
+ end
19
+
20
+ class Generator
21
+ attr_reader :klass
22
+
23
+ def initialize(klass)
24
+ @klass = klass
25
+ end
26
+
27
+ def generate
28
+ RbsRails::Util.format_rbs klass_decl
29
+ end
30
+
31
+ private
32
+
33
+ def klass_decl
34
+ <<~RBS
35
+ #{header}
36
+ #{method_decls}
37
+ #{footer}
38
+ RBS
39
+ end
40
+
41
+ def header
42
+ module_defs = module_names.map { |module_name| "module #{module_name}" }
43
+
44
+ class_name = klass.name.split("::").last
45
+ class_def = if klass.superclass
46
+ "class #{class_name} < #{klass.superclass}"
47
+ else
48
+ "class #{class_name}"
49
+ end
50
+
51
+ (module_defs + [class_def]).join("\n")
52
+ end
53
+
54
+ def method_decls
55
+ "def decorate: () -> #{klass.decorator_class.name}"
56
+ end
57
+
58
+ def footer
59
+ "end\n" * klass.module_parents.size
60
+ end
61
+
62
+ def module_names
63
+ klass.module_parents.reverse[1..].map do |mod|
64
+ mod.name.split("::").last
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "draper"
4
+ require "rbs"
5
+ require "rbs_rails"
6
+
7
+ module RbsDraper
8
+ module Decorator
9
+ def self.class_to_rbs(klass, rbs_builder)
10
+ Generator.new(klass, rbs_builder).generate
11
+ end
12
+
13
+ class Generator
14
+ attr_reader :klass, :rbs_builder
15
+
16
+ def initialize(klass, rbs_builder)
17
+ @klass = klass
18
+ @rbs_builder = rbs_builder
19
+ end
20
+
21
+ def generate
22
+ return if decorated_class.blank?
23
+
24
+ RbsRails::Util.format_rbs klass_decl
25
+ end
26
+
27
+ private
28
+
29
+ def klass_decl
30
+ <<~RBS
31
+ #{header}
32
+ def object: () -> #{klass.name.sub(/Decorator$/, "")}
33
+
34
+ #{method_decls}
35
+ #{footer}
36
+ RBS
37
+ end
38
+
39
+ def header
40
+ module_defs = module_names.map { |module_name| "module #{module_name}" }
41
+
42
+ class_name = klass.name.split("::").last
43
+ class_def = if klass.superclass
44
+ "class #{class_name} < #{klass.superclass.name}"
45
+ else
46
+ "class #{class_name}"
47
+ end
48
+
49
+ (module_defs + [class_def]).join("\n")
50
+ end
51
+
52
+ def method_decls
53
+ delegated_methods.filter_map do |name, method|
54
+ next if user_defined_class&.methods&.fetch(name, nil)
55
+
56
+ "def #{name}: #{method.method_types.map(&:to_s).join(" | ")}"
57
+ end.join("\n")
58
+ end
59
+
60
+ def footer
61
+ "end\n" * klass.module_parents.size
62
+ end
63
+
64
+ def module_names
65
+ klass.module_parents.reverse[1..].map do |mod|
66
+ mod.name.split("::").last
67
+ end
68
+ end
69
+
70
+ def decorated_class
71
+ type_name = RBS::TypeName(klass.name.sub(/Decorator$/, "")).absolute!
72
+ @decorated_class ||= rbs_builder.build_instance(type_name)
73
+ rescue StandardError
74
+ nil
75
+ end
76
+
77
+ def delegated_methods
78
+ return [] unless klass.ancestors.include? ::Draper::AutomaticDelegation
79
+
80
+ decorated_class.methods.keys.sort.filter_map do |name|
81
+ method = decorated_class.methods[name]
82
+ next if %w[::Object ::BasicObject ::Kernel].include? method.defined_in.to_s
83
+
84
+ [name, method] if method.accessibility == :public
85
+ end
86
+ end
87
+
88
+ def user_defined_class
89
+ type_name = RBS::TypeName(klass.name.to_s).absolute!
90
+ @user_defined_class ||= rbs_builder.build_instance(type_name)
91
+ rescue StandardError
92
+ nil
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require "rbs/cli"
5
+ require "pathname"
6
+ require "rake"
7
+ require "rake/tasklib"
8
+
9
+ module RbsDraper
10
+ class RakeTask < Rake::TaskLib
11
+ attr_accessor :name, :signature_root_dir
12
+
13
+ def initialize(name = :'rbs:draper', &block)
14
+ super()
15
+
16
+ @name = name
17
+ @signature_root_dir = Pathname(Rails.root / "sig/draper")
18
+
19
+ block&.call(self)
20
+
21
+ define_clean_task
22
+ define_base_class_generate_task
23
+ define_decoratables_generate_task
24
+ define_decorators_generate_task
25
+ define_setup_task
26
+ end
27
+
28
+ def define_setup_task
29
+ desc "Run all tasks of rbs_draper"
30
+
31
+ deps = [:"#{name}:clean", :"#{name}:base_class:generate", :"#{name}:decoratables:generate",
32
+ :"#{name}:decorators:generate"]
33
+ task("#{name}:setup": deps)
34
+ end
35
+
36
+ def define_clean_task
37
+ desc "Clean up generated RBS files"
38
+ task("#{name}:clean": :environment) do
39
+ sh "rm", "-rf", signature_root_dir.to_s
40
+ end
41
+ end
42
+
43
+ def define_base_class_generate_task
44
+ desc "Generate RBS files for base classes"
45
+ task("#{name}:base_class:generate": :environment) do
46
+ signature_root_dir.mkpath
47
+
48
+ basedir = Pathname(__FILE__).dirname
49
+ FileUtils.cp basedir / "sig/decoratable.rbs", signature_root_dir
50
+ FileUtils.cp basedir / "sig/decorator.rbs", signature_root_dir
51
+ end
52
+ end
53
+
54
+ def define_decoratables_generate_task
55
+ desc "Generate RBS files for decoratable models"
56
+ task("#{name}:decoratables:generate": :environment) do
57
+ Rails.application.eager_load!
58
+
59
+ RbsDraper::Decoratable.all.each do |klass|
60
+ path = signature_root_dir / "app/models/#{klass.name.underscore}.rbs"
61
+ path.dirname.mkpath
62
+ rbs = RbsDraper::Decoratable.class_to_rbs(klass)
63
+ path.write rbs if rbs
64
+ end
65
+ end
66
+ end
67
+
68
+ def define_decorators_generate_task
69
+ desc "Generate RBS files for decorators"
70
+ task("#{name}:decorators:generate": :environment) do
71
+ Rails.application.eager_load!
72
+
73
+ Draper::Decorator.descendants.each do |klass|
74
+ path = signature_root_dir / "app/decorators/#{klass.name.underscore}.rbs"
75
+ path.dirname.mkpath
76
+ rbs = RbsDraper::Decorator.class_to_rbs(klass, rbs_builder)
77
+ path.write rbs if rbs
78
+ end
79
+ end
80
+ end
81
+
82
+ private
83
+
84
+ def rbs_builder
85
+ return @rbs_builder if @rbs_builder
86
+
87
+ loader = RBS::CLI::LibraryOptions.new.loader
88
+ loader.add path: Pathname("sig")
89
+ @rbs_builder = RBS::DefinitionBuilder.new env: RBS::Environment.from_loader(loader).resolve_type_names
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,6 @@
1
+ module Draper
2
+ module Decoratable
3
+ def decorated?: () -> bool
4
+ def decorated_with?: (untyped decorator_class) -> bool
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Draper
2
+ class Decorator
3
+ def decorated?: () -> bool
4
+ def decorated_with?: (untyped decorator_class) -> bool
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RbsDraper
4
+ VERSION = "0.1.0"
5
+ end
data/lib/rbs_draper.rb ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "rbs_draper/decoratable"
4
+ require_relative "rbs_draper/decorator"
5
+ require_relative "rbs_draper/rake_task"
6
+ require_relative "rbs_draper/version"
7
+
8
+ module RbsDraper
9
+ class Error < StandardError; end
10
+ # Your code goes here...
11
+ end
@@ -0,0 +1,202 @@
1
+ ---
2
+ sources:
3
+ - type: git
4
+ name: ruby/gem_rbs_collection
5
+ revision: 280d44d7671abfa909f2966fbef94bca5be082de
6
+ remote: https://github.com/ruby/gem_rbs_collection.git
7
+ repo_dir: gems
8
+ path: ".gem_rbs_collection"
9
+ gems:
10
+ - name: abbrev
11
+ version: '0'
12
+ source:
13
+ type: stdlib
14
+ - name: actionpack
15
+ version: '6.0'
16
+ source:
17
+ type: git
18
+ name: ruby/gem_rbs_collection
19
+ revision: 280d44d7671abfa909f2966fbef94bca5be082de
20
+ remote: https://github.com/ruby/gem_rbs_collection.git
21
+ repo_dir: gems
22
+ - name: actionview
23
+ version: '6.0'
24
+ source:
25
+ type: git
26
+ name: ruby/gem_rbs_collection
27
+ revision: 280d44d7671abfa909f2966fbef94bca5be082de
28
+ remote: https://github.com/ruby/gem_rbs_collection.git
29
+ repo_dir: gems
30
+ - name: activemodel
31
+ version: '7.0'
32
+ source:
33
+ type: git
34
+ name: ruby/gem_rbs_collection
35
+ revision: 280d44d7671abfa909f2966fbef94bca5be082de
36
+ remote: https://github.com/ruby/gem_rbs_collection.git
37
+ repo_dir: gems
38
+ - name: activerecord
39
+ version: '7.0'
40
+ source:
41
+ type: git
42
+ name: ruby/gem_rbs_collection
43
+ revision: 280d44d7671abfa909f2966fbef94bca5be082de
44
+ remote: https://github.com/ruby/gem_rbs_collection.git
45
+ repo_dir: gems
46
+ - name: activesupport
47
+ version: '7.0'
48
+ source:
49
+ type: git
50
+ name: ruby/gem_rbs_collection
51
+ revision: 280d44d7671abfa909f2966fbef94bca5be082de
52
+ remote: https://github.com/ruby/gem_rbs_collection.git
53
+ repo_dir: gems
54
+ - name: ast
55
+ version: '2.4'
56
+ source:
57
+ type: git
58
+ name: ruby/gem_rbs_collection
59
+ revision: 280d44d7671abfa909f2966fbef94bca5be082de
60
+ remote: https://github.com/ruby/gem_rbs_collection.git
61
+ repo_dir: gems
62
+ - name: cgi
63
+ version: '0'
64
+ source:
65
+ type: stdlib
66
+ - name: concurrent-ruby
67
+ version: '1.1'
68
+ source:
69
+ type: git
70
+ name: ruby/gem_rbs_collection
71
+ revision: 280d44d7671abfa909f2966fbef94bca5be082de
72
+ remote: https://github.com/ruby/gem_rbs_collection.git
73
+ repo_dir: gems
74
+ - name: date
75
+ version: '0'
76
+ source:
77
+ type: stdlib
78
+ - name: i18n
79
+ version: '1.10'
80
+ source:
81
+ type: git
82
+ name: ruby/gem_rbs_collection
83
+ revision: 280d44d7671abfa909f2966fbef94bca5be082de
84
+ remote: https://github.com/ruby/gem_rbs_collection.git
85
+ repo_dir: gems
86
+ - name: json
87
+ version: '0'
88
+ source:
89
+ type: stdlib
90
+ - name: logger
91
+ version: '0'
92
+ source:
93
+ type: stdlib
94
+ - name: minitest
95
+ version: '0'
96
+ source:
97
+ type: stdlib
98
+ - name: monitor
99
+ version: '0'
100
+ source:
101
+ type: stdlib
102
+ - name: mutex_m
103
+ version: '0'
104
+ source:
105
+ type: stdlib
106
+ - name: nokogiri
107
+ version: '1.11'
108
+ source:
109
+ type: git
110
+ name: ruby/gem_rbs_collection
111
+ revision: 280d44d7671abfa909f2966fbef94bca5be082de
112
+ remote: https://github.com/ruby/gem_rbs_collection.git
113
+ repo_dir: gems
114
+ - name: optparse
115
+ version: '0'
116
+ source:
117
+ type: stdlib
118
+ - name: parallel
119
+ version: '1.20'
120
+ source:
121
+ type: git
122
+ name: ruby/gem_rbs_collection
123
+ revision: 280d44d7671abfa909f2966fbef94bca5be082de
124
+ remote: https://github.com/ruby/gem_rbs_collection.git
125
+ repo_dir: gems
126
+ - name: pathname
127
+ version: '0'
128
+ source:
129
+ type: stdlib
130
+ - name: rack
131
+ version: '2.2'
132
+ source:
133
+ type: git
134
+ name: ruby/gem_rbs_collection
135
+ revision: 280d44d7671abfa909f2966fbef94bca5be082de
136
+ remote: https://github.com/ruby/gem_rbs_collection.git
137
+ repo_dir: gems
138
+ - name: rails-dom-testing
139
+ version: '2.0'
140
+ source:
141
+ type: git
142
+ name: ruby/gem_rbs_collection
143
+ revision: 280d44d7671abfa909f2966fbef94bca5be082de
144
+ remote: https://github.com/ruby/gem_rbs_collection.git
145
+ repo_dir: gems
146
+ - name: railties
147
+ version: '6.0'
148
+ source:
149
+ type: git
150
+ name: ruby/gem_rbs_collection
151
+ revision: 280d44d7671abfa909f2966fbef94bca5be082de
152
+ remote: https://github.com/ruby/gem_rbs_collection.git
153
+ repo_dir: gems
154
+ - name: rainbow
155
+ version: '3.0'
156
+ source:
157
+ type: git
158
+ name: ruby/gem_rbs_collection
159
+ revision: 280d44d7671abfa909f2966fbef94bca5be082de
160
+ remote: https://github.com/ruby/gem_rbs_collection.git
161
+ repo_dir: gems
162
+ - name: rbs
163
+ version: 3.1.0
164
+ source:
165
+ type: rubygems
166
+ - name: rbs_rails
167
+ version: 0.12.0
168
+ source:
169
+ type: rubygems
170
+ - name: rdoc
171
+ version: '0'
172
+ source:
173
+ type: stdlib
174
+ - name: request_store
175
+ version: '1.5'
176
+ source:
177
+ type: git
178
+ name: ruby/gem_rbs_collection
179
+ revision: 280d44d7671abfa909f2966fbef94bca5be082de
180
+ remote: https://github.com/ruby/gem_rbs_collection.git
181
+ repo_dir: gems
182
+ - name: singleton
183
+ version: '0'
184
+ source:
185
+ type: stdlib
186
+ - name: tempfile
187
+ version: '0'
188
+ source:
189
+ type: stdlib
190
+ - name: time
191
+ version: '0'
192
+ source:
193
+ type: stdlib
194
+ - name: tsort
195
+ version: '0'
196
+ source:
197
+ type: stdlib
198
+ - name: uri
199
+ version: '0'
200
+ source:
201
+ type: stdlib
202
+ gemfile_lock_path: Gemfile.lock
@@ -0,0 +1,20 @@
1
+ # Download sources
2
+ sources:
3
+ - type: git
4
+ name: ruby/gem_rbs_collection
5
+ remote: https://github.com/ruby/gem_rbs_collection.git
6
+ revision: main
7
+ repo_dir: gems
8
+
9
+ # You can specify local directories as sources also.
10
+ # - type: local
11
+ # path: path/to/your/local/repository
12
+
13
+ # A directory to install the downloaded RBSs
14
+ path: .gem_rbs_collection
15
+
16
+ gems:
17
+ # Skip loading rbs gem's RBS.
18
+ # It's unnecessary if you don't use rbs as a library.
19
+ - name: steep
20
+ ignore: true
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/rbs_draper/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "rbs_draper"
7
+ spec.version = RbsDraper::VERSION
8
+ spec.authors = ["Takeshi KOMIYA"]
9
+ spec.email = ["i.tkomiya@gmail.com"]
10
+
11
+ spec.summary = "A RBS files generator for Draper decorators"
12
+ spec.description = "A RBS files generator for Draper decorators"
13
+ spec.homepage = "https://github.com/tk0miya/rbs_draper"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = ">= 3.0"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = spec.homepage
19
+ spec.metadata["changelog_uri"] = spec.homepage
20
+
21
+ spec.files = Dir.chdir(__dir__) do
22
+ `git ls-files -z`.split("\x0").reject do |f|
23
+ (File.expand_path(f) == __FILE__) || f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor])
24
+ end
25
+ end
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_dependency "draper"
31
+ spec.add_dependency "rbs_rails"
32
+
33
+ # For more information and examples about making a new gem, check out our
34
+ # guide at: https://bundler.io/guides/creating_gem.html
35
+ end
@@ -0,0 +1,21 @@
1
+ module RbsDraper
2
+ module Decoratable
3
+ def self.all: () -> Array[Class]
4
+ def self.class_to_rbs: (Class klass) -> String
5
+
6
+ class Generator
7
+ attr_reader klass: Class
8
+
9
+ def initialize: (Class klass) -> void
10
+ def generate: () -> String
11
+
12
+ private
13
+
14
+ def klass_decl: () -> String
15
+ def header: () -> String
16
+ def method_decls: () -> String
17
+ def footer: () -> String
18
+ def module_names: () -> Array[String]
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ module RbsDraper
2
+ module Decorator
3
+ def self.class_to_rbs: (Class klass, RBS::DefinitionBuilder rbs_builder) -> String?
4
+
5
+ class Generator
6
+ attr_reader klass: Class
7
+ attr_reader rbs_builder: RBS::DefinitionBuilder
8
+
9
+ @decorated_class: RBS::Definition
10
+ @user_defined_class: RBS::Definition
11
+
12
+ def initialize: (Class klass, RBS::DefinitionBuilder rbs_builder) -> void
13
+ def generate: () -> String?
14
+
15
+ private
16
+
17
+ def klass_decl: () -> String
18
+ def header: () -> String
19
+ def method_decls: () -> String?
20
+ def footer: () -> String
21
+ def module_names: () -> Array[String]
22
+ def decorated_class: () -> RBS::Definition?
23
+ def delegated_methods: () -> Array[[Symbol, RBS::Definition]]
24
+ def user_defined_class: () -> RBS::Definition?
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ module RbsDraper
2
+ class RakeTask < Rake::TaskLib
3
+ attr_accessor name: Symbol
4
+ attr_accessor signature_root_dir: Pathname
5
+
6
+ @name: Symbol
7
+ @rbs_builder: RBS::DefinitionBuilder
8
+ @signature_root_dir: Pathname
9
+
10
+ def initialize: (?Symbol name) ?{ (RakeTask) -> void } -> void
11
+ def define_setup_task: () -> void
12
+ def define_clean_task: () -> void
13
+ def define_base_class_generate_task: () -> void
14
+ def define_decoratables_generate_task: () -> void
15
+ def define_decorators_generate_task: () -> void
16
+
17
+ private
18
+
19
+ def rbs_builder: () -> RBS::DefinitionBuilder
20
+ end
21
+ end
@@ -0,0 +1,4 @@
1
+ module RbsDraper
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rbs_draper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Takeshi KOMIYA
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-06-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: draper
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rbs_rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: A RBS files generator for Draper decorators
42
+ email:
43
+ - i.tkomiya@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".rubocop.yml"
49
+ - ".vscode/extensions.json"
50
+ - ".vscode/settings.json"
51
+ - CODE_OF_CONDUCT.md
52
+ - Gemfile
53
+ - Gemfile.lock
54
+ - LICENSE.txt
55
+ - README.md
56
+ - Rakefile
57
+ - Steepfile
58
+ - lib/generators/rbs_draper/install_generator.rb
59
+ - lib/rbs_draper.rb
60
+ - lib/rbs_draper/decoratable.rb
61
+ - lib/rbs_draper/decorator.rb
62
+ - lib/rbs_draper/rake_task.rb
63
+ - lib/rbs_draper/sig/decoratable.rbs
64
+ - lib/rbs_draper/sig/decorator.rbs
65
+ - lib/rbs_draper/version.rb
66
+ - rbs_collection.lock.yaml
67
+ - rbs_collection.yaml
68
+ - rbs_draper.gemspec
69
+ - sig/rbs_draper.rbs
70
+ - sig/rbs_draper/decoratable.rbs
71
+ - sig/rbs_draper/decorator.rbs
72
+ - sig/rbs_draper/rake_task.rbs
73
+ homepage: https://github.com/tk0miya/rbs_draper
74
+ licenses:
75
+ - MIT
76
+ metadata:
77
+ homepage_uri: https://github.com/tk0miya/rbs_draper
78
+ source_code_uri: https://github.com/tk0miya/rbs_draper
79
+ changelog_uri: https://github.com/tk0miya/rbs_draper
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '3.0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubygems_version: 3.4.10
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: A RBS files generator for Draper decorators
99
+ test_files: []