Skip to content

Commit bc71b4b

Browse files
committed
feat: Add rbs-trace command
Implement a CLI tool with the following functions: - inline: Insert RBS inline comments from RBS files - merge: Merge multiple RBS files into one
1 parent a657390 commit bc71b4b

File tree

9 files changed

+238
-0
lines changed

9 files changed

+238
-0
lines changed

exe/rbs-trace

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env ruby
2+
# frozen_string_literal: true
3+
4+
lib = File.expand_path("../lib", __dir__)
5+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6+
7+
require "rbs-trace"
8+
RBS::Trace::CLI.new.run

lib/rbs/trace.rb

+4
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
require "bundler"
44
require "logger"
5+
require "optparse"
56
require "prism"
67
require "rbs"
78

89
require_relative "trace/helpers"
910
require_relative "trace/builder"
11+
require_relative "trace/cli"
12+
require_relative "trace/cli/inline"
13+
require_relative "trace/cli/merge"
1014
require_relative "trace/file"
1115
require_relative "trace/inline_comment_visitor"
1216
require_relative "trace/method_tracing"

lib/rbs/trace/cli.rb

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# frozen_string_literal: true
2+
3+
module RBS
4+
module Trace
5+
class CLI
6+
BANNER = <<~USAGE
7+
Usage: rbs-trace <command> [<args>]
8+
9+
Available commands: inline, merge
10+
USAGE
11+
12+
# @rbs (Array[String]) -> void
13+
def run(args = ARGV)
14+
opts = OptionParser.new(BANNER)
15+
opts.version = RBS::Trace::VERSION
16+
opts.order!(args)
17+
command = args.shift&.to_sym
18+
19+
klass = command_class(command)
20+
if klass
21+
klass.new.run(args)
22+
else
23+
puts opts.help
24+
end
25+
end
26+
27+
private
28+
29+
# @rbs (Symbol?) -> (singleton(Inline) | singleton(Merge))?
30+
def command_class(command)
31+
case command
32+
when :inline
33+
Inline
34+
when :merge
35+
Merge
36+
end
37+
end
38+
end
39+
end
40+
end

lib/rbs/trace/cli/inline.rb

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# frozen_string_literal: true
2+
3+
module RBS
4+
module Trace
5+
class CLI
6+
class Inline
7+
BANNER = <<~USAGE
8+
Usage: rbs-trace inline --sig-dir=DIR --rb-dir=DIR
9+
10+
Insert RBS inline comments from RBS files.
11+
12+
Examples:
13+
# Insert inline comments to `app/**/*.rb`.
14+
$ rbs-trace inline --sig-dir=sig --rb-dir=app
15+
16+
# Generate RBS files with rbs-inline.
17+
$ rbs-inline --output --opt-out app
18+
19+
# Remove method definitions that have been migrated to inline comments.
20+
$ rbs subtract --write sig sig/generated/
21+
22+
Options:
23+
USAGE
24+
25+
# @rbs (Array[String]) -> void
26+
def run(args) # rubocop:disable Metrics
27+
sig_dir = nil
28+
rb_dir = nil
29+
30+
opts = OptionParser.new(BANNER)
31+
opts.on("--sig-dir DIR") { |dir| sig_dir = dir }
32+
opts.on("--rb-dir DIR") { |dir| rb_dir = dir }
33+
opts.parse!(args)
34+
35+
if sig_dir && rb_dir
36+
env = load_env(sig_dir) # steep:ignore ArgumentTypeMismatch
37+
decls = env.class_decls.transform_values { |v| v.primary.decl }
38+
39+
Dir.glob("#{rb_dir}/**/*.rb").each do |path|
40+
file = File.new(path, decls)
41+
file.rewrite
42+
end
43+
else
44+
puts opts.help
45+
end
46+
end
47+
48+
private
49+
50+
# @rbs (String) -> Environment
51+
def load_env(dir)
52+
Environment.new.tap do |env|
53+
loader = EnvironmentLoader.new(core_root: nil)
54+
loader.add(path: Pathname(dir))
55+
loader.load(env:)
56+
end
57+
end
58+
end
59+
end
60+
end
61+
end

lib/rbs/trace/cli/merge.rb

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# frozen_string_literal: true
2+
3+
module RBS
4+
module Trace
5+
class CLI
6+
class Merge
7+
BANNER = <<~USAGE
8+
Usage: rbs-trace merge --sig-dir=DIR
9+
10+
Merge multiple RBS files into one.
11+
12+
Examples:
13+
# Merge RBS files in `tmp/sig-1/` and `tmp/sig-2/`.
14+
$ rbs-trace merge --sig-dir=tmp/sig-1 --sig-dir=tmp/sig-2
15+
16+
Options:
17+
USAGE
18+
19+
# @rbs (Array[String]) -> void
20+
def run(args) # rubocop:disable Metrics
21+
sig_dirs = [] #: Array[String]
22+
23+
opts = OptionParser.new(BANNER)
24+
opts.on("--sig-dir DIR") { |dir| sig_dirs << dir }
25+
opts.parse!(args)
26+
27+
if sig_dirs.empty?
28+
puts opts.help
29+
else
30+
envs = sig_dirs.map { |dir| load_env(dir) }
31+
env = merge_envs(envs)
32+
33+
out = StringIO.new
34+
writer = Writer.new(out:)
35+
writer.write(env.declarations)
36+
37+
puts out.string
38+
end
39+
end
40+
41+
private
42+
43+
# @rbs (String) -> Environment
44+
def load_env(dir)
45+
Environment.new.tap do |env|
46+
loader = EnvironmentLoader.new(core_root: nil)
47+
loader.add(path: Pathname(dir))
48+
loader.load(env:)
49+
end
50+
end
51+
52+
# @rbs (Array[Environment]) -> Environment
53+
def merge_envs(others)
54+
Environment.new.tap do |env|
55+
others.each do |other|
56+
other.declarations.each do |decl|
57+
env << decl
58+
end
59+
end
60+
end
61+
end
62+
end
63+
end
64+
end
65+
end

lib/rbs/trace/file.rb

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# frozen_string_literal: true
22

3+
require "stringio"
4+
35
module RBS
46
module Trace
57
class File

sig/generated/rbs/trace/cli.rbs

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Generated from lib/rbs/trace/cli.rb with RBS::Inline
2+
3+
module RBS
4+
module Trace
5+
class CLI
6+
BANNER: ::String
7+
8+
# @rbs (Array[String]) -> void
9+
def run: (Array[String]) -> void
10+
11+
private
12+
13+
# @rbs (Symbol?) -> (singleton(Inline) | singleton(Merge))?
14+
def command_class: (Symbol?) -> (singleton(Inline) | singleton(Merge))?
15+
end
16+
end
17+
end
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Generated from lib/rbs/trace/cli/inline.rb with RBS::Inline
2+
3+
module RBS
4+
module Trace
5+
class CLI
6+
class Inline
7+
BANNER: ::String
8+
9+
# @rbs (Array[String]) -> void
10+
def run: (Array[String]) -> void
11+
12+
private
13+
14+
# @rbs (String) -> Environment
15+
def load_env: (String) -> Environment
16+
end
17+
end
18+
end
19+
end

sig/generated/rbs/trace/cli/merge.rbs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Generated from lib/rbs/trace/cli/merge.rb with RBS::Inline
2+
3+
module RBS
4+
module Trace
5+
class CLI
6+
class Merge
7+
BANNER: ::String
8+
9+
# @rbs (Array[String]) -> void
10+
def run: (Array[String]) -> void
11+
12+
private
13+
14+
# @rbs (String) -> Environment
15+
def load_env: (String) -> Environment
16+
17+
# @rbs (Array[Environment]) -> Environment
18+
def merge_envs: (Array[Environment]) -> Environment
19+
end
20+
end
21+
end
22+
end

0 commit comments

Comments
 (0)