shale-builder 0.1.5 → 0.1.6

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: c029074a32dcf979db1589f717921bec3739c32cd81d6e3885ade102119d1612
4
- data.tar.gz: 7dfd4acf1e1e2442b39a8c62510f2ee332b1ada7e55a346ea7709901cdf3520d
3
+ metadata.gz: 15122ca23e6581da8b35ea0567084d915cb5fca400179505ad618470a6b5b014
4
+ data.tar.gz: 65c523711576535345141f10d2f656a892a29d111bde9f661310b0a01158b5c4
5
5
  SHA512:
6
- metadata.gz: 6d805f195b379215bc3e10b748919ba10ba3e51abb80c3973679a3546aff1f577983abd383cf1551e48da5fa1511b0110b4e4d5ac28a071f17f3f4ea3216a8c6
7
- data.tar.gz: ad11f0fb55e725fa3145941d56ac4727b3080b0dfcccceb6acc83d81afea8766b2fa7131725a83d50f9cda62090c1cd17d0cdb54d5db517723a2dbb8a350253a
6
+ metadata.gz: b2fb0f51350d3b412a92fc1c20fd3dc470313a403dbeb2a13196ad7bf7b4423cc7a6cb4862c434106964e1a3d9597c68b2648f715cbfbf77344a2b0450e7c08c
7
+ data.tar.gz: c87b6e5e6a75c80fc3b08a2c2473e7d775c452b85fcc890ac940848223c65ff847824816382922cd88c80f22c4d4f9b67cca0cacc0455b6d35de9926d1f53998
data/.rubocop.yml CHANGED
@@ -5,3 +5,9 @@ AllCops:
5
5
  TargetRubyVersion: 3.0
6
6
  Exclude:
7
7
  - lib/tapioca/**/*.rb
8
+
9
+ Style/DocumentationMethod:
10
+ Enabled: false
11
+
12
+ Style/TrailingCommaInArguments:
13
+ Enabled: false
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [0.1.6] - 2024-05-13
2
+
3
+ - Add support for doc strings in the tapioca compiler
4
+
1
5
  ## [0.1.5] - 2024-05-13
2
6
 
3
7
  - Fix a bug in the tapioca compiler
data/Gemfile CHANGED
@@ -11,3 +11,4 @@ gem 'rake', '~> 13.0' # automation tasks
11
11
  gem 'rubocop-espago', '~> 1.0' # ruby linter
12
12
  gem 'shoulda-context', '~> 2.0' # more pleasant test syntax
13
13
  gem 'solargraph', '~> 0.48' # language server
14
+ gem 'tapioca', '> 0.13' # RBI generator for sorbet
data/Gemfile.lock CHANGED
@@ -1,8 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- shale-builder (0.1.5)
4
+ shale-builder (0.1.6)
5
+ booleans (>= 0.1)
5
6
  shale (< 2.0)
7
+ sorbet-runtime (> 0.5)
6
8
 
7
9
  GEM
8
10
  remote: https://rubygems.org/
@@ -10,9 +12,11 @@ GEM
10
12
  ast (2.4.2)
11
13
  backport (1.2.0)
12
14
  benchmark (0.2.1)
15
+ booleans (0.1.1)
13
16
  byebug (11.1.3)
14
17
  diff-lcs (1.5.0)
15
18
  e2mmap (0.1.0)
19
+ erubi (1.12.0)
16
20
  jaro_winkler (1.5.4)
17
21
  json (2.6.3)
18
22
  kramdown (2.4.0)
@@ -20,6 +24,7 @@ GEM
20
24
  kramdown-parser-gfm (1.1.0)
21
25
  kramdown (~> 2.0)
22
26
  minitest (5.17.0)
27
+ netrc (0.11.0)
23
28
  nokogiri (1.14.2-arm64-darwin)
24
29
  racc (~> 1.4)
25
30
  nokogiri (1.14.2-x86_64-linux)
@@ -27,9 +32,13 @@ GEM
27
32
  parallel (1.22.1)
28
33
  parser (3.2.1.0)
29
34
  ast (~> 2.4.1)
35
+ prism (0.29.0)
30
36
  racc (1.6.2)
31
37
  rainbow (3.1.1)
32
38
  rake (13.0.6)
39
+ rbi (0.1.13)
40
+ prism (>= 0.18.0, < 1.0.0)
41
+ sorbet-runtime (>= 0.5.9204)
33
42
  regexp_parser (2.7.0)
34
43
  reverse_markdown (2.1.1)
35
44
  nokogiri
@@ -66,12 +75,37 @@ GEM
66
75
  thor (~> 1.0)
67
76
  tilt (~> 2.0)
68
77
  yard (~> 0.9, >= 0.9.24)
78
+ sorbet (0.5.11372)
79
+ sorbet-static (= 0.5.11372)
80
+ sorbet-runtime (0.5.11372)
81
+ sorbet-static (0.5.11372-universal-darwin)
82
+ sorbet-static (0.5.11372-x86_64-linux)
83
+ sorbet-static-and-runtime (0.5.11372)
84
+ sorbet (= 0.5.11372)
85
+ sorbet-runtime (= 0.5.11372)
86
+ spoom (1.3.2)
87
+ erubi (>= 1.10.0)
88
+ prism (>= 0.19.0)
89
+ sorbet-static-and-runtime (>= 0.5.10187)
90
+ thor (>= 0.19.2)
91
+ tapioca (0.14.1)
92
+ bundler (>= 2.2.25)
93
+ netrc (>= 0.11.0)
94
+ parallel (>= 1.21.0)
95
+ rbi (>= 0.1.4, < 0.2)
96
+ sorbet-static-and-runtime (>= 0.5.11087)
97
+ spoom (>= 1.2.0)
98
+ thor (>= 1.2.0)
99
+ yard-sorbet
69
100
  thor (1.2.1)
70
101
  tilt (2.1.0)
71
102
  unicode-display_width (2.4.2)
72
103
  webrick (1.7.0)
73
104
  yard (0.9.28)
74
105
  webrick (~> 1.7.0)
106
+ yard-sorbet (0.8.1)
107
+ sorbet-runtime (>= 0.5)
108
+ yard (>= 0.9)
75
109
 
76
110
  PLATFORMS
77
111
  arm64-darwin-20
@@ -86,6 +120,7 @@ DEPENDENCIES
86
120
  shale-builder!
87
121
  shoulda-context (~> 2.0)
88
122
  solargraph (~> 0.48)
123
+ tapioca (> 0.13)
89
124
 
90
125
  BUNDLED WITH
91
126
  2.4.7
data/README.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  This addon to the [shale](https://github.com/kgiszczak/shale) Ruby gem adds a simple yet powerful builder DSL.
4
4
 
5
+ It also adds support for sorbet and tapioca in shale.
6
+ This gem includes a custom tapioca DSL compiler designed for shale.
7
+
5
8
  ## Installation
6
9
 
7
10
  Install the gem and add to the application's Gemfile by executing:
@@ -48,7 +51,11 @@ class Amount < Shale::Mapper
48
51
  include Shale::Builder
49
52
 
50
53
  attribute :value, Shale::Type::Float
51
- attribute :currency, Shale::Type::String
54
+ attribute :currency, Shale::Type::String, doc: <<~DOC
55
+ This is some custom documentation that can be used by sorbet.
56
+ It will be used by the tapioca DSL compiler
57
+ to generate the RBI documentation for this attribute.
58
+ DOC
52
59
  end
53
60
  ```
54
61
 
@@ -67,6 +74,36 @@ amount = Amount.build do |a|
67
74
  end
68
75
  ```
69
76
 
77
+ If you use sorbet and run `bundle exec tapioca dsl` you'll get the following RBI file.
78
+
79
+ ```rb
80
+ # typed: true
81
+
82
+ class Amount
83
+ include ShaleAttributeMethods
84
+
85
+ module ShaleAttributeMethods
86
+ sig { returns(T.nilable(Float)) }
87
+ def value; end
88
+
89
+ sig { params(value: T.nilable(Float)).returns(T.nilable(Float)) }
90
+ def value=(value); end
91
+
92
+ # This is some custom documentation that can be used by sorbet.
93
+ # It will be used by the tapioca DSL compiler
94
+ # to generate the RBI documentation for this attribute.
95
+ sig { returns(T.nilable(String)) }
96
+ def currency; end
97
+
98
+ # This is some custom documentation that can be used by sorbet.
99
+ # It will be used by the tapioca DSL compiler
100
+ # to generate the RBI documentation for this attribute.
101
+ sig { params(value: T.nilable(String)).returns(T.nilable(String)) }
102
+ def currency=(value); end
103
+ end
104
+ end
105
+ ```
106
+
70
107
  ### Building nested objects
71
108
 
72
109
  It's kind of pointless when you've got a flat structure.
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+ # typed: true
3
+
4
+ require 'shale'
5
+
6
+ module Shale
7
+ class Attribute # rubocop:disable Style/Documentation
8
+ extend T::Sig
9
+
10
+ # Contains the documentation comment for the shale attribute
11
+ # in a Ruby String.
12
+ sig { returns(T.nilable(String)) }
13
+ attr_accessor :doc
14
+ end
15
+ end
@@ -2,7 +2,6 @@
2
2
 
3
3
  module Shale
4
4
  module Builder
5
- # @return [String]
6
- VERSION = '0.1.5'
5
+ VERSION = '0.1.6'
7
6
  end
8
7
  end
data/lib/shale/builder.rb CHANGED
@@ -1,8 +1,11 @@
1
1
  # frozen_string_literal: true
2
+ # typed: true
2
3
 
3
4
  require 'shale'
5
+ require 'sorbet-runtime'
4
6
 
5
7
  require_relative 'builder/version'
8
+ require_relative 'attribute'
6
9
 
7
10
  module Shale
8
11
  # It's meant to be included in subclasses of `Shale::Mapper`
@@ -37,11 +40,13 @@ module Shale
37
40
  # end
38
41
  #
39
42
  module Builder
43
+ extend T::Helpers
44
+
40
45
  class << self
46
+ extend T::Sig
47
+
41
48
  # Gets called after including this module in a module or class.
42
- #
43
- # @param mod [Module, Class]
44
- # @return [void]
49
+ sig { params(mod: Module).void }
45
50
  def included(mod)
46
51
  mod.extend ClassMethods
47
52
  Builder.prepare_mod(mod)
@@ -49,9 +54,7 @@ module Shale
49
54
 
50
55
  # Prepares the received module or class
51
56
  # for dynamic method definition.
52
- #
53
- # @param mod [Module, Class]
54
- # @return [void]
57
+ sig { params(mod: Module).void }
55
58
  def prepare_mod(mod)
56
59
  builder_methods_module = ::Module.new
57
60
  mod.instance_variable_set :@builder_methods_module, builder_methods_module
@@ -61,8 +64,12 @@ module Shale
61
64
 
62
65
  # Class methods provided by `Shale::Builder`
63
66
  module ClassMethods
64
- # @param subclass [Class]
65
- # @return [void]
67
+ extend T::Sig
68
+ extend T::Generic
69
+ abstract!
70
+ has_attached_class!
71
+
72
+ sig { params(subclass: Class).void }
66
73
  def inherited(subclass)
67
74
  super
68
75
  Builder.prepare_mod(subclass)
@@ -70,27 +77,37 @@ module Shale
70
77
 
71
78
  # Contains overridden getter methods for attributes
72
79
  # with complex types (so that they accept a block for building)
73
- #
74
- # @return [Module]
80
+ sig { returns(Module) }
75
81
  attr_reader :builder_methods_module
76
82
 
77
- # @return [Class, nil]
78
- attr_accessor :request_class
79
-
80
- # @yieldparam [self]
81
- # @return [self]
82
- def build
83
+ sig { params(_block: T.proc.params(arg0: T.attached_class).void).returns(T.attached_class) }
84
+ def build(&_block)
83
85
  body = new
84
86
  yield(body)
85
87
 
86
88
  body
87
89
  end
88
90
 
89
- # @param name [String, Symbol]
90
- # @param type [Class]
91
- # @return [void]
92
- def attribute(name, type, *args, collection: false, **kwargs, &block)
93
- super
91
+ sig { abstract.returns(T.attached_class) }
92
+ def new; end
93
+
94
+ sig { abstract.returns(T::Hash[Symbol, Shale::Attribute]) }
95
+ def attributes; end
96
+
97
+ sig do
98
+ params(
99
+ name: T.any(String, Symbol),
100
+ type: Class,
101
+ collection: T::Boolean,
102
+ default: T.nilable(Proc),
103
+ doc: T.nilable(String),
104
+ kwargs: Object,
105
+ block: T.nilable(T.proc.void),
106
+ ).void
107
+ end
108
+ def attribute(name, type, collection: false, default: nil, doc: nil, **kwargs, &block)
109
+ super(name, type, collection: collection, default: default, **kwargs, &block)
110
+ attributes[name.to_sym]&.doc = doc # add doc to the attribute
94
111
  return unless type < ::Shale::Mapper
95
112
 
96
113
  if collection
@@ -121,5 +138,7 @@ module Shale
121
138
 
122
139
  end
123
140
 
141
+ mixes_in_class_methods(ClassMethods)
142
+
124
143
  end
125
144
  end
@@ -2,6 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'shale'
5
+ require 'booleans'
5
6
  begin
6
7
  require 'shale/builder'
7
8
  rescue LoadError
@@ -10,9 +11,12 @@ end
10
11
  module Tapioca
11
12
  module Compilers
12
13
  class Shale < Tapioca::Dsl::Compiler
14
+ extend T::Sig
13
15
  ConstantType = type_member { { fixed: T.class_of(::Shale::Mapper) } }
14
16
 
15
17
  class << self
18
+ extend T::Sig
19
+
16
20
  sig { override.returns(T::Enumerable[Module]) }
17
21
  def gather_constants
18
22
  # Collect all the classes that inherit from Shale::Mapper
@@ -20,19 +24,27 @@ module Tapioca
20
24
  end
21
25
  end
22
26
 
27
+ SHALE_ATTRIBUTE_MODULE = 'ShaleAttributeMethods'
28
+
23
29
  sig { override.void }
24
30
  def decorate
25
31
  # Create a RBI definition for each class that inherits from Shale::Mapper
26
32
  root.create_path(constant) do |klass|
27
33
  has_shale_builder = includes_shale_builder(constant)
28
-
34
+ mod = klass.create_module(SHALE_ATTRIBUTE_MODULE)
35
+ klass.create_include(SHALE_ATTRIBUTE_MODULE)
29
36
  # For each attribute defined in the class
30
37
  constant.attributes.each_value do |attribute|
38
+ attribute = T.let(attribute, ::Shale::Attribute)
31
39
  non_nilable_type, nilable_type = shale_type_to_sorbet_type(attribute)
32
40
  type = nilable_type
33
41
  if attribute.collection?
34
42
  type = "T.nilable(T::Array[#{non_nilable_type}])"
35
43
  end
44
+ comments = T.let([], T::Array[RBI::Comment])
45
+ if shale_builder_defined? && attribute.doc
46
+ comments << RBI::Comment.new(T.must(attribute.doc))
47
+ end
36
48
 
37
49
  if has_shale_builder && attribute.type < ::Shale::Mapper
38
50
  sigs = T.let([], T::Array[RBI::Sig])
@@ -46,20 +58,22 @@ module Tapioca
46
58
  parameters: { block: "T.proc.params(arg0: #{non_nilable_type}).void" },
47
59
  return_type: non_nilable_type
48
60
  )
49
- klass.create_method_with_sigs(
61
+ mod.create_method_with_sigs(
50
62
  attribute.name,
51
63
  sigs: sigs,
64
+ comments: comments,
52
65
  parameters: [RBI::BlockParam.new('block')],
53
66
  )
54
67
  else
55
- klass.create_method(attribute.name, return_type: type)
68
+ mod.create_method(attribute.name, return_type: type, comments: comments)
56
69
  end
57
70
 
58
71
  # setter
59
- klass.create_method(
72
+ mod.create_method(
60
73
  "#{attribute.name}=",
61
74
  parameters: [create_param('value', type: type)],
62
75
  return_type: type,
76
+ comments: comments,
63
77
  )
64
78
  end
65
79
  end
@@ -75,6 +89,9 @@ module Tapioca
75
89
  klass < ::Shale::Builder
76
90
  end
77
91
 
92
+ sig { returns(T::Boolean) }
93
+ def shale_builder_defined? = Boolean(defined?(::Shale::Builder))
94
+
78
95
  SHALE_TYPES_MAP = T.let(
79
96
  {
80
97
  ::Shale::Type::Value => Object,
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shale-builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mateusz Drewniak
@@ -10,6 +10,20 @@ bindir: exe
10
10
  cert_chain: []
11
11
  date: 2024-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: booleans
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0.1'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: shale
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -24,6 +38,20 @@ dependencies:
24
38
  - - "<"
25
39
  - !ruby/object:Gem::Version
26
40
  version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sorbet-runtime
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.5'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.5'
27
55
  description: An addon to the shale Ruby gem which adds a simple yet powerful builder
28
56
  DSL.
29
57
  email:
@@ -40,6 +68,7 @@ files:
40
68
  - LICENSE
41
69
  - README.md
42
70
  - Rakefile
71
+ - lib/shale/attribute.rb
43
72
  - lib/shale/builder.rb
44
73
  - lib/shale/builder/version.rb
45
74
  - lib/tapioca/dsl/compilers/shale.rb