diff --git a/scripts/fast-format b/scripts/fast-format index 6d5973fba..9d1a04735 100755 --- a/scripts/fast-format +++ b/scripts/fast-format @@ -6,13 +6,18 @@ echo "Script started with $# arguments" echo "Arguments: $*" echo "Script location: $(dirname "$0")" -cd -- "$(dirname "$0")/.." -echo "Changed to directory: $PWD" - if [ $# -eq 0 ]; then echo "Usage: $0 [additional-formatter-args...]" echo "The file should contain one file path per line" exit 1 fi -exec -- bundle exec rake format FORMAT_FILE="$1" +path_list="$1" +if [[ "$path_list" != /* ]]; then + path_list="$PWD/$path_list" +fi + +cd -- "$(dirname "$0")/.." +echo "Changed to directory: $PWD" + +exec -- bundle exec rake format FORMAT_FILE="$path_list" "${@:2}" diff --git a/test/scripts/fast_format_test.rb b/test/scripts/fast_format_test.rb new file mode 100644 index 000000000..1319f1a7b --- /dev/null +++ b/test/scripts/fast_format_test.rb @@ -0,0 +1,79 @@ +# frozen_string_literal: true + +require "minitest/autorun" +require "fileutils" +require "json" +require "open3" +require "rbconfig" +require "tmpdir" + +class FastFormatTest < Minitest::Test + ROOT = File.expand_path("../..", __dir__) + FAST_FORMAT = File.join(ROOT, "scripts/fast-format") + + def test_resolves_relative_path_list_from_callers_directory + with_bundle_probe do |directory, executable_path| + path_list = "paths.txt" + File.write(File.join(directory, path_list), "example.rb\n") + + invocation = invoke_fast_format(executable_path, directory, path_list) + + assert_equal(ROOT, invocation.fetch("directory")) + assert_equal( + ["exec", "rake", "format", "FORMAT_FILE=#{File.join(directory, path_list)}"], + invocation.fetch("arguments") + ) + end + end + + def test_forwards_all_arguments_after_path_list + with_bundle_probe do |directory, executable_path| + path_list = File.join(directory, "paths.txt") + File.write(path_list, "example.rb\n") + additional_arguments = ["--trace", "FORMATTER_OPTION=value with spaces"] + + invocation = invoke_fast_format( + executable_path, + directory, + path_list, + *additional_arguments + ) + + assert_equal( + ["exec", "rake", "format", "FORMAT_FILE=#{path_list}", *additional_arguments], + invocation.fetch("arguments") + ) + end + end + + private + + def invoke_fast_format(executable_path, directory, *arguments) + env = {"PATH" => [executable_path, ENV.fetch("PATH")].join(File::PATH_SEPARATOR)} + stdout, stderr, status = Open3.capture3(env, FAST_FORMAT, *arguments, chdir: directory) + + assert(status.success?, stderr) + JSON.parse(stdout.lines.last) + end + + def with_bundle_probe + Dir.mktmpdir do |temporary_directory| + directory = File.join(temporary_directory, "caller") + executable_path = File.join(temporary_directory, "bin") + FileUtils.mkdir_p([directory, executable_path]) + bundle = File.join(executable_path, "bundle") + File.write( + bundle, + <<~RUBY + #!#{RbConfig.ruby} + require "json" + + puts JSON.generate("arguments" => ARGV, "directory" => Dir.pwd) + RUBY + ) + FileUtils.chmod(0o755, bundle) + + yield directory, executable_path + end + end +end