diff --git a/lib/hanami/cli/commands/gem/new.rb b/lib/hanami/cli/commands/gem/new.rb
index 0562cada..07e26460 100644
--- a/lib/hanami/cli/commands/gem/new.rb
+++ b/lib/hanami/cli/commands/gem/new.rb
@@ -2,6 +2,7 @@
require "dry/inflector"
require_relative "../../errors"
+require_relative "../../formatter"
module Hanami
module CLI
@@ -157,31 +158,43 @@ def call(
skip_view: skip_view,
database: normalized_database
)
+ out.puts Formatter.header("Setting up #{app}...", out: out)
+
generator.call(app, context: context) do
if skip_install
- out.puts "Skipping installation, please enter `#{app}' directory and run `bundle exec hanami install'"
+ out.puts ""
+ out.puts Formatter.info("Skipping installation", out: out)
+ out.puts Formatter.dim(" To complete setup, run: cd #{app} && bundle exec hanami install", out: out)
else
- out.puts "Running bundle install..."
+ out.puts ""
+ out.puts Formatter.info("Installing dependencies...", out: out)
bundler.install!
unless skip_assets
- out.puts "Running npm install..."
+ out.puts Formatter.info("Installing npm packages...", out: out)
system_call.call("npm", ["install"]).tap do |result|
unless result.successful?
- puts "NPM ERROR:"
- puts(result.err.lines.map { |line| line.prepend(" ") })
+ out.puts Formatter.error("NPM installation failed:", out: out)
+ out.puts(result.err.lines.map { |line| Formatter.dim(" #{line}", out: out) })
end
end
end
- out.puts "Running hanami install..."
+ out.puts Formatter.info("Running hanami install...", out: out)
run_install_command!(head: head)
- out.puts "Running bundle binstubs hanami-cli rake..."
+ out.puts Formatter.info("Running bundle binstubs hanami-cli rake...", out: out)
install_binstubs!
- out.puts "Initializing git repository..."
+ out.puts Formatter.info("Initializing git repository...", out: out)
init_git_repository
+
+ out.puts ""
+ out.puts Formatter.success("Successfully created #{app}!", out: out)
+ out.puts ""
+ out.puts Formatter.dim("Next steps:", out: out)
+ out.puts Formatter.dim(" cd #{app}", out: out)
+ out.puts Formatter.dim(" bundle exec hanami dev", out: out)
end
end
end
@@ -227,8 +240,8 @@ def install_binstubs!
def init_git_repository
system_call.call("git", ["init"]).tap do |result|
unless result.successful?
- out.puts "WARNING: Failed to initialize git repository"
- out.puts(result.err.lines.map { |line| line.prepend(" ") })
+ out.puts Formatter.warning("Failed to initialize git repository", out: out)
+ out.puts(result.err.lines.map { |line| Formatter.dim(" #{line}", out: out) })
end
end
end
diff --git a/lib/hanami/cli/files.rb b/lib/hanami/cli/files.rb
index e8b30118..11927f86 100644
--- a/lib/hanami/cli/files.rb
+++ b/lib/hanami/cli/files.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require "dry/files"
+require_relative "formatter"
module Hanami
module CLI
@@ -43,7 +44,7 @@ def mkdir(path)
return if exist?(path)
super
- created(dir_path(path))
+ created_directory(dir_path(path))
end
# @since 2.0.0
@@ -83,15 +84,19 @@ def delete_keepfiles(path)
end
def updated(path)
- out.puts "Updated #{path}"
+ out.puts Formatter.updated(path, out: out)
end
def created(path)
- out.puts "Created #{path}"
+ out.puts Formatter.created(path, out: out)
+ end
+
+ def created_directory(path)
+ out.puts Formatter.created_directory(path, out: out)
end
def within_folder(path)
- out.puts "-> Within #{dir_path(path)}"
+ out.puts Formatter.dim("-> Entering `#{path}/` directory...", out: out)
end
def dir_path(path)
diff --git a/lib/hanami/cli/formatter.rb b/lib/hanami/cli/formatter.rb
new file mode 100644
index 00000000..e093c286
--- /dev/null
+++ b/lib/hanami/cli/formatter.rb
@@ -0,0 +1,163 @@
+# frozen_string_literal: true
+
+module Hanami
+ module CLI
+ # Provides formatting utilities for CLI output including colors and icons
+ #
+ # There is significant overlap with Hanami-Utils ShellColor module, but hasn't been merged together yet.
+ #
+ # @api private
+ # @since 2.3.0
+ module Formatter
+ # ANSI color codes
+ COLORS = {
+ reset: "\e[0m",
+ bold: "\e[1m",
+ green: "\e[32m",
+ blue: "\e[34m",
+ cyan: "\e[36m",
+ yellow: "\e[33m",
+ red: "\e[31m",
+ gray: "\e[90m"
+ }.freeze
+
+ # Icons for different operations
+ ICONS = {
+ create: "✓",
+ update: "↻",
+ info: "→",
+ warning: "⚠",
+ error: "✗",
+ success: "✓"
+ }.freeze
+
+ module_function
+
+ # Wraps text in color codes
+ #
+ # @param text [String] the text to colorize
+ # @param color [Symbol] the color name from COLORS
+ # @param out [IO] the output stream to check for TTY (defaults to $stdout)
+ # @return [String] colorized text
+ #
+ # @api private
+ def colorize(text, color, out: $stdout)
+ return text unless out.tty?
+
+ "#{COLORS[color]}#{text}#{COLORS[:reset]}"
+ end
+
+ # Formats a create message
+ #
+ # @param path [String] the path that was created
+ # @param out [IO] the output stream to check for TTY (defaults to $stdout)
+ # @return [String] formatted message
+ #
+ # @api private
+ def created(path, out: $stdout)
+ icon = colorize(ICONS[:create], :green, out: out)
+ label = colorize("create", :green, out: out)
+ " #{icon} #{label} #{path}"
+ end
+
+ # Formats a create directory message
+ #
+ # @param path [String] the directory path that was created
+ # @param out [IO] the output stream to check for TTY (defaults to $stdout)
+ # @return [String] formatted message
+ #
+ # @api private
+ def created_directory(path, out: $stdout)
+ icon = colorize(ICONS[:create], :green, out: out)
+ label = colorize("create directory", :green, out: out)
+ "#{icon} #{label} #{path}"
+ end
+
+ # Formats an update message
+ #
+ # @param path [String] the path that was updated
+ # @param out [IO] the output stream to check for TTY (defaults to $stdout)
+ # @return [String] formatted message
+ #
+ # @api private
+ def updated(path, out: $stdout)
+ icon = colorize(ICONS[:update], :cyan, out: out)
+ label = colorize("update", :cyan, out: out)
+ " #{icon} #{label} #{path}"
+ end
+
+ # Formats an info message
+ #
+ # @param text [String] the message text
+ # @param out [IO] the output stream to check for TTY (defaults to $stdout)
+ # @return [String] formatted message
+ #
+ # @api private
+ def info(text, out: $stdout)
+ icon = colorize(ICONS[:info], :blue, out: out)
+ "#{icon} #{text}"
+ end
+
+ # Formats a success message
+ #
+ # @param text [String] the message text
+ # @param out [IO] the output stream to check for TTY (defaults to $stdout)
+ # @return [String] formatted message
+ #
+ # @api private
+ def success(text, out: $stdout)
+ icon = colorize(ICONS[:success], :green, out: out)
+ label = colorize("✓", :green, out: out)
+ "#{label} #{colorize(text, :green, out: out)}"
+ end
+
+ # Formats a warning message
+ #
+ # @param text [String] the message text
+ # @param out [IO] the output stream to check for TTY (defaults to $stdout)
+ # @return [String] formatted message
+ #
+ # @api private
+ def warning(text, out: $stdout)
+ icon = colorize(ICONS[:warning], :yellow, out: out)
+ label = colorize("warning", :yellow, out: out)
+ "#{icon} #{label} #{text}"
+ end
+
+ # Formats an error message
+ #
+ # @param text [String] the message text
+ # @param out [IO] the output stream to check for TTY (defaults to $stdout)
+ # @return [String] formatted message
+ #
+ # @api private
+ def error(text, out: $stdout)
+ icon = colorize(ICONS[:error], :red, out: out)
+ label = colorize("error", :red, out: out)
+ "#{icon} #{label} #{text}"
+ end
+
+ # Formats a section header
+ #
+ # @param text [String] the header text
+ # @param out [IO] the output stream to check for TTY (defaults to $stdout)
+ # @return [String] formatted header
+ #
+ # @api private
+ def header(text, out: $stdout)
+ "\n#{colorize(text, :bold, out: out)}"
+ end
+
+ # Formats a dim/secondary text
+ #
+ # @param text [String] the text to dim
+ # @param out [IO] the output stream to check for TTY (defaults to $stdout)
+ # @return [String] formatted text
+ #
+ # @api private
+ def dim(text, out: $stdout)
+ text # No special dim color, just return plain text for now
+ end
+ end
+ end
+end
diff --git a/spec/unit/hanami/cli/commands/app/generate/action_spec.rb b/spec/unit/hanami/cli/commands/app/generate/action_spec.rb
index db997d78..500558ae 100644
--- a/spec/unit/hanami/cli/commands/app/generate/action_spec.rb
+++ b/spec/unit/hanami/cli/commands/app/generate/action_spec.rb
@@ -33,10 +33,10 @@ def error_output = err.string.chomp
within_application_directory do
generate_action
- expect(output).to include("Updated config/routes.rb")
- expect(output).to include("Created app/actions/#{controller}/#{action}.rb")
- expect(output).to include("Created app/views/#{controller}/#{action}.rb")
- expect(output).to include("Created app/templates/#{controller}/#{action}.html.erb")
+ expect(output).to include(" ↻ update config/routes.rb")
+ expect(output).to include(" ✓ create app/actions/#{controller}/#{action}.rb")
+ expect(output).to include(" ✓ create app/views/#{controller}/#{action}.rb")
+ expect(output).to include(" ✓ create app/templates/#{controller}/#{action}.html.erb")
end
end
end
@@ -122,7 +122,7 @@ class Routes < Hanami::Routes
# route
expect(fs.read("config/routes.rb")).to eq(routes)
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
# action
action_file = <<~EXPECTED
@@ -142,7 +142,7 @@ def handle(request, response)
EXPECTED
expect(fs.read("app/actions/#{controller}/#{action}.rb")).to eq(action_file)
- expect(output).to include("Created app/actions/#{controller}/#{action}.rb")
+ expect(output).to include(" ✓ create app/actions/#{controller}/#{action}.rb")
expect(fs.directory?("app/views/#{controller}")).to eq(false)
expect(fs.exist?("app/views/#{controller}/#{action}.rb")).to eq(false)
@@ -177,31 +177,31 @@ def handle(request, response)
within_application_directory do
subject.call(name: "users.index")
expect(fs.read("config/routes.rb")).to match(%(get "/users", to: "users.index"))
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
subject.call(name: "users.new")
expect(fs.read("config/routes.rb")).to match(%(get "/users/new", to: "users.new"))
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
subject.call(name: "users.create")
expect(fs.read("config/routes.rb")).to match(%(post "/users", to: "users.create"))
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
subject.call(name: "users.edit")
expect(fs.read("config/routes.rb")).to match(%(get "/users/:id/edit", to: "users.edit"))
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
subject.call(name: "users.update")
expect(fs.read("config/routes.rb")).to match(%(patch "/users/:id", to: "users.update"))
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
subject.call(name: "users.show")
expect(fs.read("config/routes.rb")).to match(%(get "/users/:id", to: "users.show"))
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
subject.call(name: "users.destroy")
expect(fs.read("config/routes.rb")).to match(%(delete "/users/:id", to: "users.destroy"))
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
end
end
@@ -209,7 +209,7 @@ def handle(request, response)
within_application_directory do
subject.call(name: "talent.apply", url_path: "/talent/apply")
expect(fs.read("config/routes.rb")).to match(%(get "/talent/apply", to: "talent.apply"))
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
end
end
@@ -217,7 +217,7 @@ def handle(request, response)
within_application_directory do
subject.call(name: action_name, url_path: "/people")
expect(fs.read("config/routes.rb")).to match(%(get "/people", to: "users.index"))
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
end
end
@@ -225,7 +225,7 @@ def handle(request, response)
within_application_directory do
subject.call(name: action_name, http_method: "put")
expect(fs.read("config/routes.rb")).to match(%(put "/users", to: "users.index"))
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
end
end
@@ -235,7 +235,7 @@ def handle(request, response)
subject.call(name: action_name, skip_view: true)
expect(fs.read("config/routes.rb")).to match(%(get "/api/users/thing", to: "api.users.thing"))
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
action_file = <<~EXPECTED
# frozen_string_literal: true
@@ -256,7 +256,7 @@ def handle(request, response)
EXPECTED
expect(fs.read("app/actions/api/users/thing.rb")).to eq(action_file)
- expect(output).to include("Created app/actions/api/users/thing.rb")
+ expect(output).to include(" ✓ create app/actions/api/users/thing.rb")
end
end
@@ -337,7 +337,7 @@ class Routes < Hanami::Routes
# route
expect(fs.read("config/routes.rb")).to eq(routes)
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
# action
action_file = <<~EXPECTED
@@ -356,7 +356,7 @@ def handle(request, response)
EXPECTED
expect(fs.read("app/actions/#{controller}/#{action}.rb")).to eq(action_file)
- expect(output).to include("Created app/actions/#{controller}/#{action}.rb")
+ expect(output).to include(" ✓ create app/actions/#{controller}/#{action}.rb")
# view
view_file = <<~EXPECTED
@@ -373,7 +373,7 @@ class #{inflector.camelize(action)} < #{inflector.camelize(app)}::View
EXPECTED
expect(fs.read("app/views/#{controller}/#{action}.rb")).to eq(view_file)
- expect(output).to include("Created app/views/#{controller}/#{action}.rb")
+ expect(output).to include(" ✓ create app/views/#{controller}/#{action}.rb")
# template
expect(fs.directory?("app/templates/#{controller}")).to be(true)
@@ -383,7 +383,7 @@ class #{inflector.camelize(action)} < #{inflector.camelize(app)}::View
EXPECTED
expect(fs.read("app/templates/#{controller}/#{action}.html.erb")).to eq(template_file)
- expect(output).to include("Created app/templates/#{controller}/#{action}.html.erb")
+ expect(output).to include(" ✓ create app/templates/#{controller}/#{action}.html.erb")
end
end
@@ -394,7 +394,7 @@ class #{inflector.camelize(action)} < #{inflector.camelize(app)}::View
subject.call(name: action_name)
expect(fs.read("config/routes.rb")).to match(%(get "/api/users/thing", to: "api.users.thing"))
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
action_file = <<~EXPECTED
# frozen_string_literal: true
@@ -414,7 +414,7 @@ def handle(request, response)
EXPECTED
expect(fs.read("app/actions/api/users/thing.rb")).to eq(action_file)
- expect(output).to include("Created app/actions/api/users/thing.rb")
+ expect(output).to include(" ✓ create app/actions/api/users/thing.rb")
end
end
end
@@ -457,7 +457,7 @@ def handle(request, response)
EXPECTED
expect(fs.read("app/actions/#{controller}/#{action}.rb")).to eq(action_file)
- expect(output).to include("Created app/actions/#{controller}/#{action}.rb")
+ expect(output).to include(" ✓ create app/actions/#{controller}/#{action}.rb")
# view
view_file = <<~EXPECTED
@@ -474,7 +474,7 @@ class #{inflector.camelize(action)} < #{inflector.camelize(app)}::View
EXPECTED
expect(fs.read("app/views/#{controller}/#{action}.rb")).to eq(view_file)
- expect(output).to include("Created app/views/#{controller}/#{action}.rb")
+ expect(output).to include(" ✓ create app/views/#{controller}/#{action}.rb")
# template
expect(fs.directory?("app/templates/#{controller}")).to be(true)
@@ -484,7 +484,7 @@ class #{inflector.camelize(action)} < #{inflector.camelize(app)}::View
EXPECTED
expect(fs.read("app/templates/#{controller}/#{action}.html.erb")).to eq(template_file)
- expect(output).to include("Created app/templates/#{controller}/#{action}.html.erb")
+ expect(output).to include(" ✓ create app/templates/#{controller}/#{action}.html.erb")
end
end
@@ -569,7 +569,7 @@ class Routes < Hanami::Routes
# route
expect(fs.read("config/routes.rb")).to eq(expected_routes)
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
expected_action = <<~CODE
# frozen_string_literal: true
@@ -586,7 +586,7 @@ def handle(request, response)
end
CODE
expect(fs.read("app/actions/users/create.rb")).to eq(expected_action)
- expect(output).to include("Created app/actions/users/create.rb")
+ expect(output).to include(" ✓ create app/actions/users/create.rb")
expect(fs.exist?("app/views/users/create.rb")).to be(false)
expect(fs.exist?("app/templates/users/create.html.erb")).to be(false)
@@ -631,7 +631,7 @@ class Routes < Hanami::Routes
# route
expect(fs.read("config/routes.rb")).to eq(expected_routes)
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
expected_action = <<~CODE
# frozen_string_literal: true
@@ -648,7 +648,7 @@ def handle(request, response)
end
CODE
expect(fs.read("app/actions/users/create.rb")).to eq(expected_action)
- expect(output).to include("Created app/actions/users/create.rb")
+ expect(output).to include(" ✓ create app/actions/users/create.rb")
expected_view = <<~CODE
# frozen_string_literal: true
@@ -663,14 +663,14 @@ class Create < #{app}::View
end
CODE
expect(fs.read("app/views/users/create.rb")).to eq(expected_view)
- expect(output).to include("Created app/views/users/create.rb")
+ expect(output).to include(" ✓ create app/views/users/create.rb")
expected_template = <<~EXPECTED
#{inflector.camelize(app)}::Views::Users::Create
EXPECTED
expect(fs.read("app/templates/users/create.html.erb")).to eq(expected_template)
- expect(output).to include("Created app/templates/users/create.html.erb")
+ expect(output).to include(" ✓ create app/templates/users/create.html.erb")
end
end
@@ -708,7 +708,7 @@ class Routes < Hanami::Routes
# route
expect(fs.read("config/routes.rb")).to eq(expected_routes)
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
expected_action = <<~CODE
# frozen_string_literal: true
@@ -726,7 +726,7 @@ def handle(request, response)
end
CODE
expect(fs.read("app/actions/users/create.rb")).to eq(expected_action)
- expect(output).to include("Created app/actions/users/create.rb")
+ expect(output).to include(" ✓ create app/actions/users/create.rb")
expect(fs.exist?("app/views/users/create.rb")).to be(false)
expect(fs.exist?("app/templates/users/create.html.erb")).to be(false)
@@ -809,7 +809,7 @@ class Routes < Hanami::Routes
# route
expect(fs.read("config/routes.rb")).to eq(expected_routes)
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
expected_action = <<~CODE
# frozen_string_literal: true
@@ -826,7 +826,7 @@ def handle(request, response)
end
CODE
expect(fs.read("app/actions/users/update.rb")).to eq(expected_action)
- expect(output).to include("Created app/actions/users/update.rb")
+ expect(output).to include(" ✓ create app/actions/users/update.rb")
expect(fs.exist?("app/views/users/update.rb")).to be(false)
expect(fs.exist?("app/templates/users/update.html.erb")).to be(false)
@@ -871,7 +871,7 @@ class Routes < Hanami::Routes
# route
expect(fs.read("config/routes.rb")).to eq(expected_routes)
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
expected_action = <<~CODE
# frozen_string_literal: true
@@ -888,7 +888,7 @@ def handle(request, response)
end
CODE
expect(fs.read("app/actions/users/update.rb")).to eq(expected_action)
- expect(output).to include("Created app/actions/users/update.rb")
+ expect(output).to include(" ✓ create app/actions/users/update.rb")
expected_view = <<~CODE
# frozen_string_literal: true
@@ -903,14 +903,14 @@ class Update < #{app}::View
end
CODE
expect(fs.read("app/views/users/update.rb")).to eq(expected_view)
- expect(output).to include("Created app/views/users/update.rb")
+ expect(output).to include(" ✓ create app/views/users/update.rb")
expected_template = <<~EXPECTED
#{inflector.camelize(app)}::Views::Users::Update
EXPECTED
expect(fs.read("app/templates/users/update.html.erb")).to eq(expected_template)
- expect(output).to include("Created app/templates/users/update.html.erb")
+ expect(output).to include(" ✓ create app/templates/users/update.html.erb")
end
end
@@ -948,7 +948,7 @@ class Routes < Hanami::Routes
# route
expect(fs.read("config/routes.rb")).to eq(expected_routes)
- expect(output).to include("Updated config/routes.rb")
+ expect(output).to include(" ↻ update config/routes.rb")
expected_action = <<~CODE
# frozen_string_literal: true
@@ -966,7 +966,7 @@ def handle(request, response)
end
CODE
expect(fs.read("app/actions/users/update.rb")).to eq(expected_action)
- expect(output).to include("Created app/actions/users/update.rb")
+ expect(output).to include(" ✓ create app/actions/users/update.rb")
expect(fs.exist?("app/views/users/update.rb")).to be(false)
expect(fs.exist?("app/templates/users/update.html.erb")).to be(false)
@@ -1015,12 +1015,12 @@ class Routes < Hanami::Routes
# route
expect(fs.read("config/routes.rb")).to eq(routes)
- expect(output).to include("Updated config/routes.rb")
- expect(output).to include("Created slices/#{slice}/actions/#{controller}/")
+ expect(output).to include(" ↻ update config/routes.rb")
+ expect(output).to include(" ✓ create slices/#{slice}/actions/#{controller}/")
# action
expect(fs.directory?("slices/#{slice}/actions/#{controller}")).to be(true)
- expect(output).to include("Created slices/#{slice}/actions/#{controller}/")
+ expect(output).to include(" ✓ create slices/#{slice}/actions/#{controller}/")
action_file = <<~EXPECTED
# frozen_string_literal: true
@@ -1038,7 +1038,7 @@ def handle(request, response)
end
EXPECTED
expect(fs.read("slices/#{slice}/actions/#{controller}/#{action}.rb")).to eq(action_file)
- expect(output).to include("Created slices/#{slice}/actions/#{controller}/#{action}.rb")
+ expect(output).to include(" ✓ create slices/#{slice}/actions/#{controller}/#{action}.rb")
# view
expect(fs.directory?("slices/#{slice}/views/#{controller}")).to be(false)
@@ -1225,12 +1225,12 @@ class Routes < Hanami::Routes
# route
expect(fs.read("config/routes.rb")).to eq(routes)
- expect(output).to include("Updated config/routes.rb")
- expect(output).to include("Created slices/#{slice}/actions/#{controller}/")
+ expect(output).to include(" ↻ update config/routes.rb")
+ expect(output).to include(" ✓ create slices/#{slice}/actions/#{controller}/")
# action
expect(fs.directory?("slices/#{slice}/actions/#{controller}")).to be(true)
- expect(output).to include("Created slices/#{slice}/actions/#{controller}/")
+ expect(output).to include(" ✓ create slices/#{slice}/actions/#{controller}/")
action_file = <<~EXPECTED
# frozen_string_literal: true
@@ -1247,11 +1247,11 @@ def handle(request, response)
end
EXPECTED
expect(fs.read("slices/#{slice}/actions/#{controller}/#{action}.rb")).to eq(action_file)
- expect(output).to include("Created slices/#{slice}/actions/#{controller}/#{action}.rb")
+ expect(output).to include(" ✓ create slices/#{slice}/actions/#{controller}/#{action}.rb")
# view
expect(fs.directory?("slices/#{slice}/views/#{controller}")).to be(true)
- expect(output).to include("Created slices/#{slice}/views/#{controller}/")
+ expect(output).to include(" ✓ create slices/#{slice}/views/#{controller}/")
view_file = <<~EXPECTED
# frozen_string_literal: true
@@ -1266,17 +1266,17 @@ class #{inflector.camelize(action)} < #{inflector.camelize(slice)}::View
end
EXPECTED
expect(fs.read("slices/#{slice}/views/#{controller}/#{action}.rb")).to eq(view_file)
- expect(output).to include("Created slices/#{slice}/views/#{controller}/#{action}.rb")
+ expect(output).to include(" ✓ create slices/#{slice}/views/#{controller}/#{action}.rb")
# template
expect(fs.directory?("slices/#{slice}/templates/#{controller}")).to be(true)
- expect(output).to include("Created slices/#{slice}/templates/#{controller}/")
+ expect(output).to include(" ✓ create slices/#{slice}/templates/#{controller}/")
template_file = <<~EXPECTED
#{inflector.camelize(slice)}::Views::#{inflector.camelize(controller)}::#{inflector.camelize(action)}
EXPECTED
expect(fs.read("slices/#{slice}/templates/#{controller}/#{action}.html.erb")).to eq(template_file)
- expect(output).to include("Created slices/#{slice}/templates/#{controller}/#{action}.html.erb")
+ expect(output).to include(" ✓ create slices/#{slice}/templates/#{controller}/#{action}.html.erb")
end
end
@@ -1356,8 +1356,8 @@ class Routes < Hanami::Routes
# route
expect(fs.read("config/routes.rb")).to eq(expected_routes)
- expect(output).to include("Updated config/routes.rb")
- expect(output).to include("Created slices/#{slice}/actions/#{controller}/")
+ expect(output).to include(" ↻ update config/routes.rb")
+ expect(output).to include(" ✓ create slices/#{slice}/actions/#{controller}/")
# action
expected_action = <<~EXPECTED
@@ -1375,7 +1375,7 @@ def handle(request, response)
end
EXPECTED
expect(fs.read("slices/#{slice}/actions/#{controller}/#{action}.rb")).to eq(expected_action)
- expect(output).to include("Created slices/#{slice}/actions/#{controller}/#{action}.rb")
+ expect(output).to include(" ✓ create slices/#{slice}/actions/#{controller}/#{action}.rb")
# view
expect(output).to_not include("Created slices/#{slice}/views/#{controller}/#{action}.rb")
diff --git a/spec/unit/hanami/cli/commands/app/generate/component_spec.rb b/spec/unit/hanami/cli/commands/app/generate/component_spec.rb
index d56714da..b7449be6 100644
--- a/spec/unit/hanami/cli/commands/app/generate/component_spec.rb
+++ b/spec/unit/hanami/cli/commands/app/generate/component_spec.rb
@@ -38,7 +38,7 @@ class SendWelcomeEmail
EXPECTED
expect(fs.read("app/operations/send_welcome_email.rb")).to eq(component)
- expect(output).to include("Created app/operations/send_welcome_email.rb")
+ expect(output).to include(" ✓ create app/operations/send_welcome_email.rb")
end
context "with existing file" do
@@ -79,7 +79,7 @@ class SendWelcomeEmail
EXPECTED
expect(fs.read("app/operations/user/mailing/send_welcome_email.rb")).to eq(component)
- expect(output).to include("Created app/operations/user/mailing/send_welcome_email.rb")
+ expect(output).to include(" ✓ create app/operations/user/mailing/send_welcome_email.rb")
end
context "with existing file" do
@@ -119,7 +119,7 @@ class WelcomeEmail
EXPECTED
expect(fs.read("slices/main/renderers/welcome_email.rb")).to eq(component)
- expect(output).to include("Created slices/main/renderers/welcome_email.rb")
+ expect(output).to include(" ✓ create slices/main/renderers/welcome_email.rb")
end
context "with existing file" do
@@ -161,7 +161,7 @@ class WelcomeEmail
EXPECTED
expect(fs.read("slices/main/renderers/user/mailing/welcome_email.rb")).to eq(component)
- expect(output).to include("Created slices/main/renderers/user/mailing/welcome_email.rb")
+ expect(output).to include(" ✓ create slices/main/renderers/user/mailing/welcome_email.rb")
end
context "with existing file" do
@@ -205,7 +205,7 @@ class SendWelcomeEmail
EXPECTED
expect(fs.read("app/operations/send_welcome_email.rb")).to eq(component)
- expect(output).to include("Created app/operations/send_welcome_email.rb")
+ expect(output).to include(" ✓ create app/operations/send_welcome_email.rb")
end
end
@@ -223,7 +223,7 @@ class CreateEntry
EXPECTED
expect(fs.read("app/create_entry.rb")).to eq(component)
- expect(output).to include("Created app/create_entry.rb")
+ expect(output).to include(" ✓ create app/create_entry.rb")
end
context "when nested" do
@@ -242,7 +242,7 @@ class CreateEntry
EXPECTED
expect(fs.read("app/services/create_entry.rb")).to eq(component)
- expect(output).to include("Created app/services/create_entry.rb")
+ expect(output).to include(" ✓ create app/services/create_entry.rb")
end
end
@@ -262,7 +262,7 @@ class CreateEntry
EXPECTED
expect(fs.read("app/services/create_entry.rb")).to eq(component)
- expect(output).to include("Created app/services/create_entry.rb")
+ expect(output).to include(" ✓ create app/services/create_entry.rb")
end
end
@@ -282,7 +282,7 @@ class CreateEntry
EXPECTED
expect(fs.read("app/services/create_entry.rb")).to eq(component)
- expect(output).to include("Created app/services/create_entry.rb")
+ expect(output).to include(" ✓ create app/services/create_entry.rb")
end
end
end
diff --git a/spec/unit/hanami/cli/commands/app/generate/migration_spec.rb b/spec/unit/hanami/cli/commands/app/generate/migration_spec.rb
index 244bb41c..3fafb9a8 100644
--- a/spec/unit/hanami/cli/commands/app/generate/migration_spec.rb
+++ b/spec/unit/hanami/cli/commands/app/generate/migration_spec.rb
@@ -40,21 +40,21 @@ def error_output = err.string.chomp
subject.call(name: "create_posts")
expect(fs.read("config/db/migrate/20240713140600_create_posts.rb")).to eq migration_file_contents
- expect(output).to eq("Created config/db/migrate/20240713140600_create_posts.rb")
+ expect(output).to eq("✓ create config/db/migrate/20240713140600_create_posts.rb")
end
it "generates a migration for a gateway" do
subject.call(name: "create_posts", gateway: "extra")
expect(fs.read("config/db/extra_migrate/20240713140600_create_posts.rb")).to eq migration_file_contents
- expect(output).to eq("Created config/db/extra_migrate/20240713140600_create_posts.rb")
+ expect(output).to eq("✓ create config/db/extra_migrate/20240713140600_create_posts.rb")
end
it "generates a migration with underscored version of camel cased name" do
subject.call(name: "CreatePosts")
expect(fs.read("config/db/migrate/20240713140600_create_posts.rb")).to eq migration_file_contents
- expect(output).to eq("Created config/db/migrate/20240713140600_create_posts.rb")
+ expect(output).to eq("✓ create config/db/migrate/20240713140600_create_posts.rb")
end
it "raises an error if given an invalid name" do
@@ -92,7 +92,7 @@ def error_output = err.string.chomp
subject.call(name: "create_posts", slice: "main")
expect(fs.read("slices/main/config/db/migrate/20240713140600_create_posts.rb")).to eq migration_file_contents
- expect(output).to eq("Created slices/main/config/db/migrate/20240713140600_create_posts.rb")
+ expect(output).to eq("✓ create slices/main/config/db/migrate/20240713140600_create_posts.rb")
end
context "with existing file" do
diff --git a/spec/unit/hanami/cli/commands/app/generate/operation_spec.rb b/spec/unit/hanami/cli/commands/app/generate/operation_spec.rb
index 1c229d24..cc0fb8d8 100644
--- a/spec/unit/hanami/cli/commands/app/generate/operation_spec.rb
+++ b/spec/unit/hanami/cli/commands/app/generate/operation_spec.rb
@@ -30,7 +30,7 @@ def call
EXPECTED
expect(fs.read("app/add_book.rb")).to eq(operation_file)
- expect(output).to include("Created app/add_book.rb")
+ expect(output).to include(" ✓ create app/add_book.rb")
expect(output).to include(
" Note: We generated a top-level operation. " \
"To generate into a directory, add a namespace: `my_namespace.add_book`"
@@ -56,7 +56,7 @@ def call
EXPECTED
expect(fs.read("app/admin/books/add.rb")).to eq(operation_file)
- expect(output).to include("Created app/admin/books/add.rb")
+ expect(output).to include(" ✓ create app/admin/books/add.rb")
end
it "generates an operation in a deep namespace with slash separators" do
@@ -78,7 +78,7 @@ def call
EXPECTED
expect(fs.read("app/admin/books/add.rb")).to eq(operation_file)
- expect(output).to include("Created app/admin/books/add.rb")
+ expect(output).to include(" ✓ create app/admin/books/add.rb")
end
context "with existing file" do
@@ -116,7 +116,7 @@ def call
EXPECTED
expect(fs.read("slices/main/add_book.rb")).to eq(operation_file)
- expect(output).to include("Created slices/main/add_book.rb")
+ expect(output).to include(" ✓ create slices/main/add_book.rb")
expect(output).to include(
" Note: We generated a top-level operation. " \
"To generate into a directory, add a namespace: `my_namespace.add_book`"
@@ -143,7 +143,7 @@ def call
EXPECTED
expect(fs.read("slices/main/admin/books/add.rb")).to eq(operation_file)
- expect(output).to include("Created slices/main/admin/books/add.rb")
+ expect(output).to include(" ✓ create slices/main/admin/books/add.rb")
end
context "with existing file" do
diff --git a/spec/unit/hanami/cli/commands/app/generate/part_spec.rb b/spec/unit/hanami/cli/commands/app/generate/part_spec.rb
index 44b218f1..fa8b7dce 100644
--- a/spec/unit/hanami/cli/commands/app/generate/part_spec.rb
+++ b/spec/unit/hanami/cli/commands/app/generate/part_spec.rb
@@ -39,7 +39,7 @@ class Part < Hanami::View::Part
EXPECTED
expect(fs.read("app/views/part.rb")).to eq(base_part)
- expect(output).to include("Created app/views/part.rb")
+ expect(output).to include(" ✓ create app/views/part.rb")
# part
part = <<~EXPECTED
@@ -57,7 +57,7 @@ class User < Test::Views::Part
EXPECTED
expect(fs.read("app/views/parts/user.rb")).to eq(part)
- expect(output).to include("Created app/views/parts/user.rb")
+ expect(output).to include(" ✓ create app/views/parts/user.rb")
end
end
@@ -116,7 +116,7 @@ class User < Test::Views::Part
EXPECTED
expect(fs.read("app/views/parts/user.rb")).to eq(part)
- expect(output).to include("Created app/views/parts/user.rb")
+ expect(output).to include(" ✓ create app/views/parts/user.rb")
# This is still printed because the fs.write above still prints
# expect(output).to_not include("Created app/views/part.rb")
@@ -146,7 +146,7 @@ class Part < Hanami::View::Part
EXPECTED
expect(fs.read("app/views/part.rb")).to eq(app_base_part)
- expect(output).to include("Created app/views/part.rb")
+ expect(output).to include(" ✓ create app/views/part.rb")
# base_part
base_part = <<~EXPECTED
@@ -162,7 +162,7 @@ class Part < Test::Views::Part
EXPECTED
expect(fs.read("slices/main/views/part.rb")).to eq(base_part)
- expect(output).to include("Created slices/main/views/part.rb")
+ expect(output).to include(" ✓ create slices/main/views/part.rb")
# part
part = <<~EXPECTED
@@ -180,7 +180,7 @@ class User < Main::Views::Part
EXPECTED
expect(fs.read("slices/main/views/parts/user.rb")).to eq(part)
- expect(output).to include("Created slices/main/views/parts/user.rb")
+ expect(output).to include(" ✓ create slices/main/views/parts/user.rb")
end
end
end
@@ -222,7 +222,7 @@ class User < Main::Views::Part
EXPECTED
expect(fs.read("slices/main/views/parts/user.rb")).to eq(part)
- expect(output).to include("Created slices/main/views/parts/user.rb")
+ expect(output).to include(" ✓ create slices/main/views/parts/user.rb")
# This is still printed because the fs.write above still prints
# expect(output).to_not include("Created slices/main/views/part.rb")
diff --git a/spec/unit/hanami/cli/commands/app/generate/relation_spec.rb b/spec/unit/hanami/cli/commands/app/generate/relation_spec.rb
index fd09628b..9aa0323f 100644
--- a/spec/unit/hanami/cli/commands/app/generate/relation_spec.rb
+++ b/spec/unit/hanami/cli/commands/app/generate/relation_spec.rb
@@ -46,7 +46,7 @@ class Books < TestApp::DB::Relation
RUBY
expect(Hanami.app.root.join("app/relations/books.rb").read).to eq relation_file
- expect(output).to include("Created app/relations/books.rb")
+ expect(output).to include(" ✓ create app/relations/books.rb")
end
it "generates a relation in a namespace with default separator" do
@@ -67,7 +67,7 @@ class Drafts < TestApp::DB::Relation
RUBY
expect(Hanami.app.root.join("app/relations/books/drafts.rb").read).to eq(relation_file)
- expect(output).to include("Created app/relations/books/drafts.rb")
+ expect(output).to include(" ✓ create app/relations/books/drafts.rb")
end
it "generates an relation in a namespace with slash separators" do
@@ -88,7 +88,7 @@ class PublishedBooks < TestApp::DB::Relation
RUBY
expect(Hanami.app.root.join("app/relations/books/published_books.rb").read).to eq(relation_file)
- expect(output).to include("Created app/relations/books/published_books.rb")
+ expect(output).to include(" ✓ create app/relations/books/published_books.rb")
end
it "deletes the redundant .keep file" do
@@ -114,7 +114,7 @@ class Books < TestApp::DB::Relation
RUBY
expect(Hanami.app.root.join("app/relations/books.rb").read).to eq relation_file
- expect(output).to include("Created app/relations/books.rb")
+ expect(output).to include(" ✓ create app/relations/books.rb")
end
context "with existing file" do
@@ -152,7 +152,7 @@ class Books < Main::DB::Relation
RUBY
expect(Hanami.app.root.join("slices/main/relations/books.rb").read).to eq(relation_file)
- expect(output).to include("Created slices/main/relations/books.rb")
+ expect(output).to include(" ✓ create slices/main/relations/books.rb")
end
it "generates a relation in a nested namespace" do
@@ -173,7 +173,7 @@ class Drafts < Main::DB::Relation
RUBY
expect(Hanami.app.root.join("slices/main/relations/book/drafts.rb").read).to eq(relation_file)
- expect(output).to include("Created slices/main/relations/book/drafts.rb")
+ expect(output).to include(" ✓ create slices/main/relations/book/drafts.rb")
end
it "generates a relation for gateway" do
@@ -195,7 +195,7 @@ class Drafts < Main::DB::Relation
RUBY
expect(Hanami.app.root.join("slices/main/relations/book/drafts.rb").read).to eq(relation_file)
- expect(output).to include("Created slices/main/relations/book/drafts.rb")
+ expect(output).to include(" ✓ create slices/main/relations/book/drafts.rb")
end
context "with existing file" do
@@ -233,7 +233,7 @@ class Entries < TestApp::DB::Relation
RUBY
expect(Hanami.app.root.join("app/relations/entries.rb").read).to eq(relation_file)
- expect(output).to include("Created app/relations/entries.rb")
+ expect(output).to include(" ✓ create app/relations/entries.rb")
end
end
end
diff --git a/spec/unit/hanami/cli/commands/app/generate/repo_spec.rb b/spec/unit/hanami/cli/commands/app/generate/repo_spec.rb
index ffac4e4b..3db23d48 100644
--- a/spec/unit/hanami/cli/commands/app/generate/repo_spec.rb
+++ b/spec/unit/hanami/cli/commands/app/generate/repo_spec.rb
@@ -31,7 +31,7 @@ class BookRepo < Test::DB::Repo
EXPECTED
expect(fs.read("app/repos/book_repo.rb")).to eq(repo_file)
- expect(output).to include("Created app/repos/book_repo.rb")
+ expect(output).to include(" ✓ create app/repos/book_repo.rb")
end
it "passed through repo name if repo_ suffix is preent" do
@@ -49,7 +49,7 @@ class BooksRepo < Test::DB::Repo
EXPECTED
expect(fs.read("app/repos/books_repo.rb")).to eq(repo_file)
- expect(output).to include("Created app/repos/books_repo.rb")
+ expect(output).to include(" ✓ create app/repos/books_repo.rb")
end
end
@@ -70,7 +70,7 @@ class DraftsRepo < Test::DB::Repo
EXPECTED
expect(fs.read("app/repos/books/drafts_repo.rb")).to eq(repo_file)
- expect(output).to include("Created app/repos/books/drafts_repo.rb")
+ expect(output).to include(" ✓ create app/repos/books/drafts_repo.rb")
end
it "generates an repo in a deep namespace with slash separators" do
@@ -92,7 +92,7 @@ class HardcoverRepo < Test::DB::Repo
EXPECTED
expect(fs.read("app/repos/books/published/hardcover_repo.rb")).to eq(repo_file)
- expect(output).to include("Created app/repos/books/published/hardcover_repo.rb")
+ expect(output).to include(" ✓ create app/repos/books/published/hardcover_repo.rb")
end
context "with existing file" do
@@ -130,7 +130,7 @@ class BookRepo < Main::DB::Repo
EXPECTED
expect(fs.read("slices/main/repos/book_repo.rb")).to eq(repo_file)
- expect(output).to include("Created slices/main/repos/book_repo.rb")
+ expect(output).to include(" ✓ create slices/main/repos/book_repo.rb")
end
it "generates a repo in a nested namespace" do
@@ -151,7 +151,7 @@ class DraftRepo < Main::DB::Repo
EXPECTED
expect(fs.read("slices/main/repos/book/draft_repo.rb")).to eq(repo_file)
- expect(output).to include("Created slices/main/repos/book/draft_repo.rb")
+ expect(output).to include(" ✓ create slices/main/repos/book/draft_repo.rb")
end
context "with existing file" do
diff --git a/spec/unit/hanami/cli/commands/app/generate/slice_spec.rb b/spec/unit/hanami/cli/commands/app/generate/slice_spec.rb
index 79e87bae..10f760d5 100644
--- a/spec/unit/hanami/cli/commands/app/generate/slice_spec.rb
+++ b/spec/unit/hanami/cli/commands/app/generate/slice_spec.rb
@@ -47,11 +47,11 @@ class Routes < Hanami::Routes
CODE
expect(fs.read("config/routes.rb")).to include(routes)
- expect(output).to include("Created config/routes.rb")
+ expect(output).to include(" ✓ create config/routes.rb")
# Slice directory
expect(fs.directory?("slices/#{slice}")).to be(true)
- expect(output).to include("Created slices/#{slice}/")
+ expect(output).to include(" ✓ create slices/#{slice}/")
# Action
action = <<~CODE
@@ -65,9 +65,9 @@ class Action < #{app}::Action
CODE
expect(fs.read("slices/#{slice}/action.rb")).to eq(action)
- expect(output).to include("Created slices/#{slice}/action.rb")
+ expect(output).to include(" ✓ create slices/#{slice}/action.rb")
expect(fs.read("slices/#{slice}/actions/.keep")).to eq("")
- expect(output).to include("Created slices/#{slice}/actions/.keep")
+ expect(output).to include(" ✓ create slices/#{slice}/actions/.keep")
# Relation
relation = <<~EXPECTED
@@ -81,9 +81,9 @@ class Relation < Test::DB::Relation
end
EXPECTED
expect(fs.read("slices/admin/db/relation.rb")).to eq(relation)
- expect(output).to include("Created slices/admin/db/relation.rb")
+ expect(output).to include(" ✓ create slices/admin/db/relation.rb")
expect(fs.read("slices/admin/relations/.keep")).to eq("")
- expect(output).to include("Created slices/admin/relations/.keep")
+ expect(output).to include(" ✓ create slices/admin/relations/.keep")
# Repo
repo = <<~EXPECTED
@@ -97,9 +97,9 @@ class Repo < Test::DB::Repo
end
EXPECTED
expect(fs.read("slices/admin/db/repo.rb")).to eq(repo)
- expect(output).to include("Created slices/admin/db/repo.rb")
+ expect(output).to include(" ✓ create slices/admin/db/repo.rb")
expect(fs.read("slices/admin/repos/.keep")).to eq("")
- expect(output).to include("Created slices/admin/repos/.keep")
+ expect(output).to include(" ✓ create slices/admin/repos/.keep")
# Struct
struct = <<~EXPECTED
@@ -113,9 +113,9 @@ class Struct < Test::DB::Struct
end
EXPECTED
expect(fs.read("slices/admin/db/struct.rb")).to eq(struct)
- expect(output).to include("Created slices/admin/db/struct.rb")
+ expect(output).to include(" ✓ create slices/admin/db/struct.rb")
expect(fs.read("slices/admin/structs/.keep")).to eq("")
- expect(output).to include("Created slices/admin/structs/.keep")
+ expect(output).to include(" ✓ create slices/admin/structs/.keep")
view = <<~RUBY
# auto_register: false
@@ -127,7 +127,7 @@ class View < Test::View
end
RUBY
expect(fs.read("slices/#{slice}/view.rb")).to eq(view)
- expect(output).to include("Created slices/#{slice}/view.rb")
+ expect(output).to include(" ✓ create slices/#{slice}/view.rb")
helpers = <<~RUBY
# auto_register: false
@@ -142,7 +142,7 @@ module Helpers
end
RUBY
expect(fs.read("slices/#{slice}/views/helpers.rb")).to eq(helpers)
- expect(output).to include("Created slices/#{slice}/views/helpers.rb")
+ expect(output).to include(" ✓ create slices/#{slice}/views/helpers.rb")
operation = <<~RUBY
# auto_register: false
@@ -154,7 +154,7 @@ class Operation < Test::Operation
end
RUBY
expect(fs.read("slices/#{slice}/operation.rb")).to eq(operation)
- expect(output).to include("Created slices/#{slice}/operation.rb")
+ expect(output).to include(" ✓ create slices/#{slice}/operation.rb")
layout = <<~ERB
@@ -173,14 +173,14 @@ class Operation < Test::Operation