ruby / rbs

Type Signature for Ruby
Other
1.94k stars 212 forks source link

Feature proposal: `rbs diff` command #1448

Closed ksss closed 10 months ago

ksss commented 1 year ago

Problem

Differential check of generator output

When an RBS is automatically generated by a generator, it is difficult to track exactly what changes have been made to the RBS because of its large size and the order in which it is generated.

Review RBS

If the RBS included in the PR is a complex change, it is difficult for the reviewer to make a decision based on the PR alone, and for the reviewee to explain the change.

View differences by gem version

If you are managing multiple versions of RBS with gem_rbs_collection, etc., you can check the differences by version by checking the RBS file directly or writing a small script.

Feature proposal: rbs diff command

Implement and provide new commands such as the rbs diff command.

$ cat dir1/t.rbs
class Foo
  def bar: () -> void
  def self.baz: () -> (Integer | String)
  def qux: (untyped) -> untyped
end

$ cat dir2/t.rbs
module Bar
  def bar: () -> void
end

module Baz
  def baz: (Integer) -> Integer?
end

class Foo
  include Bar
  extend Baz
end
$ bundle exec rbs diff --format markdown --type-name Foo --with-defined-in --before dir1 --after dir2
| before | after |
| --- | --- |
| `(::Foo) def bar: () -> void` | `(::Bar) def bar: () -> void` |
| `(::Foo) def qux: (untyped) -> untyped` | `-` |
| `(::Foo) def self.baz: () -> (::Integer \| ::String)` | `(::Baz) def self.baz: (::Integer) -> ::Integer?` |

Options

format

Required. Specify output format.

markdown:

before after
(::Foo) def bar: () -> void (::Bar) def bar: () -> void
(::Foo) def qux: (untyped) -> untyped -
(::Foo) def self.baz: () -> (::Integer \| ::String) (::Baz) def self.baz: (::Integer) -> ::Integer?

diff:

- (::Foo) def bar: () -> void
+ (::Bar) def bar: () -> void

- (::Foo) def qux: (untyped) -> untyped
+ -

- (::Foo) def self.baz: () -> (::Integer | ::String)
+ (::Baz) def self.baz: (::Integer) -> ::Integer?

type-name

Required. Specify only one type name. Type definitions are vast, but the types we want to know about are often specific.

before, after

Required. Specify one or more directories or files.

with-defined-in

Optional. Display the class/module in which the method is defined. This display is also used for differencing.

with-visibility

Optional. Display the visibility of the method being defined. This display is also used for differencing.

or detail

with-defined-in and with-visibility are, in essence, for when you want more information. These options could be merged together as detail.

Implementation

Compare tables created with RBS::DefinitionBuilder.

ksss commented 1 year ago

Prototype of implementation https://gist.github.com/ksss/15e7d6afacc139567ccfa3b2c92d187b

ksss commented 10 months ago

It has been released by v3.3.0 🎉