Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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 @@ -30,6 +30,7 @@ Sorbet/TrueSigil:
- "**/*.rb"
Exclude:
- "spec/support/gems/baz/lib/baz.rb"
- "spec/support/repo/bin/tapioca"

Sorbet/ConstantsFromStrings:
Enabled: false
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
14 changes: 4 additions & 10 deletions lib/tapioca/config_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ class << self

sig { params(command: Symbol, options: T::Hash[String, T.untyped]).returns(Config) }
def from_options(command, options)
puts(<<~MSG) if options.include?("generate_command")
DEPRECATION: The `-c` and `--cmd` flags will be removed in a future release.
MSG
Config.from_hash(
merge_options(default_options(command), config_options, options)
)
Expand Down Expand Up @@ -40,15 +43,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 +60,7 @@ def merge_options(*options)
DEFAULT_OPTIONS = T.let({
"postrequire" => Config::DEFAULT_POSTREQUIRE,
"outdir" => nil,
"generate_command" => default_command,
"generate_command" => Config::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
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}/[email protected]"))
# 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}/[email protected]")
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