-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce CLI command to translate RBI sigs to RBS
Signed-off-by: Alexandre Terrasa <[email protected]>
- Loading branch information
Showing
3 changed files
with
174 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# typed: true | ||
# frozen_string_literal: true | ||
|
||
require "spoom/sorbet/translate_sigs" | ||
|
||
module Spoom | ||
module Cli | ||
module Srb | ||
class Sigs < Thor | ||
include Helper | ||
|
||
desc "translate", "Translate signatures from/to RBI and RBS" | ||
option :from, type: :string, aliases: :f, desc: "From format", enum: ["rbi"], default: "rbi" | ||
option :to, type: :string, aliases: :t, desc: "To format", enum: ["rbs"], default: "rbs" | ||
def translate(*paths) | ||
from = options[:from] | ||
to = options[:to] | ||
paths << "." if paths.empty? | ||
|
||
files = paths.flat_map do |path| | ||
if File.file?(path) | ||
[path] | ||
else | ||
Dir.glob("#{path}/**/*.rb") | ||
end | ||
end | ||
|
||
if files.empty? | ||
say_error("No files to translate") | ||
exit(1) | ||
end | ||
|
||
say("Translating signatures from `#{from}` to `#{to}` " \ | ||
"in `#{files.size}` file#{files.size == 1 ? "" : "s"}...\n\n") | ||
|
||
translated_files = T.let(0, Integer) | ||
|
||
files.each do |file| | ||
contents = File.read(file) | ||
contents = Spoom::Sorbet::TranslateSigs.rbi_to_rbs(contents) | ||
File.write(file, contents) | ||
translated_files += 1 | ||
rescue RBI::Error => error | ||
say_warning("Can't parse #{file}: #{error.message}") | ||
next | ||
end | ||
|
||
say("Translated signatures in `#{translated_files}` file#{translated_files == 1 ? "" : "s"}.") | ||
end | ||
|
||
no_commands do | ||
def pluralize(word, count) | ||
count == 1 ? word : "#{word}s" | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
# typed: true | ||
# frozen_string_literal: true | ||
|
||
require "test_with_project" | ||
|
||
module Spoom | ||
module Cli | ||
module Srb | ||
class SigsTest < TestWithProject | ||
def setup | ||
@project.bundle_install! | ||
end | ||
|
||
def test_only_supports_translation_from_rbi | ||
result = @project.spoom("srb sigs translate --from rbs") | ||
|
||
assert_equal(<<~ERR, result.err) | ||
Expected '--from' to be one of rbi; got rbs | ||
ERR | ||
refute(result.status) | ||
end | ||
|
||
def test_only_supports_translation_to_rbs | ||
result = @project.spoom("srb sigs translate --to rbi") | ||
|
||
assert_equal(<<~ERR, result.err) | ||
Expected '--to' to be one of rbs; got rbi | ||
ERR | ||
refute(result.status) | ||
end | ||
|
||
def test_no_files | ||
result = @project.spoom("srb sigs translate --no-color") | ||
|
||
assert_equal(<<~OUT, result.err) | ||
Error: No files to translate | ||
OUT | ||
refute(result.status) | ||
end | ||
|
||
def test_only_selected_files | ||
@project.write!("a/file1.rb", <<~RB) | ||
sig { void } | ||
def foo; end | ||
RB | ||
|
||
@project.write!("a/file2.rb", <<~RB) | ||
sig { void } | ||
def foo; end | ||
RB | ||
|
||
@project.write!("b/file1.rb", <<~RB) | ||
sig { void } | ||
def foo; end | ||
RB | ||
|
||
result = @project.spoom("srb sigs translate --no-color a/file1.rb b/") | ||
|
||
assert_empty(result.err) | ||
assert_equal(<<~OUT, result.out) | ||
Translating signatures from `rbi` to `rbs` in `2` files... | ||
Translated signatures in `2` files. | ||
OUT | ||
assert(result.status) | ||
|
||
assert_equal(<<~RB, @project.read("a/file1.rb")) | ||
#: -> void | ||
def foo; end | ||
RB | ||
|
||
assert_equal(<<~RB, @project.read("a/file2.rb")) | ||
sig { void } | ||
def foo; end | ||
RB | ||
|
||
assert_equal(<<~RB, @project.read("b/file1.rb")) | ||
#: -> void | ||
def foo; end | ||
RB | ||
end | ||
|
||
def test_encoding_support | ||
path = @project.absolute_path_to("file.rb") | ||
File.write(path, <<~RB, encoding: Encoding::ISO8859_1) | ||
# Some content with accentuated characters: éàèù | ||
sig { void } | ||
def foo; end | ||
RB | ||
|
||
result = @project.spoom("srb sigs translate --no-color --encoding ISO-8859-1") | ||
|
||
assert_empty(result.err) | ||
assert_equal(<<~OUT, result.out) | ||
Translating signatures from `rbi` to `rbs` in `1` file... | ||
Translated signatures in `1` file. | ||
OUT | ||
assert(result.status) | ||
|
||
contents = File.read(path, encoding: Encoding::ISO8859_1) | ||
assert_equal(<<~RB.encode(Encoding::ISO8859_1), contents) | ||
# Some content with accentuated characters: éàèù | ||
#: -> void | ||
def foo; end | ||
RB | ||
end | ||
end | ||
end | ||
end | ||
end |