Class: RBS::Trace::CLI::Merge

Inherits:
Object
  • Object
show all
Defined in:
lib/rbs/trace/cli/merge.rb

Constant Summary collapse

<<~USAGE
  Usage: rbs-trace merge --sig-dir=DIR

  Merge multiple RBS files into one.

  Examples:
    # Merge RBS files in `tmp/sig-1/` and `tmp/sig-2/`.
    $ rbs-trace merge --sig-dir=tmp/sig-1 --sig-dir=tmp/sig-2

    # Or you can specify a glob pattern.
    $ rbs-trace merge --sig-dir=tmp/sig-*

  Options:
USAGE

Instance Method Summary collapse

Instance Method Details

#merge_envs(others) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/rbs/trace/cli/merge.rb', line 46

def merge_envs(others) # rubocop:disable Metrics
  Environment.new.tap do |env|
    others.each do |other|
      other.declarations.each do |decl|
        next unless decl.is_a?(AST::Declarations::Class) || decl.is_a?(AST::Declarations::Module)

        entry = env.module_class_entry(decl.name.absolute!)

        if entry.is_a?(Environment::MultiEntry)
          decl.members.each { |member| merge(entry.primary.decl, member) }
        else
          env << decl
        end
      end
    end
  end
end

#run(args) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/rbs/trace/cli/merge.rb', line 23

def run(args) # rubocop:disable Metrics
  sig_dirs = [] #: Array[String]

  opts = OptionParser.new(BANNER)
  opts.on("--sig-dir DIR") { |dir| sig_dirs << dir }
  opts.parse!(args)

  if sig_dirs.empty?
    puts opts.help
  else
    envs = sig_dirs.flat_map { |sig_dir| Dir.glob(sig_dir) }
                   .map { |dir| load_env(dir) }
    env = merge_envs(envs)

    out = StringIO.new
    writer = Writer.new(out:)
    writer.write(env.declarations)

    puts out.string
  end
end