Skip to content

Commit 1ae4ec6

Browse files
authored
Remove ARGV use during runtime (#65)
This PR removes `ARGV` from being used implicitly during runtime. Before this change, ARGV would be used and modified in `Parser#parse` which made it hard to reason about how `ModelFilesGetter#list_model_files_from_argument` works. `ARGV` is still used at the time of execution but gets cloned in `Parser#new`.
1 parent b3cd190 commit 1ae4ec6

File tree

6 files changed

+30
-40
lines changed

6 files changed

+30
-40
lines changed

lib/annotate_rb/model_annotator/model_files_getter.rb

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,9 @@ class << self
99
# of model files from root dir. Otherwise we take all the model files
1010
# in the model_dir directory.
1111
def call(options)
12-
model_files = []
12+
model_files = list_model_files_from_argument(options)
1313

14-
# Note: This is currently broken as we don't set `is_rake` anywhere.
15-
# It's an artifact from the old Annotate gem and how it did control flow.
16-
model_files = list_model_files_from_argument(options) if !options[:is_rake]
17-
18-
return model_files if !model_files.empty?
14+
return model_files if model_files.any?
1915

2016
options[:model_dir].each do |dir|
2117
Dir.chdir(dir) do
@@ -41,9 +37,9 @@ def call(options)
4137
private
4238

4339
def list_model_files_from_argument(options)
44-
return [] if ARGV.empty?
40+
return [] if options.get_state(:working_args).empty?
4541

46-
specified_files = ARGV.map { |file| File.expand_path(file) }
42+
specified_files = options.get_state(:working_args).map { |file| File.expand_path(file) }
4743

4844
model_files = options[:model_dir].flat_map do |dir|
4945
absolute_dir_path = File.expand_path(dir)

lib/annotate_rb/options.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,5 +210,9 @@ def set_state(key, value, overwrite = false)
210210
def get_state(key)
211211
@state[key]
212212
end
213+
214+
def print
215+
# TODO: prints options and state
216+
end
213217
end
214218
end

lib/annotate_rb/parser.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ def self.parse(args, existing_options = {})
3535
}.freeze
3636

3737
def initialize(args, existing_options)
38-
@args = args
38+
@args = args.clone
3939
base_options = DEFAULT_OPTIONS.dup
4040
@options = base_options.merge(existing_options)
4141
@commands = []
42-
@options[:original_args] = args.dup
42+
@options[:original_args] = args.clone
4343
end
4444

4545
def parse
@@ -52,6 +52,12 @@ def parse
5252
@options
5353
end
5454

55+
def remaining_args
56+
# `@args` gets modified throughout the lifecycle of this class.
57+
# It starts as a shallow clone of ARGV, then arguments matching commands and options are removed in #parse
58+
@args
59+
end
60+
5561
private
5662

5763
def parse_command(args)

lib/annotate_rb/runner.rb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@ def run(args)
99
end
1010

1111
def run(args)
12-
_original_args = args.dup
13-
1412
config_file_options = ConfigLoader.load_config
15-
parsed_options = Parser.parse(args)
13+
parser = Parser.new(args, {})
14+
15+
parsed_options = parser.parse
16+
remaining_args = parser.remaining_args
1617

1718
options = config_file_options.merge(parsed_options)
1819

19-
@options = Options.from(options, {})
20+
@options = Options.from(options, {working_args: remaining_args})
2021
AnnotateRb::RakeBootstrapper.call(@options)
2122

2223
if @options[:command]

spec/lib/annotate_rb/annotate_models/annotate_models_annotating_a_file_spec.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class User < ActiveRecord::Base
5454
end
5555

5656
it "displays just the error message with trace disabled (default)" do
57-
options = AnnotateRb::Options.from({model_dir: @model_dir, is_rake: true})
57+
options = AnnotateRb::Options.from({model_dir: @model_dir}, {working_args: []})
5858

5959
expect { described_class.do_annotations(options) }.to output(a_string_including("Unable to process #{@model_dir}/user.rb: oops")).to_stderr
6060

@@ -63,7 +63,7 @@ class User < ActiveRecord::Base
6363
end
6464

6565
it "displays the error message and stacktrace with trace enabled" do
66-
options = AnnotateRb::Options.from({model_dir: @model_dir, is_rake: true, trace: true})
66+
options = AnnotateRb::Options.from({model_dir: @model_dir, trace: true}, {working_args: []})
6767
expect { described_class.do_annotations(options) }.to output(a_string_including("Unable to process #{@model_dir}/user.rb: oops")).to_stderr
6868

6969
# TODO: Find another way of testing trace without hardcoding the file name as part of the spec
@@ -83,14 +83,14 @@ class User < ActiveRecord::Base
8383
end
8484

8585
it "displays just the error message with trace disabled (default)" do
86-
options = AnnotateRb::Options.from({model_dir: @model_dir, is_rake: true})
86+
options = AnnotateRb::Options.from({model_dir: @model_dir}, {working_args: []})
8787

8888
expect { described_class.remove_annotations(options) }.to output(a_string_including("Unable to process #{@model_dir}/user.rb: oops")).to_stderr
8989
expect { described_class.remove_annotations(options) }.not_to output(a_string_including("/user.rb:2:in `<class:User>'")).to_stderr
9090
end
9191

9292
it "displays the error message and stacktrace with trace enabled" do
93-
options = AnnotateRb::Options.from({model_dir: @model_dir, is_rake: true, trace: true})
93+
options = AnnotateRb::Options.from({model_dir: @model_dir, trace: true}, {working_args: []})
9494

9595
expect { described_class.remove_annotations(options) }.to output(a_string_including("Unable to process #{@model_dir}/user.rb: oops")).to_stderr
9696
expect { described_class.remove_annotations(options) }.to output(a_string_including("/user.rb:2:in `<class:User>'")).to_stderr

spec/lib/annotate_rb/model_annotator/model_files_getter_spec.rb

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
before do
66
$stdout = StringIO.new
77
$stderr = StringIO.new
8-
9-
ARGV.clear
108
end
119

1210
after do
@@ -30,7 +28,7 @@
3028
context "when the model files are not specified" do
3129
context "when no option is specified" do
3230
let(:base_options) { {model_dir: [model_dir]} }
33-
let(:options) { AnnotateRb::Options.new(base_options) }
31+
let(:options) { AnnotateRb::Options.new(base_options, {working_args: []}) }
3432

3533
it "returns all model files under `model_dir` directory" do
3634
is_expected.to contain_exactly(
@@ -43,7 +41,7 @@
4341

4442
context "when `ignore_model_sub_dir` option is enabled" do
4543
let(:base_options) { {model_dir: [model_dir], ignore_model_sub_dir: true} }
46-
let(:options) { AnnotateRb::Options.new(base_options) }
44+
let(:options) { AnnotateRb::Options.new(base_options, {working_args: []}) }
4745

4846
it "returns model files just below `model_dir` directory" do
4947
is_expected.to contain_exactly([model_dir, "foo.rb"])
@@ -60,11 +58,9 @@
6058
]
6159
end
6260

63-
before { ARGV.concat(model_files) }
64-
6561
context "when no option is specified" do
6662
let(:base_options) { {model_dir: [model_dir, additional_model_dir]} }
67-
let(:options) { AnnotateRb::Options.new(base_options) }
63+
let(:options) { AnnotateRb::Options.new(base_options, {working_args: model_files}) }
6864

6965
context "when all the specified files are in `model_dir` directory" do
7066
it "returns specified files" do
@@ -77,34 +73,21 @@
7773

7874
context "when a model file outside `model_dir` directory is specified" do
7975
let(:base_options) { {model_dir: [model_dir]} }
80-
let(:options) { AnnotateRb::Options.new(base_options) }
76+
let(:options) { AnnotateRb::Options.new(base_options, {working_args: model_files}) }
8177

8278
it "writes to $stderr" do
8379
subject
8480
expect($stderr.string).to include("The specified file could not be found in directory")
8581
end
8682
end
8783
end
88-
89-
context "when `is_rake` option is enabled" do
90-
let(:base_options) { {model_dir: [model_dir], is_rake: true} }
91-
let(:options) { AnnotateRb::Options.new(base_options) }
92-
93-
it "returns all model files under `model_dir` directory" do
94-
is_expected.to contain_exactly(
95-
[model_dir, "foo.rb"],
96-
[model_dir, File.join("bar", "baz.rb")],
97-
[model_dir, File.join("bar", "qux", "quux.rb")]
98-
)
99-
end
100-
end
10184
end
10285
end
10386

10487
context "when `model_dir` is invalid" do
10588
let(:model_dir) { "/not_exist_path" }
10689
let(:base_options) { {model_dir: [model_dir]} }
107-
let(:options) { AnnotateRb::Options.new(base_options) }
90+
let(:options) { AnnotateRb::Options.new(base_options, {working_args: []}) }
10891

10992
it "writes to $stderr" do
11093
subject

0 commit comments

Comments
 (0)