factory_sloth 1.2.1 β 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +28 -16
- data/lib/factory_sloth/cli.rb +12 -8
- data/lib/factory_sloth/code_mod.rb +100 -70
- data/lib/factory_sloth/color.rb +21 -0
- data/lib/factory_sloth/create_call.rb +1 -1
- data/lib/factory_sloth/done_tracker.rb +2 -0
- data/lib/factory_sloth/execution_check.rb +39 -0
- data/lib/factory_sloth/file_processor.rb +9 -25
- data/lib/factory_sloth/spec_runner.rb +21 -6
- data/lib/factory_sloth/version.rb +1 -1
- data/lib/factory_sloth.rb +5 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9032b54abec61f25adcfd938a503f312017667f64b4aa1f303ede50a346a62be
|
4
|
+
data.tar.gz: 901d358d3572a708ec8190c2d2e59dbdab3bce42f894301284dc285895d48f19
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1aa29c8c7dd007c5e82ee4cfbc164df1550ace4c2d7880e0471b4a892a2dad33a8e03469c56ec5620f99e7c2dc8c6c47f0d7256102910385acea9a3f97f4b74
|
7
|
+
data.tar.gz: bace623884d7e447200af29fb216f8814f86a7bae4deda093105bb9df716c8151332136a473c31cd6c9e51bc07ded9f2306e9eda29b536b7b4aa130384f0059a
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.3.0] - 2023-05-22
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- nicer output
|
8
|
+
- verbose mode
|
9
|
+
|
10
|
+
## [1.2.2] - 2023-05-18
|
11
|
+
|
12
|
+
### Fixed
|
13
|
+
|
14
|
+
- No longer changes create to build for records that are persisted later
|
15
|
+
- Fixed duplicate entries in `.factory_sloth_done` file
|
16
|
+
|
3
17
|
## [1.2.1] - 2023-05-17
|
4
18
|
|
5
19
|
### Fixed
|
data/README.md
CHANGED
@@ -27,6 +27,7 @@ Examples:
|
|
27
27
|
Options:
|
28
28
|
-f, --force Ignore ./.factory_sloth_done
|
29
29
|
-l, --lint Dont fix, just list bad create calls
|
30
|
+
-V, --verbose Verbose output, useful for debugging
|
30
31
|
-v, --version Show gem version
|
31
32
|
-h, --help Show this help
|
32
33
|
```
|
@@ -36,20 +37,25 @@ Options:
|
|
36
37
|
While running, `factory_sloth` produces output like this:
|
37
38
|
|
38
39
|
```
|
39
|
-
|
40
|
-
π‘ 2 create calls found, 0 replaced
|
40
|
+
π‘ spec/features/sign_up_spec.rb: 2 create calls found, 0 replaced
|
41
41
|
|
42
|
-
|
43
|
-
βͺοΈ 0 create calls found, 0 replaced
|
42
|
+
βͺοΈ spec/lib/string_ext_spec.rb: 0 create calls found, 0 replaced
|
44
43
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
π’ 3 create calls found, 2 replaced
|
44
|
+
spec/models/user_spec.rb:3:2: create replaced with build
|
45
|
+
expect(create(:user)).not_to be_nil
|
46
|
+
^^^^^^
|
49
47
|
|
50
|
-
|
51
|
-
|
52
|
-
|
48
|
+
spec/models/user_spec.rb:4:2: create_list replaced with build_list
|
49
|
+
expect(create_list(:user, 2).count).to eq 2
|
50
|
+
^^^^^^^^^^^
|
51
|
+
|
52
|
+
π’ spec/models/user_spec.rb: 3 create calls found, 2 replaced
|
53
|
+
|
54
|
+
spec/weird_dir/crazy_spec.rb:8:4: create replaced with build_stubbed
|
55
|
+
expect(create(:user)).not_to be_nil
|
56
|
+
^^^^^^
|
57
|
+
|
58
|
+
π΄ spec/weird_dir/crazy_spec.rb: 33 create calls found, 0 replaced (conflict)
|
53
59
|
|
54
60
|
Scanned 4 files, found 2 unnecessary create calls across 1 files and 1 broken specs
|
55
61
|
```
|
@@ -58,15 +64,21 @@ The `conflict` case is rare. It only happens if individual examples were green a
|
|
58
64
|
|
59
65
|
## Limitations / known issues
|
60
66
|
|
61
|
-
|
67
|
+
`factory_sloth` only works with RSpec so far. It also works best with unit tests such as model specs. It generates **false positives** in cases where create calls are done but only the *absence* of any effect is tested, e.g.:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
user = create(:user)
|
71
|
+
User.delete_all
|
72
|
+
expect(User.count).to eq 0
|
73
|
+
```
|
74
|
+
|
75
|
+
This test will still pass if `user` is never inserted into the database in the first place, leading `factory_sloth` to believe that `build` suffices here. However, this change makes the test no longer assert the same thing and reduces coverage. Magic comments can be used to prevent `factory_sloth` from making such changes. `factory_sloth` will not touch lines with inline `# sloth:disable` comments, or sections framed in `# sloth:disable` / `# sloth:enable` comments. Another option is to write the test in a different (and arguably more assertive) way, e.g.:
|
62
76
|
|
63
77
|
```ruby
|
64
|
-
|
65
|
-
user2 = create(:user, in_search: false)
|
66
|
-
expect(User.searchable).to eq(user1)
|
78
|
+
expect { User.delete_all }.to change { User.count }.from(1).to(0)
|
67
79
|
```
|
68
80
|
|
69
|
-
|
81
|
+
If you have a good idea about how to detect such cases automatically, let me know :)
|
70
82
|
|
71
83
|
## Development
|
72
84
|
|
data/lib/factory_sloth/cli.rb
CHANGED
@@ -7,8 +7,7 @@ module FactorySloth
|
|
7
7
|
def call(argv = ARGV)
|
8
8
|
args = option_parser.parse!(argv)
|
9
9
|
specs = SpecPicker.call(paths: args)
|
10
|
-
|
11
|
-
results = FileProcessor.call(files: specs, forced_files: forced_files, dry_run: @lint)
|
10
|
+
results = FileProcessor.call(files: specs, forced_files: args)
|
12
11
|
print_summary(results)
|
13
12
|
end
|
14
13
|
|
@@ -29,11 +28,16 @@ module FactorySloth
|
|
29
28
|
opts.separator 'Options:'
|
30
29
|
|
31
30
|
opts.on('-f', '--force', "Ignore #{DoneTracker.file}") do
|
32
|
-
|
31
|
+
FactorySloth.force = true
|
33
32
|
end
|
34
33
|
|
35
34
|
opts.on('-l', '--lint', 'Dont fix, just list bad create calls') do
|
36
|
-
|
35
|
+
FactorySloth.dry_run = true
|
36
|
+
FactorySloth.lint = true
|
37
|
+
end
|
38
|
+
|
39
|
+
opts.on('-V', '--verbose', 'Verbose output, useful for debugging') do
|
40
|
+
FactorySloth.verbose = true
|
37
41
|
end
|
38
42
|
|
39
43
|
opts.on('-v', '--version', 'Show gem version') do
|
@@ -49,14 +53,14 @@ module FactorySloth
|
|
49
53
|
end
|
50
54
|
|
51
55
|
def print_summary(results)
|
52
|
-
|
53
|
-
changed_specs = results.keys.select { |path| results[path][:
|
56
|
+
change_sum = results.values.sum { |v| v[:change_count] }
|
57
|
+
changed_specs = results.keys.select { |path| results[path][:change_count] > 0 }
|
54
58
|
broken_specs = results.keys.select { |path| !results[path][:ok] }
|
55
|
-
stats = "Scanned #{results.count} files, found #{
|
59
|
+
stats = "Scanned #{results.count} files, found #{change_sum}"\
|
56
60
|
" unnecessary create calls across #{changed_specs.count} files"\
|
57
61
|
"#{" and #{broken_specs.count} broken specs" if broken_specs.any?}"
|
58
62
|
|
59
|
-
if
|
63
|
+
if FactorySloth.lint && change_sum > 0
|
60
64
|
warn "#{stats}:\n#{(changed_specs + broken_specs).join("\n")}"
|
61
65
|
exit 1
|
62
66
|
else
|
@@ -1,87 +1,117 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module FactorySloth
|
2
|
+
class CodeMod
|
3
|
+
attr_reader :create_calls, :changed_create_calls, :path, :original_code, :patched_code
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
end
|
7
|
-
|
8
|
-
def initialize(path, code)
|
9
|
-
self.path = path
|
10
|
-
self.original_code = code
|
11
|
-
self.patched_code = code
|
12
|
-
end
|
5
|
+
require 'forwardable'
|
6
|
+
extend Forwardable
|
13
7
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
# Performance note: it might be faster to write ALL possible patches for a
|
18
|
-
# given spec file to tempfiles first, and then run them all in a single
|
19
|
-
# rspec call. However, this would make it impossible to use `--fail-fast`,
|
20
|
-
# and might make examples fail that are not as idempotent as they should be.
|
21
|
-
self.changed_create_calls =
|
22
|
-
create_calls
|
23
|
-
.sort_by { |call| [-call.line, -call.column] }
|
24
|
-
.select { |call| try_patch(call, 'build') || try_patch(call, 'build_stubbed') }
|
25
|
-
|
26
|
-
# validate whole spec after changes, e.g. to detect side-effects
|
27
|
-
self.ok = changed_create_calls.none? ||
|
28
|
-
FactorySloth::SpecRunner.call(path, patched_code)
|
29
|
-
changed_create_calls.clear unless ok?
|
30
|
-
patched_code.replace(original_code) unless ok?
|
31
|
-
end
|
8
|
+
def_delegator :changed_create_calls, :any?, :changed?
|
9
|
+
def_delegator :changed_create_calls, :count, :change_count
|
10
|
+
def_delegator :create_calls, :count, :create_count
|
32
11
|
|
33
|
-
|
34
|
-
|
35
|
-
|
12
|
+
def self.call(path, code)
|
13
|
+
new(path, code).tap(&:call)
|
14
|
+
end
|
36
15
|
|
37
|
-
|
38
|
-
|
39
|
-
|
16
|
+
def initialize(path, code)
|
17
|
+
self.path = path
|
18
|
+
self.original_code = code
|
19
|
+
self.patched_code = code
|
20
|
+
end
|
40
21
|
|
41
|
-
|
42
|
-
|
43
|
-
end
|
22
|
+
def call
|
23
|
+
self.create_calls = CreateCallFinder.call(code: original_code)
|
44
24
|
|
45
|
-
|
46
|
-
|
47
|
-
|
25
|
+
# Performance note: it might be faster to write ALL possible patches for a
|
26
|
+
# given spec file to tempfiles first, and then run them all in a single
|
27
|
+
# rspec call. However, this would make it impossible to use `--fail-fast`,
|
28
|
+
# and might make examples fail that are not as idempotent as they should be.
|
29
|
+
self.changed_create_calls =
|
30
|
+
create_calls.sort_by { |call| [-call.line, -call.column] }.select do |call|
|
31
|
+
build_result = try_patch(call, 'build')
|
32
|
+
next if build_result == ABORT
|
48
33
|
|
49
|
-
|
34
|
+
build_result == SUCCESS || try_patch(call, 'build_stubbed') == SUCCESS
|
35
|
+
end
|
50
36
|
|
51
|
-
|
37
|
+
# validate whole spec after changes, e.g. to detect side-effects
|
38
|
+
self.ok = changed_create_calls.none? || begin
|
39
|
+
FactorySloth.verbose && puts("Checking whole file after changes")
|
40
|
+
run(patched_code).success?
|
41
|
+
end
|
42
|
+
ok? || changed_create_calls.clear && patched_code.replace(original_code)
|
43
|
+
end
|
52
44
|
|
53
|
-
|
54
|
-
|
55
|
-
new_patched_code = patched_code.sub(
|
56
|
-
/\A(?:.*\n){#{call.line - 1}}.{#{call.column}}\K#{call.name}/,
|
57
|
-
variant
|
58
|
-
)
|
59
|
-
checked_patched_code = with_execution_check(new_patched_code, call.line, variant)
|
60
|
-
if FactorySloth::SpecRunner.call(path, checked_patched_code, line: call.line)
|
61
|
-
puts "- #{call.name} in line #{call.line} can be replaced with #{variant}"
|
62
|
-
self.patched_code = new_patched_code
|
45
|
+
def ok?
|
46
|
+
@ok
|
63
47
|
end
|
64
|
-
end
|
65
48
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
executed_lines = []
|
49
|
+
def message
|
50
|
+
stats = "#{path}: #{create_count} create calls found, #{change_count} "\
|
51
|
+
"#{FactorySloth.dry_run ? 'replaceable' : 'replaced'}"
|
70
52
|
|
71
|
-
|
72
|
-
alias ___original_#{variant} #{variant}
|
53
|
+
return "π΄ #{stats} (conflict)" unless ok?
|
73
54
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
55
|
+
if create_count == 0
|
56
|
+
"βͺοΈ #{stats}"
|
57
|
+
elsif change_count == 0
|
58
|
+
"π‘ #{stats}"
|
59
|
+
else
|
60
|
+
"π’ #{stats}"
|
61
|
+
end
|
62
|
+
end
|
79
63
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
64
|
+
private
|
65
|
+
|
66
|
+
attr_writer :create_calls, :changed_create_calls, :ok, :path, :original_code, :patched_code
|
67
|
+
|
68
|
+
def try_patch(call, base_variant)
|
69
|
+
variant = call.name.sub('create', base_variant)
|
70
|
+
FactorySloth.verbose && puts("#{link_to_call(call)}: trying #{variant} ...")
|
71
|
+
|
72
|
+
new_patched_code = patched_code.sub(
|
73
|
+
/\A(?:.*\R){#{call.line - 1}}.{#{call.column}}\K#{call.name}/,
|
74
|
+
variant
|
75
|
+
)
|
76
|
+
checked_patched_code = new_patched_code + ExecutionCheck.for(call.line, variant)
|
77
|
+
|
78
|
+
result = run(checked_patched_code, line: call.line)
|
79
|
+
|
80
|
+
if result.success?
|
81
|
+
info = FactorySloth.dry_run ? 'can be replaced' : 'replaced'
|
82
|
+
puts call_message(call, "#{info} with #{variant}"), ''
|
83
|
+
self.patched_code = new_patched_code
|
84
|
+
SUCCESS
|
85
|
+
elsif result.exitstatus == ExecutionCheck::FACTORY_UNUSED_CODE
|
86
|
+
puts call_message(call, "is never executed, skipping"), ''
|
87
|
+
ABORT
|
88
|
+
elsif result.exitstatus == ExecutionCheck::FACTORY_PERSISTED_LATER_CODE
|
89
|
+
FactorySloth.verbose && puts("Record is persisted later, skipping")
|
90
|
+
ABORT
|
84
91
|
end
|
85
|
-
|
92
|
+
end
|
93
|
+
|
94
|
+
def run(code, line: nil)
|
95
|
+
result = SpecRunner.call(path, code, line: line)
|
96
|
+
FactorySloth.verbose && puts(' RSpec output:', result.output.gsub(/^/, ' '))
|
97
|
+
result
|
98
|
+
end
|
99
|
+
|
100
|
+
ABORT = :ABORT # returned if there is no need to try other variants
|
101
|
+
SUCCESS = :SUCCESS
|
102
|
+
|
103
|
+
def call_message(call, message)
|
104
|
+
line_content = original_code[/\A(?:.*\R){#{call.line - 1}}\K.*/]
|
105
|
+
indent = line_content[/^\s*/]
|
106
|
+
|
107
|
+
"#{link_to_call(call)}: #{call.name} #{message}\n"\
|
108
|
+
" #{line_content.delete_prefix(indent)}\n"\
|
109
|
+
" #{' ' * (call.column - indent.size)}#{Color.yellow('^' * call.name.size)}"
|
110
|
+
end
|
111
|
+
|
112
|
+
def link_to_call(call)
|
113
|
+
# note: column from Ripper is 0-indexed, editors expect 1-indexed columns
|
114
|
+
Color.light_blue("#{path}:#{call.line}:#{call.column + 1}")
|
115
|
+
end
|
86
116
|
end
|
87
117
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module FactorySloth::Color
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def yellow(str)
|
7
|
+
colorize(str, 33)
|
8
|
+
end
|
9
|
+
|
10
|
+
def light_blue(str)
|
11
|
+
colorize(str, 36)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def colorize(str, color_code)
|
17
|
+
return str unless $stdout.is_a?(IO) && $stdout.tty?
|
18
|
+
|
19
|
+
"\e[#{color_code}m#{str}\e[0m"
|
20
|
+
end
|
21
|
+
end
|
@@ -1 +1 @@
|
|
1
|
-
FactorySloth::CreateCall = Struct.new(:
|
1
|
+
FactorySloth::CreateCall = Struct.new(:column, :line, :name, keyword_init: true)
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# This adds code that makes a spec run fail and thus prevents changes if:
|
2
|
+
# a) the patched factory in the given line is never called
|
3
|
+
# b) the built record was persisted later anyway
|
4
|
+
# The rationale behind a) is that things like skipped examples should not
|
5
|
+
# be broken. The rationale behind b) is that not much DB work would be saved,
|
6
|
+
# but diff noise would be increased and ease of editing the example reduced.
|
7
|
+
|
8
|
+
module FactorySloth::ExecutionCheck
|
9
|
+
FACTORY_UNUSED_CODE = 77
|
10
|
+
FACTORY_PERSISTED_LATER_CODE = 78
|
11
|
+
|
12
|
+
def self.for(line, variant)
|
13
|
+
<<~RUBY
|
14
|
+
; defined?(FactoryBot) && defined?(RSpec) && RSpec.configure do |config|
|
15
|
+
records_by_line = {} # track records initialized through factories per line
|
16
|
+
|
17
|
+
FactoryBot::Syntax::Methods.class_eval do
|
18
|
+
alias ___original_#{variant} #{variant} # e.g. ___original_build build
|
19
|
+
|
20
|
+
define_method("#{variant}") do |*args, **kwargs, &blk| # e.g. build
|
21
|
+
result = ___original_#{variant}(*args, **kwargs, &blk)
|
22
|
+
list = records_by_line[caller_locations(1, 1)&.first&.lineno] ||= []
|
23
|
+
list.concat([result].flatten) # to work with single, list, and pair
|
24
|
+
result
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
config.after(:suite) do
|
29
|
+
records = records_by_line[#{line}]
|
30
|
+
records&.any? || exit!(#{FACTORY_UNUSED_CODE})
|
31
|
+
unless "#{variant}".include?('stub') # factory_bot stub stubs persisted? as true
|
32
|
+
records.any? { |r| r.respond_to?(:persisted?) && r.persisted? } &&
|
33
|
+
exit!(#{FACTORY_PERSISTED_LATER_CODE})
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
RUBY
|
38
|
+
end
|
39
|
+
end
|
@@ -2,46 +2,30 @@ module FactorySloth
|
|
2
2
|
module FileProcessor
|
3
3
|
extend self
|
4
4
|
|
5
|
-
def call(files:, forced_files: []
|
5
|
+
def call(files:, forced_files: [])
|
6
6
|
files.each_with_object({}) do |path, acc|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
puts "π΅ Skipped (marked as done in #{DoneTracker.file})", ''
|
7
|
+
if DoneTracker.done?(path) &&
|
8
|
+
!(FactorySloth.force || forced_files.include?(path))
|
9
|
+
puts "π΅ #{path}: skipped (marked as done in #{DoneTracker.file})", ''
|
11
10
|
next
|
12
11
|
end
|
13
12
|
|
14
|
-
result = process(path
|
15
|
-
acc[path] = { ok: result.ok?,
|
13
|
+
result = process(path)
|
14
|
+
acc[path] = { ok: result.ok?, change_count: result.change_count }
|
16
15
|
DoneTracker.mark_as_done(path)
|
17
16
|
end
|
18
17
|
end
|
19
18
|
|
20
19
|
private
|
21
20
|
|
22
|
-
def process(path
|
21
|
+
def process(path)
|
23
22
|
code = File.read(path)
|
24
23
|
result = CodeMod.call(path, code)
|
25
|
-
unless dry_run
|
24
|
+
unless FactorySloth.dry_run
|
26
25
|
File.write(path, result.patched_code) if result.changed?
|
27
26
|
end
|
28
|
-
puts
|
27
|
+
puts result.message, ''
|
29
28
|
result
|
30
29
|
end
|
31
|
-
|
32
|
-
def result_message(result, dry_run)
|
33
|
-
stats = "#{result.create_count} create calls found, "\
|
34
|
-
"#{result.change_count} #{dry_run ? 'replaceable' : 'replaced'}"
|
35
|
-
|
36
|
-
return "π΄ #{stats} (conflict)" unless result.ok?
|
37
|
-
|
38
|
-
if result.create_count == 0
|
39
|
-
"βͺοΈ #{stats}"
|
40
|
-
elsif result.change_count == 0
|
41
|
-
"π‘ #{stats}"
|
42
|
-
else
|
43
|
-
"π’ #{stats}"
|
44
|
-
end
|
45
|
-
end
|
46
30
|
end
|
47
31
|
end
|
@@ -1,13 +1,28 @@
|
|
1
|
+
require 'open3'
|
1
2
|
require 'tmpdir'
|
2
3
|
|
3
4
|
module FactorySloth::SpecRunner
|
4
5
|
def self.call(spec_path, spec_code, line: nil)
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
path = File.join(tmpdir, spec_path)
|
7
|
+
FileUtils.mkdir_p(File.dirname(path))
|
8
|
+
File.write(path, spec_code)
|
9
|
+
path_arg = [path, line].compact.map(&:to_s).join(':')
|
10
|
+
command = "bundle exec rspec #{path_arg} --fail-fast --order defined 2>&1"
|
11
|
+
output, process_status = Open3.capture2(command)
|
12
|
+
Result.new(output: output, process_status: process_status)
|
13
|
+
end
|
14
|
+
|
15
|
+
Result = Struct.new(:output, :process_status, keyword_init: true) do
|
16
|
+
require 'forwardable'
|
17
|
+
extend Forwardable
|
18
|
+
def_delegators :process_status, :exitstatus, :success?
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.tmpdir
|
22
|
+
@tmpdir ||= begin
|
23
|
+
dir = Dir.mktmpdir('factory_sloth-')
|
24
|
+
at_exit { FileUtils.remove_entry(dir) if File.exist?(dir) }
|
25
|
+
dir
|
11
26
|
end
|
12
27
|
end
|
13
28
|
end
|
data/lib/factory_sloth.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
|
-
module FactorySloth
|
1
|
+
module FactorySloth
|
2
|
+
singleton_class.attr_accessor :dry_run, :force, :lint, :verbose
|
3
|
+
end
|
2
4
|
|
3
5
|
require_relative 'factory_sloth/cli'
|
4
6
|
require_relative 'factory_sloth/code_mod'
|
7
|
+
require_relative 'factory_sloth/color'
|
5
8
|
require_relative 'factory_sloth/create_call'
|
6
9
|
require_relative 'factory_sloth/create_call_finder'
|
7
10
|
require_relative 'factory_sloth/done_tracker'
|
11
|
+
require_relative 'factory_sloth/execution_check'
|
8
12
|
require_relative 'factory_sloth/file_processor'
|
9
13
|
require_relative 'factory_sloth/spec_picker'
|
10
14
|
require_relative 'factory_sloth/spec_runner'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: factory_sloth
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Janosch MuΜller
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -28,9 +28,11 @@ files:
|
|
28
28
|
- lib/factory_sloth.rb
|
29
29
|
- lib/factory_sloth/cli.rb
|
30
30
|
- lib/factory_sloth/code_mod.rb
|
31
|
+
- lib/factory_sloth/color.rb
|
31
32
|
- lib/factory_sloth/create_call.rb
|
32
33
|
- lib/factory_sloth/create_call_finder.rb
|
33
34
|
- lib/factory_sloth/done_tracker.rb
|
35
|
+
- lib/factory_sloth/execution_check.rb
|
34
36
|
- lib/factory_sloth/file_processor.rb
|
35
37
|
- lib/factory_sloth/spec_picker.rb
|
36
38
|
- lib/factory_sloth/spec_runner.rb
|