33require 'fileutils'
44require 'matrixeval/ruby/config'
55require 'matrixeval/ruby/command_line'
6+ require "concurrent/utility/processor_counter"
7+ require 'terminal-table'
68
79module Matrixeval
810 module Ruby
@@ -13,35 +15,147 @@ def start(argv)
1315 end
1416 end
1517
16- attr_reader :argv
18+ attr_reader :argv , :command
1719
1820 def initialize ( argv )
1921 @argv = argv
22+ @command = CommandLine . new ( argv )
2023 end
2124
2225 def start
23- command = CommandLine . new ( argv )
2426 if command . init?
25- Config ::YAML . create
26- Gitignore . update
27+ init
28+ elsif command . all?
29+ run_all_contexts
2730 else
28- Config ::YAML . create
29- DockerCompose ::YAML . create
30- GemfileLocks . create
31- Gitignore . update
32-
33- if command . all?
34- Context . all . each do |context |
35- docker_compose = DockerCompose . new ( context )
36- docker_compose . run ( command . rest_arguments )
37- end
38- else
39- context = Context . find_by_command_options! ( command . context_options )
31+ run_a_specific_context
32+ end
33+ ensure
34+ turn_on_stty_opost
35+ end
36+
37+ private
38+
39+ def init
40+ Config ::YAML . create
41+ Gitignore . update
42+ end
43+
44+ def run_all_contexts
45+ Config ::YAML . create
46+ DockerCompose ::YAML . create
47+ GemfileLocks . create
48+ Gitignore . update
49+
50+ if workers_count == 1
51+ run_all_contexts_sequentially
52+ else
53+ run_all_contexts_in_parallel
54+ end
55+ end
56+
57+ def run_all_contexts_sequentially
58+ Context . all . each do |context |
59+ puts Rainbow ( "[ MatrixEval ] " ) . blue . bright + Rainbow ( " #{ context . name } " ) . white . bright . bg ( :blue )
60+ puts Rainbow ( "[ MatrixEval ] Run \" #{ command . rest_arguments . join ( " " ) } \" " ) . blue . bright
61+
62+ docker_compose = DockerCompose . new ( context )
63+ success = docker_compose . run ( command . rest_arguments )
64+
65+ matrixeval_results << [ context , !!success ]
66+ end
67+
68+ report
69+ end
70+
71+ def run_all_contexts_in_parallel
72+ parallel do |contexts |
73+ Thread . current [ :matrixeval_results ] = [ ]
4074
75+ contexts . each do |context |
4176 docker_compose = DockerCompose . new ( context )
42- docker_compose . run ( command . rest_arguments )
77+ success = docker_compose . run ( command . rest_arguments )
78+
79+ Thread . current [ :matrixeval_results ] << [ context , !!success ]
4380 end
4481 end
82+
83+ report
84+ end
85+
86+ def run_a_specific_context
87+ Config ::YAML . create
88+ DockerCompose ::YAML . create
89+ GemfileLocks . create
90+ Gitignore . update
91+
92+ context = Context . find_by_command_options! ( command . context_options )
93+
94+ puts Rainbow ( "[ MatrixEval ] " ) . blue . bright + Rainbow ( " #{ context . name } " ) . white . bright . bg ( :blue )
95+ puts Rainbow ( "[ MatrixEval ] Run \" #{ command . rest_arguments . join ( " " ) } \" " ) . blue . bright
96+
97+ docker_compose = DockerCompose . new ( context )
98+ docker_compose . run ( command . rest_arguments )
99+ end
100+
101+ def report
102+ turn_on_stty_opost
103+
104+ table = Terminal ::Table . new ( title : Rainbow ( "MatrixEval" ) . blue . bright + " Summary" , alignment : :center ) do |table |
105+
106+ table . add_row ( Config . vectors . map ( &:key ) + [ 'result' ] )
107+ table . add_separator
108+
109+ matrixeval_results . each do |context , success |
110+ success_cell = [ success ? Rainbow ( 'Success' ) . green : Rainbow ( 'Failed' ) . red ]
111+ row = ( context . variants . map ( &:key ) + success_cell ) . map do |value |
112+ { value : value , alignment : :center }
113+ end
114+
115+ table . add_row row
116+ end
117+
118+ end
119+
120+ puts table
121+ end
122+
123+ def parallel
124+ contexts = Context . all
125+
126+ contexts . each_slice ( contexts . count / workers_count ) do |sub_contexts |
127+ threads << Thread . new do
128+ yield sub_contexts
129+ end
130+ end
131+
132+ threads . each ( &:join )
133+
134+ threads . each do |thread |
135+ matrixeval_results += thread [ :matrixeval_results ]
136+ end
137+ end
138+
139+ def threads
140+ @threads ||= [ ]
141+ end
142+
143+ def matrixeval_results
144+ @matrixeval_results ||= [ ]
145+ end
146+
147+ def workers_count
148+ count = if Config . parallel_workers == "number_of_processors"
149+ Concurrent . physical_processor_count
150+ else
151+ Integer ( Config . parallel_workers )
152+ end
153+
154+ [ count , 1 ] . max
155+ end
156+
157+ def turn_on_stty_opost
158+ system ( "stty opost" )
45159 end
46160
47161 end
0 commit comments