From 5fbd4171d73c9d258882374e97c135563f22da69 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Tue, 15 Jul 2025 10:59:58 -0400 Subject: [PATCH] Add config option to CLI Fixes #478 --- lib/syntax_tree/cli.rb | 49 +++++++++++++++++++++++++++++++++++------- test/cli_test.rb | 46 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 85 insertions(+), 10 deletions(-) diff --git a/lib/syntax_tree/cli.rb b/lib/syntax_tree/cli.rb index 0baaef3d..e3bac8f1 100644 --- a/lib/syntax_tree/cli.rb +++ b/lib/syntax_tree/cli.rb @@ -455,17 +455,26 @@ def run(item) #{Color.bold("stree write [--plugins=...] [--print-width=NUMBER] [-e SCRIPT] FILE")} Read, format, and write back the source of the given files + --ignore-files=... + A glob pattern to ignore files when processing. This can be specified + multiple times to ignore multiple patterns. + --plugins=... A comma-separated list of plugins to load. - --print-width=NUMBER + --print-width=... The maximum line width to use when formatting. - -e SCRIPT + -e ... Parse an inline string. - --extension=EXTENSION - A file extension matching the content passed in via STDIN or -e. Defaults to 'rb' + --extension=... + A file extension matching the content passed in via STDIN or -e. + Defaults to '.rb'. + + --config=... + Path to a configuration file. Defaults to .streerc in the current + working directory. HELP # This represents all of the options that can be passed to the CLI. It is @@ -563,8 +572,16 @@ class ConfigFile attr_reader :filepath - def initialize - @filepath = File.join(Dir.pwd, FILENAME) + def initialize(filepath = nil) + if filepath + if File.readable?(filepath) + @filepath = filepath + else + raise ArgumentError, "Invalid configuration file: #{filepath}" + end + else + @filepath = File.join(Dir.pwd, FILENAME) + end end def exists? @@ -582,8 +599,24 @@ class << self def run(argv) name, *arguments = argv - config_file = ConfigFile.new - arguments.unshift(*config_file.arguments) + # First, we need to check if there's a --config option specified + # so we can use the custom config file path. + config_filepath = nil + arguments.each_with_index do |arg, index| + if arg.start_with?("--config=") + config_filepath = arg.split("=", 2)[1] + arguments.delete_at(index) + break + elsif arg == "--config" && arguments[index + 1] + config_filepath = arguments[index + 1] + arguments.delete_at(index + 1) + arguments.delete_at(index) + break + end + end + + config_file = ConfigFile.new(config_filepath) + arguments = config_file.arguments.concat(arguments) options = Options.new options.parse(arguments) diff --git a/test/cli_test.rb b/test/cli_test.rb index 200cd8d7..a0d6001d 100644 --- a/test/cli_test.rb +++ b/test/cli_test.rb @@ -308,6 +308,48 @@ def test_plugin_args_with_config_file end end + def test_config_file_custom_path + with_plugin_directory do |directory| + plugin = directory.plugin("puts 'Custom config!'") + config = <<~TXT + --print-width=80 + --plugins=#{plugin} + TXT + + filepath = File.join(Dir.tmpdir, "#{SecureRandom.hex}.streerc") + with_config_file(config, filepath) do + contents = "#{"a" * 30} + #{"b" * 30}\n" + result = run_cli("format", "--config=#{filepath}", contents: contents) + + assert_equal("Custom config!\n#{contents}", result.stdio) + end + end + end + + def test_config_file_custom_path_space_separated + with_plugin_directory do |directory| + plugin = directory.plugin("puts 'Custom config space!'") + config = <<~TXT + --print-width=80 + --plugins=#{plugin} + TXT + + filepath = File.join(Dir.tmpdir, "#{SecureRandom.hex}.streerc") + with_config_file(config, filepath) do + contents = "#{"a" * 30} + #{"b" * 30}\n" + result = run_cli("format", "--config", filepath, contents: contents) + + assert_equal("Custom config space!\n#{contents}", result.stdio) + end + end + end + + def test_config_file_nonexistent_path + assert_raises(ArgumentError) do + run_cli("format", "--config=/nonexistent/path.streerc") + end + end + Result = Struct.new(:status, :stdio, :stderr, keyword_init: true) private @@ -342,8 +384,8 @@ def run_cli(command, *args, contents: :default) tempfile.unlink end - def with_config_file(contents) - filepath = File.join(Dir.pwd, SyntaxTree::CLI::ConfigFile::FILENAME) + def with_config_file(contents, filepath = nil) + filepath ||= File.join(Dir.pwd, SyntaxTree::CLI::ConfigFile::FILENAME) File.write(filepath, contents) yield