Drop 2.3 ruby support (#108)

This commit is contained in:
Ivan Shamatov 2021-02-03 11:43:17 +03:00 committed by GitHub
parent 080d225576
commit 5cbcddd3c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 962 additions and 998 deletions

View File

@ -15,7 +15,7 @@ name: ci
pull_request:
branches:
- master
create:
create:
jobs:
tests:
runs-on: ubuntu-latest

View File

@ -7,5 +7,4 @@ jobs:
- "2.6"
- "2.5"
- "2.4"
- "2.3"
- "jruby"

View File

@ -8,8 +8,7 @@ group :test do
gem "simplecov", require: false, platforms: :ruby
gem "simplecov-cobertura", require: false, platforms: :ruby
gem "rexml", require: false
gem "warning" if RUBY_VERSION >= "2.4.0"
gem "warning"
end
group :tools do

View File

@ -1,8 +1,8 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
require 'bundler/setup'
require 'dry/cli'
require "bundler/setup"
require "dry/cli"
# You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like.
@ -11,5 +11,5 @@ require 'dry/cli'
# require "pry"
# Pry.start
require 'irb'
require "irb"
IRB.start(__FILE__)

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require 'dry/cli/program_name'
require "dry/cli/program_name"
module Dry
class CLI
@ -49,7 +49,7 @@ module Dry
def self.command_examples(command, name)
return if command.examples.empty?
"\nExamples:\n#{command.examples.map { |example| " #{name} #{example}" }.join("\n")}" # rubocop:disable Metrics/LineLength
"\nExamples:\n#{command.examples.map { |example| " #{name} #{example}" }.join("\n")}"
end
# @since 0.1.0
@ -86,18 +86,18 @@ module Dry
required_arguments = command.required_arguments
optional_arguments = command.optional_arguments
required = required_arguments.map { |arg| arg.name.upcase }.join(' ') if required_arguments.any? # rubocop:disable Metrics/LineLength
optional = optional_arguments.map { |arg| "[#{arg.name.upcase}]" }.join(' ') if optional_arguments.any? # rubocop:disable Metrics/LineLength
required = required_arguments.map { |arg| arg.name.upcase }.join(" ") if required_arguments.any? # rubocop:disable Metrics/LineLength
optional = optional_arguments.map { |arg| "[#{arg.name.upcase}]" }.join(" ") if optional_arguments.any? # rubocop:disable Metrics/LineLength
result = [required, optional].compact
" #{result.join(' ')}" unless result.empty?
" #{result.join(" ")}" unless result.empty?
end
# @since 0.1.0
# @api private
def self.extended_command_arguments(command)
command.arguments.map do |argument|
" #{argument.name.to_s.upcase.ljust(32)} # #{'REQUIRED ' if argument.required?}#{argument.desc}" # rubocop:disable Metrics/LineLength
" #{argument.name.to_s.upcase.ljust(32)} # #{"REQUIRED " if argument.required?}#{argument.desc}" # rubocop:disable Metrics/LineLength
end.join("\n")
end
@ -114,14 +114,14 @@ module Dry
else
"#{name}=VALUE"
end
name = "#{name}, #{option.alias_names.join(', ')}" if option.aliases.any?
name = "#{name}, #{option.alias_names.join(", ")}" if option.aliases.any?
name = " --#{name.ljust(30)}"
name = "#{name} # #{option.desc}"
name = "#{name}, default: #{option.default.inspect}" unless option.default.nil?
name
end
result << " --#{'help, -h'.ljust(30)} # Print this help"
result << " --#{"help, -h".ljust(30)} # Print this help"
result.join("\n")
end

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'forwardable'
require 'dry/cli/option'
require "forwardable"
require "dry/cli/option"
module Dry
class CLI
@ -369,7 +369,7 @@ module Dry
required_arguments
optional_arguments
subcommands
] => 'self.class'
] => "self.class"
end
end
end

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require 'set'
require "set"
module Dry
class CLI

View File

@ -10,7 +10,7 @@ module Dry
def self.dasherize(input)
return nil unless input
input.to_s.downcase.gsub(/[[[:space:]]_]/, '-')
input.to_s.downcase.gsub(/[[[:space:]]_]/, "-")
end
end
end

View File

@ -1,10 +1,10 @@
# frozen_string_literal: true
require 'backports/2.5.0/module/define_method' if RUBY_VERSION < '2.5'
require "backports/2.5.0/module/define_method" if RUBY_VERSION < "2.5"
module Dry
class CLI
require 'dry/cli'
require "dry/cli"
# Inline Syntax (aka DSL) to implement one-file applications
#
# `dry/cli/inline` is not required by default

View File

@ -32,7 +32,7 @@ module Dry
# @api private
def desc
desc = options[:desc]
values ? "#{desc}: (#{values.join('/')})" : desc
values ? "#{desc}: (#{values.join("/")})" : desc
end
# @since 0.1.0
@ -108,7 +108,7 @@ module Dry
# @api private
def alias_names
aliases
.map { |name| name.gsub(/^-{1,2}/, '') }
.map { |name| name.gsub(/^-{1,2}/, "") }
.compact
.uniq
.map { |name| name.size == 1 ? "-#{name}" : "--#{name}" }

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'optparse'
require 'dry/cli/program_name'
require "optparse"
require "dry/cli/program_name"
module Dry
class CLI
@ -24,7 +24,7 @@ module Dry
end
end
opts.on_tail('-h', '--help') do
opts.on_tail("-h", "--help") do
return Result.help
end
end.parse!(arguments)
@ -32,7 +32,7 @@ module Dry
parsed_options = command.default_params.merge(parsed_options)
parse_required_params(command, arguments, prog_name, parsed_options)
rescue ::OptionParser::ParseError
Result.failure("ERROR: \"#{prog_name}\" was called with arguments \"#{original_arguments.join(' ')}\"") # rubocop:disable Metrics/LineLength
Result.failure("ERROR: \"#{prog_name}\" was called with arguments \"#{original_arguments.join(" ")}\"") # rubocop:disable Metrics/LineLength
end
# @since 0.1.0
@ -49,14 +49,14 @@ module Dry
unless all_required_params_satisfied
parsed_required_params_values = parsed_required_params.values.compact
usage = "\nUsage: \"#{prog_name} #{command.required_arguments.map(&:description_name).join(' ')}" # rubocop:disable Metrics/LineLength
usage = "\nUsage: \"#{prog_name} #{command.required_arguments.map(&:description_name).join(" ")}" # rubocop:disable Metrics/LineLength
usage += " | #{prog_name} SUBCOMMAND" if command.subcommands.any?
usage += '"'
if parsed_required_params_values.empty?
return Result.failure("ERROR: \"#{prog_name}\" was called with no arguments#{usage}") # rubocop:disable Metrics/LineLength
return Result.failure("ERROR: \"#{prog_name}\" was called with no arguments#{usage}")
else
return Result.failure("ERROR: \"#{prog_name}\" was called with arguments #{parsed_required_params_values}#{usage}") # rubocop:disable Metrics/LineLength
end
@ -101,7 +101,7 @@ module Dry
# @since 0.1.0
# @api private
def self.failure(error = 'Error: Invalid param provided')
def self.failure(error = "Error: Invalid param provided")
new(error: error)
end

View File

@ -9,7 +9,7 @@ module Dry
module ProgramName
# @since 0.1.0
# @api private
SEPARATOR = ' '
SEPARATOR = " "
# @since 0.1.0
# @api private

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require 'dry/cli/command_registry'
require "dry/cli/command_registry"
module Dry
class CLI
@ -272,7 +272,7 @@ module Dry
private
COMMAND_NAME_SEPARATOR = ' '
COMMAND_NAME_SEPARATOR = " "
# @since 0.2.0
# @api private

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require 'dry/cli/program_name'
require "dry/cli/program_name"
module Dry
class CLI
@ -11,13 +11,13 @@ module Dry
module Usage
# @since 0.1.0
# @api private
SUBCOMMAND_BANNER = ' [SUBCOMMAND]'
ROOT_COMMAND_WITH_SUBCOMMANDS_BANNER = ' [ARGUMENT|SUBCOMMAND]'
SUBCOMMAND_BANNER = " [SUBCOMMAND]"
ROOT_COMMAND_WITH_SUBCOMMANDS_BANNER = " [ARGUMENT|SUBCOMMAND]"
# @since 0.1.0
# @api private
def self.call(result)
header = 'Commands:'
header = "Commands:"
max_length, commands = commands_and_arguments(result)
commands.map do |banner, node|
@ -55,11 +55,11 @@ module Dry
required_arguments = command.required_arguments
optional_arguments = command.optional_arguments
required = required_arguments.map { |arg| arg.name.upcase }.join(' ') if required_arguments.any? # rubocop:disable Metrics/LineLength
optional = optional_arguments.map { |arg| "[#{arg.name.upcase}]" }.join(' ') if optional_arguments.any? # rubocop:disable Metrics/LineLength
required = required_arguments.map { |arg| arg.name.upcase }.join(" ") if required_arguments.any? # rubocop:disable Metrics/LineLength
optional = optional_arguments.map { |arg| "[#{arg.name.upcase}]" }.join(" ") if optional_arguments.any? # rubocop:disable Metrics/LineLength
result = [required, optional].compact
" #{result.join(' ')}" unless result.empty?
" #{result.join(" ")}" unless result.empty?
end
# @since 0.1.0
@ -73,7 +73,7 @@ module Dry
# @since 0.1.0
# @api private
def self.justify(string, padding, usage)
return string.chomp(' ') if usage.nil?
return string.chomp(" ") if usage.nil?
string.ljust(padding + padding / 2)
end

View File

@ -1,8 +1,7 @@
# frozen_string_literal: true
require 'pathname'
require 'fileutils'
require 'backports/2.4.0/string/match' if RUBY_VERSION < '2.4'
require "pathname"
require "fileutils"
module Dry
class CLI
@ -33,7 +32,7 @@ module Dry
# @since 0.3.1
def self.write(path, *content)
mkdir_p(path)
open(path, ::File::CREAT | ::File::WRONLY | ::File::TRUNC, *content) # rubocop:disable LineLength, Security/Open - this isn't a call to `::Kernel.open`, but to `self.open`
open(path, ::File::CREAT | ::File::WRONLY | ::File::TRUNC, *content) # rubocop:disable Security/Open - this isn't a call to `::Kernel.open`, but to `self.open`
end
# Copies source into destination.
@ -315,7 +314,7 @@ module Dry
starting = index(content, path, target)
line = content[starting]
size = line[/\A[[:space:]]*/].bytesize
closing = (' ' * size) + (target.match?(/{/) ? '}' : 'end')
closing = (" " * size) + (target.match?(/{/) ? "}" : "end")
ending = starting + index(content[starting..-1], path, closing)
content.slice!(starting..ending)

View File

@ -3,6 +3,6 @@
module Dry
class CLI
# @since 0.1.0
VERSION = '0.6.0'
VERSION = "0.6.0"
end
end

View File

@ -4,10 +4,10 @@ gemspec:
authors: ["Luca Guidi"]
email: ["me@lucaguidi.com"]
summary: "Common framework to build command line interfaces with Ruby"
required_ruby_version: ">= 2.3.0"
required_ruby_version: ">= 2.4.0"
development_dependencies:
- [bundler, ">= 1.6", "< 3"]
- [rake, "~> 13.0"]
- [rspec, "~> 3.7"]
- [simplecov, "~> 0.17.1"]
- [rubocop, "0.81"]
- [rubocop, "~> 0.82"]

View File

@ -1,12 +1,12 @@
# frozen_string_literal: true
RSpec.describe 'Commands' do
context 'with extra params' do
context 'when there is a required argument' do
context 'and there are options' do
it 'parses both separately' do
RSpec.describe "Commands" do
context "with extra params" do
context "when there is a required argument" do
context "and there are options" do
it "parses both separately" do
output = `foo variadic with-mandatory-and-options uno -- due tre --blah`
expect(output).to eq("first: uno\nurl: \nmethod: \nUnused Arguments: due, tre, --blah\n") # rubocop:disable Metrics/LineLength
expect(output).to eq("first: uno\nurl: \nmethod: \nUnused Arguments: due, tre, --blah\n")
end
end
end

View File

@ -1,12 +1,12 @@
# frozen_string_literal: true
require 'open3'
require "open3"
RSpec.describe 'Inline' do
context 'with command' do
let(:cmd) { 'inline' }
RSpec.describe "Inline" do
context "with command" do
let(:cmd) { "inline" }
it 'shows help' do
it "shows help" do
output = `inline -h`
expected_output = <<~OUTPUT
Command:
@ -31,19 +31,10 @@ RSpec.describe 'Inline' do
expect(output).to eq(expected_output)
end
it 'with option_one', if: RUBY_VERSION < '2.4' do
output = `inline first_arg --option-one=test2 -bd test3`
expect(output).to eq(
'mandatory_arg: first_arg. optional_arg: optional_arg. ' \
'Options: {:option_with_default=>"test3", :option_one=>"test2", :boolean_option=>true}' \
"\n"
)
end
it 'with underscored option_one', if: RUBY_VERSION >= '2.4' do
it "with underscored option_one" do
output = `inline first_arg -1 test2 -bd test3`
expect(output).to eq(
'mandatory_arg: first_arg. optional_arg: optional_arg. ' \
"mandatory_arg: first_arg. optional_arg: optional_arg. " \
'Options: {:option_with_default=>"test3", :option_one=>"test2", :boolean_option=>true}' \
"\n"
)

View File

@ -1,10 +1,10 @@
# frozen_string_literal: true
require 'open3'
require "open3"
RSpec.describe 'Rendering' do
it 'prints available commands for unknown command' do
_, stderr, = Open3.capture3('foo unknown')
RSpec.describe "Rendering" do
it "prints available commands for unknown command" do
_, stderr, = Open3.capture3("foo unknown")
expected = <<~DESC
Commands:

View File

@ -1,19 +1,19 @@
# frozen_string_literal: true
require 'open3'
require "open3"
RSpec.describe 'Single command' do
context 'with command' do
let(:cmd) { 'baz' }
RSpec.describe "Single command" do
context "with command" do
let(:cmd) { "baz" }
it 'shows usage' do
_, stderr, = Open3.capture3('baz')
it "shows usage" do
_, stderr, = Open3.capture3("baz")
expect(stderr).to eq(
"ERROR: \"#{cmd}\" was called with no arguments\nUsage: \"#{cmd} MANDATORY_ARG\"\n"
)
end
it 'shows help' do
it "shows help" do
output = `baz -h`
expected_output = <<~OUTPUT
Command:
@ -38,25 +38,25 @@ RSpec.describe 'Single command' do
expect(output).to eq(expected_output)
end
it 'with option_one' do
it "with option_one" do
output = `baz first_arg --option-one=test2`
expect(output).to eq(
'mandatory_arg: first_arg. optional_arg: optional_arg. ' \
"mandatory_arg: first_arg. optional_arg: optional_arg. " \
"Options: {:option_with_default=>\"test\", :option_one=>\"test2\"}\n"
)
end
it 'with combination of aliases' do
it "with combination of aliases" do
output = `baz first_arg -bd test3`
expect(output).to eq(
'mandatory_arg: first_arg. optional_arg: optional_arg. ' \
"mandatory_arg: first_arg. optional_arg: optional_arg. " \
"Options: {:option_with_default=>\"test3\", :boolean_option=>true}\n"
)
end
end
context 'root command with arguments and subcommands' do
it 'with arguments' do
context "root command with arguments and subcommands" do
it "with arguments" do
output = `foo root-command "hello world"`
expected = <<~DESC
@ -67,7 +67,7 @@ RSpec.describe 'Single command' do
expect(output).to eq(expected)
end
it 'with options' do
it "with options" do
output = `foo root-command "hello world" --root-command-option="bye world"`
expected = <<~DESC

View File

@ -1,10 +1,10 @@
# frozen_string_literal: true
require 'open3'
require "open3"
RSpec.describe 'Subcommands' do
context 'works with params' do
it 'with help param' do
RSpec.describe "Subcommands" do
context "works with params" do
it "with help param" do
output = `foo generate model --help`
expected = <<~DESC
@ -33,8 +33,8 @@ RSpec.describe 'Subcommands' do
end
end
context 'works with root command subcommands' do
it 'with params' do
context "works with root command subcommands" do
it "with params" do
output = `foo root-command sub-command "hello world"`
expected = <<~DESC
@ -45,7 +45,7 @@ RSpec.describe 'Subcommands' do
expect(output).to eq(expected)
end
it 'with options' do
it "with options" do
option = '--root-command-sub-command-option="bye world"'
output = `foo root-command sub-command "hello world" #{option}`

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.describe 'Third-party gems' do
it 'allows to add callbacks as a block' do
RSpec.describe "Third-party gems" do
it "allows to add callbacks as a block" do
output = `foo callbacks . --url=https://hanamirb.test`
expected = <<~OUTPUT

View File

@ -8,7 +8,7 @@ require_relative "./support/rspec"
%w[support unit].each do |dir|
Dir[File.join(Dir.pwd, "spec", dir, "**", "*.rb")].each do |file|
unless RUBY_VERSION < "2.4.0" && file["support/warnings.rb"]
unless file["support/warnings.rb"]
require_relative file
end
end

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require 'rspec/expectations'
require "rspec/expectations"
RSpec::Matchers.define :have_content do |expected|
match do |actual|

View File

@ -1,9 +1,9 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
$LOAD_PATH.unshift __dir__ + '/../../lib'
require 'dry/cli'
$LOAD_PATH.unshift __dir__ + "/../../lib"
require "dry/cli"
require_relative 'baz_command'
require_relative "baz_command"
Dry.CLI(Baz::CLI).call

View File

@ -2,15 +2,15 @@
module Baz
class CLI < Dry::CLI::Command
desc 'Baz command line interface'
argument :mandatory_arg, required: true, aliases: %w[m], desc: 'Mandatory argument'
desc "Baz command line interface"
argument :mandatory_arg, required: true, aliases: %w[m], desc: "Mandatory argument"
argument :optional_arg, aliases: %w[o],
desc: 'Optional argument (has to have default value in call method)'
option :option_one, aliases: %w[1], desc: 'Option one'
option :boolean_option, aliases: %w[b], desc: 'Option boolean', type: :boolean
option :option_with_default, aliases: %w[d], desc: 'Option default', default: 'test'
desc: "Optional argument (has to have default value in call method)"
option :option_one, aliases: %w[1], desc: "Option one"
option :boolean_option, aliases: %w[b], desc: "Option boolean", type: :boolean
option :option_with_default, aliases: %w[d], desc: "Option default", default: "test"
def call(mandatory_arg:, optional_arg: 'optional_arg', **options)
def call(mandatory_arg:, optional_arg: "optional_arg", **options)
puts "mandatory_arg: #{mandatory_arg}. " \
"optional_arg: #{optional_arg}. " \
"Options: #{options.inspect}"

View File

@ -2,8 +2,8 @@
# frozen_string_literal: true
# rubocop:disable Metrics/LineLength
$LOAD_PATH.unshift __dir__ + '/../../lib'
require 'dry/cli'
$LOAD_PATH.unshift __dir__ + "/../../lib"
require "dry/cli"
module Foo
module CLI
@ -15,10 +15,10 @@ module Foo
module Assets
class Precompile < Dry::CLI::Command
desc 'Precompile assets for deployment'
desc "Precompile assets for deployment"
example [
'FOO_ENV=production # Precompile assets for production environment'
"FOO_ENV=production # Precompile assets for production environment"
]
def call(*); end
@ -26,12 +26,12 @@ module Foo
end
class Console < Dry::CLI::Command
desc 'Starts Foo console'
option :engine, desc: 'Force a console engine', values: %w[irb pry ripl]
desc "Starts Foo console"
option :engine, desc: "Force a console engine", values: %w[irb pry ripl]
example [
' # Uses the bundled engine',
'--engine=pry # Force to use Pry'
" # Uses the bundled engine",
"--engine=pry # Force to use Pry"
]
def call(engine: nil, **)
@ -41,57 +41,57 @@ module Foo
module DB
class Apply < Dry::CLI::Command
desc 'Migrate, dump the SQL schema, and delete the migrations (experimental)'
desc "Migrate, dump the SQL schema, and delete the migrations (experimental)"
def call(*); end
end
class Console < Dry::CLI::Command
desc 'Starts a database console'
desc "Starts a database console"
def call(*); end
end
class Create < Dry::CLI::Command
desc 'Create the database (only for development/test)'
desc "Create the database (only for development/test)"
def call(*); end
end
class Drop < Dry::CLI::Command
desc 'Drop the database (only for development/test)'
desc "Drop the database (only for development/test)"
def call(*); end
end
class Migrate < Dry::CLI::Command
desc 'Migrate the database'
argument :version, desc: 'The target version of the migration (see `foo db version`)'
desc "Migrate the database"
argument :version, desc: "The target version of the migration (see `foo db version`)"
example [
' # Migrate to the last version',
'20170721120747 # Migrate to a specific version'
" # Migrate to the last version",
"20170721120747 # Migrate to a specific version"
]
def call(*); end
end
class Prepare < Dry::CLI::Command
desc 'Drop, create, and migrate the database (only for development/test)'
desc "Drop, create, and migrate the database (only for development/test)"
def call(*); end
end
class Version < Dry::CLI::Command
desc 'Print the current migrated version'
desc "Print the current migrated version"
def call(*); end
end
class Rollback < Dry::CLI::Command
desc 'Rollback the database'
desc "Rollback the database"
argument :steps, desc: 'Number of versions to rollback', default: 1
argument :steps, desc: "Number of versions to rollback", default: 1
def call(steps:, **)
puts steps
@ -101,15 +101,15 @@ module Foo
module Destroy
class Action < Dry::CLI::Command
desc 'Destroy an action from app'
desc "Destroy an action from app"
example [
'web home#index # Basic usage',
'admin users#index # Destroy from `admin` app'
"web home#index # Basic usage",
"admin users#index # Destroy from `admin` app"
]
argument :app, required: true, desc: 'The application name (eg. `web`)'
argument :action, required: true, desc: 'The action name (eg. `home#index`)'
argument :app, required: true, desc: "The application name (eg. `web`)"
argument :action, required: true, desc: "The action name (eg. `home#index`)"
def call(app:, action:, **)
puts "destroy action - app: #{app}, action: #{action}"
@ -117,48 +117,48 @@ module Foo
end
class App < Dry::CLI::Command
desc 'Destroy an app'
desc "Destroy an app"
argument :app, required: true, desc: 'The application name (eg. `web`)'
argument :app, required: true, desc: "The application name (eg. `web`)"
example [
'admin # Destroy `admin` app'
"admin # Destroy `admin` app"
]
def call(*); end
end
class Mailer < Dry::CLI::Command
desc 'Destroy a mailer'
desc "Destroy a mailer"
argument :mailer, required: true, desc: 'The mailer name (eg. `welcome`)'
argument :mailer, required: true, desc: "The mailer name (eg. `welcome`)"
example [
'welcome # Destroy `WelcomeMailer` mailer'
"welcome # Destroy `WelcomeMailer` mailer"
]
def call(*); end
end
class Migration < Dry::CLI::Command
desc 'Destroy a migration'
desc "Destroy a migration"
argument :migration, required: true, desc: 'The migration name (eg. `create_users`)'
argument :migration, required: true, desc: "The migration name (eg. `create_users`)"
example [
'create_users # Destroy `db/migrations/20170721120747_create_users.rb`'
"create_users # Destroy `db/migrations/20170721120747_create_users.rb`"
]
def call(*); end
end
class Model < Dry::CLI::Command
desc 'Destroy a model'
desc "Destroy a model"
argument :model, required: true, desc: 'The model name (eg. `user`)'
argument :model, required: true, desc: "The model name (eg. `user`)"
example [
'user # Destroy `User` entity and `UserRepository` repository'
"user # Destroy `User` entity and `UserRepository` repository"
]
def call(*); end
@ -167,22 +167,22 @@ module Foo
module Generate
class Action < Dry::CLI::Command
desc 'Generate an action for app'
desc "Generate an action for app"
example [
'web home#index # Basic usage',
'admin home#index # Generate for `admin` app',
'web home#index --url=/ # Specify URL',
'web sessions#destroy --method=GET # Specify HTTP method',
'web books#create --skip-view # Skip view and template'
"web home#index # Basic usage",
"admin home#index # Generate for `admin` app",
"web home#index --url=/ # Specify URL",
"web sessions#destroy --method=GET # Specify HTTP method",
"web books#create --skip-view # Skip view and template"
]
argument :app, required: true, desc: 'The application name (eg. `web`)'
argument :action, required: true, desc: 'The action name (eg. `home#index`)'
argument :app, required: true, desc: "The application name (eg. `web`)"
argument :action, required: true, desc: "The action name (eg. `home#index`)"
option :url, desc: 'The action URL'
option :method, desc: 'The action HTTP method'
option :skip_view, type: :boolean, default: false, desc: 'Skip view and template'
option :url, desc: "The action URL"
option :method, desc: "The action HTTP method"
option :skip_view, type: :boolean, default: false, desc: "Skip view and template"
def call(app:, action:, **options)
puts "generate action - app: #{app}, action: #{action}, options: #{options.inspect}"
@ -190,30 +190,30 @@ module Foo
end
class App < Dry::CLI::Command
desc 'Generate an app'
desc "Generate an app"
argument :app, required: true, desc: 'The application name (eg. `web`)'
option :application_base_url, desc: 'The app base URL (eg. `/api/v1`)'
argument :app, required: true, desc: "The application name (eg. `web`)"
option :application_base_url, desc: "The app base URL (eg. `/api/v1`)"
example [
'admin # Generate `admin` app',
'api --application-base-url=/api/v1 # Generate `api` app and mount at `/api/v1`'
"admin # Generate `admin` app",
"api --application-base-url=/api/v1 # Generate `api` app and mount at `/api/v1`"
]
def call(*); end
end
class Mailer < Dry::CLI::Command
desc 'Generate a mailer'
desc "Generate a mailer"
argument :mailer, required: true, desc: 'The mailer name (eg. `welcome`)'
argument :mailer, required: true, desc: "The mailer name (eg. `welcome`)"
option :from, desc: 'The default `from` field of the mail'
option :to, desc: 'The default `to` field of the mail'
option :subject, desc: 'The mail subject'
option :from, desc: "The default `from` field of the mail"
option :to, desc: "The default `to` field of the mail"
option :subject, desc: "The mail subject"
example [
'welcome # Basic usage',
"welcome # Basic usage",
'welcome --from="noreply@example.com" # Generate with default `from` value',
'announcement --to="users@example.com" # Generate with default `to` value',
'forgot_password --subject="Your password reset" # Generate with default `subject`'
@ -223,26 +223,26 @@ module Foo
end
class Migration < Dry::CLI::Command
desc 'Generate a migration'
desc "Generate a migration"
argument :migration, required: true, desc: 'The migration name (eg. `create_users`)'
argument :migration, required: true, desc: "The migration name (eg. `create_users`)"
example [
'create_users # Generate `db/migrations/20170721120747_create_users.rb`'
"create_users # Generate `db/migrations/20170721120747_create_users.rb`"
]
def call(*); end
end
class Model < Dry::CLI::Command
desc 'Generate a model'
desc "Generate a model"
argument :model, required: true, desc: 'Model name (eg. `user`)'
option :skip_migration, type: :boolean, default: false, desc: 'Skip migration'
argument :model, required: true, desc: "Model name (eg. `user`)"
option :skip_migration, type: :boolean, default: false, desc: "Skip migration"
example [
'user # Generate `User` entity, `UserRepository` repository, and the migration',
'user --skip-migration # Generate `User` entity and `UserRepository` repository'
"user # Generate `User` entity, `UserRepository` repository, and the migration",
"user --skip-migration # Generate `User` entity and `UserRepository` repository"
]
def call(model:, **)
@ -251,13 +251,13 @@ module Foo
end
class Secret < Dry::CLI::Command
desc 'Generate session secret'
desc "Generate session secret"
argument :app, desc: 'The application name (eg. `web`)'
argument :app, desc: "The application name (eg. `web`)"
example [
' # Prints secret (eg. `6fad60e21f3f6bfcaf8e56cdb0f835d644b4892c3badc58328126812429bf073`)',
'web # Prints session secret (eg. `WEB_SESSIONS_SECRET=6fad60e21f3f6bfcaf8e56cdb0f835d644b4892c3badc58328126812429bf073`)'
" # Prints secret (eg. `6fad60e21f3f6bfcaf8e56cdb0f835d644b4892c3badc58328126812429bf073`)",
"web # Prints session secret (eg. `WEB_SESSIONS_SECRET=6fad60e21f3f6bfcaf8e56cdb0f835d644b4892c3badc58328126812429bf073`)"
]
def call(app: nil, **)
@ -267,22 +267,22 @@ module Foo
end
class New < Dry::CLI::Command
desc 'Generate a new Foo project'
desc "Generate a new Foo project"
argument :project, required: true
option :database, desc: 'Database (sqlite/postgres/mysql)', default: 'sqlite', aliases: ['-d', '--db']
option :application_name, desc: 'App name', default: 'web'
option :application_base_url, desc: 'App base URL', default: '/'
option :template, desc: 'Template engine (erb/haml/slim)', default: 'erb'
option :test, desc: 'Project testing framework (minitest/rspec)', default: 'minitest'
option :foo_head, desc: 'Use Foo HEAD (true/false)', type: :boolean, default: false
option :database, desc: "Database (sqlite/postgres/mysql)", default: "sqlite", aliases: ["-d", "--db"]
option :application_name, desc: "App name", default: "web"
option :application_base_url, desc: "App base URL", default: "/"
option :template, desc: "Template engine (erb/haml/slim)", default: "erb"
option :test, desc: "Project testing framework (minitest/rspec)", default: "minitest"
option :foo_head, desc: "Use Foo HEAD (true/false)", type: :boolean, default: false
example [
'bookshelf # Basic usage',
'bookshelf --test=rspec # Setup RSpec testing framework',
'bookshelf --database=postgres # Setup Postgres database',
'bookshelf --template=slim # Setup Slim template engine',
'bookshelf --foo-head # Use Foo HEAD'
"bookshelf # Basic usage",
"bookshelf --test=rspec # Setup RSpec testing framework",
"bookshelf --database=postgres # Setup Postgres database",
"bookshelf --template=slim # Setup Slim template engine",
"bookshelf --foo-head # Use Foo HEAD"
]
def call(project:, **)
@ -291,29 +291,29 @@ module Foo
end
class Routes < Dry::CLI::Command
desc 'Print routes'
desc "Print routes"
def call(*); end
end
class Server < Dry::CLI::Command
desc 'Start Foo server (only for development)'
desc "Start Foo server (only for development)"
option :server, desc: 'Force a server engine (eg, webrick, puma, thin, etc..)'
option :host, desc: 'The host address to bind to'
option :port, desc: 'The port to run the server on', aliases: ['-p']
option :debug, desc: 'Turn on debug output'
option :warn, desc: 'Turn on warnings'
option :daemonize, desc: 'Daemonize the server'
option :pid, desc: 'Path to write a pid file after daemonize'
option :code_reloading, desc: 'Code reloading', type: :boolean, default: true
option :server, desc: "Force a server engine (eg, webrick, puma, thin, etc..)"
option :host, desc: "The host address to bind to"
option :port, desc: "The port to run the server on", aliases: ["-p"]
option :debug, desc: "Turn on debug output"
option :warn, desc: "Turn on warnings"
option :daemonize, desc: "Daemonize the server"
option :pid, desc: "Path to write a pid file after daemonize"
option :code_reloading, desc: "Code reloading", type: :boolean, default: true
example [
' # Basic usage (it uses the bundled server engine)',
'--server=webrick # Force `webrick` server engine',
'--host=0.0.0.0 # Bind to a host',
'--port=2306 # Bind to a port',
'--no-code-reloading # Disable code reloading'
" # Basic usage (it uses the bundled server engine)",
"--server=webrick # Force `webrick` server engine",
"--host=0.0.0.0 # Bind to a host",
"--port=2306 # Bind to a port",
"--no-code-reloading # Disable code reloading"
]
def call(options)
@ -322,18 +322,18 @@ module Foo
end
class Version < Dry::CLI::Command
desc 'Print Foo version'
desc "Print Foo version"
def call(*)
puts 'v1.0.0'
puts "v1.0.0"
end
end
class Exec < Dry::CLI::Command
desc 'Execute a task'
desc "Execute a task"
argument :task, desc: 'Task to execute', type: :string, required: true
argument :dirs, desc: 'Directories', type: :array, required: false
argument :task, desc: "Task to execute", type: :string, required: true
argument :dirs, desc: "Directories", type: :array, required: false
def call(task:, dirs: [], **)
puts "exec - Task: #{task} - Directories: #{dirs.inspect}"
@ -347,7 +347,7 @@ module Foo
end
class Greeting < Dry::CLI::Command
argument :response, default: 'Hello World'
argument :response, default: "Hello World"
option :person
@ -357,36 +357,36 @@ module Foo
end
class VariadicArguments < Dry::CLI::Command
desc 'accept multiple arguments at the end of the command'
desc "accept multiple arguments at the end of the command"
def call(**options)
puts "Unused Arguments: #{options[:args].join(', ')}"
puts "Unused Arguments: #{options[:args].join(", ")}"
end
end
class MandatoryAndVariadicArguments < Dry::CLI::Command
desc 'require one command and accept multiple unused arguments'
desc "require one command and accept multiple unused arguments"
argument :first, desc: 'mandatory first argument', required: true
argument :first, desc: "mandatory first argument", required: true
def call(first:, **options)
puts "first: #{first}"
puts "Unused Arguments: #{options[:args].join(', ')}"
puts "Unused Arguments: #{options[:args].join(", ")}"
end
end
class MandatoryOptionsAndVariadicArguments < Dry::CLI::Command
desc 'require one command, accept options and multiple unused arguments'
desc "require one command, accept options and multiple unused arguments"
argument :first, desc: 'mandatory first argument', required: true
option :url, desc: 'The action URL'
option :method, desc: 'The action HTTP method'
argument :first, desc: "mandatory first argument", required: true
option :url, desc: "The action URL"
option :method, desc: "The action HTTP method"
def call(first:, **options)
puts "first: #{first}"
puts "url: #{options[:url]}"
puts "method: #{options[:method]}"
puts "Unused Arguments: #{options[:args].join(', ')}"
puts "Unused Arguments: #{options[:args].join(", ")}"
end
end
@ -399,9 +399,9 @@ module Foo
end
class RootCommand < Dry::CLI::Command
desc 'Root command with arguments and subcommands'
argument :root_command_argument, desc: 'Root command argument', required: true
option :root_command_option, desc: 'Root command option'
desc "Root command with arguments and subcommands"
argument :root_command_argument, desc: "Root command argument", required: true
option :root_command_option, desc: "Root command option"
def call(**params)
puts "I'm a root-command argument:#{params[:root_command_argument]}"
@ -411,9 +411,9 @@ module Foo
module RootCommands
class SubCommand < Dry::CLI::Command
desc 'Root command sub command'
argument :root_command_sub_command_argument, desc: 'Root command sub command argument', required: true
option :root_command_sub_command_option, desc: 'Root command sub command option'
desc "Root command sub command"
argument :root_command_sub_command_argument, desc: "Root command sub command argument", required: true
option :root_command_sub_command_option, desc: "Root command sub command option"
def call(**params)
puts "I'm a root-command sub-command argument:#{params[:root_command_sub_command_argument]}"
@ -425,56 +425,56 @@ module Foo
end
end
Foo::CLI::Commands.register 'assets precompile', Foo::CLI::Commands::Assets::Precompile
Foo::CLI::Commands.register 'console', Foo::CLI::Commands::Console
Foo::CLI::Commands.register 'db' do |prefix|
prefix.register 'apply', Foo::CLI::Commands::DB::Apply
prefix.register 'console', Foo::CLI::Commands::DB::Console
prefix.register 'create', Foo::CLI::Commands::DB::Create
prefix.register 'drop', Foo::CLI::Commands::DB::Drop
prefix.register 'migrate', Foo::CLI::Commands::DB::Migrate
prefix.register 'prepare', Foo::CLI::Commands::DB::Prepare
prefix.register 'version', Foo::CLI::Commands::DB::Version
prefix.register 'rollback', Foo::CLI::Commands::DB::Rollback
Foo::CLI::Commands.register "assets precompile", Foo::CLI::Commands::Assets::Precompile
Foo::CLI::Commands.register "console", Foo::CLI::Commands::Console
Foo::CLI::Commands.register "db" do |prefix|
prefix.register "apply", Foo::CLI::Commands::DB::Apply
prefix.register "console", Foo::CLI::Commands::DB::Console
prefix.register "create", Foo::CLI::Commands::DB::Create
prefix.register "drop", Foo::CLI::Commands::DB::Drop
prefix.register "migrate", Foo::CLI::Commands::DB::Migrate
prefix.register "prepare", Foo::CLI::Commands::DB::Prepare
prefix.register "version", Foo::CLI::Commands::DB::Version
prefix.register "rollback", Foo::CLI::Commands::DB::Rollback
end
Foo::CLI::Commands.register 'destroy', aliases: ['d'] do |prefix|
prefix.register 'action', Foo::CLI::Commands::Destroy::Action
prefix.register 'app', Foo::CLI::Commands::Destroy::App
prefix.register 'mailer', Foo::CLI::Commands::Destroy::Mailer
prefix.register 'migration', Foo::CLI::Commands::Destroy::Migration
prefix.register 'model', Foo::CLI::Commands::Destroy::Model
Foo::CLI::Commands.register "destroy", aliases: ["d"] do |prefix|
prefix.register "action", Foo::CLI::Commands::Destroy::Action
prefix.register "app", Foo::CLI::Commands::Destroy::App
prefix.register "mailer", Foo::CLI::Commands::Destroy::Mailer
prefix.register "migration", Foo::CLI::Commands::Destroy::Migration
prefix.register "model", Foo::CLI::Commands::Destroy::Model
end
Foo::CLI::Commands.register 'generate', aliases: ['g'] do |prefix|
prefix.register 'action', Foo::CLI::Commands::Generate::Action
prefix.register 'app', Foo::CLI::Commands::Generate::App
prefix.register 'mailer', Foo::CLI::Commands::Generate::Mailer
prefix.register 'migration', Foo::CLI::Commands::Generate::Migration
prefix.register 'model', Foo::CLI::Commands::Generate::Model
prefix.register 'secret', Foo::CLI::Commands::Generate::Secret
Foo::CLI::Commands.register "generate", aliases: ["g"] do |prefix|
prefix.register "action", Foo::CLI::Commands::Generate::Action
prefix.register "app", Foo::CLI::Commands::Generate::App
prefix.register "mailer", Foo::CLI::Commands::Generate::Mailer
prefix.register "migration", Foo::CLI::Commands::Generate::Migration
prefix.register "model", Foo::CLI::Commands::Generate::Model
prefix.register "secret", Foo::CLI::Commands::Generate::Secret
end
Foo::CLI::Commands.register 'new', Foo::CLI::Commands::New
Foo::CLI::Commands.register 'routes', Foo::CLI::Commands::Routes
Foo::CLI::Commands.register 'server', Foo::CLI::Commands::Server, aliases: ['s']
Foo::CLI::Commands.register 'version', Foo::CLI::Commands::Version, aliases: ['v', '-v', '--version']
Foo::CLI::Commands.register 'exec', Foo::CLI::Commands::Exec
Foo::CLI::Commands.register "new", Foo::CLI::Commands::New
Foo::CLI::Commands.register "routes", Foo::CLI::Commands::Routes
Foo::CLI::Commands.register "server", Foo::CLI::Commands::Server, aliases: ["s"]
Foo::CLI::Commands.register "version", Foo::CLI::Commands::Version, aliases: ["v", "-v", "--version"]
Foo::CLI::Commands.register "exec", Foo::CLI::Commands::Exec
Foo::CLI::Commands.register 'hello', Foo::CLI::Commands::Hello
Foo::CLI::Commands.register 'greeting', Foo::CLI::Commands::Greeting
Foo::CLI::Commands.register 'sub command', Foo::CLI::Commands::Sub::Command
Foo::CLI::Commands.register 'root-command', Foo::CLI::Commands::RootCommand
Foo::CLI::Commands.register 'root-command sub-command', Foo::CLI::Commands::RootCommands::SubCommand
Foo::CLI::Commands.register "hello", Foo::CLI::Commands::Hello
Foo::CLI::Commands.register "greeting", Foo::CLI::Commands::Greeting
Foo::CLI::Commands.register "sub command", Foo::CLI::Commands::Sub::Command
Foo::CLI::Commands.register "root-command", Foo::CLI::Commands::RootCommand
Foo::CLI::Commands.register "root-command sub-command", Foo::CLI::Commands::RootCommands::SubCommand
Foo::CLI::Commands.register 'variadic default', Foo::CLI::Commands::VariadicArguments
Foo::CLI::Commands.register 'variadic with-mandatory', Foo::CLI::Commands::MandatoryAndVariadicArguments
Foo::CLI::Commands.register 'variadic with-mandatory-and-options', Foo::CLI::Commands::MandatoryOptionsAndVariadicArguments
Foo::CLI::Commands.register "variadic default", Foo::CLI::Commands::VariadicArguments
Foo::CLI::Commands.register "variadic with-mandatory", Foo::CLI::Commands::MandatoryAndVariadicArguments
Foo::CLI::Commands.register "variadic with-mandatory-and-options", Foo::CLI::Commands::MandatoryOptionsAndVariadicArguments
module Foo
module Webpack
module CLI
class Generate < Dry::CLI::Command
desc 'Generate webpack configuration'
desc "Generate webpack configuration"
option :apps, desc: 'Generate webpack apps', type: :array
option :apps, desc: "Generate webpack apps", type: :array
def call(apps: [], **)
puts "generate webpack. Apps: #{apps}"
@ -482,23 +482,23 @@ module Foo
end
class Hello < Dry::CLI::Command
desc 'Print a greeting'
desc "Print a greeting"
def call(*)
puts 'hello from webpack'
puts "hello from webpack"
end
end
class SubCommand < Dry::CLI::Command
desc 'Override a subcommand'
desc "Override a subcommand"
def call(**)
puts 'override from webpack'
puts "override from webpack"
end
end
class CallbacksCommand < Dry::CLI::Command
desc 'Command with callbacks'
desc "Command with callbacks"
argument :dir, required: true
option :url
@ -510,19 +510,19 @@ module Foo
end
end
Foo::CLI::Commands.register 'generate webpack', Foo::Webpack::CLI::Generate
Foo::CLI::Commands.register 'hello', Foo::Webpack::CLI::Hello
Foo::CLI::Commands.register 'sub command', Foo::Webpack::CLI::SubCommand
Foo::CLI::Commands.register 'callbacks', Foo::Webpack::CLI::CallbacksCommand
Foo::CLI::Commands.register "generate webpack", Foo::Webpack::CLI::Generate
Foo::CLI::Commands.register "hello", Foo::Webpack::CLI::Hello
Foo::CLI::Commands.register "sub command", Foo::Webpack::CLI::SubCommand
Foo::CLI::Commands.register "callbacks", Foo::Webpack::CLI::CallbacksCommand
# we need to be sure that command will not override with nil command
Foo::CLI::Commands.register 'generate webpack', nil
Foo::CLI::Commands.register "generate webpack", nil
Foo::CLI::Commands.before('callbacks') do |args|
Foo::CLI::Commands.before("callbacks") do |args|
puts "before command callback #{self.class.name} #{args.inspect}"
end
Foo::CLI::Commands.after('callbacks') do |args|
Foo::CLI::Commands.after("callbacks") do |args|
puts "after command callback #{self.class.name} #{args.inspect}"
end
@ -577,10 +577,10 @@ module Callbacks
end
# rubocop:enable Metrics/LineLength
Foo::CLI::Commands.before('callbacks', Callbacks::BeforeClass)
Foo::CLI::Commands.after('callbacks', Callbacks::AfterClass)
Foo::CLI::Commands.before('callbacks', Callbacks::Before.new)
Foo::CLI::Commands.after('callbacks', Callbacks::After.new)
Foo::CLI::Commands.before("callbacks", Callbacks::BeforeClass)
Foo::CLI::Commands.after("callbacks", Callbacks::AfterClass)
Foo::CLI::Commands.before("callbacks", Callbacks::Before.new)
Foo::CLI::Commands.after("callbacks", Callbacks::After.new)
cli = Dry::CLI.new(Foo::CLI::Commands)
cli.call

View File

@ -1,19 +1,19 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
$LOAD_PATH.unshift __dir__ + '/../../../lib'
require 'dry/cli'
require_relative '../../../lib/dry/cli/inline'
$LOAD_PATH.unshift __dir__ + "/../../../lib"
require "dry/cli"
require_relative "../../../lib/dry/cli/inline"
desc 'Baz command line interface'
argument :mandatory_arg, required: true, aliases: %w[m], desc: 'Mandatory argument'
desc "Baz command line interface"
argument :mandatory_arg, required: true, aliases: %w[m], desc: "Mandatory argument"
argument :optional_arg, aliases: %w[o],
desc: 'Optional argument (has to have default value in call method)'
option :option_one, aliases: %w[1], desc: 'Option one'
option :boolean_option, aliases: %w[b], desc: 'Option boolean', type: :boolean
option :option_with_default, aliases: %w[d], desc: 'Option default', default: 'test'
desc: "Optional argument (has to have default value in call method)"
option :option_one, aliases: %w[1], desc: "Option one"
option :boolean_option, aliases: %w[b], desc: "Option boolean", type: :boolean
option :option_with_default, aliases: %w[d], desc: "Option default", default: "test"
run do |mandatory_arg:, optional_arg: 'optional_arg', **options|
run do |mandatory_arg:, optional_arg: "optional_arg", **options|
puts "mandatory_arg: #{mandatory_arg}. " \
"optional_arg: #{optional_arg}. " \
"Options: #{options.inspect}"

View File

@ -9,7 +9,7 @@ module Bar
def call(*); end
end
register 'alpha', Alpha
register "alpha", Alpha
end
end
end

View File

@ -7,10 +7,10 @@ module Commands
module Assets
class Precompile < Dry::CLI::Command
desc 'Precompile assets for deployment'
desc "Precompile assets for deployment"
example [
'FOO_ENV=production # Precompile assets for production environment'
"FOO_ENV=production # Precompile assets for production environment"
]
def call(*); end
@ -18,12 +18,12 @@ module Commands
end
class Console < Dry::CLI::Command
desc 'Starts Foo console'
option :engine, desc: 'Force a console engine', values: %w[irb pry ripl]
desc "Starts Foo console"
option :engine, desc: "Force a console engine", values: %w[irb pry ripl]
example [
' # Uses the bundled engine',
'--engine=pry # Force to use Pry'
" # Uses the bundled engine",
"--engine=pry # Force to use Pry"
]
def call(engine: nil, **)
@ -33,57 +33,57 @@ module Commands
module DB
class Apply < Dry::CLI::Command
desc 'Migrate, dump the SQL schema, and delete the migrations (experimental)'
desc "Migrate, dump the SQL schema, and delete the migrations (experimental)"
def call(*); end
end
class Console < Dry::CLI::Command
desc 'Starts a database console'
desc "Starts a database console"
def call(*); end
end
class Create < Dry::CLI::Command
desc 'Create the database (only for development/test)'
desc "Create the database (only for development/test)"
def call(*); end
end
class Drop < Dry::CLI::Command
desc 'Drop the database (only for development/test)'
desc "Drop the database (only for development/test)"
def call(*); end
end
class Migrate < Dry::CLI::Command
desc 'Migrate the database'
argument :version, desc: 'The target version of the migration (see `foo db version`)'
desc "Migrate the database"
argument :version, desc: "The target version of the migration (see `foo db version`)"
example [
' # Migrate to the last version',
'20170721120747 # Migrate to a specific version'
" # Migrate to the last version",
"20170721120747 # Migrate to a specific version"
]
def call(*); end
end
class Prepare < Dry::CLI::Command
desc 'Drop, create, and migrate the database (only for development/test)'
desc "Drop, create, and migrate the database (only for development/test)"
def call(*); end
end
class Version < Dry::CLI::Command
desc 'Print the current migrated version'
desc "Print the current migrated version"
def call(*); end
end
class Rollback < Dry::CLI::Command
desc 'Rollback the database'
desc "Rollback the database"
argument :steps, desc: 'Number of versions to rollback', default: 1
argument :steps, desc: "Number of versions to rollback", default: 1
def call(steps:, **)
puts steps
@ -93,15 +93,15 @@ module Commands
module Destroy
class Action < Dry::CLI::Command
desc 'Destroy an action from app'
desc "Destroy an action from app"
example [
'web home#index # Basic usage',
'admin users#index # Destroy from `admin` app'
"web home#index # Basic usage",
"admin users#index # Destroy from `admin` app"
]
argument :app, required: true, desc: 'The application name (eg. `web`)'
argument :action, required: true, desc: 'The action name (eg. `home#index`)'
argument :app, required: true, desc: "The application name (eg. `web`)"
argument :action, required: true, desc: "The action name (eg. `home#index`)"
def call(app:, action:, **)
puts "destroy action - app: #{app}, action: #{action}"
@ -109,48 +109,48 @@ module Commands
end
class App < Dry::CLI::Command
desc 'Destroy an app'
desc "Destroy an app"
argument :app, required: true, desc: 'The application name (eg. `web`)'
argument :app, required: true, desc: "The application name (eg. `web`)"
example [
'admin # Destroy `admin` app'
"admin # Destroy `admin` app"
]
def call(*); end
end
class Mailer < Dry::CLI::Command
desc 'Destroy a mailer'
desc "Destroy a mailer"
argument :mailer, required: true, desc: 'The mailer name (eg. `welcome`)'
argument :mailer, required: true, desc: "The mailer name (eg. `welcome`)"
example [
'welcome # Destroy `WelcomeMailer` mailer'
"welcome # Destroy `WelcomeMailer` mailer"
]
def call(*); end
end
class Migration < Dry::CLI::Command
desc 'Destroy a migration'
desc "Destroy a migration"
argument :migration, required: true, desc: 'The migration name (eg. `create_users`)'
argument :migration, required: true, desc: "The migration name (eg. `create_users`)"
example [
'create_users # Destroy `db/migrations/20170721120747_create_users.rb`'
"create_users # Destroy `db/migrations/20170721120747_create_users.rb`"
]
def call(*); end
end
class Model < Dry::CLI::Command
desc 'Destroy a model'
desc "Destroy a model"
argument :model, required: true, desc: 'The model name (eg. `user`)'
argument :model, required: true, desc: "The model name (eg. `user`)"
example [
'user # Destroy `User` entity and `UserRepository` repository'
"user # Destroy `User` entity and `UserRepository` repository"
]
def call(*); end
@ -159,22 +159,22 @@ module Commands
module Generate
class Action < Dry::CLI::Command
desc 'Generate an action for app'
desc "Generate an action for app"
example [
'web home#index # Basic usage',
'admin home#index # Generate for `admin` app',
'web home#index --url=/ # Specify URL',
'web sessions#destroy --method=GET # Specify HTTP method',
'web books#create --skip-view # Skip view and template'
"web home#index # Basic usage",
"admin home#index # Generate for `admin` app",
"web home#index --url=/ # Specify URL",
"web sessions#destroy --method=GET # Specify HTTP method",
"web books#create --skip-view # Skip view and template"
]
argument :app, required: true, desc: 'The application name (eg. `web`)'
argument :action, required: true, desc: 'The action name (eg. `home#index`)'
argument :app, required: true, desc: "The application name (eg. `web`)"
argument :action, required: true, desc: "The action name (eg. `home#index`)"
option :url, desc: 'The action URL'
option :method, desc: 'The action HTTP method'
option :skip_view, type: :boolean, default: false, desc: 'Skip view and template'
option :url, desc: "The action URL"
option :method, desc: "The action HTTP method"
option :skip_view, type: :boolean, default: false, desc: "Skip view and template"
def call(app:, action:, **options)
puts "generate action - app: #{app}, action: #{action}, options: #{options.inspect}"
@ -182,30 +182,30 @@ module Commands
end
class App < Dry::CLI::Command
desc 'Generate an app'
desc "Generate an app"
argument :app, required: true, desc: 'The application name (eg. `web`)'
option :application_base_url, desc: 'The app base URL (eg. `/api/v1`)'
argument :app, required: true, desc: "The application name (eg. `web`)"
option :application_base_url, desc: "The app base URL (eg. `/api/v1`)"
example [
'admin # Generate `admin` app',
'api --application-base-url=/api/v1 # Generate `api` app and mount at `/api/v1`'
"admin # Generate `admin` app",
"api --application-base-url=/api/v1 # Generate `api` app and mount at `/api/v1`"
]
def call(*); end
end
class Mailer < Dry::CLI::Command
desc 'Generate a mailer'
desc "Generate a mailer"
argument :mailer, required: true, desc: 'The mailer name (eg. `welcome`)'
argument :mailer, required: true, desc: "The mailer name (eg. `welcome`)"
option :from, desc: 'The default `from` field of the mail'
option :to, desc: 'The default `to` field of the mail'
option :subject, desc: 'The mail subject'
option :from, desc: "The default `from` field of the mail"
option :to, desc: "The default `to` field of the mail"
option :subject, desc: "The mail subject"
example [
'welcome # Basic usage',
"welcome # Basic usage",
'welcome --from="noreply@example.com" # Generate with default `from` value',
'announcement --to="users@example.com" # Generate with default `to` value',
'forgot_password --subject="Your password reset" # Generate with default `subject`'
@ -215,26 +215,26 @@ module Commands
end
class Migration < Dry::CLI::Command
desc 'Generate a migration'
desc "Generate a migration"
argument :migration, required: true, desc: 'The migration name (eg. `create_users`)'
argument :migration, required: true, desc: "The migration name (eg. `create_users`)"
example [
'create_users # Generate `db/migrations/20170721120747_create_users.rb`'
"create_users # Generate `db/migrations/20170721120747_create_users.rb`"
]
def call(*); end
end
class Model < Dry::CLI::Command
desc 'Generate a model'
desc "Generate a model"
argument :model, required: true, desc: 'Model name (eg. `user`)'
option :skip_migration, type: :boolean, default: false, desc: 'Skip migration'
argument :model, required: true, desc: "Model name (eg. `user`)"
option :skip_migration, type: :boolean, default: false, desc: "Skip migration"
example [
'user # Generate `User` entity, `UserRepository` repository, and the migration',
'user --skip-migration # Generate `User` entity and `UserRepository` repository'
"user # Generate `User` entity, `UserRepository` repository, and the migration",
"user --skip-migration # Generate `User` entity and `UserRepository` repository"
]
def call(model:, **)
@ -243,13 +243,13 @@ module Commands
end
class Secret < Dry::CLI::Command
desc 'Generate session secret'
desc "Generate session secret"
argument :app, desc: 'The application name (eg. `web`)'
argument :app, desc: "The application name (eg. `web`)"
example [
' # Prints secret (eg. `6fad60e21f3f6bfcaf8e56cdb0f835d644b4892c3badc58328126812429bf073`)',
'web # Prints session secret (eg. `WEB_SESSIONS_SECRET=6fad60e21f3f6bfcaf8e56cdb0f835d644b4892c3badc58328126812429bf073`)'
" # Prints secret (eg. `6fad60e21f3f6bfcaf8e56cdb0f835d644b4892c3badc58328126812429bf073`)",
"web # Prints session secret (eg. `WEB_SESSIONS_SECRET=6fad60e21f3f6bfcaf8e56cdb0f835d644b4892c3badc58328126812429bf073`)"
]
def call(app: nil, **)
@ -259,22 +259,22 @@ module Commands
end
class New < Dry::CLI::Command
desc 'Generate a new Foo project'
desc "Generate a new Foo project"
argument :project, required: true
option :database, desc: 'Database (sqlite/postgres/mysql)', default: 'sqlite', aliases: ['-d', '--db']
option :application_name, desc: 'App name', default: 'web'
option :application_base_url, desc: 'App base URL', default: '/'
option :template, desc: 'Template engine (erb/haml/slim)', default: 'erb'
option :test, desc: 'Project testing framework (minitest/rspec)', default: 'minitest'
option :foo_head, desc: 'Use Foo HEAD (true/false)', type: :boolean, default: false
option :database, desc: "Database (sqlite/postgres/mysql)", default: "sqlite", aliases: ["-d", "--db"]
option :application_name, desc: "App name", default: "web"
option :application_base_url, desc: "App base URL", default: "/"
option :template, desc: "Template engine (erb/haml/slim)", default: "erb"
option :test, desc: "Project testing framework (minitest/rspec)", default: "minitest"
option :foo_head, desc: "Use Foo HEAD (true/false)", type: :boolean, default: false
example [
'bookshelf # Basic usage',
'bookshelf --test=rspec # Setup RSpec testing framework',
'bookshelf --database=postgres # Setup Postgres database',
'bookshelf --template=slim # Setup Slim template engine',
'bookshelf --foo-head # Use Foo HEAD'
"bookshelf # Basic usage",
"bookshelf --test=rspec # Setup RSpec testing framework",
"bookshelf --database=postgres # Setup Postgres database",
"bookshelf --template=slim # Setup Slim template engine",
"bookshelf --foo-head # Use Foo HEAD"
]
def call(project:, **)
@ -283,30 +283,30 @@ module Commands
end
class Routes < Dry::CLI::Command
desc 'Print routes'
desc "Print routes"
def call(*); end
end
class Server < Dry::CLI::Command
desc 'Start Foo server (only for development)'
desc "Start Foo server (only for development)"
option :server, desc: 'Force a server engine (eg, webrick, puma, thin, etc..)'
option :host, desc: 'The host address to bind to'
option :port, desc: 'The port to run the server on', aliases: ['-p', 'p', '--p']
option :debug, desc: 'Turn on debug output'
option :warn, desc: 'Turn on warnings'
option :daemonize, desc: 'Daemonize the server'
option :pid, desc: 'Path to write a pid file after daemonize'
option :code_reloading, desc: 'Code reloading', type: :boolean, default: true
option :deps, desc: 'List of extra dependencies', type: :array, default: %w[dep1 dep2]
option :server, desc: "Force a server engine (eg, webrick, puma, thin, etc..)"
option :host, desc: "The host address to bind to"
option :port, desc: "The port to run the server on", aliases: ["-p", "p", "--p"]
option :debug, desc: "Turn on debug output"
option :warn, desc: "Turn on warnings"
option :daemonize, desc: "Daemonize the server"
option :pid, desc: "Path to write a pid file after daemonize"
option :code_reloading, desc: "Code reloading", type: :boolean, default: true
option :deps, desc: "List of extra dependencies", type: :array, default: %w[dep1 dep2]
example [
' # Basic usage (it uses the bundled server engine)',
'--server=webrick # Force `webrick` server engine',
'--host=0.0.0.0 # Bind to a host',
'--port=2306 # Bind to a port',
'--no-code-reloading # Disable code reloading'
" # Basic usage (it uses the bundled server engine)",
"--server=webrick # Force `webrick` server engine",
"--host=0.0.0.0 # Bind to a host",
"--port=2306 # Bind to a port",
"--no-code-reloading # Disable code reloading"
]
def call(**options)
@ -315,18 +315,18 @@ module Commands
end
class Version < Dry::CLI::Command
desc 'Print Foo version'
desc "Print Foo version"
def call(*)
puts 'v1.0.0'
puts "v1.0.0"
end
end
class Exec < Dry::CLI::Command
desc 'Execute a task'
desc "Execute a task"
argument :task, desc: 'Task to execute', type: :string, required: true
argument :dirs, desc: 'Directories', type: :array, required: false
argument :task, desc: "Task to execute", type: :string, required: true
argument :dirs, desc: "Directories", type: :array, required: false
def call(task:, dirs: [], **)
puts "exec - Task: #{task} - Directories: #{dirs.inspect}"
@ -340,7 +340,7 @@ module Commands
end
class Greeting < Dry::CLI::Command
argument :response, default: 'Hello World'
argument :response, default: "Hello World"
option :person
@ -350,45 +350,45 @@ module Commands
end
class VariadicArguments < Dry::CLI::Command
desc 'accept multiple arguments at the end of the command'
desc "accept multiple arguments at the end of the command"
def call(**options)
puts "Unused Arguments: #{options[:args].join(', ')}"
puts "Unused Arguments: #{options[:args].join(", ")}"
end
end
class MandatoryAndVariadicArguments < Dry::CLI::Command
desc 'require one command and accept multiple unused arguments'
desc "require one command and accept multiple unused arguments"
argument :first, desc: 'mandatory first argument', required: true
argument :first, desc: "mandatory first argument", required: true
def call(first:, **options)
puts "first: #{first}"
puts "Unused Arguments: #{options[:args].join(', ')}"
puts "Unused Arguments: #{options[:args].join(", ")}"
end
end
class MandatoryOptionsAndVariadicArguments < Dry::CLI::Command
desc 'require one command, accept options and multiple unused arguments'
desc "require one command, accept options and multiple unused arguments"
argument :first, desc: 'mandatory first argument', required: true
option :url, desc: 'The action URL'
option :method, desc: 'The action HTTP method'
argument :first, desc: "mandatory first argument", required: true
option :url, desc: "The action URL"
option :method, desc: "The action HTTP method"
def call(first:, **options)
puts "first: #{first}"
puts "url: #{options[:url]}"
puts "method: #{options[:method]}"
puts "Unused Arguments: #{options[:args].join(', ')}"
puts "Unused Arguments: #{options[:args].join(", ")}"
end
end
class OptionsWithAliases < Dry::CLI::Command
desc 'Accepts options with aliases'
desc "Accepts options with aliases"
option :url, desc: 'The action URL', aliases: %w[-u u --u]
option :flag, desc: 'The flag', type: :boolean, aliases: %w[f]
option :opt, desc: 'The opt', type: :boolean, aliases: %w[o], default: false
option :url, desc: "The action URL", aliases: %w[-u u --u]
option :flag, desc: "The flag", type: :boolean, aliases: %w[f]
option :opt, desc: "The opt", type: :boolean, aliases: %w[o], default: false
def call(**options)
puts "options with aliases - #{options.inspect}"
@ -404,9 +404,9 @@ module Commands
end
class RootCommand < Dry::CLI::Command
desc 'Root command with arguments and subcommands'
argument :root_command_argument, desc: 'Root command argument', required: true
option :root_command_option, desc: 'Root command option'
desc "Root command with arguments and subcommands"
argument :root_command_argument, desc: "Root command argument", required: true
option :root_command_option, desc: "Root command option"
def call(**params)
puts "I'm a root-command argument:#{params[:root_command_argument]}"
@ -416,9 +416,9 @@ module Commands
module RootCommands
class SubCommand < Dry::CLI::Command
desc 'Root command sub command'
argument :root_command_sub_command_argument, desc: 'Root command sub command argument', required: true
option :root_command_sub_command_option, desc: 'Root command sub command option'
desc "Root command sub command"
argument :root_command_sub_command_argument, desc: "Root command sub command argument", required: true
option :root_command_sub_command_option, desc: "Root command sub command option"
def call(**params)
puts "I'm a root-command sub-command argument:#{params[:root_command_sub_command_argument]}"
@ -427,9 +427,9 @@ module Commands
end
class SubCommand2 < Dry::CLI::Command
desc 'Root command sub command'
argument :root_command_sub_command_argument, desc: 'Root command sub command argument', required: true
option :root_command_sub_command_option, desc: 'Root command sub command option'
desc "Root command sub command"
argument :root_command_sub_command_argument, desc: "Root command sub command argument", required: true
option :root_command_sub_command_option, desc: "Root command sub command option"
def call(**params)
puts "I'm a root-command sub-command argument:#{params[:root_command_sub_command_argument]}"
@ -454,9 +454,9 @@ end
module Webpack
module CLI
class Generate < Dry::CLI::Command
desc 'Generate webpack configuration'
desc "Generate webpack configuration"
option :apps, desc: 'Generate webpack apps', type: :array
option :apps, desc: "Generate webpack apps", type: :array
def call(apps: [], **)
puts "generate webpack. Apps: #{apps}"
@ -464,23 +464,23 @@ module Webpack
end
class Hello < Dry::CLI::Command
desc 'Print a greeting'
desc "Print a greeting"
def call(*)
puts 'hello from webpack'
puts "hello from webpack"
end
end
class SubCommand < Dry::CLI::Command
desc 'Override a subcommand'
desc "Override a subcommand"
def call(**)
puts 'override from webpack'
puts "override from webpack"
end
end
class CallbacksCommand < Dry::CLI::Command
desc 'Command with callbacks'
desc "Command with callbacks"
argument :dir, required: true
option :url

View File

@ -1,79 +1,79 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
$LOAD_PATH.unshift __dir__ + '/../../lib'
require 'dry/cli'
require_relative 'shared_commands'
$LOAD_PATH.unshift __dir__ + "/../../lib"
require "dry/cli"
require_relative "shared_commands"
WithBlock = Dry::CLI.new do |cli|
cli.register 'assets precompile', Commands::Assets::Precompile
cli.register 'console', Commands::Console
cli.register "assets precompile", Commands::Assets::Precompile
cli.register "console", Commands::Console
cli.register 'new', Commands::New
cli.register 'routes', Commands::Routes
cli.register 'server', Commands::Server, aliases: ['s']
cli.register 'version', Commands::Version, aliases: ['v', '-v', '--version']
cli.register 'exec', Commands::Exec
cli.register "new", Commands::New
cli.register "routes", Commands::Routes
cli.register "server", Commands::Server, aliases: ["s"]
cli.register "version", Commands::Version, aliases: ["v", "-v", "--version"]
cli.register "exec", Commands::Exec
cli.register 'hello', Commands::Hello
cli.register 'greeting', Commands::Greeting
cli.register 'sub command', Commands::Sub::Command
cli.register 'with-initializer', Commands::InitializedCommand.new(prop: 'prop_val')
cli.register 'root-command', Commands::RootCommand do |prefix|
prefix.register 'sub-command', Commands::RootCommands::SubCommand
cli.register "hello", Commands::Hello
cli.register "greeting", Commands::Greeting
cli.register "sub command", Commands::Sub::Command
cli.register "with-initializer", Commands::InitializedCommand.new(prop: "prop_val")
cli.register "root-command", Commands::RootCommand do |prefix|
prefix.register "sub-command", Commands::RootCommands::SubCommand
end
cli.register 'options-with-aliases', Commands::OptionsWithAliases
cli.register 'variadic default', Commands::VariadicArguments
cli.register 'variadic with-mandatory', Commands::MandatoryAndVariadicArguments
cli.register 'variadic with-mandatory-and-options', Commands::MandatoryOptionsAndVariadicArguments
cli.register "options-with-aliases", Commands::OptionsWithAliases
cli.register "variadic default", Commands::VariadicArguments
cli.register "variadic with-mandatory", Commands::MandatoryAndVariadicArguments
cli.register "variadic with-mandatory-and-options", Commands::MandatoryOptionsAndVariadicArguments
cli.register 'generate webpack', Webpack::CLI::Generate
cli.register 'hello', Webpack::CLI::Hello
cli.register 'sub command', Webpack::CLI::SubCommand
cli.register 'callbacks', Webpack::CLI::CallbacksCommand
cli.register "generate webpack", Webpack::CLI::Generate
cli.register "hello", Webpack::CLI::Hello
cli.register "sub command", Webpack::CLI::SubCommand
cli.register "callbacks", Webpack::CLI::CallbacksCommand
cli.register 'db' do |prefix|
prefix.register 'apply', Commands::DB::Apply
prefix.register 'console', Commands::DB::Console
prefix.register 'create', Commands::DB::Create
prefix.register 'drop', Commands::DB::Drop
prefix.register 'migrate', Commands::DB::Migrate
prefix.register 'prepare', Commands::DB::Prepare
prefix.register 'version', Commands::DB::Version
prefix.register 'rollback', Commands::DB::Rollback
cli.register "db" do |prefix|
prefix.register "apply", Commands::DB::Apply
prefix.register "console", Commands::DB::Console
prefix.register "create", Commands::DB::Create
prefix.register "drop", Commands::DB::Drop
prefix.register "migrate", Commands::DB::Migrate
prefix.register "prepare", Commands::DB::Prepare
prefix.register "version", Commands::DB::Version
prefix.register "rollback", Commands::DB::Rollback
end
cli.register 'destroy', aliases: ['d'] do |prefix|
prefix.register 'action', Commands::Destroy::Action
prefix.register 'app', Commands::Destroy::App
prefix.register 'mailer', Commands::Destroy::Mailer
prefix.register 'migration', Commands::Destroy::Migration
prefix.register 'model', Commands::Destroy::Model
cli.register "destroy", aliases: ["d"] do |prefix|
prefix.register "action", Commands::Destroy::Action
prefix.register "app", Commands::Destroy::App
prefix.register "mailer", Commands::Destroy::Mailer
prefix.register "migration", Commands::Destroy::Migration
prefix.register "model", Commands::Destroy::Model
end
cli.register 'generate', aliases: ['g'] do |prefix|
prefix.register 'action', Commands::Generate::Action
prefix.register 'app', Commands::Generate::App
prefix.register 'mailer', Commands::Generate::Mailer
prefix.register 'migration', Commands::Generate::Migration
prefix.register 'model', Commands::Generate::Model
prefix.register 'secret', Commands::Generate::Secret
cli.register "generate", aliases: ["g"] do |prefix|
prefix.register "action", Commands::Generate::Action
prefix.register "app", Commands::Generate::App
prefix.register "mailer", Commands::Generate::Mailer
prefix.register "migration", Commands::Generate::Migration
prefix.register "model", Commands::Generate::Model
prefix.register "secret", Commands::Generate::Secret
end
# we need to be sure that command will not override with nil command
cli.register 'generate webpack', nil
cli.register "generate webpack", nil
cli.before('callbacks') do |args|
cli.before("callbacks") do |args|
puts "before command callback #{self.class.name} #{args.inspect}"
end
cli.after('callbacks') do |args|
cli.after("callbacks") do |args|
puts "after command callback #{self.class.name} #{args.inspect}"
end
cli.before 'callbacks', Callbacks::BeforeClass
cli.after 'callbacks', Callbacks::AfterClass
cli.before 'callbacks', Callbacks::Before.new
cli.after 'callbacks', Callbacks::After.new
cli.before "callbacks", Callbacks::BeforeClass
cli.after "callbacks", Callbacks::AfterClass
cli.before "callbacks", Callbacks::Before.new
cli.after "callbacks", Callbacks::After.new
end

View File

@ -1,81 +1,81 @@
# frozen_string_literal: true
$LOAD_PATH.unshift __dir__ + '/../../lib'
require 'dry/cli'
require_relative 'shared_commands'
$LOAD_PATH.unshift __dir__ + "/../../lib"
require "dry/cli"
require_relative "shared_commands"
module Foo
module CLI
module Commands
extend Dry::CLI::Registry
register 'assets precompile', ::Commands::Assets::Precompile
register 'console', ::Commands::Console
register 'db' do |prefix|
prefix.register 'apply', ::Commands::DB::Apply
prefix.register 'console', ::Commands::DB::Console
prefix.register 'create', ::Commands::DB::Create
prefix.register 'drop', ::Commands::DB::Drop
prefix.register 'migrate', ::Commands::DB::Migrate
prefix.register 'prepare', ::Commands::DB::Prepare
prefix.register 'version', ::Commands::DB::Version
prefix.register 'rollback', ::Commands::DB::Rollback
register "assets precompile", ::Commands::Assets::Precompile
register "console", ::Commands::Console
register "db" do |prefix|
prefix.register "apply", ::Commands::DB::Apply
prefix.register "console", ::Commands::DB::Console
prefix.register "create", ::Commands::DB::Create
prefix.register "drop", ::Commands::DB::Drop
prefix.register "migrate", ::Commands::DB::Migrate
prefix.register "prepare", ::Commands::DB::Prepare
prefix.register "version", ::Commands::DB::Version
prefix.register "rollback", ::Commands::DB::Rollback
end
register 'destroy', aliases: ['d'] do |prefix|
prefix.register 'action', ::Commands::Destroy::Action
prefix.register 'app', ::Commands::Destroy::App
prefix.register 'mailer', ::Commands::Destroy::Mailer
prefix.register 'migration', ::Commands::Destroy::Migration
prefix.register 'model', ::Commands::Destroy::Model
register "destroy", aliases: ["d"] do |prefix|
prefix.register "action", ::Commands::Destroy::Action
prefix.register "app", ::Commands::Destroy::App
prefix.register "mailer", ::Commands::Destroy::Mailer
prefix.register "migration", ::Commands::Destroy::Migration
prefix.register "model", ::Commands::Destroy::Model
end
register 'generate', aliases: ['g'] do |prefix|
prefix.register 'action', ::Commands::Generate::Action
prefix.register 'app', ::Commands::Generate::App
prefix.register 'mailer', ::Commands::Generate::Mailer
prefix.register 'migration', ::Commands::Generate::Migration
prefix.register 'model', ::Commands::Generate::Model
prefix.register 'secret', ::Commands::Generate::Secret
register "generate", aliases: ["g"] do |prefix|
prefix.register "action", ::Commands::Generate::Action
prefix.register "app", ::Commands::Generate::App
prefix.register "mailer", ::Commands::Generate::Mailer
prefix.register "migration", ::Commands::Generate::Migration
prefix.register "model", ::Commands::Generate::Model
prefix.register "secret", ::Commands::Generate::Secret
end
register 'new', ::Commands::New
register 'routes', ::Commands::Routes
register 'server', ::Commands::Server, aliases: ['s']
register 'version', ::Commands::Version, aliases: ['v', '-v', '--version']
register 'exec', ::Commands::Exec
register "new", ::Commands::New
register "routes", ::Commands::Routes
register "server", ::Commands::Server, aliases: ["s"]
register "version", ::Commands::Version, aliases: ["v", "-v", "--version"]
register "exec", ::Commands::Exec
register 'hello', ::Commands::Hello
register 'greeting', ::Commands::Greeting
register 'sub command', ::Commands::Sub::Command
register 'with-initializer', ::Commands::InitializedCommand.new(prop: 'prop_val')
register 'root-command', ::Commands::RootCommand
register 'root-command sub-command', ::Commands::RootCommands::SubCommand
register "hello", ::Commands::Hello
register "greeting", ::Commands::Greeting
register "sub command", ::Commands::Sub::Command
register "with-initializer", ::Commands::InitializedCommand.new(prop: "prop_val")
register "root-command", ::Commands::RootCommand
register "root-command sub-command", ::Commands::RootCommands::SubCommand
register 'options-with-aliases', ::Commands::OptionsWithAliases
register 'variadic default', ::Commands::VariadicArguments
register 'variadic with-mandatory', ::Commands::MandatoryAndVariadicArguments # rubocop:disable Metrics/LineLength
register 'variadic with-mandatory-and-options', ::Commands::MandatoryOptionsAndVariadicArguments # rubocop:disable Metrics/LineLength
register "options-with-aliases", ::Commands::OptionsWithAliases
register "variadic default", ::Commands::VariadicArguments
register "variadic with-mandatory", ::Commands::MandatoryAndVariadicArguments
register "variadic with-mandatory-and-options", ::Commands::MandatoryOptionsAndVariadicArguments # rubocop:disable Metrics/LineLength
register 'generate webpack', ::Webpack::CLI::Generate
register 'hello', ::Webpack::CLI::Hello
register 'sub command', ::Webpack::CLI::SubCommand
register 'callbacks', ::Webpack::CLI::CallbacksCommand
register "generate webpack", ::Webpack::CLI::Generate
register "hello", ::Webpack::CLI::Hello
register "sub command", ::Webpack::CLI::SubCommand
register "callbacks", ::Webpack::CLI::CallbacksCommand
register 'generate webpack', nil
register "generate webpack", nil
before('callbacks') do |args|
before("callbacks") do |args|
puts "before command callback #{self.class.name} #{args.inspect}"
end
after('callbacks') do |args|
after("callbacks") do |args|
puts "after command callback #{self.class.name} #{args.inspect}"
end
before('callbacks', ::Callbacks::BeforeClass)
after('callbacks', ::Callbacks::AfterClass)
before('callbacks', ::Callbacks::Before.new)
after('callbacks', ::Callbacks::After.new)
before("callbacks", ::Callbacks::BeforeClass)
after("callbacks", ::Callbacks::AfterClass)
before("callbacks", ::Callbacks::Before.new)
after("callbacks", ::Callbacks::After.new)
end
end
end

View File

@ -1,80 +1,80 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
$LOAD_PATH.unshift __dir__ + '/../../lib'
require 'dry/cli'
require_relative 'shared_commands'
$LOAD_PATH.unshift __dir__ + "/../../lib"
require "dry/cli"
require_relative "shared_commands"
WithZeroArityBlock = Dry.CLI do
register 'assets precompile', Commands::Assets::Precompile
register 'console', Commands::Console
register "assets precompile", Commands::Assets::Precompile
register "console", Commands::Console
register 'new', Commands::New
register 'routes', Commands::Routes
register 'server', Commands::Server, aliases: ['s']
register 'version', Commands::Version, aliases: ['v', '-v', '--version']
register 'exec', Commands::Exec
register "new", Commands::New
register "routes", Commands::Routes
register "server", Commands::Server, aliases: ["s"]
register "version", Commands::Version, aliases: ["v", "-v", "--version"]
register "exec", Commands::Exec
register 'hello', Commands::Hello
register 'greeting', Commands::Greeting
register 'sub command', Commands::Sub::Command
register 'with-initializer', Commands::InitializedCommand.new(prop: 'prop_val')
register 'root-command', Commands::RootCommand
register 'root-command' do
register 'sub-command', Commands::RootCommands::SubCommand
register "hello", Commands::Hello
register "greeting", Commands::Greeting
register "sub command", Commands::Sub::Command
register "with-initializer", Commands::InitializedCommand.new(prop: "prop_val")
register "root-command", Commands::RootCommand
register "root-command" do
register "sub-command", Commands::RootCommands::SubCommand
end
register 'options-with-aliases', Commands::OptionsWithAliases
register 'variadic default', Commands::VariadicArguments
register 'variadic with-mandatory', Commands::MandatoryAndVariadicArguments
register 'variadic with-mandatory-and-options', Commands::MandatoryOptionsAndVariadicArguments
register "options-with-aliases", Commands::OptionsWithAliases
register "variadic default", Commands::VariadicArguments
register "variadic with-mandatory", Commands::MandatoryAndVariadicArguments
register "variadic with-mandatory-and-options", Commands::MandatoryOptionsAndVariadicArguments
register 'generate webpack', Webpack::CLI::Generate
register 'hello', Webpack::CLI::Hello
register 'sub command', Webpack::CLI::SubCommand
register 'callbacks', Webpack::CLI::CallbacksCommand
register "generate webpack", Webpack::CLI::Generate
register "hello", Webpack::CLI::Hello
register "sub command", Webpack::CLI::SubCommand
register "callbacks", Webpack::CLI::CallbacksCommand
register 'db' do
register 'apply', Commands::DB::Apply
register 'console', Commands::DB::Console
register 'create', Commands::DB::Create
register 'drop', Commands::DB::Drop
register 'migrate', Commands::DB::Migrate
register 'prepare', Commands::DB::Prepare
register 'version', Commands::DB::Version
register 'rollback', Commands::DB::Rollback
register "db" do
register "apply", Commands::DB::Apply
register "console", Commands::DB::Console
register "create", Commands::DB::Create
register "drop", Commands::DB::Drop
register "migrate", Commands::DB::Migrate
register "prepare", Commands::DB::Prepare
register "version", Commands::DB::Version
register "rollback", Commands::DB::Rollback
end
register 'destroy', aliases: ['d'] do
register 'action', Commands::Destroy::Action
register 'app', Commands::Destroy::App
register 'mailer', Commands::Destroy::Mailer
register 'migration', Commands::Destroy::Migration
register 'model', Commands::Destroy::Model
register "destroy", aliases: ["d"] do
register "action", Commands::Destroy::Action
register "app", Commands::Destroy::App
register "mailer", Commands::Destroy::Mailer
register "migration", Commands::Destroy::Migration
register "model", Commands::Destroy::Model
end
register 'generate', aliases: ['g'] do
register 'action', Commands::Generate::Action
register 'app', Commands::Generate::App
register 'mailer', Commands::Generate::Mailer
register 'migration', Commands::Generate::Migration
register 'model', Commands::Generate::Model
register 'secret', Commands::Generate::Secret
register "generate", aliases: ["g"] do
register "action", Commands::Generate::Action
register "app", Commands::Generate::App
register "mailer", Commands::Generate::Mailer
register "migration", Commands::Generate::Migration
register "model", Commands::Generate::Model
register "secret", Commands::Generate::Secret
end
# we need to be sure that command will not override with nil command
register 'generate webpack', nil
register "generate webpack", nil
before('callbacks') do |args|
before("callbacks") do |args|
puts "before command callback #{self.class.name} #{args.inspect}"
end
after('callbacks') do |args|
after("callbacks") do |args|
puts "after command callback #{self.class.name} #{args.inspect}"
end
before 'callbacks', Callbacks::BeforeClass
after 'callbacks', Callbacks::AfterClass
before 'callbacks', Callbacks::Before.new
after 'callbacks', Callbacks::After.new
before "callbacks", Callbacks::BeforeClass
after "callbacks", Callbacks::AfterClass
before "callbacks", Callbacks::Before.new
after "callbacks", Callbacks::After.new
end

View File

@ -4,7 +4,7 @@ module RSpec
module Support
module Helpers
def capture_output
require 'stringio'
require "stringio"
output = StringIO.new
original_stdout = $stdout
$stdout = output
@ -17,7 +17,7 @@ module RSpec
end
def capture_error
require 'stringio'
require "stringio"
error = StringIO.new
original_stderr = $stderr
$stderr = error

View File

@ -6,12 +6,12 @@ module RSpec
def self.included(base)
base.class_eval do
before do
@original_path = ENV['PATH']
ENV['PATH'] = __dir__ + '/fixtures:' + ENV['PATH']
@original_path = ENV["PATH"]
ENV["PATH"] = __dir__ + "/fixtures:" + ENV["PATH"]
end
after do
ENV['PATH'] = @original_path
ENV["PATH"] = @original_path
end
end
end

View File

@ -17,7 +17,7 @@ RSpec.configure do |config|
config.warnings = true
config.default_formatter = 'doc' if config.files_to_run.one?
config.default_formatter = "doc" if config.files_to_run.one?
config.profile_examples = 10
config.order = :random

View File

@ -1,49 +1,49 @@
# frozen_string_literal: true
# rubocop:disable Metrics/LineLength
RSpec.shared_examples 'Commands' do |cli|
RSpec.shared_examples "Commands" do |cli|
let(:cli) { cli }
let(:cmd) { File.basename($PROGRAM_NAME, File.extname($PROGRAM_NAME)) }
it 'calls basic command' do
output = capture_output { cli.call(arguments: ['version']) }
it "calls basic command" do
output = capture_output { cli.call(arguments: ["version"]) }
expect(output).to eq("v1.0.0\n")
end
it 'calls basic command with alias' do
output = capture_output { cli.call(arguments: ['v']) }
it "calls basic command with alias" do
output = capture_output { cli.call(arguments: ["v"]) }
expect(output).to eq("v1.0.0\n")
output = capture_output { cli.call(arguments: ['-v']) }
output = capture_output { cli.call(arguments: ["-v"]) }
expect(output).to eq("v1.0.0\n")
output = capture_output { cli.call(arguments: ['--version']) }
output = capture_output { cli.call(arguments: ["--version"]) }
expect(output).to eq("v1.0.0\n")
end
it 'calls subcommand via intermediate alias' do
it "calls subcommand via intermediate alias" do
output = capture_output { cli.call(arguments: %w[g secret web]) }
expect(output).to eq("generate secret - app: web\n")
end
context 'works with params' do
it 'without params' do
output = capture_output { cli.call(arguments: ['server']) }
context "works with params" do
it "without params" do
output = capture_output { cli.call(arguments: ["server"]) }
expect(output).to eq("server - {:code_reloading=>true, :deps=>[\"dep1\", \"dep2\"]}\n")
end
it 'a param using space' do
it "a param using space" do
output = capture_output { cli.call(arguments: %w[server --server thin]) }
expect(output).to eq("server - {:code_reloading=>true, :deps=>[\"dep1\", \"dep2\"], :server=>\"thin\"}\n")
end
it 'a param using equal sign' do
it "a param using equal sign" do
output = capture_output { cli.call(arguments: %w[server --host=localhost]) }
expect(output).to eq("server - {:code_reloading=>true, :deps=>[\"dep1\", \"dep2\"], :host=>\"localhost\"}\n")
end
it 'a param using alias' do
it "a param using alias" do
output = capture_output { cli.call(arguments: %w[options-with-aliases -u test]) }
expect(output).to eq("options with aliases - {:opt=>false, :url=>\"test\"}\n")
@ -60,48 +60,48 @@ RSpec.shared_examples 'Commands' do |cli|
expect(output).to eq("options with aliases - {:opt=>true, :flag=>true}\n")
end
it 'a param with unknown param' do
it "a param with unknown param" do
error = capture_error { cli.call(arguments: %w[server --unknown 1234]) }
expect(error).to eq("ERROR: \"rspec server\" was called with arguments \"--unknown 1234\"\n")
end
it 'with boolean param' do
output = capture_output { cli.call(arguments: ['server']) }
it "with boolean param" do
output = capture_output { cli.call(arguments: ["server"]) }
expect(output).to eq("server - {:code_reloading=>true, :deps=>[\"dep1\", \"dep2\"]}\n")
output = capture_output { cli.call(arguments: %w[server --no-code-reloading]) }
expect(output).to eq("server - {:code_reloading=>false, :deps=>[\"dep1\", \"dep2\"]}\n")
end
context 'with array param' do
it 'allows to omit optional array argument' do
context "with array param" do
it "allows to omit optional array argument" do
output = capture_output { cli.call(arguments: %w[exec test]) }
expect(output).to eq("exec - Task: test - Directories: []\n")
end
it 'capture all the remaining arguments' do
it "capture all the remaining arguments" do
output = capture_output { cli.call(arguments: %w[exec test api admin]) }
expect(output).to eq("exec - Task: test - Directories: [\"api\", \"admin\"]\n")
end
end
context 'with supported values' do
context 'and with supported value passed' do
it 'call the command with the option' do
context "with supported values" do
context "and with supported value passed" do
it "call the command with the option" do
output = capture_output { cli.call(arguments: %w[console --engine=pry]) }
expect(output).to eq("console - engine: pry\n")
end
end
context 'and with an unknown value passed' do
it 'prints error' do
context "and with an unknown value passed" do
it "prints error" do
error = capture_error { cli.call(arguments: %w[console --engine=unknown]) }
expect(error).to eq("ERROR: \"rspec console\" was called with arguments \"--engine=unknown\"\n") # rubocop:disable Metrics/LineLength
end
end
end
it 'with help param' do
it "with help param" do
output = capture_output { cli.call(arguments: %w[server --help]) }
expected = <<~DESC
@ -137,18 +137,18 @@ RSpec.shared_examples 'Commands' do |cli|
expect(output).to eq(expected)
end
context 'with required params' do
it 'can be used' do
context "with required params" do
it "can be used" do
output = capture_output { cli.call(arguments: %w[new bookshelf]) }
expect(output).to eq("new - project: bookshelf\n")
end
it 'with unknown param' do
it "with unknown param" do
error = capture_error { cli.call(arguments: %w[new bookshelf --unknown 1234]) }
expect(error).to eq("ERROR: \"rspec new\" was called with arguments \"bookshelf --unknown 1234\"\n") # rubocop:disable Metrics/LineLength
end
it 'no required' do
it "no required" do
output = capture_output { cli.call(arguments: %w[generate secret web]) }
expect(output).to eq("generate secret - app: web\n")
@ -157,7 +157,7 @@ RSpec.shared_examples 'Commands' do |cli|
end
it "an error is displayed if there aren't required params" do
error = capture_error { cli.call(arguments: ['new']) }
error = capture_error { cli.call(arguments: ["new"]) }
expected_error = <<~DESC
ERROR: "#{cmd} new" was called with no arguments
Usage: "#{cmd} new PROJECT"
@ -165,7 +165,7 @@ RSpec.shared_examples 'Commands' do |cli|
expect(error).to eq(expected_error)
end
it 'with default value and using options' do
it "with default value and using options" do
output = capture_output { cli.call(arguments: %w[greeting --person=Alfonso]) }
expect(output).to eq("response: Hello World, person: Alfonso\n")
@ -174,24 +174,24 @@ RSpec.shared_examples 'Commands' do |cli|
end
end
context 'with extra params' do
it 'is accessible via options[:args]' do
context "with extra params" do
it "is accessible via options[:args]" do
output = capture_output { cli.call(arguments: %w[variadic default bar baz]) }
expect(output).to eq("Unused Arguments: bar, baz\n")
end
context 'when there is a required argument' do
it 'parses both separately' do
output = capture_output { cli.call(arguments: ['variadic', 'with-mandatory', cmd, 'bar', 'baz']) }
context "when there is a required argument" do
it "parses both separately" do
output = capture_output { cli.call(arguments: ["variadic", "with-mandatory", cmd, "bar", "baz"]) }
expect(output).to eq("first: #{cmd}\nUnused Arguments: bar, baz\n")
end
context 'and there are options' do
it 'parses both separately' do
output = capture_output { cli.call(arguments: ['variadic', 'with-mandatory-and-options', cmd, 'bar', 'baz']) }
context "and there are options" do
it "parses both separately" do
output = capture_output { cli.call(arguments: ["variadic", "with-mandatory-and-options", cmd, "bar", "baz"]) }
expect(output).to eq("first: #{cmd}\nurl: \nmethod: \nUnused Arguments: bar, baz\n")
output = capture_output { cli.call(arguments: ['variadic', 'with-mandatory-and-options', '--url=root', '--method=index', cmd, 'bar', 'baz']) }
output = capture_output { cli.call(arguments: ["variadic", "with-mandatory-and-options", "--url=root", "--method=index", cmd, "bar", "baz"]) }
expect(output).to eq("first: #{cmd}\nurl: root\nmethod: index\nUnused Arguments: bar, baz\n")
output = capture_output { cli.call(arguments: %w[variadic with-mandatory-and-options uno -- due tre --blah]) }
@ -202,8 +202,8 @@ RSpec.shared_examples 'Commands' do |cli|
end
end
context 'works with command with arguments and subcommands' do
it 'shows help' do
context "works with command with arguments and subcommands" do
it "shows help" do
output = capture_output { cli.call(arguments: %w[root-command -h]) }
expected = <<~DESC
Command:
@ -232,8 +232,8 @@ RSpec.shared_examples 'Commands' do |cli|
expect(output).to eq(expected)
end
context 'works with params' do
it 'without params' do
context "works with params" do
it "without params" do
error = capture_error { cli.call(arguments: %w[root-command]) }
expected = <<~DESC
ERROR: "rspec root-command" was called with no arguments
@ -243,9 +243,9 @@ RSpec.shared_examples 'Commands' do |cli|
expect(error).to eq(expected)
end
it 'with params' do
it "with params" do
output = capture_output {
cli.call(arguments: ['root-command', '"hello world"'])
cli.call(arguments: ["root-command", '"hello world"'])
}
expected = <<~DESC
I'm a root-command argument:"hello world"
@ -255,12 +255,12 @@ RSpec.shared_examples 'Commands' do |cli|
expect(output).to eq(expected)
end
it 'with option using space' do
it "with option using space" do
output = capture_output {
cli.call(arguments: [
'root-command',
"root-command",
'"hello world"',
'--root-command-option',
"--root-command-option",
'"bye world"'
])
}
@ -272,10 +272,10 @@ RSpec.shared_examples 'Commands' do |cli|
expect(output).to eq(expected)
end
it 'with option using equal sign' do
it "with option using equal sign" do
output = capture_output {
cli.call(arguments: [
'root-command',
"root-command",
'"hello world"',
'--root-command-option="bye world"'
])
@ -290,8 +290,8 @@ RSpec.shared_examples 'Commands' do |cli|
end
end
context 'works with instances of commands' do
it 'executes instance' do
context "works with instances of commands" do
it "executes instance" do
output = capture_output { cli.call(arguments: %w[with-initializer]) }
expect(output).to eq("The value of prop is prop_val\n")
end

View File

@ -1,11 +1,11 @@
# frozen_string_literal: true
RSpec.shared_examples 'Rendering' do |cli|
RSpec.shared_examples "Rendering" do |cli|
let(:cli) { cli }
let(:cmd) { File.basename($PROGRAM_NAME, File.extname($PROGRAM_NAME)) }
it 'prints required params' do
it "prints required params" do
error = capture_error { cli.call }
expected = <<~DESC
Commands:
@ -32,8 +32,8 @@ RSpec.shared_examples 'Rendering' do |cli|
expect(error).to eq(expected)
end
it 'prints required params with labels' do
error = capture_error { cli.call(arguments: ['destroy']) }
it "prints required params with labels" do
error = capture_error { cli.call(arguments: ["destroy"]) }
expected = <<~DESC
Commands:
@ -47,7 +47,7 @@ RSpec.shared_examples 'Rendering' do |cli|
expect(error).to eq(expected)
end
it 'prints available commands for unknown subcommand' do
it "prints available commands for unknown subcommand" do
error = capture_error { cli.call(arguments: %w[generate unknown]) }
expected = <<~DESC
@ -64,8 +64,8 @@ RSpec.shared_examples 'Rendering' do |cli|
expect(error).to eq(expected)
end
it 'prints available commands for unknown command' do
error = capture_error { cli.call(arguments: ['unknown']) }
it "prints available commands for unknown command" do
error = capture_error { cli.call(arguments: ["unknown"]) }
expected = <<~DESC
Commands:
@ -92,7 +92,7 @@ RSpec.shared_examples 'Rendering' do |cli|
expect(error).to eq(expected)
end
it 'prints first level' do
it "prints first level" do
error = capture_error { cli.call }
expected = <<~DESC
@ -121,7 +121,7 @@ RSpec.shared_examples 'Rendering' do |cli|
end
it "prints subcommand's commands" do
error = capture_error { cli.call(arguments: ['generate']) }
error = capture_error { cli.call(arguments: ["generate"]) }
expected = <<~DESC
Commands:
@ -153,7 +153,7 @@ RSpec.shared_examples 'Rendering' do |cli|
expect(error).to eq(expected)
end
it 'prints list options when calling help' do
it "prints list options when calling help" do
output = capture_output { cli.call(arguments: %w[options-with-aliases --help]) }
expected = <<~DESC

View File

@ -1,11 +1,11 @@
# frozen_string_literal: true
RSpec.shared_examples 'Subcommands' do |cli|
RSpec.shared_examples "Subcommands" do |cli|
let(:cli) { cli }
let(:cmd) { File.basename($PROGRAM_NAME, File.extname($PROGRAM_NAME)) }
it 'calls subcommand' do
it "calls subcommand" do
error = capture_error { cli.call(arguments: %w[generate model]) }
expected = <<~DESC
ERROR: "#{cmd} generate model" was called with no arguments
@ -15,8 +15,8 @@ RSpec.shared_examples 'Subcommands' do |cli|
expect(error).to eq(expected)
end
context 'works with params' do
it 'without params' do
context "works with params" do
it "without params" do
error = capture_error { cli.call(arguments: %w[generate model]) }
expected = <<~DESC
ERROR: "#{cmd} generate model" was called with no arguments
@ -26,28 +26,28 @@ RSpec.shared_examples 'Subcommands' do |cli|
expect(error).to eq(expected)
end
it 'a param using space' do
it "a param using space" do
output = capture_output { cli.call(arguments: %w[server --port 2306]) }
expect(output).to eq(
"server - {:code_reloading=>true, :deps=>[\"dep1\", \"dep2\"], :port=>\"2306\"}\n"
)
end
it 'a param using equal sign' do
it "a param using equal sign" do
output = capture_output { cli.call(arguments: %w[server --port=2306]) }
expect(output).to eq(
"server - {:code_reloading=>true, :deps=>[\"dep1\", \"dep2\"], :port=>\"2306\"}\n"
)
end
it 'a param using alias' do
it "a param using alias" do
output = capture_output { cli.call(arguments: %w[server -p 2306]) }
expect(output).to eq(
"server - {:code_reloading=>true, :deps=>[\"dep1\", \"dep2\"], :port=>\"2306\"}\n"
)
end
it 'with help param' do
it "with help param" do
output = capture_output { cli.call(arguments: %w[generate model --help]) }
expected = <<~DESC
@ -75,28 +75,28 @@ RSpec.shared_examples 'Subcommands' do |cli|
expect(output).to eq(expected)
end
context 'with required params' do
it 'only one param' do
context "with required params" do
it "only one param" do
output = capture_output { cli.call(arguments: %w[generate model user]) }
expect(output).to eq("generate model - model: user\n")
end
it 'more than one param' do
it "more than one param" do
output = capture_output { cli.call(arguments: %w[destroy action web users#index]) }
expect(output).to eq("destroy action - app: web, action: users#index\n")
end
it 'more than one param and with optional params' do
it "more than one param and with optional params" do
output = capture_output { cli.call(arguments: %w[generate action web users#index --url=/signin]) } # rubocop:disable Metrics/LineLength
expect(output).to eq("generate action - app: web, action: users#index, options: {:skip_view=>false, :url=>\"/signin\"}\n") # rubocop:disable Metrics/LineLength
end
it 'more than one param and with boolean params' do
it "more than one param and with boolean params" do
output = capture_output { cli.call(arguments: %w[generate action web users#index --skip-view --url=/signin]) } # rubocop:disable Metrics/LineLength
expect(output).to eq("generate action - app: web, action: users#index, options: {:skip_view=>true, :url=>\"/signin\"}\n") # rubocop:disable Metrics/LineLength
end
it 'more than required params' do
it "more than required params" do
output = capture_output { cli.call(arguments: %w[destroy action web users#index unexpected_param]) } # rubocop:disable Metrics/LineLength
expect(output).to eq("destroy action - app: web, action: users#index\n")
end
@ -111,7 +111,7 @@ RSpec.shared_examples 'Subcommands' do |cli|
expect(error).to eq(expected)
end
it 'an error is displayed if there are some required params' do
it "an error is displayed if there are some required params" do
error = capture_error { cli.call(arguments: %w[destroy action web]) }
expected = <<~DESC
ERROR: "#{cmd} destroy action" was called with arguments [\"web\"]
@ -121,14 +121,14 @@ RSpec.shared_examples 'Subcommands' do |cli|
expect(error).to eq(expected)
end
context 'and a default value' do
it 'returns the default value if nothing is passed' do
context "and a default value" do
it "returns the default value if nothing is passed" do
output = capture_output { cli.call(arguments: %w[db rollback]) }
expect(output).to eq("1\n")
end
it 'returns the passed value' do
it "returns the passed value" do
output = capture_output { cli.call(arguments: %w[db rollback 3]) }
expect(output).to eq("3\n")
@ -137,8 +137,8 @@ RSpec.shared_examples 'Subcommands' do |cli|
end
end
context 'works with root command' do
it 'shows help' do
context "works with root command" do
it "shows help" do
output = capture_output { cli.call(arguments: %w[root-command sub-command -h]) }
expected = <<~DESC
Command:
@ -164,8 +164,8 @@ RSpec.shared_examples 'Subcommands' do |cli|
expect(output).to eq(expected)
end
context 'works with params' do
it 'without params' do
context "works with params" do
it "without params" do
error = capture_error { cli.call(arguments: %w[root-command sub-command]) }
expected = <<~DESC
ERROR: "rspec root-command sub-command" was called with no arguments
@ -175,9 +175,9 @@ RSpec.shared_examples 'Subcommands' do |cli|
expect(error).to eq(expected)
end
it 'with params' do
it "with params" do
output = capture_output {
cli.call(arguments: ['root-command', 'sub-command', '"hello world"'])
cli.call(arguments: ["root-command", "sub-command", '"hello world"'])
}
expected = <<~DESC
I'm a root-command sub-command argument:"hello world"
@ -187,13 +187,13 @@ RSpec.shared_examples 'Subcommands' do |cli|
expect(output).to eq(expected)
end
it 'with option using space' do
it "with option using space" do
output = capture_output {
cli.call(arguments: [
'root-command',
'sub-command',
"root-command",
"sub-command",
'"hello world"',
'--root-command-sub-command-option',
"--root-command-sub-command-option",
'"bye world"'
])
}
@ -205,11 +205,11 @@ RSpec.shared_examples 'Subcommands' do |cli|
expect(output).to eq(expected)
end
it 'with option using equal sign' do
it "with option using equal sign" do
output = capture_output {
cli.call(arguments: [
'root-command',
'sub-command',
"root-command",
"sub-command",
'"hello world"',
'--root-command-sub-command-option="bye world"'
])

View File

@ -1,32 +1,32 @@
# frozen_string_literal: true
RSpec.shared_examples 'Third-party gems' do |cli|
RSpec.shared_examples "Third-party gems" do |cli|
let(:cli) { cli }
let(:cmd) { File.basename($PROGRAM_NAME, File.extname($PROGRAM_NAME)) }
it 'allows to add a subcommand' do
it "allows to add a subcommand" do
output = capture_output { cli.call(arguments: %w[generate webpack]) }
expect(output).to eq("generate webpack. Apps: []\n")
end
it 'allows to invoke a subcommand via an inherited subcomand aliases' do
it "allows to invoke a subcommand via an inherited subcomand aliases" do
output = capture_output { cli.call(arguments: %w[g webpack]) }
expect(output).to eq("generate webpack. Apps: []\n")
end
it 'allows to override basic commands' do
output = capture_output { cli.call(arguments: ['hello']) }
it "allows to override basic commands" do
output = capture_output { cli.call(arguments: ["hello"]) }
expect(output).to eq("hello from webpack\n")
end
it 'allows to override a subcommand' do
it "allows to override a subcommand" do
output = capture_output { cli.call(arguments: %w[sub command]) }
expect(output).to eq("override from webpack\n")
end
context 'callbacks' do
it 'allows to add callbacks as a block' do
context "callbacks" do
it "allows to add callbacks as a block" do
expected = <<~OUTPUT
before command callback Webpack::CLI::CallbacksCommand {:url=>"https://hanamirb.test", :dir=>"."}
before callback (class), 2 arg(s): {:url=>"https://hanamirb.test", :dir=>"."}
@ -42,7 +42,7 @@ RSpec.shared_examples 'Third-party gems' do |cli|
end
end
it 'allows to call array option' do
it "allows to call array option" do
output = capture_output { cli.call(arguments: %w[generate webpack --apps=test,api,admin]) }
expect(output).to eq("generate webpack. Apps: [\"test\", \"api\", \"admin\"]\n")
end

View File

@ -1,35 +1,35 @@
# frozen_string_literal: true
RSpec.describe 'CLI' do
context 'when registry' do
context 'passing module' do
include_examples 'Commands', WithRegistry
include_examples 'Rendering', WithRegistry
include_examples 'Subcommands', WithRegistry
include_examples 'Third-party gems', WithRegistry
RSpec.describe "CLI" do
context "when registry" do
context "passing module" do
include_examples "Commands", WithRegistry
include_examples "Rendering", WithRegistry
include_examples "Subcommands", WithRegistry
include_examples "Third-party gems", WithRegistry
end
context 'passing block' do
include_examples 'Commands', WithBlock
include_examples 'Rendering', WithBlock
include_examples 'Subcommands', WithBlock
include_examples 'Third-party gems', WithBlock
context "passing block" do
include_examples "Commands", WithBlock
include_examples "Rendering", WithBlock
include_examples "Subcommands", WithBlock
include_examples "Third-party gems", WithBlock
end
context 'passing block with no arguments' do
include_examples 'Commands', WithZeroArityBlock
include_examples 'Rendering', WithZeroArityBlock
include_examples 'Subcommands', WithZeroArityBlock
include_examples 'Third-party gems', WithZeroArityBlock
context "passing block with no arguments" do
include_examples "Commands", WithZeroArityBlock
include_examples "Rendering", WithZeroArityBlock
include_examples "Subcommands", WithZeroArityBlock
include_examples "Third-party gems", WithZeroArityBlock
end
end
context 'with command' do
context "with command" do
let(:cli) { Dry.CLI(Baz::CLI) }
let(:cmd) { File.basename($PROGRAM_NAME, File.extname($PROGRAM_NAME)) }
it 'shows help' do
output = capture_output { cli.call(arguments: ['-h']) }
it "shows help" do
output = capture_output { cli.call(arguments: ["-h"]) }
expected_output = <<~OUTPUT
Command:
#{cmd}
@ -53,90 +53,66 @@ RSpec.describe 'CLI' do
expect(output).to eq(expected_output)
end
it 'with required_argument' do
output = capture_output { cli.call(arguments: ['first_arg']) }
it "with required_argument" do
output = capture_output { cli.call(arguments: ["first_arg"]) }
expect(output).to eq(
'mandatory_arg: first_arg. optional_arg: optional_arg. ' \
"mandatory_arg: first_arg. optional_arg: optional_arg. " \
"Options: {:option_with_default=>\"test\"}\n"
)
end
it 'with optional_arg' do
it "with optional_arg" do
output = capture_output { cli.call(arguments: %w[first_arg opt_arg]) }
expect(output).to eq(
'mandatory_arg: first_arg. optional_arg: opt_arg. ' \
"mandatory_arg: first_arg. optional_arg: opt_arg. " \
"Options: {:option_with_default=>\"test\", :args=>[\"opt_arg\"]}\n"
)
end
it 'with option_one', if: RUBY_VERSION < '2.4' do
output = capture_output { cli.call(arguments: %w[first_arg --option-one=test2]) }
expect(output).to eq(
'mandatory_arg: first_arg. optional_arg: optional_arg. ' \
"Options: {:option_with_default=>\"test\", :option_one=>\"test2\"}\n"
)
end
it 'with underscored option_one', if: RUBY_VERSION >= '2.4' do
it "with underscored option_one" do
output = capture_output { cli.call(arguments: %w[first_arg --option_one=test2]) }
expect(output).to eq(
'mandatory_arg: first_arg. optional_arg: optional_arg. ' \
"mandatory_arg: first_arg. optional_arg: optional_arg. " \
"Options: {:option_with_default=>\"test\", :option_one=>\"test2\"}\n"
)
end
it 'with option_one alias' do
it "with option_one alias" do
output = capture_output { cli.call(arguments: %w[first_arg -1 test2]) }
expect(output).to eq(
'mandatory_arg: first_arg. optional_arg: optional_arg. ' \
"mandatory_arg: first_arg. optional_arg: optional_arg. " \
"Options: {:option_with_default=>\"test\", :option_one=>\"test2\"}\n"
)
end
it 'with boolean_option', if: RUBY_VERSION < '2.4' do
output = capture_output { cli.call(arguments: %w[first_arg --boolean-option]) }
expect(output).to eq(
'mandatory_arg: first_arg. optional_arg: optional_arg. ' \
"Options: {:option_with_default=>\"test\", :boolean_option=>true}\n"
)
end
it 'with underscored boolean_option', if: RUBY_VERSION >= '2.4' do
it "with underscored boolean_option" do
output = capture_output { cli.call(arguments: %w[first_arg --boolean_option]) }
expect(output).to eq(
'mandatory_arg: first_arg. optional_arg: optional_arg. ' \
"mandatory_arg: first_arg. optional_arg: optional_arg. " \
"Options: {:option_with_default=>\"test\", :boolean_option=>true}\n"
)
end
it 'with boolean_option alias' do
it "with boolean_option alias" do
output = capture_output { cli.call(arguments: %w[first_arg -b]) }
expect(output).to eq(
'mandatory_arg: first_arg. optional_arg: optional_arg. ' \
"mandatory_arg: first_arg. optional_arg: optional_arg. " \
"Options: {:option_with_default=>\"test\", :boolean_option=>true}\n"
)
end
it 'with option_with_default alias', if: RUBY_VERSION < '2.4' do
output = capture_output { cli.call(arguments: %w[first_arg --option-with-default=test3]) }
expect(output).to eq(
'mandatory_arg: first_arg. optional_arg: optional_arg. ' \
"Options: {:option_with_default=>\"test3\"}\n"
)
end
it 'with underscoreed option_with_default alias', if: RUBY_VERSION >= '2.4' do
it "with underscoreed option_with_default alias" do
output = capture_output { cli.call(arguments: %w[first_arg --option_with_default=test3]) }
expect(output).to eq(
'mandatory_arg: first_arg. optional_arg: optional_arg. ' \
"mandatory_arg: first_arg. optional_arg: optional_arg. " \
"Options: {:option_with_default=>\"test3\"}\n"
)
end
it 'with combination of aliases' do
it "with combination of aliases" do
output = capture_output { cli.call(arguments: %w[first_arg -bd test3]) }
expect(output).to eq(
'mandatory_arg: first_arg. optional_arg: optional_arg. ' \
"mandatory_arg: first_arg. optional_arg: optional_arg. " \
"Options: {:option_with_default=>\"test3\", :boolean_option=>true}\n"
)
end

View File

@ -1,26 +1,26 @@
# frozen_string_literal: true
RSpec.describe Dry::CLI::Inflector do
describe '.dasherize' do
it 'returns nil if input is nil' do
describe ".dasherize" do
it "returns nil if input is nil" do
expect(described_class.dasherize(nil)).to be(nil)
end
it 'downcases input' do
expect(described_class.dasherize('Dry')).to eq('dry')
expect(described_class.dasherize('CLI')).to eq('cli')
it "downcases input" do
expect(described_class.dasherize("Dry")).to eq("dry")
expect(described_class.dasherize("CLI")).to eq("cli")
end
it 'replaces spaces with dashes' do
expect(described_class.dasherize('Command Line Interface')).to eq('command-line-interface')
it "replaces spaces with dashes" do
expect(described_class.dasherize("Command Line Interface")).to eq("command-line-interface")
end
it 'replaces underscores with dashes' do
expect(described_class.dasherize('fast_code_reloading')).to eq('fast-code-reloading')
it "replaces underscores with dashes" do
expect(described_class.dasherize("fast_code_reloading")).to eq("fast-code-reloading")
end
it 'accepts any object that respond to #to_s' do
expect(described_class.dasherize(:dry)).to eq('dry')
it "accepts any object that respond to #to_s" do
expect(described_class.dasherize(:dry)).to eq("dry")
end
end
end

View File

@ -1,11 +1,11 @@
# frozen_string_literal: true
RSpec.describe Dry::CLI::Registry do
describe '.before' do
describe ".before" do
context "when command can't be found" do
it 'raises error' do
it "raises error" do
expect do
Bar::CLI::Commands.before('pixel') { puts 'hello' }
Bar::CLI::Commands.before("pixel") { puts "hello" }
end.to raise_error(
Dry::CLI::UnknownCommandError,
"unknown command: `pixel'"
@ -13,12 +13,12 @@ RSpec.describe Dry::CLI::Registry do
end
end
context 'when object is given' do
context "when object is given" do
it "raises error when it doesn't respond to #call" do
callback = Object.new
expect do
Bar::CLI::Commands.before('alpha', callback)
Bar::CLI::Commands.before("alpha", callback)
end.to raise_error(
Dry::CLI::InvalidCallbackError,
"expected `#{callback.inspect}' to respond to `#call'"
@ -26,12 +26,12 @@ RSpec.describe Dry::CLI::Registry do
end
end
context 'when class is given' do
it 'raises error when #initialize arity is not equal to 0' do
context "when class is given" do
it "raises error when #initialize arity is not equal to 0" do
callback = Struct
expect do
Bar::CLI::Commands.before('alpha', callback)
Bar::CLI::Commands.before("alpha", callback)
end.to raise_error(
Dry::CLI::InvalidCallbackError,
"expected `#{callback.inspect}' to respond to `#initialize' with arity 0"
@ -40,21 +40,21 @@ RSpec.describe Dry::CLI::Registry do
end
end
describe '.after' do
describe ".after" do
context "when command can't be found" do
it 'raises error' do
it "raises error" do
expect do
Bar::CLI::Commands.after('peta') { puts 'hello' }
Bar::CLI::Commands.after("peta") { puts "hello" }
end.to raise_error(Dry::CLI::UnknownCommandError, "unknown command: `peta'")
end
end
context 'when object is given' do
context "when object is given" do
it "raises error when it doesn't respond to #call" do
callback = Object.new
expect do
Bar::CLI::Commands.after('alpha', callback)
Bar::CLI::Commands.after("alpha", callback)
end.to raise_error(
Dry::CLI::InvalidCallbackError,
"expected `#{callback.inspect}' to respond to `#call'"
@ -62,12 +62,12 @@ RSpec.describe Dry::CLI::Registry do
end
end
context 'when class is given' do
it 'raises error when #initialize arity is not equal to 0' do
context "when class is given" do
it "raises error when #initialize arity is not equal to 0" do
callback = Struct
expect do
Bar::CLI::Commands.after('alpha', callback)
Bar::CLI::Commands.after("alpha", callback)
end.to raise_error(
Dry::CLI::InvalidCallbackError,
"expected `#{callback.inspect}' to respond to `#initialize' with arity 0"

View File

@ -1,139 +1,139 @@
# frozen_string_literal: true
require 'dry/cli/utils/files'
require 'securerandom'
require "dry/cli/utils/files"
require "securerandom"
RSpec.describe Dry::CLI::Utils::Files do
let(:root) { Pathname.new(Dir.pwd).join('tmp', SecureRandom.uuid).tap(&:mkpath) }
let(:root) { Pathname.new(Dir.pwd).join("tmp", SecureRandom.uuid).tap(&:mkpath) }
after do
FileUtils.remove_entry_secure(root)
end
describe '.touch' do
it 'creates an empty file' do
path = root.join('touch')
describe ".touch" do
it "creates an empty file" do
path = root.join("touch")
described_class.touch(path)
expect(path).to exist
expect(path).to have_content('')
expect(path).to have_content("")
end
it 'creates intermediate directories' do
path = root.join('path', 'to', 'file', 'touch')
it "creates intermediate directories" do
path = root.join("path", "to", "file", "touch")
described_class.touch(path)
expect(path).to exist
expect(path).to have_content('')
expect(path).to have_content("")
end
it 'leaves untouched existing file' do
path = root.join('touch')
path.open('wb+') { |p| p.write('foo') }
it "leaves untouched existing file" do
path = root.join("touch")
path.open("wb+") { |p| p.write("foo") }
described_class.touch(path)
expect(path).to exist
expect(path).to have_content('foo')
expect(path).to have_content("foo")
end
end
describe '.write' do
it 'creates an file with given contents' do
path = root.join('write')
describe ".write" do
it "creates an file with given contents" do
path = root.join("write")
described_class.write(path, "Hello\nWorld")
expect(path).to exist
expect(path).to have_content("Hello\nWorld")
end
it 'creates intermediate directories' do
path = root.join('path', 'to', 'file', 'write')
described_class.write(path, ':)')
it "creates intermediate directories" do
path = root.join("path", "to", "file", "write")
described_class.write(path, ":)")
expect(path).to exist
expect(path).to have_content(':)')
expect(path).to have_content(":)")
end
it 'overwrites file when it already exists' do
path = root.join('write')
described_class.write(path, 'many many many many words')
described_class.write(path, 'new words')
it "overwrites file when it already exists" do
path = root.join("write")
described_class.write(path, "many many many many words")
described_class.write(path, "new words")
expect(path).to exist
expect(path).to have_content('new words')
expect(path).to have_content("new words")
end
end
describe '.cp' do
let(:source) { root.join('..', 'source') }
describe ".cp" do
let(:source) { root.join("..", "source") }
before do
source.delete if source.exist?
end
it 'creates a file with given contents' do
described_class.write(source, 'the source')
it "creates a file with given contents" do
described_class.write(source, "the source")
destination = root.join('cp')
destination = root.join("cp")
described_class.cp(source, destination)
expect(destination).to exist
expect(destination).to have_content('the source')
expect(destination).to have_content("the source")
end
it 'creates intermediate directories' do
source = root.join('..', 'source')
described_class.write(source, 'the source for intermediate directories')
it "creates intermediate directories" do
source = root.join("..", "source")
described_class.write(source, "the source for intermediate directories")
destination = root.join('cp', 'destination')
destination = root.join("cp", "destination")
described_class.cp(source, destination)
expect(destination).to exist
expect(destination).to have_content('the source for intermediate directories')
expect(destination).to have_content("the source for intermediate directories")
end
it 'overrides already existing file' do
source = root.join('..', 'source')
described_class.write(source, 'the source')
it "overrides already existing file" do
source = root.join("..", "source")
described_class.write(source, "the source")
destination = root.join('cp')
described_class.write(destination, 'the destination')
destination = root.join("cp")
described_class.write(destination, "the destination")
described_class.cp(source, destination)
expect(destination).to exist
expect(destination).to have_content('the source')
expect(destination).to have_content("the source")
end
end
describe '.mkdir' do
it 'creates directory' do
path = root.join('mkdir')
describe ".mkdir" do
it "creates directory" do
path = root.join("mkdir")
described_class.mkdir(path)
expect(path).to be_directory
end
it 'creates intermediate directories' do
path = root.join('path', 'to', 'mkdir')
it "creates intermediate directories" do
path = root.join("path", "to", "mkdir")
described_class.mkdir(path)
expect(path).to be_directory
end
end
describe '.mkdir_p' do
it 'creates directory' do
directory = root.join('mkdir_p')
path = directory.join('file.rb')
describe ".mkdir_p" do
it "creates directory" do
directory = root.join("mkdir_p")
path = directory.join("file.rb")
described_class.mkdir_p(path)
expect(directory).to be_directory
expect(path).to_not exist
end
it 'creates intermediate directories' do
directory = root.join('path', 'to', 'mkdir_p')
path = directory.join('file.rb')
it "creates intermediate directories" do
directory = root.join("path", "to", "mkdir_p")
path = directory.join("file.rb")
described_class.mkdir_p(path)
expect(directory).to be_directory
@ -141,9 +141,9 @@ RSpec.describe Dry::CLI::Utils::Files do
end
end
describe '.delete' do
it 'deletes path' do
path = root.join('delete', 'file')
describe ".delete" do
it "deletes path" do
path = root.join("delete", "file")
described_class.touch(path)
described_class.delete(path)
@ -151,20 +151,20 @@ RSpec.describe Dry::CLI::Utils::Files do
end
it "raises error if path doesn't exist" do
path = root.join('delete', 'file')
path = root.join("delete", "file")
expect { described_class.delete(path) }.to raise_error do |exception|
expect(exception).to be_kind_of(Errno::ENOENT)
expect(exception.message).to match('No such file or directory')
expect(exception.message).to match("No such file or directory")
end
expect(path).to_not exist
end
end
describe '.delete_directory' do
it 'deletes directory' do
path = root.join('delete', 'directory')
describe ".delete_directory" do
it "deletes directory" do
path = root.join("delete", "directory")
described_class.mkdir(path)
described_class.delete_directory(path)
@ -172,27 +172,27 @@ RSpec.describe Dry::CLI::Utils::Files do
end
it "raises error if directory doesn't exist" do
path = root.join('delete', 'directory')
path = root.join("delete", "directory")
expect { described_class.delete_directory(path) }.to raise_error do |exception|
expect(exception).to be_kind_of(Errno::ENOENT)
expect(exception.message).to match('No such file or directory')
expect(exception.message).to match("No such file or directory")
end
expect(path).to_not exist
end
end
describe '.unshift' do
it 'adds a line at the top of the file' do
path = root.join('unshift.rb')
describe ".unshift" do
it "adds a line at the top of the file" do
path = root.join("unshift.rb")
content = <<~CONTENT
class Unshift
end
CONTENT
described_class.write(path, content)
described_class.unshift(path, '# frozen_string_literal: true')
described_class.unshift(path, "# frozen_string_literal: true")
expected = <<~CONTENT
# frozen_string_literal: true
@ -205,7 +205,7 @@ RSpec.describe Dry::CLI::Utils::Files do
# https://github.com/hanami/utils/issues/348
it "adds a line at the top of a file that doesn't end with a newline" do
path = root.join('unshift_missing_newline.rb')
path = root.join("unshift_missing_newline.rb")
content = "get '/tires', to: 'sunshine#index'"
described_class.write(path, content)
@ -217,20 +217,20 @@ RSpec.describe Dry::CLI::Utils::Files do
end
it "raises error if path doesn't exist" do
path = root.join('unshift_no_exist.rb')
path = root.join("unshift_no_exist.rb")
expect { described_class.unshift(path, '# frozen_string_literal: true') }.to raise_error do |exception| # rubocop:disable Metrics/LineLength
expect { described_class.unshift(path, "# frozen_string_literal: true") }.to raise_error do |exception|
expect(exception).to be_kind_of(Errno::ENOENT)
expect(exception.message).to match('No such file or directory')
expect(exception.message).to match("No such file or directory")
end
expect(path).to_not exist
end
end
describe '.append' do
it 'adds a line at the bottom of the file' do
path = root.join('append.rb')
describe ".append" do
it "adds a line at the bottom of the file" do
path = root.join("append.rb")
content = <<~CONTENT
class Append
end
@ -251,7 +251,7 @@ RSpec.describe Dry::CLI::Utils::Files do
# https://github.com/hanami/utils/issues/348
it "adds a line at the bottom of a file that doesn't end with a newline" do
path = root.join('append_missing_newline.rb')
path = root.join("append_missing_newline.rb")
content = "root to: 'home#index'"
described_class.write(path, content)
@ -266,20 +266,20 @@ RSpec.describe Dry::CLI::Utils::Files do
end
it "raises error if path doesn't exist" do
path = root.join('append_no_exist.rb')
path = root.join("append_no_exist.rb")
expect { described_class.append(path, "\n Foo.register Append") }.to raise_error do |exception| # rubocop:disable Metrics/LineLength
expect { described_class.append(path, "\n Foo.register Append") }.to raise_error do |exception|
expect(exception).to be_kind_of(Errno::ENOENT)
expect(exception.message).to match('No such file or directory')
expect(exception.message).to match("No such file or directory")
end
expect(path).to_not exist
end
end
describe '.replace_first_line' do
it 'replaces string target with replacement' do
path = root.join('replace_string.rb')
describe ".replace_first_line" do
it "replaces string target with replacement" do
path = root.join("replace_string.rb")
content = <<~CONTENT
class Replace
def self.perform
@ -288,7 +288,7 @@ RSpec.describe Dry::CLI::Utils::Files do
CONTENT
described_class.write(path, content)
described_class.replace_first_line(path, 'perform', ' def self.call(input)')
described_class.replace_first_line(path, "perform", " def self.call(input)")
expected = <<~CONTENT
class Replace
@ -300,8 +300,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'replaces regexp target with replacement' do
path = root.join('replace_regexp.rb')
it "replaces regexp target with replacement" do
path = root.join("replace_regexp.rb")
content = <<~CONTENT
class Replace
def self.perform
@ -310,7 +310,7 @@ RSpec.describe Dry::CLI::Utils::Files do
CONTENT
described_class.write(path, content)
described_class.replace_first_line(path, /perform/, ' def self.call(input)')
described_class.replace_first_line(path, /perform/, " def self.call(input)")
expected = <<~CONTENT
class Replace
@ -322,8 +322,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'replaces only the first occurrence of target with replacement' do
path = root.join('replace_first.rb')
it "replaces only the first occurrence of target with replacement" do
path = root.join("replace_first.rb")
content = <<~CONTENT
class Replace
def self.perform
@ -335,7 +335,7 @@ RSpec.describe Dry::CLI::Utils::Files do
CONTENT
described_class.write(path, content)
described_class.replace_first_line(path, 'perform', ' def self.call(input)')
described_class.replace_first_line(path, "perform", " def self.call(input)")
expected = <<~CONTENT
class Replace
@ -350,8 +350,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'raises error if target cannot be found in path' do
path = root.join('replace_not_found.rb')
it "raises error if target cannot be found in path" do
path = root.join("replace_not_found.rb")
content = <<~CONTENT
class Replace
def self.perform
@ -361,7 +361,7 @@ RSpec.describe Dry::CLI::Utils::Files do
described_class.write(path, content)
expect { described_class.replace_first_line(path, 'not existing target', ' def self.call(input)') }.to raise_error do |exception| # rubocop:disable Metrics/LineLength
expect { described_class.replace_first_line(path, "not existing target", " def self.call(input)") }.to raise_error do |exception|
expect(exception).to be_kind_of(ArgumentError)
expect(exception.message).to eq("Cannot find `not existing target' inside `#{path}'.")
end
@ -370,20 +370,20 @@ RSpec.describe Dry::CLI::Utils::Files do
end
it "raises error if path doesn't exist" do
path = root.join('replace_no_exist.rb')
path = root.join("replace_no_exist.rb")
expect { described_class.replace_first_line(path, 'perform', ' def self.call(input)') }.to raise_error do |exception| # rubocop:disable Metrics/LineLength
expect { described_class.replace_first_line(path, "perform", " def self.call(input)") }.to raise_error do |exception|
expect(exception).to be_kind_of(Errno::ENOENT)
expect(exception.message).to match('No such file or directory')
expect(exception.message).to match("No such file or directory")
end
expect(path).to_not exist
end
end
describe '.replace_last_line' do
it 'replaces string target with replacement' do
path = root.join('replace_last_string.rb')
describe ".replace_last_line" do
it "replaces string target with replacement" do
path = root.join("replace_last_string.rb")
content = <<~CONTENT
class ReplaceLast
def self.perform
@ -392,7 +392,7 @@ RSpec.describe Dry::CLI::Utils::Files do
CONTENT
described_class.write(path, content)
described_class.replace_last_line(path, 'perform', ' def self.call(input)')
described_class.replace_last_line(path, "perform", " def self.call(input)")
expected = <<~CONTENT
class ReplaceLast
@ -404,8 +404,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'replaces regexp target with replacement' do
path = root.join('replace_last_regexp.rb')
it "replaces regexp target with replacement" do
path = root.join("replace_last_regexp.rb")
content = <<~CONTENT
class ReplaceLast
def self.perform
@ -414,7 +414,7 @@ RSpec.describe Dry::CLI::Utils::Files do
CONTENT
described_class.write(path, content)
described_class.replace_last_line(path, /perform/, ' def self.call(input)')
described_class.replace_last_line(path, /perform/, " def self.call(input)")
expected = <<~CONTENT
class ReplaceLast
@ -426,8 +426,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'replaces only the last occurrence of target with replacement' do
path = root.join('replace_last.rb')
it "replaces only the last occurrence of target with replacement" do
path = root.join("replace_last.rb")
content = <<~CONTENT
class ReplaceLast
def self.perform
@ -439,7 +439,7 @@ RSpec.describe Dry::CLI::Utils::Files do
CONTENT
described_class.write(path, content)
described_class.replace_last_line(path, 'perform', ' def self.call(input)')
described_class.replace_last_line(path, "perform", " def self.call(input)")
expected = <<~CONTENT
class ReplaceLast
@ -454,8 +454,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'raises error if target cannot be found in path' do
path = root.join('replace_last_not_found.rb')
it "raises error if target cannot be found in path" do
path = root.join("replace_last_not_found.rb")
content = <<~CONTENT
class ReplaceLast
def self.perform
@ -465,7 +465,7 @@ RSpec.describe Dry::CLI::Utils::Files do
described_class.write(path, content)
expect { described_class.replace_last_line(path, 'not existing target', ' def self.call(input)') }.to raise_error do |exception| # rubocop:disable Metrics/LineLength
expect { described_class.replace_last_line(path, "not existing target", " def self.call(input)") }.to raise_error do |exception|
expect(exception).to be_kind_of(ArgumentError)
expect(exception.message).to eq("Cannot find `not existing target' inside `#{path}'.")
end
@ -474,20 +474,20 @@ RSpec.describe Dry::CLI::Utils::Files do
end
it "raises error if path doesn't exist" do
path = root.join('replace_last_no_exist.rb')
path = root.join("replace_last_no_exist.rb")
expect { described_class.replace_last_line(path, 'perform', ' def self.call(input)') }.to raise_error do |exception| # rubocop:disable Metrics/LineLength
expect { described_class.replace_last_line(path, "perform", " def self.call(input)") }.to raise_error do |exception|
expect(exception).to be_kind_of(Errno::ENOENT)
expect(exception.message).to match('No such file or directory')
expect(exception.message).to match("No such file or directory")
end
expect(path).to_not exist
end
end
describe '.inject_line_before' do
it 'injects line before target (string)' do
path = root.join('inject_before_string.rb')
describe ".inject_line_before" do
it "injects line before target (string)" do
path = root.join("inject_before_string.rb")
content = <<~CONTENT
class InjectBefore
def self.call
@ -496,7 +496,7 @@ RSpec.describe Dry::CLI::Utils::Files do
CONTENT
described_class.write(path, content)
described_class.inject_line_before(path, 'call', ' # It performs the operation')
described_class.inject_line_before(path, "call", " # It performs the operation")
expected = <<~CONTENT
class InjectBefore
@ -509,8 +509,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'injects line before target (regexp)' do
path = root.join('inject_before_regexp.rb')
it "injects line before target (regexp)" do
path = root.join("inject_before_regexp.rb")
content = <<~CONTENT
class InjectBefore
def self.call
@ -519,7 +519,7 @@ RSpec.describe Dry::CLI::Utils::Files do
CONTENT
described_class.write(path, content)
described_class.inject_line_before(path, /call/, ' # It performs the operation')
described_class.inject_line_before(path, /call/, " # It performs the operation")
expected = <<~CONTENT
class InjectBefore
@ -532,8 +532,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'raises error if target cannot be found in path' do
path = root.join('inject_before_not_found.rb')
it "raises error if target cannot be found in path" do
path = root.join("inject_before_not_found.rb")
content = <<~CONTENT
class InjectBefore
def self.call
@ -543,7 +543,7 @@ RSpec.describe Dry::CLI::Utils::Files do
described_class.write(path, content)
expect { described_class.inject_line_before(path, 'not existing target', ' # It performs the operation') }.to raise_error do |exception| # rubocop:disable Metrics/LineLength
expect { described_class.inject_line_before(path, "not existing target", " # It performs the operation") }.to raise_error do |exception|
expect(exception).to be_kind_of(ArgumentError)
expect(exception.message).to eq("Cannot find `not existing target' inside `#{path}'.")
end
@ -552,20 +552,20 @@ RSpec.describe Dry::CLI::Utils::Files do
end
it "raises error if path doesn't exist" do
path = root.join('inject_before_no_exist.rb')
path = root.join("inject_before_no_exist.rb")
expect { described_class.inject_line_before(path, 'call', ' # It performs the operation') }.to raise_error do |exception| # rubocop:disable Metrics/LineLength
expect { described_class.inject_line_before(path, "call", " # It performs the operation") }.to raise_error do |exception|
expect(exception).to be_kind_of(Errno::ENOENT)
expect(exception.message).to match('No such file or directory')
expect(exception.message).to match("No such file or directory")
end
expect(path).to_not exist
end
end
describe '.inject_line_before_last' do
it 'injects line before last target (string)' do
path = root.join('inject_before_last_string.rb')
describe ".inject_line_before_last" do
it "injects line before last target (string)" do
path = root.join("inject_before_last_string.rb")
content = <<~CONTENT
class InjectBefore
def self.call
@ -576,7 +576,7 @@ RSpec.describe Dry::CLI::Utils::Files do
CONTENT
described_class.write(path, content)
described_class.inject_line_before_last(path, 'call', ' # It performs the operation')
described_class.inject_line_before_last(path, "call", " # It performs the operation")
expected = <<~CONTENT
class InjectBefore
@ -591,8 +591,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'injects line before last target (regexp)' do
path = root.join('inject_before_last_regexp.rb')
it "injects line before last target (regexp)" do
path = root.join("inject_before_last_regexp.rb")
content = <<~CONTENT
class InjectBefore
def self.call
@ -603,7 +603,7 @@ RSpec.describe Dry::CLI::Utils::Files do
CONTENT
described_class.write(path, content)
described_class.inject_line_before_last(path, /call/, ' # It performs the operation')
described_class.inject_line_before_last(path, /call/, " # It performs the operation")
expected = <<~CONTENT
class InjectBefore
@ -618,8 +618,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'raises error if target cannot be found in path' do
path = root.join('inject_before_last_not_found.rb')
it "raises error if target cannot be found in path" do
path = root.join("inject_before_last_not_found.rb")
content = <<~CONTENT
class InjectBefore
def self.call
@ -631,7 +631,7 @@ RSpec.describe Dry::CLI::Utils::Files do
described_class.write(path, content)
expect { described_class.inject_line_before_last(path, 'not existing target', ' # It performs the operation') }.to raise_error do |exception| # rubocop:disable Metrics/LineLength
expect { described_class.inject_line_before_last(path, "not existing target", " # It performs the operation") }.to raise_error do |exception|
expect(exception).to be_kind_of(ArgumentError)
expect(exception.message).to eq("Cannot find `not existing target' inside `#{path}'.")
end
@ -640,20 +640,20 @@ RSpec.describe Dry::CLI::Utils::Files do
end
it "raises error if path doesn't exist" do
path = root.join('inject_before_last_no_exist.rb')
path = root.join("inject_before_last_no_exist.rb")
expect { described_class.inject_line_before_last(path, 'call', ' # It performs the operation') }.to raise_error do |exception| # rubocop:disable Metrics/LineLength
expect { described_class.inject_line_before_last(path, "call", " # It performs the operation") }.to raise_error do |exception|
expect(exception).to be_kind_of(Errno::ENOENT)
expect(exception.message).to match('No such file or directory')
expect(exception.message).to match("No such file or directory")
end
expect(path).to_not exist
end
end
describe '.inject_line_after' do
it 'injects line after target (string)' do
path = root.join('inject_after.rb')
describe ".inject_line_after" do
it "injects line after target (string)" do
path = root.join("inject_after.rb")
content = <<~CONTENT
class InjectAfter
def self.call
@ -662,7 +662,7 @@ RSpec.describe Dry::CLI::Utils::Files do
CONTENT
described_class.write(path, content)
described_class.inject_line_after(path, 'call', ' :result')
described_class.inject_line_after(path, "call", " :result")
expected = <<~CONTENT
class InjectAfter
@ -675,8 +675,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'injects line after target (regexp)' do
path = root.join('inject_after.rb')
it "injects line after target (regexp)" do
path = root.join("inject_after.rb")
content = <<~CONTENT
class InjectAfter
def self.call
@ -685,7 +685,7 @@ RSpec.describe Dry::CLI::Utils::Files do
CONTENT
described_class.write(path, content)
described_class.inject_line_after(path, /call/, ' :result')
described_class.inject_line_after(path, /call/, " :result")
expected = <<~CONTENT
class InjectAfter
@ -698,8 +698,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'raises error if target cannot be found in path' do
path = root.join('inject_after_not_found.rb')
it "raises error if target cannot be found in path" do
path = root.join("inject_after_not_found.rb")
content = <<~CONTENT
class InjectAfter
def self.call
@ -709,7 +709,7 @@ RSpec.describe Dry::CLI::Utils::Files do
described_class.write(path, content)
expect { described_class.inject_line_after(path, 'not existing target', ' :result') }.to raise_error do |exception| # rubocop:disable Metrics/LineLength
expect { described_class.inject_line_after(path, "not existing target", " :result") }.to raise_error do |exception|
expect(exception).to be_kind_of(ArgumentError)
expect(exception.message).to eq("Cannot find `not existing target' inside `#{path}'.")
end
@ -718,20 +718,20 @@ RSpec.describe Dry::CLI::Utils::Files do
end
it "raises error if path doesn't exist" do
path = root.join('inject_after_no_exist.rb')
path = root.join("inject_after_no_exist.rb")
expect { described_class.inject_line_after(path, 'call', ' :result') }.to raise_error do |exception| # rubocop:disable Metrics/LineLength
expect { described_class.inject_line_after(path, "call", " :result") }.to raise_error do |exception|
expect(exception).to be_kind_of(Errno::ENOENT)
expect(exception.message).to match('No such file or directory')
expect(exception.message).to match("No such file or directory")
end
expect(path).to_not exist
end
end
describe '.inject_line_after_last' do
it 'injects line after last target (string)' do
path = root.join('inject_after_last.rb')
describe ".inject_line_after_last" do
it "injects line after last target (string)" do
path = root.join("inject_after_last.rb")
content = <<~CONTENT
class InjectAfter
def self.call
@ -742,7 +742,7 @@ RSpec.describe Dry::CLI::Utils::Files do
CONTENT
described_class.write(path, content)
described_class.inject_line_after_last(path, 'call', ' :result')
described_class.inject_line_after_last(path, "call", " :result")
expected = <<~CONTENT
class InjectAfter
@ -757,8 +757,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'injects line after last target (regexp)' do
path = root.join('inject_after_last.rb')
it "injects line after last target (regexp)" do
path = root.join("inject_after_last.rb")
content = <<~CONTENT
class InjectAfter
def self.call
@ -769,7 +769,7 @@ RSpec.describe Dry::CLI::Utils::Files do
CONTENT
described_class.write(path, content)
described_class.inject_line_after_last(path, /call/, ' :result')
described_class.inject_line_after_last(path, /call/, " :result")
expected = <<~CONTENT
class InjectAfter
@ -784,8 +784,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'raises error if target cannot be found in path' do
path = root.join('inject_after_last_not_found.rb')
it "raises error if target cannot be found in path" do
path = root.join("inject_after_last_not_found.rb")
content = <<~CONTENT
class InjectAfter
def self.call
@ -797,7 +797,7 @@ RSpec.describe Dry::CLI::Utils::Files do
described_class.write(path, content)
expect { described_class.inject_line_after_last(path, 'not existing target', ' :result') }.to raise_error do |exception| # rubocop:disable Metrics/LineLength
expect { described_class.inject_line_after_last(path, "not existing target", " :result") }.to raise_error do |exception|
expect(exception).to be_kind_of(ArgumentError)
expect(exception.message).to eq("Cannot find `not existing target' inside `#{path}'.")
end
@ -806,20 +806,20 @@ RSpec.describe Dry::CLI::Utils::Files do
end
it "raises error if path doesn't exist" do
path = root.join('inject_after_last_no_exist.rb')
path = root.join("inject_after_last_no_exist.rb")
expect { described_class.inject_line_after_last(path, 'call', ' :result') }.to raise_error do |exception| # rubocop:disable Metrics/LineLength
expect { described_class.inject_line_after_last(path, "call", " :result") }.to raise_error do |exception|
expect(exception).to be_kind_of(Errno::ENOENT)
expect(exception.message).to match('No such file or directory')
expect(exception.message).to match("No such file or directory")
end
expect(path).to_not exist
end
end
describe '.remove_line' do
it 'removes line (string)' do
path = root.join('remove_line_string.rb')
describe ".remove_line" do
it "removes line (string)" do
path = root.join("remove_line_string.rb")
content = <<~CONTENT
# frozen_string_literal: true
class RemoveLine
@ -829,7 +829,7 @@ RSpec.describe Dry::CLI::Utils::Files do
CONTENT
described_class.write(path, content)
described_class.remove_line(path, 'frozen')
described_class.remove_line(path, "frozen")
expected = <<~CONTENT
class RemoveLine
@ -841,8 +841,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'removes line (regexp)' do
path = root.join('remove_line_regexp.rb')
it "removes line (regexp)" do
path = root.join("remove_line_regexp.rb")
content = <<~CONTENT
# frozen_string_literal: true
class RemoveLine
@ -864,8 +864,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'raises error if target cannot be found in path' do
path = root.join('remove_line_not_found.rb')
it "raises error if target cannot be found in path" do
path = root.join("remove_line_not_found.rb")
content = <<~CONTENT
# frozen_string_literal: true
class RemoveLine
@ -876,7 +876,7 @@ RSpec.describe Dry::CLI::Utils::Files do
described_class.write(path, content)
expect { described_class.remove_line(path, 'not existing target') }.to raise_error do |exception| # rubocop:disable Metrics/LineLength
expect { described_class.remove_line(path, "not existing target") }.to raise_error do |exception|
expect(exception).to be_kind_of(ArgumentError)
expect(exception.message).to eq("Cannot find `not existing target' inside `#{path}'.")
end
@ -885,20 +885,20 @@ RSpec.describe Dry::CLI::Utils::Files do
end
it "raises error if path doesn't exist" do
path = root.join('remove_line_no_exist.rb')
path = root.join("remove_line_no_exist.rb")
expect { described_class.remove_line(path, 'frozen') }.to raise_error do |exception|
expect { described_class.remove_line(path, "frozen") }.to raise_error do |exception|
expect(exception).to be_kind_of(Errno::ENOENT)
expect(exception.message).to match('No such file or directory')
expect(exception.message).to match("No such file or directory")
end
expect(path).to_not exist
end
end
describe '.remove_block' do
it 'removes block from Ruby file' do
path = root.join('remove_block_simple.rb')
describe ".remove_block" do
it "removes block from Ruby file" do
path = root.join("remove_block_simple.rb")
content = <<~CONTENT
class RemoveBlock
configure do
@ -908,7 +908,7 @@ RSpec.describe Dry::CLI::Utils::Files do
CONTENT
described_class.write(path, content)
described_class.remove_block(path, 'configure')
described_class.remove_block(path, "configure")
expected = <<~CONTENT
class RemoveBlock
@ -918,8 +918,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'removes nested block from Ruby file' do
path = root.join('remove_block_simple.rb')
it "removes nested block from Ruby file" do
path = root.join("remove_block_simple.rb")
content = <<~CONTENT
class RemoveBlock
configure do
@ -935,7 +935,7 @@ RSpec.describe Dry::CLI::Utils::Files do
CONTENT
described_class.write(path, content)
described_class.remove_block(path, 'assets')
described_class.remove_block(path, "assets")
expected = <<~CONTENT
class RemoveBlock
@ -949,8 +949,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(expected)
end
it 'raises error if block cannot be found in path' do
path = root.join('remove_block_not_found.rb')
it "raises error if block cannot be found in path" do
path = root.join("remove_block_not_found.rb")
content = <<~CONTENT
class RemoveBlock
configure do
@ -961,7 +961,7 @@ RSpec.describe Dry::CLI::Utils::Files do
described_class.write(path, content)
expect { described_class.remove_block(path, 'not existing target') }.to raise_error do |exception| # rubocop:disable Metrics/LineLength
expect { described_class.remove_block(path, "not existing target") }.to raise_error do |exception|
expect(exception).to be_kind_of(ArgumentError)
expect(exception.message).to eq("Cannot find `not existing target' inside `#{path}'.")
end
@ -969,8 +969,8 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(content)
end
it 'raises error if block cannot be found' do
path = root.join('remove_block_string_simple.rb')
it "raises error if block cannot be found" do
path = root.join("remove_block_string_simple.rb")
content = <<~CONTENT
class RemoveBlock
configure do
@ -981,7 +981,7 @@ RSpec.describe Dry::CLI::Utils::Files do
described_class.write(path, content)
expect { described_class.remove_block(path, 'not existing target') }.to raise_error do |exception| # rubocop:disable Metrics/LineLength
expect { described_class.remove_block(path, "not existing target") }.to raise_error do |exception|
expect(exception).to be_kind_of(ArgumentError)
expect(exception.message).to eq("Cannot find `not existing target' inside `#{path}'.")
end
@ -989,55 +989,55 @@ RSpec.describe Dry::CLI::Utils::Files do
expect(path).to have_content(content)
end
it 'raises an error when the file was not found' do
path = root.join('remove_block_not_found.rb')
it "raises an error when the file was not found" do
path = root.join("remove_block_not_found.rb")
expect { described_class.remove_block(path, 'configure') }.to raise_error do |exception|
expect { described_class.remove_block(path, "configure") }.to raise_error do |exception|
expect(exception).to be_kind_of(Errno::ENOENT)
expect(exception.message).to match('No such file or directory')
expect(exception.message).to match("No such file or directory")
end
end
end
describe '.exist?' do
it 'returns true for file' do
path = root.join('exist_file')
describe ".exist?" do
it "returns true for file" do
path = root.join("exist_file")
described_class.touch(path)
expect(described_class.exist?(path)).to be(true)
end
it 'returns true for directory' do
path = root.join('exist_directory')
it "returns true for directory" do
path = root.join("exist_directory")
described_class.mkdir(path)
expect(described_class.exist?(path)).to be(true)
end
it 'returns false for non-existing file' do
path = root.join('exist_not_found')
it "returns false for non-existing file" do
path = root.join("exist_not_found")
expect(described_class.exist?(path)).to be(false)
end
end
describe '.directory?' do
it 'returns true for directory' do
path = root.join('directory_directory')
describe ".directory?" do
it "returns true for directory" do
path = root.join("directory_directory")
described_class.mkdir(path)
expect(described_class.exist?(path)).to be(true)
end
it 'returns false for file' do
path = root.join('directory_file')
it "returns false for file" do
path = root.join("directory_file")
described_class.touch(path)
expect(described_class.directory?(path)).to be(false)
end
it 'returns false for non-existing path' do
path = root.join('directory_not_found')
it "returns false for non-existing path" do
path = root.join("directory_not_found")
expect(described_class.exist?(path)).to be(false)
end

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
RSpec.describe 'Dry::CLI::VERSION' do
it 'exposes version' do
expect(Dry::CLI::VERSION).to eq('0.6.0')
RSpec.describe "Dry::CLI::VERSION" do
it "exposes version" do
expect(Dry::CLI::VERSION).to eq("0.6.0")
end
end