diff --git a/spec/primitives/external_command_spec.cr b/spec/primitives/external_command_spec.cr new file mode 100644 index 000000000000..91687f7c2d21 --- /dev/null +++ b/spec/primitives/external_command_spec.cr @@ -0,0 +1,34 @@ +{% skip_file if flag?(:interpreted) %} + +require "../spec_helper" + +describe Crystal::Command do + it "exec external commands", tags: %w[slow] do + with_temp_executable "crystal-external" do |path| + with_tempfile "crystal-external.cr" do |source_file| + File.write source_file, <<-CRYSTAL + puts ENV["CRYSTAL"]? + puts PROGRAM_NAME + puts ARGV + CRYSTAL + + Process.run(ENV["CRYSTAL_SPEC_COMPILER_BIN"]? || "bin/crystal", ["build", source_file, "-o", path]) + end + + File.exists?(path).should be_true + + process = Process.new(ENV["CRYSTAL_SPEC_COMPILER_BIN"]? || "bin/crystal", + ["external", "foo", "bar"], + output: :pipe, + env: {"PATH" => {ENV["PATH"], File.dirname(path)}.join(Process::PATH_DELIMITER)} + ) + output = process.output.gets_to_end + status = process.wait + status.success?.should be_true + lines = output.lines + lines[0].should match /crystal/ + lines[1].should match /crystal-external/ + lines[2].should eq %(["foo", "bar"]) + end + end +end diff --git a/src/compiler/crystal/command.cr b/src/compiler/crystal/command.cr index f8ece87e3d4b..1354594706fb 100644 --- a/src/compiler/crystal/command.cr +++ b/src/compiler/crystal/command.cr @@ -130,6 +130,9 @@ class Crystal::Command else if command.ends_with?(".cr") error "file '#{command}' does not exist" + elsif external_command = Process.find_executable("crystal-#{command}") + options.shift + Process.exec(external_command, options, env: {"CRYSTAL" => Process.executable_path}) else error "unknown command: #{command}" end