From ceec27038b3bd77e23b7744e9d6ee69671ae07a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Tue, 19 Aug 2025 13:23:28 +0200 Subject: [PATCH 1/6] Use `Process.exec` in `shards run` --- src/commands/run.cr | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/commands/run.cr b/src/commands/run.cr index 59fb531d..a8a7fa25 100644 --- a/src/commands/run.cr +++ b/src/commands/run.cr @@ -28,10 +28,8 @@ module Shards Commands::Build.run(path, [target.name], options) Log.info { "Executing: #{target.name} #{run_options.join(' ')}" } - status = Process.run(File.join(Shards.bin_path, target.name), args: run_options, input: Process::Redirect::Inherit, output: Process::Redirect::Inherit, error: Process::Redirect::Inherit) - unless status.success? - exit status.exit_code - end + + Process.exec(File.join(Shards.bin_path, target.name), args: run_options) else raise Error.new("Error target #{name} was not found in #{SPEC_FILENAME}") end From 87e02f5f72a045aa1a8c0d5dfcafc6640da242df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Tue, 19 Aug 2025 18:34:22 +0200 Subject: [PATCH 2/6] Close builder --- src/commands/run.cr | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/commands/run.cr b/src/commands/run.cr index a8a7fa25..8833a156 100644 --- a/src/commands/run.cr +++ b/src/commands/run.cr @@ -29,6 +29,10 @@ module Shards Log.info { "Executing: #{target.name} #{run_options.join(' ')}" } + # FIXME: The explicit close is necessary to flush the last log message + # before `exec`. + ::Log.builder.try(&.close) + Process.exec(File.join(Shards.bin_path, target.name), args: run_options) else raise Error.new("Error target #{name} was not found in #{SPEC_FILENAME}") From 4ff90fbf88bae0c97221cc9dc76e968d7b38b7c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Tue, 19 Aug 2025 18:39:26 +0200 Subject: [PATCH 3/6] fixup --- src/commands/run.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/run.cr b/src/commands/run.cr index 8833a156..aa3cdb8f 100644 --- a/src/commands/run.cr +++ b/src/commands/run.cr @@ -31,7 +31,7 @@ module Shards # FIXME: The explicit close is necessary to flush the last log message # before `exec`. - ::Log.builder.try(&.close) + ::Log.builder.close Process.exec(File.join(Shards.bin_path, target.name), args: run_options) else From 5bf21e7bd110da22dafddf3b208abaa732681d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Wed, 20 Aug 2025 14:37:07 +0200 Subject: [PATCH 4/6] Add reference to issue --- src/commands/run.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/run.cr b/src/commands/run.cr index aa3cdb8f..df6293e6 100644 --- a/src/commands/run.cr +++ b/src/commands/run.cr @@ -30,7 +30,7 @@ module Shards Log.info { "Executing: #{target.name} #{run_options.join(' ')}" } # FIXME: The explicit close is necessary to flush the last log message - # before `exec`. + # before `exec`. https://github.com/crystal-lang/crystal/issues/14422#issuecomment-3204803933 ::Log.builder.close Process.exec(File.join(Shards.bin_path, target.name), args: run_options) From 1de49f69a242bf74a7270c3795ceae9c0da9f9e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Wed, 20 Aug 2025 14:39:47 +0200 Subject: [PATCH 5/6] Fallback on Windows --- src/commands/run.cr | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/commands/run.cr b/src/commands/run.cr index df6293e6..1961aab9 100644 --- a/src/commands/run.cr +++ b/src/commands/run.cr @@ -29,11 +29,18 @@ module Shards Log.info { "Executing: #{target.name} #{run_options.join(' ')}" } - # FIXME: The explicit close is necessary to flush the last log message - # before `exec`. https://github.com/crystal-lang/crystal/issues/14422#issuecomment-3204803933 - ::Log.builder.close + {% if flag?(:win32) %} + # FIXME: Process.exec doesn't work as expected on Windows, we need to run + # as a child process and report the exit code afterwards. https://github.com/crystal-lang/crystal/issues/14422#issuecomment-3204803933 + status = Process.run(File.join(Shards.bin_path, target.name), args: run_options, input: Process::Redirect::Inherit, output: Process::Redirect::Inherit, error: Process::Redirect::Inherit) + exit status.exit_code + {% else %} + # FIXME: The explicit close is necessary to flush the last log message + # before `exec`. https://github.com/crystal-lang/crystal/issues/14422#issuecomment-3204803933 + ::Log.builder.close - Process.exec(File.join(Shards.bin_path, target.name), args: run_options) + Process.exec(File.join(Shards.bin_path, target.name), args: run_options) + {% end %} else raise Error.new("Error target #{name} was not found in #{SPEC_FILENAME}") end From 9f5d93e0c04b080abbadff5abae2c9058e5bc9fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Wed, 20 Aug 2025 14:40:30 +0200 Subject: [PATCH 6/6] Simplify control flow with early raise --- src/commands/run.cr | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/commands/run.cr b/src/commands/run.cr index 1961aab9..95613d81 100644 --- a/src/commands/run.cr +++ b/src/commands/run.cr @@ -24,26 +24,26 @@ module Shards name = targets.first end - if target = spec.targets.find { |t| t.name == name } - Commands::Build.run(path, [target.name], options) - - Log.info { "Executing: #{target.name} #{run_options.join(' ')}" } - - {% if flag?(:win32) %} - # FIXME: Process.exec doesn't work as expected on Windows, we need to run - # as a child process and report the exit code afterwards. https://github.com/crystal-lang/crystal/issues/14422#issuecomment-3204803933 - status = Process.run(File.join(Shards.bin_path, target.name), args: run_options, input: Process::Redirect::Inherit, output: Process::Redirect::Inherit, error: Process::Redirect::Inherit) - exit status.exit_code - {% else %} - # FIXME: The explicit close is necessary to flush the last log message - # before `exec`. https://github.com/crystal-lang/crystal/issues/14422#issuecomment-3204803933 - ::Log.builder.close - - Process.exec(File.join(Shards.bin_path, target.name), args: run_options) - {% end %} - else - raise Error.new("Error target #{name} was not found in #{SPEC_FILENAME}") - end + target = spec.targets.find { |t| t.name == name } + + raise Error.new("Error target #{name} was not found in #{SPEC_FILENAME}") unless target + + Commands::Build.run(path, [target.name], options) + + Log.info { "Executing: #{target.name} #{run_options.join(' ')}" } + + {% if flag?(:win32) %} + # FIXME: Process.exec doesn't work as expected on Windows, we need to run + # as a child process and report the exit code afterwards. https://github.com/crystal-lang/crystal/issues/14422#issuecomment-3204803933 + status = Process.run(File.join(Shards.bin_path, target.name), args: run_options, input: Process::Redirect::Inherit, output: Process::Redirect::Inherit, error: Process::Redirect::Inherit) + exit status.exit_code + {% else %} + # FIXME: The explicit close is necessary to flush the last log message + # before `exec`. https://github.com/crystal-lang/crystal/issues/14422#issuecomment-3204803933 + ::Log.builder.close + + Process.exec(File.join(Shards.bin_path, target.name), args: run_options) + {% end %} end end end