-
Notifications
You must be signed in to change notification settings - Fork 83
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Steep::RakeTask to run Steep CLI commands
- Loading branch information
1 parent
fecbd20
commit b74545a
Showing
2 changed files
with
214 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
require "rake" | ||
require "rake/tasklib" | ||
|
||
module Steep | ||
# Provides Rake tasks for running Steep commands. | ||
# | ||
# require "steep/rake_task" | ||
# Steep::RakeTask.new do |t| | ||
# t.check.severity_level = :error | ||
# t.watch.verbose | ||
# end | ||
class RakeTask < Rake::TaskLib | ||
attr_accessor :name | ||
|
||
def self.available_commands | ||
require "steep/cli" | ||
|
||
skipped_commands = %i[langserver checkfile] | ||
|
||
Steep::CLI.available_commands - skipped_commands | ||
end | ||
|
||
def initialize(name = :steep, cli_runner = default_cli_runner) | ||
super() | ||
|
||
@name = name | ||
|
||
configuration = TaskConfiguration.new | ||
|
||
yield configuration if block_given? | ||
|
||
define_tasks(configuration, cli_runner) | ||
end | ||
|
||
private | ||
|
||
# :nodoc: | ||
class TaskConfiguration | ||
def initialize | ||
@commands = {} | ||
end | ||
|
||
def method_missing(command) | ||
if respond_to?(command) | ||
@commands[command] ||= CommandConfiguration.new | ||
else | ||
super | ||
end | ||
end | ||
|
||
def respond_to_missing?(name, include_private = false) | ||
RakeTask.available_commands.include?(name) || super | ||
end | ||
|
||
def options(command) | ||
@commands[command]&.to_a || [] | ||
end | ||
end | ||
|
||
# :nodoc: | ||
class CommandConfiguration | ||
def initialize | ||
@options = [] | ||
end | ||
|
||
def method_missing(name, value = nil) | ||
@options << "--#{name.to_s.gsub(/_/, '-').gsub(/=/, '')}" | ||
@options << value.to_s unless value.nil? | ||
end | ||
|
||
def respond_to_missing?(_name) | ||
true | ||
end | ||
|
||
def to_a | ||
@options | ||
end | ||
end | ||
|
||
def default_cli_runner | ||
lambda do |arguments| | ||
require "steep" | ||
|
||
cli = Steep::CLI.new( | ||
stdout: $stdout, | ||
stdin: $stdin, | ||
stderr: $stderr, | ||
argv: arguments | ||
) | ||
|
||
cli.run | ||
end | ||
end | ||
|
||
def define_tasks(configuration, cli_runner) | ||
namespace name do | ||
RakeTask.available_commands.each do |command| | ||
desc "Run steep #{command}" | ||
|
||
task command do |_, args| | ||
configured_options = configuration.options(command) | ||
|
||
argv = [ | ||
command.to_s, | ||
*configured_options, | ||
*args.extras | ||
] | ||
|
||
result = cli_runner[argv] | ||
|
||
raise "Steep failed" if result.nonzero? | ||
end | ||
end | ||
|
||
desc "Run steep help" | ||
task "help" do | ||
arguments = ["--help"] | ||
|
||
cli_runner[arguments] | ||
end | ||
end | ||
|
||
# Default steep task to steep:check | ||
desc "Run steep check" unless ::Rake.application.last_description | ||
task name => ["#{name}:check"] | ||
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,86 @@ | ||
require_relative "test_helper" | ||
|
||
require_relative "../lib/steep/rake_task" | ||
|
||
require "minitest/mock" | ||
|
||
class RakeTaskTest < Minitest::Test | ||
def test_task_configuration | ||
configuration = Steep::RakeTask::TaskConfiguration.new | ||
|
||
configuration.check.severity_level = :error | ||
configuration.watch.verbose | ||
|
||
assert_raises(NoMethodError) do | ||
configuration.missing_command.verbose | ||
end | ||
|
||
assert_equal ["--severity-level", "error"], configuration.options(:check) | ||
assert_equal ["--verbose"], configuration.options(:watch) | ||
assert_equal [], configuration.options(:stats) | ||
end | ||
|
||
def test_define_task_with_options | ||
cli = mock_cli(expecting: %w[check --severity-level error]) | ||
|
||
setup_rake_tasks!(cli) do |task| | ||
task.check.severity_level = :error | ||
end | ||
|
||
Rake::Task["steep:check"].invoke | ||
end | ||
|
||
def test_rake_arguments | ||
cli = mock_cli(expecting: %w[check --severity-level error]) | ||
|
||
setup_rake_tasks!(cli) | ||
|
||
Rake::Task["steep:check"].invoke("--severity-level", "error") | ||
end | ||
|
||
def test_help_task | ||
cli = mock_cli(expecting: %w[--help]) | ||
|
||
setup_rake_tasks!(cli) | ||
|
||
Rake::Task["steep:help"].invoke | ||
end | ||
|
||
def test_default_task | ||
cli = mock_cli(expecting: %w[check --verbose]) | ||
|
||
setup_rake_tasks!(cli) do |task| | ||
task.check.verbose | ||
end | ||
|
||
Rake::Task["steep"].invoke | ||
end | ||
|
||
def test_skipped_commands | ||
setup_rake_tasks! | ||
|
||
assert Rake::Task.task_defined?("steep:help") | ||
|
||
refute Rake::Task.task_defined?("steep:langserver") | ||
end | ||
|
||
private | ||
|
||
def setup_rake_tasks!(cli_runner = nil, &block) | ||
Rake::Task.clear | ||
|
||
Steep::RakeTask.new(:steep, cli_runner, &block) | ||
end | ||
|
||
def mock_cli(expecting:) | ||
cli = Minitest::Mock.new | ||
|
||
cli.expect(:run, nil, [expecting]) | ||
|
||
lambda do |arguments| | ||
cli.run(arguments) | ||
|
||
0 | ||
end | ||
end | ||
end |