From 36968dc5a6783749444a44d43a893e1023233a2c Mon Sep 17 00:00:00 2001 From: Jeremy Woertink Date: Sun, 6 Oct 2024 15:38:58 -0700 Subject: [PATCH] Can now run crystal scripts as uncompiled lucky tasks --- Earthfile | 1 + fixtures/hello_crystal.cr | 1 + spec/integration/lucky_cli_spec.cr | 29 +++++++++++++++++++--------- src/lucky.cr | 31 ++++++++++++++++++++++-------- 4 files changed, 45 insertions(+), 17 deletions(-) create mode 100644 fixtures/hello_crystal.cr diff --git a/Earthfile b/Earthfile index af536c8f..4570d072 100644 --- a/Earthfile +++ b/Earthfile @@ -58,6 +58,7 @@ integration-specs: FROM +base-image COPY +build-lucky/lucky /usr/bin/lucky COPY fixtures/hello_world.cr fixtures/ + COPY fixtures/hello_crystal.cr bin/lucky.hello_crystal.cr COPY fixtures/tasks.cr fixtures/ RUN shards build lucky.hello_world --without-development RUN crystal spec --tag integration diff --git a/fixtures/hello_crystal.cr b/fixtures/hello_crystal.cr new file mode 100644 index 00000000..58d66257 --- /dev/null +++ b/fixtures/hello_crystal.cr @@ -0,0 +1 @@ +puts "Hello, Crystal!" diff --git a/spec/integration/lucky_cli_spec.cr b/spec/integration/lucky_cli_spec.cr index 5efd77b7..a85dd5ad 100644 --- a/spec/integration/lucky_cli_spec.cr +++ b/spec/integration/lucky_cli_spec.cr @@ -9,10 +9,21 @@ describe "Lucky CLI", tags: "integration" do shell: true, output: io ) - status.exit_status.should eq(0) + status.exit_code.should eq(0) io.to_s.should eq("Hello World!\n") end + it "runs non-compiled tasks" do + io = IO::Memory.new + status = run_lucky( + args: %w[hello_crystal], + shell: true, + output: io + ) + status.exit_code.should eq(0) + io.to_s.should eq("Hello, Crystal!\n") + end + it "allows tasks to accept input from STDIN" do io = IO::Memory.new run_lucky( @@ -32,7 +43,7 @@ describe "Lucky CLI", tags: "integration" do it "returns the lucky CLI help message when passing the -h flag" do io = IO::Memory.new status = run_lucky(args: %w[-h], shell: true, output: io) - status.exit_status.should eq(0) + status.exit_code.should eq(0) io.to_s.should contain("Usage: lucky [command]") end @@ -47,7 +58,7 @@ describe "Lucky CLI", tags: "integration" do "LUCKY_TASKS_FILE" => fixtures_tasks_path.to_s, } ) - status.exit_status.should eq(0) + status.exit_code.should eq(0) io.to_s.should contain("Usage: lucky tasks") end @@ -61,7 +72,7 @@ describe "Lucky CLI", tags: "integration" do "LUCKY_TASKS_FILE" => fixtures_tasks_path.to_s, } ) - status.exit_status.should eq(0) + status.exit_code.should eq(0) io.to_s.should contain("Usage: lucky dev") end end @@ -78,7 +89,7 @@ describe "Lucky CLI", tags: "integration" do "LUCKY_TASKS_FILE" => fixtures_tasks_path.to_s, } ) - status.exit_status.should eq(0) + status.exit_code.should eq(0) io.to_s.should contain("Custom help message") end end @@ -99,7 +110,7 @@ describe "Lucky CLI", tags: "integration" do args: %w[init.custom test-project --dir my-project], shell: true, ) - status.exit_status.should eq(0) + status.exit_code.should eq(0) Dir.cd("my-project/test-project") do File.read("src/shards.cr").should contain("lucky") end @@ -113,7 +124,7 @@ describe "Lucky CLI", tags: "integration" do shell: true, output: io ) - status.exit_status.should eq(0) + status.exit_code.should eq(0) io.to_s.should contain("Folder named test-project already exists, please use a different name") end @@ -124,7 +135,7 @@ describe "Lucky CLI", tags: "integration" do shell: true, output: io ) - status.exit_status.should_not eq(0) + status.exit_code.should_not eq(0) io.to_s.should contain("Project name should only contain lowercase letters, numbers, underscores, and dashes.") end @@ -135,7 +146,7 @@ describe "Lucky CLI", tags: "integration" do shell: true, output: io ) - status.exit_status.should_not eq(0) + status.exit_code.should_not eq(0) io.to_s.should contain("Projects cannot be named app, app_database, app_server, shards, start_server.") end end diff --git a/src/lucky.cr b/src/lucky.cr index c2876b72..413917c4 100755 --- a/src/lucky.cr +++ b/src/lucky.cr @@ -10,24 +10,29 @@ require "./build_and_run_task" include LuckyTask::TextHelpers args = ARGV.join(" ") -tasks_file = ENV.fetch("LUCKY_TASKS_FILE", "./tasks.cr") +tasks_file = ENV.fetch("LUCKY_TASKS_FILE", Path["./tasks.cr"].to_s) inside_app_directory = File.file?(tasks_file) private def task_name : String? ARGV.first? end -private def task_precompiled? : Bool - path = precompiled_task_path - !path.nil? && File.file?(path) +private def task_compiled? : Bool + path = task_path + !path.nil? && {% if compare_versions(Crystal::VERSION, "1.13.0") >= 0 %}File::Info.executable?(path){% else %}File.executable?(path){% end %} end -private def precompiled_task_path : String? +private def task_path(ext : String = "") : Path? task_name.try do |name| - "bin/lucky.#{name}" + Path.new("bin", "lucky.#{name}#{ext}") end end +private def task_not_compiled? : Bool + path = task_path(".cr") + !path.nil? && File.file?(path) +end + private def built_in_commands : Array(String) ["dev", "tasks", "init", "init.custom"] end @@ -148,15 +153,25 @@ elsif start_wizard LuckyCli::Init.run elsif generate_custom_app # already running -elsif task_precompiled? +elsif task_compiled? exit Process.run( - precompiled_task_path.to_s, + task_path.to_s, ARGV.skip(1), shell: true, input: STDIN, output: STDOUT, error: STDERR ).exit_code +elsif task_not_compiled? + crystal_command = {% if flag?(:windows) %}"crystal.exe"{% else %}"crystal"{% end %} + exit Process.run( + crystal_command, + [task_path(".cr").to_s] + ARGV.skip(1), + shell: true, + input: STDIN, + output: STDOUT, + error: STDERR + ).exit_code elsif inside_app_directory # Run task from tasks.cr file since this task is not precompiled LuckyCli::BuildAndRunTask.call(tasks_file, args)