From 5d6fbc2d83a000e3e22201ad8d1c8945a31fce6c Mon Sep 17 00:00:00 2001 From: mario Date: Fri, 25 Oct 2024 14:30:08 +0100 Subject: [PATCH 1/2] allow output to STDOUT --- lib/ruboclean.rb | 1 + lib/ruboclean/runner.rb | 8 +++++--- lib/ruboclean/stream_writer.rb | 27 +++++++++++++++++++++++++++ test/ruboclean/runner_test.rb | 12 +++++++++++- test/ruboclean/stream_writer_test.rb | 24 ++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 lib/ruboclean/stream_writer.rb create mode 100644 test/ruboclean/stream_writer_test.rb diff --git a/lib/ruboclean.rb b/lib/ruboclean.rb index 6391a3a..c489e80 100644 --- a/lib/ruboclean.rb +++ b/lib/ruboclean.rb @@ -6,6 +6,7 @@ require "ruboclean/grouper" require "ruboclean/path_cleanup" require "ruboclean/runner" +require "ruboclean/stream_writer" require "ruboclean/to_yaml_converter" require "ruboclean/version" diff --git a/lib/ruboclean/runner.rb b/lib/ruboclean/runner.rb index 8b603b8..42d381d 100644 --- a/lib/ruboclean/runner.rb +++ b/lib/ruboclean/runner.rb @@ -16,7 +16,7 @@ def run! load_file.then(&method(:order)) .then(&method(:cleanup_paths)) .then(&method(:convert_to_yaml)) - .then(&method(:write_file!)) + .then(&method(:write_stream!)) .then(&method(:changed?)) end @@ -62,12 +62,14 @@ def convert_to_yaml(configuration_hash) ToYamlConverter.new(configuration_hash, cli_arguments.preserve_comments?, source_yaml).to_yaml end - def write_file!(target_yaml) + def write_stream!(target_yaml) target_yaml.tap do |content| - target_file_pathname.write(content) unless verify? + StreamWriter.new(target_file_pathname, content).write! unless verify? end end + # TODO: Find a better place to compute source_file_pathname and target_file_pathname + # Preferrably it should happen early in the lifecycle, as it includes (and raises) argument validations def source_file_pathname @source_file_pathname ||= find_source_file_pathname end diff --git a/lib/ruboclean/stream_writer.rb b/lib/ruboclean/stream_writer.rb new file mode 100644 index 0000000..3f4ec71 --- /dev/null +++ b/lib/ruboclean/stream_writer.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Ruboclean + # Orders the items within the groups alphabetically + class StreamWriter + def initialize(target_file_pathname, content) + @target_file_pathname = target_file_pathname + @content = content + end + + def write! + if stdout? + puts content + else + target_file_pathname.write(content) + end + end + + private + + attr_reader :target_file_pathname, :content + + def stdout? + target_file_pathname.basename.to_s == "STDOUT" + end + end +end diff --git a/test/ruboclean/runner_test.rb b/test/ruboclean/runner_test.rb index d61a425..cbaf036 100644 --- a/test/ruboclean/runner_test.rb +++ b/test/ruboclean/runner_test.rb @@ -104,7 +104,7 @@ def test_run_with_output_argument_absolute_path end def test_run_with_output_argument_relative_path # rubocop:disable Metrics/MethodLength - # we need to read it here, because we're leaving the working directory soon + # we need to read it here, because we're leaving the working directory (see `Dir.chdir` below) expected_target_file_content = fixture_file_path("00_expected_output.yml").read using_fixture_files("00_input.yml") do |fixture_path| @@ -124,6 +124,16 @@ def test_run_with_output_argument_relative_path # rubocop:disable Metrics/Method end end + def test_run_with_output_argument_stdout + using_fixture_files("00_input.yml") do |fixture_path| + arguments = [fixture_path, "--output=STDOUT"] + + assert_output(fixture_file_path("00_expected_output.yml").read) do + Ruboclean::Runner.new(arguments).run! + end + end + end + def test_run_with_output_argument_overrides_a_file using_fixture_files("00_input.yml") do |fixture_path| output_pathname = Pathname.new(fixture_path).dirname.join("custom_output_path.yml") diff --git a/test/ruboclean/stream_writer_test.rb b/test/ruboclean/stream_writer_test.rb new file mode 100644 index 0000000..2371110 --- /dev/null +++ b/test/ruboclean/stream_writer_test.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require "test_helper" + +module Ruboclean + class StreamWriterTest < BaseTest + def test_writes_to_path + Tempfile.create do |tmpfile| + target_file_pathname = Pathname.new(tmpfile) + Ruboclean::StreamWriter.new(target_file_pathname, "magnificent file output").write! + + assert_equal "magnificent file output", target_file_pathname.read + end + end + + def test_writes_to_stdout + target_file_pathname = Pathname.new("STDOUT") + + assert_output("magnificent STDOUT output\n") do + Ruboclean::StreamWriter.new(target_file_pathname, "magnificent STDOUT output").write! + end + end + end +end From 9c8845baeaba2e55642080285ea1d6e9f2e538f4 Mon Sep 17 00:00:00 2001 From: mario Date: Fri, 25 Oct 2024 14:30:37 +0100 Subject: [PATCH 2/2] revisit README, particularly Parameters section --- README.md | 59 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 8c605ee..6d0a48d 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Finally it orders the configurations **alphabetically** within these groups. -## Example +## Main example ### Input `.rubocop.yml`: @@ -84,21 +84,22 @@ gem install ruboclean ## Command synopsis ```shell -ruboclean [path] [--silent] [--preserve-comments] [--preserve-paths] [--verify] +ruboclean [path] \ + [--output=/path/to/file.yml] \ + [--silent] \ + [--preserve-comments] \ + [--preserve-paths] \ + [--verify] ``` ### Parameters -| Parameter | Description | -|:---------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------| -| `path` | Can be a directory that contains a `.rubocop.yml`, or a path to a `.rubocop.yml` directly. Defaults to the current working directory. | -| `--output=[/path/to/output.yml]` | Output path, where the result is written to. Can be either absolute or relative of the current working directory | -| `--silent` | Suppress any output displayed on the screen when executing the command. | -| `--preserve-comments` | Preserves **preceding** comments for each top-level entry in the configuration. Inline comments are **not** preserved. | -| `--preserve-paths` | Skips the path cleanup that are applied against `Include:` and `Exclude:` configuration. | -| `--verify` | Executes in dry-run mode. Exits with 1 if changes are needed, otherwise 0. | +#### `path` -### Examples +Can be a directory that contains a `.rubocop.yml`, or a path to a `.rubocop.yml` directly. +Defaults to the current working directory. + +##### Examples ```shell ruboclean # uses `.rubocop.yml` of current working directory @@ -106,6 +107,42 @@ ruboclean /path/to/dir # uses `.rubocop.yml` of /path/to/dir ruboclean /path/to/dir/.rubocop.yml ``` +#### `--output=/path/to/file.yml` + +Output path where the result is written to. +Can be absolute or relative to the current working directory. +`--output=STDOUT` prints it to STDOUT and not to a file. + +##### Examples + +```shell +ruboclean --output=/absolute/path.yml +ruboclean --output=relative/path.yml # relative to current working directory +ruboclean --output=STDOUT # does not write anything to a file +``` + +#### `--silent` + +Suppress any log output displayed on the screen when executing the command. +It still prints to STDOUT if used in combination with `--output=STDOUT`. + +#### `--preserve-comments` + +Preserves **preceding** comments for each top-level entry in the configuration. +Inline comments are **not** preserved. + +See main example above for explanation. + +#### `--preserve-paths` + +Skips the path cleanup that are applied against `Include:` and `Exclude:` configurations. + +See main example above for explanation. + +#### `--verify` + +Executes in dry-run mode. Exits with `1` if changes are needed, otherwise `0`. + ## Development After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.