Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ AllCops:
TargetRubyVersion: 2.4
Exclude:
- 'vendor/**/*'
- "spec/support/repo/bin/tapioca"

Style/CaseEquality:
Enabled: false
Expand Down
45 changes: 31 additions & 14 deletions lib/tapioca/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,20 +38,9 @@ class Cli < Thor

desc "init", "initializes folder structure"
def init
create_file(Config::SORBET_CONFIG, skip: true) do
<<~CONTENT
--dir
.
CONTENT
end
create_file(Config::DEFAULT_POSTREQUIRE, skip: true) do
<<~CONTENT
# typed: false
# frozen_string_literal: true

# Add your extra requires here
CONTENT
end
create_config
create_post_require
generate_binstub
end

desc "require", "generate the list of files to be required by tapioca"
Expand Down Expand Up @@ -103,6 +92,34 @@ def __print_version
puts "Tapioca v#{Tapioca::VERSION}"
end

private

def create_config
create_file(Config::SORBET_CONFIG, skip: true) do
<<~CONTENT
--dir
.
CONTENT
end
end

def create_post_require
create_file(Config::DEFAULT_POSTREQUIRE, skip: true) do
<<~CONTENT
# typed: false
# frozen_string_literal: true

# Add your extra requires here
CONTENT
end
end

def generate_binstub
installer = Bundler::Installer.new(Bundler.root, Bundler.definition)
spec = Bundler.definition.specs.find { |s| s.name == "tapioca" }
installer.generate_bundler_executable_stubs(spec, { force: true })
end

no_commands do
def self.exit_on_failure?
true
Expand Down
2 changes: 1 addition & 1 deletion lib/tapioca/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ class Config < T::Struct
const(:outdir, String)
const(:prerequire, T.nilable(String))
const(:postrequire, String)
const(:generate_command, String)
const(:exclude, T::Array[String])
const(:typed_overrides, T::Hash[String, String])
const(:todos_path, String)
Expand All @@ -27,6 +26,7 @@ def outpath
TAPIOCA_PATH = T.let("#{SORBET_PATH}/tapioca", String)
TAPIOCA_CONFIG = T.let("#{TAPIOCA_PATH}/config.yml", String)

DEFAULT_COMMAND = T.let("bin/tapioca", String)
DEFAULT_POSTREQUIRE = T.let("#{TAPIOCA_PATH}/require.rb", String)
DEFAULT_RBIDIR = T.let("#{SORBET_PATH}/rbi", String)
DEFAULT_DSLDIR = T.let("#{DEFAULT_RBIDIR}/dsl", String)
Expand Down
20 changes: 7 additions & 13 deletions lib/tapioca/config_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ class << self

sig { params(command: Symbol, options: T::Hash[String, T.untyped]).returns(Config) }
def from_options(command, options)
Config.from_hash(
merge_options(default_options(command), config_options, options)
)
merged_options = merge_options(default_options(command), config_options, options)

puts(<<~MSG) if merged_options.include?("generate_command")
DEPRECATION: The `-c` and `--cmd` flags will be removed in a future release.
MSG

Config.from_hash(merged_options)
end

private
Expand Down Expand Up @@ -40,15 +44,6 @@ def default_options(command)
DEFAULT_OPTIONS.merge("outdir" => default_outdir)
end

sig { returns(String) }
def default_command
command = File.basename($PROGRAM_NAME)
# Hack to avoid flags ending up in the header of the RBIs
args = ARGV.grep_v(/^-/).join(" ")

"#{command} #{args}".strip
end

sig { params(options: T::Hash[String, T.untyped]).returns(T::Hash[String, T.untyped]) }
def merge_options(*options)
options.each_with_object({}) do |option, result|
Expand All @@ -66,7 +61,6 @@ def merge_options(*options)
DEFAULT_OPTIONS = T.let({
"postrequire" => Config::DEFAULT_POSTREQUIRE,
"outdir" => nil,
"generate_command" => default_command,
"exclude" => [],
"typed_overrides" => Config::DEFAULT_OVERRIDES,
"todos_path" => Config::DEFAULT_TODOSPATH,
Expand Down
17 changes: 8 additions & 9 deletions lib/tapioca/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def build_requires

content = String.new
content << rbi_header(
config.generate_command,
"#{Config::DEFAULT_COMMAND} require",
reason: "explicit gem requires",
strictness: "false"
)
Expand All @@ -76,8 +76,8 @@ def build_requires
say("Done", :green)

say("All requires from this application have been written to #{name}.", [:green, :bold])
cmd = set_color("tapioca sync", :yellow, :bold)
say("Please review changes and commit them, then run #{cmd}.", [:green, :bold])
cmd = set_color("#{Config::DEFAULT_COMMAND} sync", :yellow, :bold)
say("Please review changes and commit them, then run `#{cmd}`.", [:green, :bold])
end

sig { void }
Expand All @@ -99,7 +99,7 @@ def build_todos

content = String.new
content << rbi_header(
config.generate_command,
"#{Config::DEFAULT_COMMAND} todo",
reason: "unresolved constants",
strictness: "false"
)
Expand Down Expand Up @@ -225,7 +225,7 @@ def explain_failed_require(file, error)
say_error("If you populated ", :yellow)
say_error("#{file} ", :bold, :blue)
say_error("with ", :yellow)
say_error("tapioca require", :bold, :blue)
say_error("`#{Config::DEFAULT_COMMAND} require`", :bold, :blue)
say_error("you should probably review it and remove the faulty line.", :yellow)
end

Expand Down Expand Up @@ -484,7 +484,7 @@ def compile_gem_rbi(gem)
rbi_body_content = compiler.compile(gem)
content = String.new
content << rbi_header(
config.generate_command,
"#{Config::DEFAULT_COMMAND} sync",
reason: "types exported from the `#{gem.name}` gem",
strictness: strictness
)
Expand All @@ -510,14 +510,13 @@ def compile_gem_rbi(gem)
def compile_dsl_rbi(constant, contents, outpath: config.outpath)
return if contents.nil?

command = format(config.generate_command, constant.name)
constant_name = Module.instance_method(:name).bind(constant).call
rbi_name = constant_name.underscore + ".rbi"
filename = outpath / rbi_name

out = String.new
out << rbi_header(
command,
"#{Config::DEFAULT_COMMAND} dsl #{constant_name}",
reason: "dynamic methods in `#{constant.name}`"
)
out << contents
Expand Down Expand Up @@ -555,7 +554,7 @@ def verify_dsl_rbi(tmp_dir:)
sig { params(dir: String).void }
def perform_dsl_verification(dir)
if (error = verify_dsl_rbi(tmp_dir: Pathname.new(dir)))
say("RBI files are out-of-date, please run `#{config.generate_command}` to update.")
say("RBI files are out-of-date, please run `#{Config::DEFAULT_COMMAND} dsl` to update.")
say("Reason: ", [:red])
say(error)
exit(1)
Expand Down
2 changes: 1 addition & 1 deletion spec/support/repo/bin/tapioca
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ end
require "rubygems"
require "bundler/setup"

load(Gem.bin_path("tapioca", "tapioca"))
load Gem.bin_path("tapioca", "tapioca")
54 changes: 36 additions & 18 deletions spec/tapioca/cli_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module Contents
FOO_RBI = <<~CONTENTS
# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `foo` gem.
# Please instead update this file by running `generate command`.
# Please instead update this file by running `bin/tapioca sync`.

# typed: true

Expand All @@ -25,7 +25,7 @@ def bar(a = T.unsafe(nil), b: T.unsafe(nil), **opts); end
BAR_RBI = <<~CONTENTS
# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `bar` gem.
# Please instead update this file by running `generate command`.
# Please instead update this file by running `bin/tapioca sync`.

# typed: true

Expand All @@ -41,7 +41,7 @@ def bar(a = T.unsafe(nil), b: T.unsafe(nil), **opts); end
BAZ_RBI = <<~CONTENTS
# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `baz` gem.
# Please instead update this file by running `generate command`.
# Please instead update this file by running `bin/tapioca sync`.

# typed: true

Expand All @@ -68,7 +68,6 @@ class Tapioca::CliSpec < Minitest::HooksSpec
def execute(command, args = [], flags = {})
flags = {
outdir: outdir,
generate_command: "'generate command'",
}.merge(flags).flat_map { |k, v| ["--#{k}", v.to_s] }

exec_command = [
Expand Down Expand Up @@ -142,6 +141,8 @@ def execute(command, args = [], flags = {})

# Add your extra requires here
CONTENTS

assert_path_exists(repo_path / "bin/tapioca")
end

it 'must not overwrite files' do
Expand Down Expand Up @@ -204,7 +205,7 @@ def foo
assert_equal(<<~CONTENTS, File.read(repo_path / "sorbet/rbi/todo.rbi"))
# DO NOT EDIT MANUALLY
# This is an autogenerated file for unresolved constants.
# Please instead update this file by running `generate command`.
# Please instead update this file by running `bin/tapioca todo`.

# typed: false

Expand All @@ -220,7 +221,7 @@ module Foo::Undef2; end
File.write(repo_path / "sorbet/rbi/todo.rbi", <<-RBI)
# DO NOT EDIT MANUALLY
# This is an autogenerated file for unresolved constants.
# Please instead update this file by running `generate command`.
# Please instead update this file by running `bin/tapioca todo`.

# typed: false

Expand Down Expand Up @@ -274,14 +275,14 @@ module Foo::Undef2; end
assert_equal(<<~OUTPUT, output)
Compiling sorbet/tapioca/require.rb, this may take a few seconds... Done
All requires from this application have been written to sorbet/tapioca/require.rb.
Please review changes and commit them, then run tapioca sync.
Please review changes and commit them, then run `bin/tapioca sync`.
OUTPUT

assert_path_exists(repo_path / "sorbet/tapioca/require.rb")
assert_equal(<<~CONTENTS, File.read(repo_path / "sorbet/tapioca/require.rb"))
# DO NOT EDIT MANUALLY
# This is an autogenerated file for explicit gem requires.
# Please instead update this file by running `generate command`.
# Please instead update this file by running `bin/tapioca require`.

# typed: false

Expand All @@ -305,14 +306,14 @@ module Foo::Undef2; end
assert_equal(<<~OUTPUT, output)
Compiling sorbet/tapioca/require.rb, this may take a few seconds... Done
All requires from this application have been written to sorbet/tapioca/require.rb.
Please review changes and commit them, then run tapioca sync.
Please review changes and commit them, then run `bin/tapioca sync`.
OUTPUT

assert_path_exists(repo_path / "sorbet/tapioca/require.rb")
assert_equal(<<~CONTENTS, File.read(repo_path / "sorbet/tapioca/require.rb"))
# DO NOT EDIT MANUALLY
# This is an autogenerated file for explicit gem requires.
# Please instead update this file by running `generate command`.
# Please instead update this file by running `bin/tapioca require`.

# typed: false

Expand Down Expand Up @@ -363,7 +364,7 @@ module Foo::Undef2; end
assert_equal(<<~CONTENTS.chomp, File.read("#{outdir}/post.rbi"))
# DO NOT EDIT MANUALLY
# This is an autogenerated file for dynamic methods in `Post`.
# Please instead update this file by running `generate command`.
# Please instead update this file by running `bin/tapioca dsl Post`.

# typed: true
class Post
Expand Down Expand Up @@ -448,7 +449,7 @@ def title=(title); end
assert_equal(<<~CONTENTS.chomp, File.read("#{outdir}/baz/role.rbi"))
# DO NOT EDIT MANUALLY
# This is an autogenerated file for dynamic methods in `Baz::Role`.
# Please instead update this file by running `generate command`.
# Please instead update this file by running `bin/tapioca dsl Baz::Role`.

# typed: true
module Baz
Expand All @@ -465,7 +466,7 @@ def title=(title); end
assert_equal(<<~CONTENTS.chomp, File.read("#{outdir}/post.rbi"))
# DO NOT EDIT MANUALLY
# This is an autogenerated file for dynamic methods in `Post`.
# Please instead update this file by running `generate command`.
# Please instead update this file by running `bin/tapioca dsl Post`.

# typed: true
class Post
Expand All @@ -480,7 +481,7 @@ def title=(title); end
assert_equal(<<~CONTENTS.chomp, File.read("#{outdir}/namespace/comment.rbi"))
# DO NOT EDIT MANUALLY
# This is an autogenerated file for dynamic methods in `Namespace::Comment`.
# Please instead update this file by running `generate command`.
# Please instead update this file by running `bin/tapioca dsl Namespace::Comment`.

# typed: true
module Namespace
Expand Down Expand Up @@ -612,7 +613,7 @@ class Image
output = execute("dsl", "--verify")

assert_includes(output, <<~OUTPUT)
RBI files are out-of-date, please run `generate command` to update.
RBI files are out-of-date, please run `bin/tapioca dsl` to update.
Reason: New file(s) introduced.
OUTPUT
assert_includes($?.to_s, "exit 1") # rubocop:disable Style/SpecialGlobalVars
Expand Down Expand Up @@ -653,7 +654,7 @@ class Image
output = execute("dsl", "--verify")

assert_includes(output, <<~OUTPUT)
RBI files are out-of-date, please run `generate command` to update.
RBI files are out-of-date, please run `bin/tapioca dsl` to update.
Reason: File(s) updated:
- sorbet/rbi/dsl/image.rbi
OUTPUT
Expand Down Expand Up @@ -717,7 +718,7 @@ class Foo::Secret
LoadError: cannot load such file -- foo/will_fail

Tapioca could not load all the gems required by your application.
If you populated /postrequire_faulty.rb with tapioca require
If you populated /postrequire_faulty.rb with `bin/tapioca require`
you should probably review it and remove the faulty line.
OUTPUT
end
Expand Down Expand Up @@ -879,7 +880,7 @@ class Foo::Secret
assert_equal(<<~CONTENTS.chomp, File.read("#{outdir}/qux@0.5.0.rbi"))
# DO NOT EDIT MANUALLY
# This is an autogenerated file for types exported from the `qux` gem.
# Please instead update this file by running `generate command`.
# Please instead update this file by running `bin/tapioca sync`.

# typed: true

Expand Down Expand Up @@ -994,4 +995,21 @@ class Foo::Secret
refute_path_exists("#{outdir}/baz@0.0.1.rbi")
end
end

describe("deprecations") do
it "prints the correct deprecation message with -c" do
output = execute("dsl", ["-c", "foo"])
assert_includes(output, "DEPRECATION: The `-c` and `--cmd` flags will be removed in a future release.")
end

it "prints the correct deprecation message with --cmd" do
output = execute("dsl", ["--cmd", "foo"])
assert_includes(output, "DEPRECATION: The `-c` and `--cmd` flags will be removed in a future release.")
end

it "doesn't print the correct deprecation message with no flag" do
output = execute("dsl")
refute_includes(output, "DEPRECATION: The `-c` and `--cmd` flags will be removed in a future release.")
end
end
end