sord 1.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 86ef36c437c7c9a02b0cc18fddd6c11253f4d0be6f9d68283c8039cfd69d310e
4
- data.tar.gz: 38f53748c92a22b44745d8fff1dfca5fe41ee4b4424b3c61c63853d07eb5d396
3
+ metadata.gz: c04d27e18791a912df49bf20c04c3d8555c04ce7f4e9d97d566398c705b4d826
4
+ data.tar.gz: c9868a430d1cace15d5c11463c7718aa768e2f4b195c9877ba0cb9a995bb8d7e
5
5
  SHA512:
6
- metadata.gz: 3359eca2a431b010b81c9920f6dd2705422df7ee3b47ab014caf63d498168945e14e5b3ba789ab08dff2b1a081682ae0d05de3c1796d2ac948778ca1a8a8c9c5
7
- data.tar.gz: 92ef1253541f9d4a837486fe51a886341251db0acc145d224048e8e3d94368beb86e59edab5a3638e486bb877f65a188da38c1543a2708cac10b14eef81e5da1
6
+ metadata.gz: 2e1266f3b0950874993fb09814431d6ccc7e379128b7146bd46865571d422676df3103ec602534d2cd2e517e1b24b098d8e1edb09cb7002226369fa41d65c127
7
+ data.tar.gz: c358bd3954399bc55db8883720a40bf1452131771367eb0613637899f5c4d319af6ee3c4d261cb70cb355d83cc21339489562ec1847c47f2893cb40a9c192818
File without changes
File without changes
data/.gitignore CHANGED
File without changes
data/.parlour CHANGED
@@ -1,7 +1,11 @@
1
- output_file: rbi/sord.rbi
1
+ parser: false
2
+
3
+ output_file:
4
+ rbi: rbi/sord.rbi
2
5
 
3
6
  requires:
4
7
  - sord
5
8
 
6
9
  plugins:
7
- Sord::ParlourPlugin: {}
10
+ Sord::ParlourPlugin:
11
+ rbi: yes
data/.rspec CHANGED
File without changes
File without changes
@@ -3,6 +3,64 @@ All notable changes to this project will be documented in this file.
3
3
 
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
5
5
 
6
+ ## [3.0.1] - 2020-12-28
7
+ ### Fixed
8
+ - Fixed `SortedSet` crash on Ruby 3
9
+ - Fixed incorrect `extend` order on YARD 0.9.26
10
+
11
+ ## [3.0.0] - 2020-12-26
12
+ ### Added
13
+ - Sord now uses the Parlour 5 beta's RBS generation to generate RBS files!
14
+ - Added `--rbi` and `--rbs` to select an output format to use (if neither given,
15
+ tries to infer from file extension).
16
+
17
+ ### Changed
18
+ - `RbiGenerator` has been renamed to `Generator`.
19
+ - `TypeConverter#yard_to_sorbet` is now `TypeConverter#yard_to_parlour`, and
20
+ returns `Parlour::Types::Type` instances rather than strings.
21
+
22
+ ### Fixed
23
+ - `#return [nil]` no longer produces a union of zero types, instead becoming
24
+ `void` for method returns or `untyped` for attributes.
25
+
26
+
27
+ <details>
28
+ <summary>3.0.0 pre-releases</summary>
29
+
30
+ ## [3.0.0.beta.2] - 2020-10-05
31
+ ### Added
32
+ - Sord is no longer limited to a known set of generics, and will instead
33
+ generate `Parlour::Types::Generic` types for user-defined generics.
34
+
35
+ ## [3.0.0.beta.1] - 2020-09-16
36
+ ### Added
37
+ - Sord now uses the Parlour 5 beta's RBS generation to generate RBS files!
38
+ - Added `--rbi` and `--rbs` to select an output format to use (if neither given,
39
+ tries to infer from file extension).
40
+
41
+ ### Changed
42
+ - `RbiGenerator` has been renamed to `Generator`.
43
+ - `TypeConverter#yard_to_sorbet` is now `TypeConverter#yard_to_parlour`, and
44
+ returns `Parlour::Types::Type` instances rather than strings.
45
+
46
+ ### Fixed
47
+ - `#return [nil]` no longer produces a union of zero types, instead becoming
48
+ `void` for method returns or `untyped` for attributes.
49
+
50
+ </details>
51
+
52
+ ## [2.0.0] - 2020-03-16
53
+ ### Added
54
+ - Sord now supports generating `attr_accessor`, `attr_reader` and `attr_writer`
55
+ and will do so automatically when these are used in your code.
56
+ - Depending on what you're doing with Sord, this is **potentially breaking**,
57
+ as for example attributes which would previously generate two `foo` and `foo=`
58
+ methods in Sord will now just generate an `attr_accessor`.
59
+ - `#initialize` is now always typed as returning `void`, which is
60
+ **potentially breaking** if you directly call `#initialize` in code.
61
+ - The `--use-original-initialize-return` flag restores the old behaviour of
62
+ using whatever return type is provided, like any other method.
63
+
6
64
  ## [1.0.0] - 2020-02-16
7
65
  ### Added
8
66
  - Added the `--skip-constants` flag to avoid generating RBIs for constants.
File without changes
data/Gemfile CHANGED
File without changes
File without changes
data/README.md CHANGED
@@ -3,24 +3,27 @@
3
3
  ## Overview
4
4
 
5
5
  Sord is a [**So**rbet](https://sorbet.org) and [YA**RD**](https://yardoc.org/)
6
- crossover. It can automatically generate Sorbet type signatures files by
7
- looking at the types specified in YARD documentation comments.
6
+ crossover. It can **automatically generate RBI and RBS type signature files** by
7
+ looking at the **types specified in YARD documentation** comments.
8
8
 
9
9
  If your project is already YARD documented, then this can generate most of the
10
- Sorbet signatures you need!
10
+ type signatures you need!
11
+
12
+ Sord is the perfect way to jump-start the adoption of types in your project,
13
+ whether you plan to use Sorbet's RBI format or Ruby 3/Steep's RBS format.
11
14
 
12
15
  Sord has the following features:
13
16
  - Automatically generates signatures for modules, classes and methods
14
- - Support for multiple parameter or return types (`T.any`)
15
- - Gracefully handles missing YARD types (`T.untyped`)
17
+ - Support for multiple parameter or return types (`T.any`/`|`)
18
+ - Gracefully handles missing YARD types (`T.untyped`/`untyped`)
16
19
  - Can infer setter parameter type from the corresponding getter's return type
17
20
  - Recognises mixins (`include` and `extend`)
18
21
  - Support for generic types such as `Array<T>` and `Hash<K, V>`
19
22
  - Can infer namespaced classes (`[Bar]` can become `GemName::Foo::Bar`)
20
- - Handles return types which can be `nil` (`T.nilable`)
21
- - Handles duck types (`T.untyped`)
23
+ - Handles return types which can be `nil` (`T.nilable`/`untyped`)
24
+ - Handles duck types (`T.untyped`/`untyped`)
22
25
  - Support for ordered list types (`[Array(Integer, Symbol)]` becomes `[Integer, Symbol]`)
23
- - Support for boolean types (`[true, false]` becomes `T::Boolean`)
26
+ - Support for boolean types (`[true, false]` becomes `T::Boolean`/`bool`)
24
27
  - Support for `&block` parameters documented with `@yieldparam` and `@yieldreturn`
25
28
 
26
29
  ## Usage
@@ -29,7 +32,7 @@ Install Sord with `gem install sord`.
29
32
 
30
33
  Sord is a command line tool. To use it, open a terminal in the root directory
31
34
  of your project and invoke `sord`, passing a path where you'd like to save your
32
- `.rbi` (this file will be overwritten):
35
+ file (this file will be overwritten):
33
36
 
34
37
  ```
35
38
  sord defs.rbi
@@ -37,7 +40,12 @@ sord defs.rbi
37
40
 
38
41
  Sord will generate YARD docs and then print information about what it's inferred
39
42
  as it runs. It is best to fix any issues in the YARD documentation, as any edits
40
- made to the resulting RBI file will be replaced if you re-run Sord.
43
+ made to the resulting file will be replaced if you re-run Sord.
44
+
45
+ The output type is inferred by the file extension you use, but you can also
46
+ specify it explicitly with `--rbi` or `--rbs`.
47
+
48
+ ## Shipping RBI Types
41
49
 
42
50
  RBI files generated by Sord can be used in two main ways:
43
51
 
@@ -50,18 +58,22 @@ where the maintainer is unwilling to ship type signatures with the gem itself.
50
58
 
51
59
  ### Flags
52
60
 
53
- Sord also takes some flags to alter the generated `.rbi` file:
61
+ Sord also takes some flags to alter the generated file:
54
62
 
55
- - `--no-sord-comments`: Generates the `.rbi` file without any Sord comments
56
- about warnings/inferences/errors. (The original file's comments will still
57
- be included.)
63
+ - `--rbi`/`--rbs`: Override the output format inferred from the file
64
+ extension.
65
+ - `--no-sord-comments`: Generates the file without any Sord comments about
66
+ warnings/inferences/errors. (The original file's comments will still be
67
+ included.)
58
68
  - `--no-regenerate`: By default, Sord will regenerate a repository's YARD
59
69
  docs for you. This option skips regenerating the YARD docs.
60
70
  - `--break-params`: Determines how many parameters are necessary before
61
71
  the signature is changed from a single-line to a multi-line block.
62
72
  (Default: 4)
63
- - `--replace-errors-with-untyped`: Uses `T.untyped` instead of `SORD_ERROR_*` constants.
64
- - `--replace-unresolved-with-untyped`: Uses `T.untyped` when Sord is unable to resolve a constant.
73
+ - `--replace-errors-with-untyped`: Uses `T.untyped` instead of `SORD_ERROR_*`
74
+ constants.
75
+ - `--replace-unresolved-with-untyped`: Uses `T.untyped` when Sord is unable to
76
+ resolve a constant.
65
77
  - `--include-messages` and `--exclude-messages`: Used to filter the logging
66
78
  messages given by Sord. `--include-messages` acts as a whitelist, printing
67
79
  only messages of the specified logging kinds, whereas `--exclude-messages`
@@ -85,10 +97,10 @@ module Example
85
97
  @age = age
86
98
  end
87
99
 
88
- # @return name [String]
100
+ # @return [String]
89
101
  attr_accessor :name
90
102
 
91
- # @return age [Integer]
103
+ # @return [Integer]
92
104
  attr_accessor :age
93
105
 
94
106
  # @param possible_names [Array<String>] An array of potential names to choose from.
@@ -106,9 +118,8 @@ First, generate a YARD registry by running `yardoc test.rb`. Then, we can run
106
118
  files! Note the `.rbi` file extension.) In doing this, Sord prints:
107
119
 
108
120
  ```
109
- [INFER] (Example::Person#name=) inferred type of parameter "value" as String using getter's return type
110
- [INFER] (Example::Person#age=) inferred type of parameter "value" as Integer using getter's return type
111
- [DONE ] Processed 8 objects
121
+ [INFER] Assuming from filename you wish to generate in RBI format
122
+ [DONE ] Processed 8 objects (2 namespaces and 6 methods)
112
123
  ```
113
124
 
114
125
  The `test.rbi` file then contains a complete RBI file for `test.rb`:
@@ -117,29 +128,45 @@ The `test.rbi` file then contains a complete RBI file for `test.rb`:
117
128
  # typed: strong
118
129
  module Example
119
130
  class Person
120
- # @param `name` — The name of the Person to create.
121
- # @param `age` — The age of the Person to create.
122
- sig { params(name: String, age: Integer).returns(Example::Person) }
131
+ # _@param_ `name` — The name of the Person to create.
132
+ #
133
+ # _@param_ `age` The age of the Person to create.
134
+ sig { params(name: String, age: Integer).void }
123
135
  def initialize(name, age); end
124
136
 
125
- sig { returns(String) }
126
- def name; end
137
+ # _@param_ `possible_names` — An array of potential names to choose from.
138
+ #
139
+ # _@param_ `possible_ages` — An array of potential ages to choose from.
140
+ sig { params(possible_names: T::Array[String], possible_ages: T::Array[Integer]).returns(Example::Person) }
141
+ def self.construct_randomly(possible_names, possible_ages); end
127
142
 
128
- # sord infer - inferred type of parameter "value" as String using getter's return type
129
- sig { params(value: String).returns(String) }
130
- def name=(value); end
143
+ sig { returns(String) }
144
+ attr_accessor :name
131
145
 
132
146
  sig { returns(Integer) }
133
- def age; end
147
+ attr_accessor :age
148
+ end
149
+ end
150
+ ```
134
151
 
135
- # sord infer - inferred type of parameter "value" as Integer using getter's return type
136
- sig { params(value: Integer).returns(Integer) }
137
- def age=(value); end
152
+ If we had instead generated `test.rbs`, we would get this file in RBS format:
138
153
 
139
- # @param `possible_names` — An array of potential names to choose from.
140
- # @param `possible_ages` — An array of potential ages to choose from.
141
- sig { params(possible_names: T::Array[String], possible_ages: T::Array[Integer]).returns(Example::Person) }
142
- def self.construct_randomly(possible_names, possible_ages); end
154
+ ```ruby
155
+ module Example
156
+ class Person
157
+ # _@param_ `name` — The name of the Person to create.
158
+ #
159
+ # _@param_ `age` — The age of the Person to create.
160
+ def initialize: (String name, Integer age) -> void
161
+
162
+ # _@param_ `possible_names` — An array of potential names to choose from.
163
+ #
164
+ # _@param_ `possible_ages` — An array of potential ages to choose from.
165
+ def self.construct_randomly: (Array[String] possible_names, Array[Integer] possible_ages) -> Example::Person
166
+
167
+ attr_accessor name: String
168
+
169
+ attr_accessor age: Integer
143
170
  end
144
171
  end
145
172
  ```
@@ -148,12 +175,13 @@ end
148
175
 
149
176
  The general rule of thumb for type conversions is:
150
177
 
151
- - If Sord understands the YARD type, then it is converted into the Sorbet type.
178
+ - If Sord understands the YARD type, then it is converted into the RBI or RBS
179
+ type.
152
180
  - If the YARD type is missing, Sord fills in `T.untyped`.
153
181
  - If the YARD type can't be understood, Sord creates an undefined Ruby constant
154
182
  with a similar name to the unknown YARD type. For example, the obviously
155
183
  invalid YARD type `A%B` will become a constant called `SORD_ERROR_AB`.
156
- You should search through your resulting RBI to find and fix and
184
+ You should search through your resulting file to find and fix and
157
185
  `SORD_ERROR`s.
158
186
 
159
187
  ## Contributing
@@ -161,11 +189,11 @@ The general rule of thumb for type conversions is:
161
189
  Bug reports and pull requests are welcome on GitHub at https://github.com/AaronC81/sord. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
162
190
 
163
191
  While contributing, if you want to see the results of your changes to Sord you
164
- can use the `examples:seed` Rake task. The task uses Sord to generate RBIs for
192
+ can use the `examples:seed` Rake task. The task uses Sord to generate types for
165
193
  a number of open source Ruby gems, including Bundler, Haml, Rouge, and RSpec.
166
- `rake examples:seed` (and `rake examples:reseed` to regenerate the RBI files)
167
- will clone the repositories of these gems into `sord_examples/` and then
168
- generate the RBI files into the same directory.
194
+ `rake examples:seed` (and `rake examples:reseed` to regenerate the files) will
195
+ clone the repositories of these gems into `sord_examples/` and then generate the
196
+ files into the same directory.
169
197
 
170
198
  ## License
171
199
 
data/Rakefile CHANGED
@@ -24,12 +24,21 @@ namespace :examples do
24
24
  require 'rainbow'
25
25
 
26
26
  desc "Clone git repositories and run Sord on them as examples"
27
- task :seed, [:clean] do |t, args|
27
+ task :seed, [:mode, :clean] do |t, args|
28
28
  if File.directory?('sord_examples')
29
29
  puts Rainbow('sord_examples directory already exists, please delete the directory or run a reseed!').red
30
30
  exit
31
31
  end
32
32
 
33
+ if args[:mode] == 'rbi'
34
+ mode_arg = '--rbi'
35
+ elsif args[:mode] == 'rbs'
36
+ mode_arg = '--rbs'
37
+ else
38
+ puts Rainbow('please specify \'rbi\' or \'rbs\'!').red
39
+ exit
40
+ end
41
+
33
42
  FileUtils.mkdir 'sord_examples'
34
43
  FileUtils.cd 'sord_examples'
35
44
 
@@ -46,11 +55,11 @@ namespace :examples do
46
55
  # Generate sri
47
56
  puts "Generating rbi for #{name}..."
48
57
  if args[:clean]
49
- system("bundle exec sord ../#{name}.rbi --no-sord-comments --replace-errors-with-untyped --replace-unresolved-with-untyped")
58
+ system("bundle exec sord ../#{name}.#{args[:mode]} #{mode_arg} --no-sord-comments --replace-errors-with-untyped --replace-unresolved-with-untyped")
50
59
  else
51
- system("bundle exec sord ../#{name}.rbi")
60
+ system("bundle exec sord ../#{name}.#{args[:mode]} #{mode_arg}")
52
61
  end
53
- puts "#{name}.rbi generated!"
62
+ puts "#{name}.#{args[:mode]} generated!"
54
63
  FileUtils.cd '..'
55
64
  end
56
65
  end
@@ -59,21 +68,30 @@ namespace :examples do
59
68
  end
60
69
 
61
70
  desc 'Regenerate the rbi files in sord_examples.'
62
- task :reseed, [:clean] do |t, args|
71
+ task :reseed, [:mode, :clean] do |t, args|
63
72
  if Dir.exist?('sord_examples')
64
73
  FileUtils.cd 'sord_examples'
65
74
  else
66
75
  raise Rainbow("The sord_examples directory does not exist. Have you run the seed task?").red.bold
67
76
  end
68
77
 
78
+ if args[:mode] == 'rbi'
79
+ mode_arg = '--rbi'
80
+ elsif args[:mode] == 'rbs'
81
+ mode_arg = '--rbs'
82
+ else
83
+ puts Rainbow('please specify \'rbi\' or \'rbs\'!').red
84
+ exit
85
+ end
86
+
69
87
  REPOS.keys.each do |name|
70
88
  FileUtils.cd name.to_s
71
89
  puts "Regenerating rbi file for #{name}..."
72
90
  Bundler.with_clean_env do
73
91
  if args[:clean]
74
- system("bundle exec sord ../#{name}.rbi --no-regenerate --no-sord-comments --replace-errors-with-untyped --replace-unresolved-with-untyped")
92
+ system("bundle exec sord ../#{name}.#{args[:mode]} #{mode_arg} --no-regenerate --no-sord-comments --replace-errors-with-untyped --replace-unresolved-with-untyped")
75
93
  else
76
- system("bundle exec sord ../#{name}.rbi --no-regenerate")
94
+ system("bundle exec sord ../#{name}.#{args[:mode]} #{mode_arg} --no-regenerate")
77
95
  end
78
96
  end
79
97
  FileUtils.cd '..'
data/exe/sord CHANGED
@@ -10,8 +10,10 @@ program :description, 'Generate Sorbet RBIs from YARD documentation'
10
10
  default_command :gen
11
11
  command :gen do |c|
12
12
  c.syntax = 'sord gen <output-file> [options]'
13
- c.description = 'Generates an RBI file from this directory\'s YARD docs'
14
- c.option '--[no-]sord-comments', 'Controls informational/warning comments in the RBI file'
13
+ c.description = 'Generates a type signature file from this directory\'s YARD docs'
14
+ c.option '--rbi', 'Use Sorbet\'s RBI format'
15
+ c.option '--rbs', 'Use Steep/Ruby 3\'s RBS format'
16
+ c.option '--[no-]sord-comments', 'Controls informational/warning comments in the file'
15
17
  c.option '--[no-]regenerate', 'Controls whether YARD is executed before Sord runs'
16
18
  c.option '--break-params INTEGER', Integer, 'Break params onto their own lines if there are this many'
17
19
  c.option '--replace-errors-with-untyped', 'Uses T.untyped rather than SORD_ERROR_ constants'
@@ -19,10 +21,13 @@ command :gen do |c|
19
21
  c.option '--exclude-messages STRING', String, 'Blacklists a comma-separated string of log message types'
20
22
  c.option '--include-messages STRING', String, 'Whitelists a comma-separated string of log message types'
21
23
  c.option '--keep-original-comments', 'Retains original YARD comments rather than converting them to Markdown'
22
- c.option '--skip-constants', 'Excludes constants from generated RBI'
24
+ c.option '--skip-constants', 'Excludes constants from generated file'
25
+ c.option '--use-original-initialize-return', 'Uses the specified return type for #initialize rather than void'
23
26
 
24
27
  c.action do |args, options|
25
28
  options.default(
29
+ rbi: false,
30
+ rbs: false,
26
31
  sord_comments: true,
27
32
  regenerate: true,
28
33
  break_params: 4,
@@ -31,22 +36,55 @@ command :gen do |c|
31
36
  exclude_messages: nil,
32
37
  include_messages: nil,
33
38
  keep_original_comments: false,
34
- skip_constants: false
39
+ skip_constants: false,
40
+ use_original_initialize_return: false,
35
41
  )
36
42
 
37
43
  if args.length != 1
38
44
  Sord::Logging.error('Must specify filename')
39
45
  exit 1
40
46
  end
41
-
47
+
42
48
  plugin_options = options.__hash__
43
49
  plugin_options[:exclude_options] = plugin_options[:exclude_options]&.split(',')
44
50
  plugin_options[:include_options] = plugin_options[:include_options]&.split(',')
45
51
 
52
+ if !(plugin_options[:rbi] || plugin_options[:rbs])
53
+ if args.first
54
+ if args.first.end_with?('.rbi')
55
+ Sord::Logging.infer('Assuming from filename you wish to generate in RBI format')
56
+ plugin_options[:rbi] = true
57
+ elsif args.first.end_with?('.rbs')
58
+ Sord::Logging.infer('Assuming from filename you wish to generate in RBS format')
59
+ plugin_options[:rbs] = true
60
+ else
61
+ Sord::Logging.error('An output format could not be inferred from your filename; please specify --rbi or --rbs')
62
+ exit 1
63
+ end
64
+ else
65
+ Sord::Logging.error('No output format given; please specify --rbi or --rbs')
66
+ exit 1
67
+ end
68
+ end
69
+
70
+ if (plugin_options[:rbi] && plugin_options[:rbs])
71
+ Sord::Logging.error('You cannot specify both --rbi and --rbs; please use only one')
72
+ exit 1
73
+ end
74
+
46
75
  plugin = Sord::ParlourPlugin.new(plugin_options)
47
- plugin.parlour = Parlour::RbiGenerator.new(break_params: plugin_options[:break_params])
76
+
77
+ if plugin_options[:rbi]
78
+ klass = Parlour::RbiGenerator
79
+ generator_method = :rbi
80
+ elsif plugin_options[:rbs]
81
+ klass = Parlour::RbsGenerator
82
+ generator_method = :rbs
83
+ end
84
+
85
+ plugin.parlour = klass.new(break_params: plugin_options[:break_params])
48
86
  plugin.generate(plugin.parlour.root)
49
87
 
50
- File.write(args.first, plugin.parlour.rbi)
88
+ File.write(args.first, plugin.parlour.send(generator_method))
51
89
  end
52
90
  end