side_by_side 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: bdf8e83de80358a9e62037120d19a3e28522903138edaee965a0dd7144a02e5d
4
+ data.tar.gz: 752a8127bc392c07010260965d82dd15a619c7f9d11a5e84abfc99bc00b2ee86
5
+ SHA512:
6
+ metadata.gz: 4d82efa128bcdb98d35055fb5957756298a2f3d5a178c787d10f384df9e9d59d07cbd8db2edc875eed645b36df9dbfc7aaf3ccb03310fe51ab9cfc523cae50fc
7
+ data.tar.gz: 18682c811e75b84328183752b6cc65ccfaef1b013f4b217fe56ecdc32ace82c22a8c6f1ede13813fedc7e953eefefcf9a1a6ea0062fd0d4eddb9b674263180e6
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in process_bot.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,50 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ side_by_side (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ ast (2.4.2)
10
+ json (2.6.2)
11
+ parallel (1.22.1)
12
+ parser (3.1.2.1)
13
+ ast (~> 2.4.1)
14
+ rainbow (3.1.1)
15
+ regexp_parser (2.6.0)
16
+ rexml (3.2.5)
17
+ rubocop (1.37.0)
18
+ json (~> 2.3)
19
+ parallel (~> 1.10)
20
+ parser (>= 3.1.2.1)
21
+ rainbow (>= 2.2.2, < 4.0)
22
+ regexp_parser (>= 1.8, < 3.0)
23
+ rexml (>= 3.2.5, < 4.0)
24
+ rubocop-ast (>= 1.22.0, < 2.0)
25
+ ruby-progressbar (~> 1.7)
26
+ unicode-display_width (>= 1.4.0, < 3.0)
27
+ rubocop-ast (1.22.0)
28
+ parser (>= 3.1.1.0)
29
+ rubocop-performance (1.15.0)
30
+ rubocop (>= 1.7.0, < 2.0)
31
+ rubocop-ast (>= 0.4.0)
32
+ rubocop-rake (0.6.0)
33
+ rubocop (~> 1.0)
34
+ rubocop-rspec (2.13.2)
35
+ rubocop (~> 1.33)
36
+ ruby-progressbar (1.11.0)
37
+ unicode-display_width (2.3.0)
38
+
39
+ PLATFORMS
40
+ x86_64-linux
41
+
42
+ DEPENDENCIES
43
+ rubocop
44
+ rubocop-performance
45
+ rubocop-rake
46
+ rubocop-rspec
47
+ side_by_side!
48
+
49
+ BUNDLED WITH
50
+ 2.3.15
data/exe/side_by_side ADDED
@@ -0,0 +1,67 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/side_by_side"
4
+
5
+ time_total_start = Time.new
6
+ processes_to_run = []
7
+
8
+ ARGV.each do |arg|
9
+ process_to_run = SideBySide::ProcessToRun.new(command: arg)
10
+ process_to_run.run_async
11
+
12
+ processes_to_run << process_to_run
13
+ end
14
+
15
+ puts "Started processes: #{processes_to_run.length}"
16
+
17
+ def output!(type:, output:)
18
+ if type == :stdout
19
+ $stdout.print output
20
+ elsif type == :stderr
21
+ $stderr.print output
22
+ else
23
+ raise "Unknown type: #{type}"
24
+ end
25
+ end
26
+
27
+ processes_to_run.each do |process_to_run|
28
+ time_start = Time.new
29
+
30
+ puts "Process: #{process_to_run.command}"
31
+
32
+ process_to_run.monitor.synchronize do
33
+ # Print output generated so far
34
+ process_to_run.output.each do |out|
35
+ output!(**out)
36
+ end
37
+
38
+ # Print output to come
39
+ process_to_run.on_output do |out|
40
+ output!(**out)
41
+ end
42
+ end
43
+
44
+ # Wait for process to finish
45
+ process_to_run.join
46
+ end
47
+
48
+ time_total_stop = Time.new
49
+
50
+ # Return failed exit status if any of the processes failed
51
+ puts "Status for #{processes_to_run.length} processes"
52
+ puts
53
+ result_exit_status = 0
54
+
55
+ processes_to_run.each do |process_to_run|
56
+ puts process_to_run.command
57
+ puts " Exit status: #{process_to_run.exit_status}"
58
+ puts " Seconds: #{process_to_run.seconds}"
59
+ puts
60
+
61
+ result_exit_status = process_to_run.exit_status if process_to_run.exit_status != 0
62
+ end
63
+
64
+ puts "Seconds total: #{time_total_stop.to_f - time_total_start.to_f}"
65
+ puts "Result: #{result_exit_status}"
66
+
67
+ exit(result_exit_status)
@@ -0,0 +1,88 @@
1
+ require "pty"
2
+
3
+ class SideBySide::ProcessToRun
4
+ attr_reader :command, :exit_status, :monitor, :on_output_callback, :output, :pid, :start_time, :stop_time, :thread
5
+
6
+ def initialize(command:)
7
+ @command = command
8
+ @output = []
9
+ @monitor = Monitor.new
10
+ end
11
+
12
+ def join
13
+ while !thread
14
+ puts "Pass - waiting for thread"
15
+ Thread.pass
16
+ end
17
+
18
+ thread.join
19
+ end
20
+
21
+ def on_output(&blk)
22
+ puts "Setting on output for: #{command}"
23
+ @on_output_callback = blk
24
+ end
25
+
26
+ def output!(out)
27
+ type = out.fetch(:type)
28
+
29
+ if type == :stdout
30
+ $stdout << out.fetch(:output)
31
+ elsif type == :stderr
32
+ $stderr << out.fetch(:output)
33
+ else
34
+ raise "Unknown type: #{type}"
35
+ end
36
+ end
37
+
38
+ def run_async
39
+ @thread = Thread.new do
40
+ @start_time = Time.new
41
+ stderr_reader, stderr_writer = IO.pipe
42
+
43
+ PTY.spawn(command, err: stderr_writer.fileno) do |stdout, stdin, pid|
44
+ @pid = pid
45
+
46
+ puts "Command running: #{command} - #{stdout.class.name}"
47
+
48
+ stdout_reader_thread = Thread.new do
49
+ begin
50
+ stdout.each_char do |chunk|
51
+ monitor.synchronize do
52
+ out = {type: :stdout, output: chunk}
53
+ output << out
54
+ on_output_callback&.call(out)
55
+ end
56
+ end
57
+ rescue Errno::EIO => e
58
+ # Process done
59
+ ensure
60
+ status = Process::Status.wait(@pid, 0)
61
+
62
+ @exit_status = status.exitstatus
63
+ stderr_writer.close
64
+ end
65
+ end
66
+
67
+ stderr_reader_thread = Thread.new do
68
+ stderr_reader.each_char do |chunk|
69
+ monitor.synchronize do
70
+ out = {type: :stderr, output: chunk}
71
+ output << out
72
+ on_output_callback&.call(out)
73
+ end
74
+ end
75
+ end
76
+
77
+ stdout_reader_thread.join
78
+ stderr_reader_thread.join
79
+
80
+ @stop_time = Time.new
81
+ end
82
+ end
83
+ end
84
+
85
+ def seconds
86
+ @stop_time.to_f - @start_time.to_f
87
+ end
88
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ class SideBySide
4
+ autoload :ProcessToRun, "#{__dir__}/side_by_side/process_to_run"
5
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: side_by_side
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - kaspernj
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-11-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rubocop
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubocop-performance
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop-rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop-rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Run and control processes.
70
+ email:
71
+ - k@spernj.org
72
+ executables:
73
+ - side_by_side
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - Gemfile
78
+ - Gemfile.lock
79
+ - exe/side_by_side
80
+ - lib/side_by_side.rb
81
+ - lib/side_by_side/process_to_run.rb
82
+ homepage: https://github.com/kaspernj/side_by_side
83
+ licenses:
84
+ - MIT
85
+ metadata:
86
+ allowed_push_host: https://rubygems.org
87
+ homepage_uri: https://github.com/kaspernj/side_by_side
88
+ source_code_uri: https://github.com/kaspernj/side_by_side
89
+ changelog_uri: https://github.com/kaspernj/side_by_side/blob/master/CHANGELOG.md
90
+ rubygems_mfa_required: 'true'
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: 2.6.0
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubygems_version: 3.3.7
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: Run and control processes.
110
+ test_files: []