Skip to content

Commit

Permalink
Merge pull request #52 from lxxxvi/add-output-flag
Browse files Browse the repository at this point in the history
basics for `--output`
  • Loading branch information
lxxxvi authored Oct 25, 2024
2 parents 3d25a94 + f7ef7de commit d1f35ad
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 16 deletions.
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,14 @@ ruboclean [path] [--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. |
| `--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. |
| 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. |

### Examples

Expand Down
41 changes: 35 additions & 6 deletions lib/ruboclean/cli_arguments.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
module Ruboclean
# Reads command line arguments and exposes corresponding reader methods
class CliArguments
FLAG_DEFAULTS = {
"--output" => nil,
"--silent" => false,
"--preserve-comments" => false,
"--preserve-paths" => false,
"--verify" => false
}.freeze

def initialize(command_line_arguments = [])
@command_line_arguments = Array(command_line_arguments)
end
Expand All @@ -11,24 +19,28 @@ def path
@path ||= find_path
end

def output_path
flag_arguments.fetch("--output")
end

def verbose?
!silent?
end

def silent?
@silent ||= find_argument("--silent")
flag_arguments.fetch("--silent")
end

def preserve_comments?
@preserve_comments ||= find_argument("--preserve-comments")
flag_arguments.fetch("--preserve-comments")
end

def preserve_paths?
@preserve_paths ||= find_argument("--preserve-paths")
flag_arguments.fetch("--preserve-paths")
end

def verify?
@verify ||= find_argument("--verify")
flag_arguments.fetch("--verify")
end

private
Expand All @@ -43,8 +55,25 @@ def find_path
end
end

def find_argument(name)
command_line_arguments.any? { |argument| argument == name }
def flag_arguments
@flag_arguments ||= FLAG_DEFAULTS.dup.merge(custom_flag_arguments)
end

def custom_flag_arguments
command_line_arguments.each_with_object({}) do |item, hash|
next unless item.start_with?("--")

flag_name, flag_value = item.split("=")

raise ArgumentError, "invalid argument '#{item}'" unless FLAG_DEFAULTS.include?(flag_name)

flag_default_value = FLAG_DEFAULTS[flag_name]

hash[flag_name] = flag_value

# Subject to change: We may need to find another way to determine if an argument has Boolean characteristics
hash[flag_name] = !flag_value if flag_default_value.is_a?(FalseClass)
end
end
end
end
17 changes: 16 additions & 1 deletion lib/ruboclean/runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,18 @@ def convert_to_yaml(configuration_hash)

def write_file!(target_yaml)
target_yaml.tap do |content|
source_file_pathname.write(content) unless verify?
target_file_pathname.write(content) unless verify?
end
end

def source_file_pathname
@source_file_pathname ||= find_source_file_pathname
end

def target_file_pathname
@target_file_pathname ||= find_target_file_pathname
end

def find_source_file_pathname
source_path = Pathname.new(cli_arguments.path)

Expand All @@ -81,5 +85,16 @@ def find_source_file_pathname

raise ArgumentError, "path does not exist: '#{source_path}'"
end

def find_target_file_pathname
return source_file_pathname if cli_arguments.output_path.nil?

target_path = Pathname.new(cli_arguments.output_path)
target_path = Pathname.new(Dir.pwd).join(target_path) if target_path.relative?

return target_path unless target_path.directory?

raise ArgumentError, "output path (--output=#{target_path}) cannot be a directory"
end
end
end
11 changes: 10 additions & 1 deletion test/ruboclean/cli_arguments_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

module Ruboclean
class ArgumentsTest < BaseTest
def test_path_defaults
def test_path_defaults # rubocop:disable Minitest/MultipleAssertions
Ruboclean::CliArguments.new.tap do |cli_arguments|
assert_equal Dir.pwd.to_s, cli_arguments.path
assert_nil cli_arguments.output_path
assert_predicate cli_arguments, :verbose?
refute_predicate cli_arguments, :silent?
refute_predicate cli_arguments, :preserve_comments?
refute_predicate cli_arguments, :preserve_paths?
refute_predicate cli_arguments, :verify?
end
end
Expand All @@ -18,6 +20,13 @@ def test_path_custom
assert_equal "foo/bar.yml", Ruboclean::CliArguments.new(["foo/bar.yml"]).path
end

def test_output_path_custom
Ruboclean::CliArguments.new(["--output=/foo/bar"]).tap do |cli_arguments|
assert_equal Dir.pwd.to_s, cli_arguments.path
assert_equal "/foo/bar", cli_arguments.output_path
end
end

def test_silent_custom
Ruboclean::CliArguments.new(["--silent"]).tap do |cli_arguments|
assert_equal Dir.pwd.to_s, cli_arguments.path
Expand Down
68 changes: 67 additions & 1 deletion test/ruboclean/runner_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
require "test_helper"

module Ruboclean
class RunnerTest < BaseTest
class RunnerTest < BaseTest # rubocop:disable Metrics/ClassLength
def test_run_without_arguments
using_fixture_files("00_input.yml") do |fixture_path, directory_path|
changed = Dir.chdir(directory_path) do
Expand Down Expand Up @@ -88,6 +88,72 @@ def test_run_without_require_block
end
end

def test_run_with_output_argument_absolute_path
using_fixture_files("00_input.yml") do |fixture_path|
output_pathname = Pathname.new(fixture_path).dirname.join("custom_output_path.yml")
arguments = [fixture_path, "--output=#{output_pathname}"]
Ruboclean::Runner.new(arguments).run!

assert_predicate output_pathname, :exist?

assert_equal(
fixture_file_path("00_expected_output.yml").read,
output_pathname.read
)
end
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
expected_target_file_content = fixture_file_path("00_expected_output.yml").read

using_fixture_files("00_input.yml") do |fixture_path|
Dir.mktmpdir do |tmpdir|
Dir.chdir(tmpdir) do
arguments = [fixture_path, "--output=relative_path.yml"]

Ruboclean::Runner.new(arguments).run!

output_pathname = Pathname.new(tmpdir).join("relative_path.yml")

assert_predicate output_pathname, :exist?
assert_equal expected_target_file_content,
output_pathname.read
end
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")
arguments = [fixture_path, "--output=#{output_pathname}"]
output_pathname.write("file content before")

Ruboclean::Runner.new(arguments).run!

assert_equal(
fixture_file_path("00_expected_output.yml").read,
output_pathname.read
)
end
end

def test_run_with_output_argument_raises_if_target_exists_as_directory
using_fixture_files("00_input.yml") do |fixture_path|
output_pathname = Pathname.new(fixture_path).dirname.join("some_directory")
arguments = [fixture_path, "--output=#{output_pathname}"]
output_pathname.mkdir

error = assert_raises ArgumentError do
Ruboclean::Runner.new(arguments).run!
end

assert_equal "output path (--output=#{output_pathname}) cannot be a directory",
error.message
end
end

def test_run_with_preserve_comments_flag
using_fixture_files("00_input.yml") do |fixture_path|
arguments = [fixture_path, "--preserve-comments"]
Expand Down

0 comments on commit d1f35ad

Please sign in to comment.