ree_spec 0.0.5 → 0.0.6
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/Gemfile.lock +1 -1
- data/lib/ree_spec/packages/ree_spec_cli/package/ree_spec_cli/run_command.rb +3 -3
- data/lib/ree_spec/packages/ree_spec_cli/package/ree_spec_cli/services/command_builder.rb +16 -17
- data/lib/ree_spec/packages/ree_spec_cli/package/ree_spec_cli/services/run_specs.rb +132 -28
- data/lib/ree_spec/packages/ree_spec_cli/package/ree_spec_cli.rb +4 -0
- data/lib/ree_spec/packages/ree_spec_cli/spec/ree_spec_cli/run_command_spec.rb +2 -0
- data/lib/ree_spec/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 971f1556635ff273e2a921facab36b08918b9d3cddfa236146e054ee59114bbb
|
4
|
+
data.tar.gz: 44d05a565bd7cd4683274361594d90bae3cbdd0d443044b71276cd8a7f77bb38
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e366fe6c67b093aef3a47bf71edb74fb283a1d9d098c51f3cbab46f2b190bf644e17645cca216192eccac4d7e47a25982be14c4da3f85c9dfbb9826341fdd74b
|
7
|
+
data.tar.gz: b74d0c9e98c680445835ac9d366e6e4e6f8a6cbc76fa8526cd4001f6d20cf804f68394a053bd3a03f52f1a3b9eaec0f821dcb869987965f8986387d551ff8da4
|
data/Gemfile.lock
CHANGED
@@ -9,10 +9,10 @@ class ReeSpecCli::RunCommand
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def call
|
12
|
-
action_proc = Proc.new do |package_names, spec_matcher, tag, files, run_all, project_path, process_count
|
12
|
+
action_proc = Proc.new do |package_names, spec_matcher, tag, files, run_all, only_failed, project_path, process_count|
|
13
13
|
run_specs(
|
14
|
-
package_names, spec_matcher, tag, files, run_all,
|
15
|
-
project_path, process_count
|
14
|
+
package_names, spec_matcher, tag, files, run_all, only_failed,
|
15
|
+
project_path, process_count
|
16
16
|
)
|
17
17
|
end
|
18
18
|
|
@@ -2,14 +2,12 @@ class ReeSpecCli::CommandBuilder
|
|
2
2
|
include Commander::Methods
|
3
3
|
|
4
4
|
DEFAULT_PROCESS_COUNT = 1
|
5
|
-
DEFAULT_SPECS_PER_PROCESS_COUNT = 5
|
6
5
|
|
7
6
|
def build(&action_proc)
|
8
7
|
files = []
|
9
8
|
package_names = []
|
10
9
|
run_all = false
|
11
10
|
process_count = DEFAULT_PROCESS_COUNT
|
12
|
-
specs_per_process = DEFAULT_SPECS_PER_PROCESS_COUNT
|
13
11
|
|
14
12
|
program :name, "Ree Spec"
|
15
13
|
program :version, "1.0"
|
@@ -25,7 +23,8 @@ class ReeSpecCli::CommandBuilder
|
|
25
23
|
c.example "ree spec --tag wip", "Run specs for packages which have \"wip\" tag"
|
26
24
|
c.option "--project_path [ROOT_DIR]", String, "Root project dir path"
|
27
25
|
c.option "--tag TAG_NAME", String, "Run specs for packages with specified tag"
|
28
|
-
c.option "--parallel
|
26
|
+
c.option "--parallel PROCESS_COUNT", String, "Run specs in parallel processes (e.g. --parallel 15, 15 processes)"
|
27
|
+
c.option "--only-failed", "Run only failed specs from previous run"
|
29
28
|
|
30
29
|
c.option "-f SPEC_FILE", "--fule SPEC_FILE", String, "List of spec files" do |f|
|
31
30
|
files ||= []
|
@@ -39,11 +38,16 @@ class ReeSpecCli::CommandBuilder
|
|
39
38
|
c.action do |args, options|
|
40
39
|
package_name = args[0]&.to_sym
|
41
40
|
spec_matcher = args[1]
|
42
|
-
options_hash = options.__hash__
|
43
|
-
options_hash.delete(:trace)
|
44
41
|
|
45
|
-
if
|
46
|
-
|
42
|
+
if options.project_path
|
43
|
+
path = File.expand_path(options.project_path.to_s)
|
44
|
+
|
45
|
+
if !File.directory?(path)
|
46
|
+
puts("Project path not found: #{options.project_path}")
|
47
|
+
exit 1
|
48
|
+
end
|
49
|
+
|
50
|
+
options.project_path = File.expand_path(options.project_path.to_s)
|
47
51
|
end
|
48
52
|
|
49
53
|
if package_name
|
@@ -54,13 +58,8 @@ class ReeSpecCli::CommandBuilder
|
|
54
58
|
run_all = true
|
55
59
|
end
|
56
60
|
|
57
|
-
if
|
58
|
-
|
59
|
-
process_count = Integer(parallel.first)
|
60
|
-
|
61
|
-
if parallel.size > 1
|
62
|
-
specs_per_process = Integer(parallel.last)
|
63
|
-
end
|
61
|
+
if options.parallel
|
62
|
+
process_count = Integer(options.parallel)
|
64
63
|
end
|
65
64
|
|
66
65
|
if package_names.size > 1
|
@@ -68,9 +67,9 @@ class ReeSpecCli::CommandBuilder
|
|
68
67
|
end
|
69
68
|
|
70
69
|
action_proc.call(
|
71
|
-
package_names, spec_matcher,
|
72
|
-
run_all,
|
73
|
-
process_count
|
70
|
+
package_names, spec_matcher, options.tag, files,
|
71
|
+
run_all, !!options.only_failed, options.project_path || File.expand_path(Dir.pwd),
|
72
|
+
process_count
|
74
73
|
)
|
75
74
|
end
|
76
75
|
end
|
@@ -2,21 +2,23 @@ class ReeSpecCli::RunSpecs
|
|
2
2
|
include Ree::FnDSL
|
3
3
|
|
4
4
|
fn :run_specs do
|
5
|
-
link :in_groups_of, from: :ree_array
|
6
5
|
link :run_package_specs
|
6
|
+
link :from_json, from: :ree_json
|
7
|
+
link :symbolize_keys, from: :ree_hash
|
8
|
+
link :group_by, from: :ree_array
|
9
|
+
link :index_by, from: :ree_array
|
10
|
+
link :to_hash, from: :ree_object
|
11
|
+
link :to_json, from: :ree_json
|
7
12
|
end
|
8
13
|
|
9
|
-
|
14
|
+
SPEC_META_FILENAME = "ree_spec_meta.json"
|
10
15
|
|
11
|
-
contract ArrayOf[Symbol], Nilor[String], Nilor[String], ArrayOf[String], Bool,
|
12
|
-
def call(package_names, spec_matcher, tag, files, run_all, project_path,
|
13
|
-
process_count, specs_per_process)
|
16
|
+
contract ArrayOf[Symbol], Nilor[String], Nilor[String], ArrayOf[String], Bool, Bool, String, Integer => nil
|
17
|
+
def call(package_names, spec_matcher, tag, files, run_all, only_failed, project_path, process_count)
|
14
18
|
init_ree_project(project_path)
|
15
19
|
|
16
20
|
packages = filter_packages_to_run(package_names, tag, run_all)
|
17
|
-
|
18
|
-
jobs = get_jobs(packages, specs_per_process, spec_matcher, files)
|
19
|
-
|
21
|
+
jobs, meta_index = get_jobs(packages, spec_matcher, files, only_failed)
|
20
22
|
processes = build_processes(process_count)
|
21
23
|
error_files = []
|
22
24
|
success_files = []
|
@@ -29,9 +31,35 @@ class ReeSpecCli::RunSpecs
|
|
29
31
|
|
30
32
|
processes[number] = Process.fork do
|
31
33
|
print_start_message(job)
|
32
|
-
result = run_package_specs(job.package, job.files, number)
|
33
34
|
|
34
|
-
|
35
|
+
prev_meta = meta_index[job.abs_path]
|
36
|
+
start_time = Time.now
|
37
|
+
|
38
|
+
result = run_package_specs(job.package, [job.abs_path], number)
|
39
|
+
|
40
|
+
end_time = Time.now
|
41
|
+
exec_time = end_time - start_time
|
42
|
+
is_success = result.status.exitstatus == 0
|
43
|
+
|
44
|
+
duration = if is_success
|
45
|
+
exec_time
|
46
|
+
elsif prev_meta
|
47
|
+
prev_meta.duration
|
48
|
+
else
|
49
|
+
exec_time
|
50
|
+
end
|
51
|
+
|
52
|
+
update_scan_metadata(
|
53
|
+
SpecMeta.new(
|
54
|
+
package: job.package.name.to_s,
|
55
|
+
abs_path: job.abs_path,
|
56
|
+
duration: duration,
|
57
|
+
last_scan_at: Time.now,
|
58
|
+
success: is_success
|
59
|
+
)
|
60
|
+
)
|
61
|
+
|
62
|
+
if !is_success
|
35
63
|
error_file.write(result.out)
|
36
64
|
error_file.rewind
|
37
65
|
puts(result.out)
|
@@ -83,7 +111,7 @@ class ReeSpecCli::RunSpecs
|
|
83
111
|
end
|
84
112
|
|
85
113
|
def print_start_message(job)
|
86
|
-
puts("
|
114
|
+
puts("Running spec for :#{job.package.name}:\n#{job.abs_path}")
|
87
115
|
end
|
88
116
|
|
89
117
|
def print_messages(error_files, success_files)
|
@@ -119,23 +147,53 @@ class ReeSpecCli::RunSpecs
|
|
119
147
|
number
|
120
148
|
end
|
121
149
|
|
122
|
-
class Job
|
150
|
+
class Job
|
151
|
+
include ReeDto::DSL
|
152
|
+
|
153
|
+
build_dto do
|
154
|
+
field :package, Ree::Package
|
155
|
+
field :abs_path, String
|
156
|
+
end
|
157
|
+
end
|
123
158
|
|
124
|
-
def get_jobs(package_names,
|
159
|
+
def get_jobs(package_names, spec_matcher, files, only_failed)
|
160
|
+
prev_scan_meta = read_prev_scan_metadata
|
125
161
|
result = []
|
126
162
|
packages = package_names.map { packages_facade.get_package(_1) }
|
163
|
+
scan_index = index_by(prev_scan_meta) { _1.abs_path }
|
127
164
|
|
128
165
|
packages.each do |package|
|
129
|
-
dir = Ree::PathHelper.abs_package_module_dir(package)
|
130
|
-
|
131
166
|
spec_files = get_spec_files(package, spec_matcher, files)
|
132
167
|
|
133
|
-
|
134
|
-
result << Job.new(package
|
168
|
+
spec_files.each do |abs_path|
|
169
|
+
result << Job.new(package:, abs_path:)
|
135
170
|
end
|
136
171
|
end
|
137
172
|
|
138
|
-
|
173
|
+
if only_failed
|
174
|
+
result = result.select do |item|
|
175
|
+
if scan_index[item.abs_path]
|
176
|
+
!scan_index[item.abs_path].success
|
177
|
+
else
|
178
|
+
false
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
cur_min_duration = prev_scan_meta.min { _1.duration }&.duration || 0
|
184
|
+
|
185
|
+
result.sort_by do |item|
|
186
|
+
dur = if el = scan_index[item.abs_path]
|
187
|
+
el.duration
|
188
|
+
else
|
189
|
+
cur_min_duration -= 1
|
190
|
+
cur_min_duration
|
191
|
+
end
|
192
|
+
|
193
|
+
-dur
|
194
|
+
end
|
195
|
+
|
196
|
+
[result, scan_index]
|
139
197
|
end
|
140
198
|
|
141
199
|
def get_spec_files(package, spec_matcher, files)
|
@@ -172,21 +230,11 @@ class ReeSpecCli::RunSpecs
|
|
172
230
|
result
|
173
231
|
end
|
174
232
|
end
|
175
|
-
elsif files && files.size > 0
|
176
|
-
files
|
177
233
|
else
|
178
234
|
all_specs
|
179
235
|
end
|
180
236
|
end
|
181
237
|
|
182
|
-
def calculate_specs_per_process(process_count, specs_per_process)
|
183
|
-
if process_count > 1
|
184
|
-
specs_per_process
|
185
|
-
else
|
186
|
-
MAX_SPECS_PER_PROCESS
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
238
|
def filter_packages_to_run(package_names, tag, run_all)
|
191
239
|
packages_to_run = []
|
192
240
|
|
@@ -238,4 +286,60 @@ class ReeSpecCli::RunSpecs
|
|
238
286
|
package.tags.include?(tag)
|
239
287
|
end
|
240
288
|
end
|
289
|
+
|
290
|
+
def spec_meta_file_name
|
291
|
+
dir = Dir.pwd
|
292
|
+
File.join(dir, SPEC_META_FILENAME)
|
293
|
+
end
|
294
|
+
|
295
|
+
def read_prev_scan_metadata
|
296
|
+
path = spec_meta_file_name
|
297
|
+
|
298
|
+
if File.exist?(path)
|
299
|
+
result = begin
|
300
|
+
from_json(File.read(path))
|
301
|
+
rescue
|
302
|
+
[]
|
303
|
+
end
|
304
|
+
|
305
|
+
build_metadata(result)
|
306
|
+
else
|
307
|
+
build_metadata([])
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
def update_scan_metadata(spec_meta)
|
312
|
+
meta = read_prev_scan_metadata
|
313
|
+
prev_spec = meta.find { _1.abs_path == spec_meta.abs_path }
|
314
|
+
meta.delete(prev_spec) if prev_spec
|
315
|
+
meta << spec_meta
|
316
|
+
|
317
|
+
result = to_json(meta.map { to_hash(_1) })
|
318
|
+
|
319
|
+
File.open(spec_meta_file_name, "w") do |f|
|
320
|
+
f.flock(File::LOCK_EX)
|
321
|
+
f.write(result)
|
322
|
+
f.flock(File::LOCK_UN)
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
class SpecMeta
|
327
|
+
include ReeDto::DSL
|
328
|
+
|
329
|
+
build_dto do
|
330
|
+
field :package, String
|
331
|
+
field :abs_path, String
|
332
|
+
field :duration, Float
|
333
|
+
field :last_scan_at, Time
|
334
|
+
field :success, Bool
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def build_metadata(data)
|
339
|
+
data.map do |d|
|
340
|
+
SpecMeta.new(symbolize_keys(d))
|
341
|
+
end.compact
|
342
|
+
rescue
|
343
|
+
[]
|
344
|
+
end
|
241
345
|
end
|
data/lib/ree_spec/version.rb
CHANGED