paralines 1.0.0 → 1.1.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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +21 -0
  3. data/README.md +126 -0
  4. data/lib/paralines.rb +32 -23
  5. metadata +6 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 529c8563443dc4d0433a4e969ad894b76ded11e579a8f1781d859bd004e83464
4
- data.tar.gz: 4f96bf28dfcc1726a27fe770f558b82b1ae7d77f4216abf818df34c970043fc0
3
+ metadata.gz: ed6bff64ad603e59c3cc6a32adf7bbaba2872a69bb7c84bbe4173434bd2165c8
4
+ data.tar.gz: faffc56b4a7f731fa92057d0e01daefb7f33c2252715df5fd604925a22bf5ec7
5
5
  SHA512:
6
- metadata.gz: 849db8748f0ffac034e984a3083ff6feab2e238a01b23b8c8ce77059ae804349413870444077d374eab0570e261fcb855b425dd7e94905ff289a9d72affd9527
7
- data.tar.gz: 87cc010c941f8a029ed86f5a8b1945e5ce37cfbb0661cb90052874b74cb81e023ea68eab46ed2ccd4db06e81100c58f03b135ec6b1c0f8d169a3401eaf916f6c
6
+ metadata.gz: 169868a642b113e709e6e1b76b20a829971b46e525020f3ce61ab91bb9d0a50c17583a1818002676a64d3c3594568be31eac91dfdd21d5543fb7a89dc4e756df
7
+ data.tar.gz: fec478726daccb53dd2ec805ec0784a220e82c85a5ae2abe2c9dd686f31b9820b97186db0d2a59cf0d737b1458c19f8a4bc76587e72434223c76d4c981a77493
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022 Inversion
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # ParaLines Ruby Gem [![version](https://badge.fury.io/rb/paralines.svg)](https://rubygems.org/gems/paralines)
2
+
3
+ Nice output to console/file from concurrent threads:
4
+
5
+ ![sample output](sample_output.gif)
6
+
7
+ #### Features:
8
+ - only 170 lines of code;
9
+ - no dependencies;
10
+ - works on Linux and Windows;
11
+ - if output to file and the script crashes in the middle — it is handled with at_exit and in the file, you will find partial output not an empty file.
12
+
13
+ ## Installation
14
+
15
+ gem install paralines
16
+
17
+ or in your Gemfile
18
+
19
+ gem 'paralines'
20
+
21
+ ## Sample with all the features (output is on the gif animation)
22
+
23
+ ```ruby
24
+ require 'paralines'
25
+
26
+ puts '- start -'
27
+
28
+ ParaLines.new do |plines|
29
+
30
+ odd_line = plines.add_shared_line 'Odd: '
31
+ even_line = plines.add_shared_line 'Even: '
32
+ done_order_line = plines.add_shared_line 'Done order: '
33
+
34
+ workers = (0..9).map do |n|
35
+ Thread.new do
36
+ if n == 0
37
+ # special case with sub-tasks in sub-threads
38
+ shared_line = plines.add_shared_line "Worker_#{n}: "
39
+ (1..3).map do |sn|
40
+ Thread.new do
41
+ sleep 0.01
42
+ ticks_n = 5
43
+ part = shared_line.part_open "[subtask#{sn}…#{' '*(ticks_n-1)}] "
44
+ ticks_n.times do |n|
45
+ sleep rand
46
+ part.close '.' * (n+1)
47
+ end
48
+ end
49
+ end.each &:join
50
+ next
51
+ else
52
+ sleep n>5 ? 0.3 : 0.1 # make Worker_0 to be the first in the list
53
+ end
54
+ plines << "Worker_#{n}"
55
+ start = Time.now
56
+ n.odd? \
57
+ ? (odd_part = odd_line.part_open "#{n}… ")
58
+ : (even_part = even_line.part_open "[#{n} ")
59
+ 2.times do
60
+ sleep rand
61
+ plines << '.'
62
+ fail if rand < 0.07 if !:with_fail_chanse # remove ! here to test crashes
63
+ end
64
+ time = Time.now - start
65
+ plines << "done (in %.3fs)" % time
66
+ done_order_line << n
67
+ odd_part&.close '+'
68
+ even_part&.close ']'
69
+ end
70
+ .tap do
71
+ if n==5
72
+ sleep 0.2
73
+ plines.add_static_line '- 5 workers added'
74
+ elsif n==9
75
+ sleep 0.4
76
+ plines.add_static_line '- all workers added'
77
+ end
78
+ end
79
+ end.each &:join
80
+
81
+ end
82
+
83
+ puts '- ready -'
84
+
85
+ ```
86
+
87
+ ### Usage without a block
88
+ ```ruby
89
+ require 'paralines'
90
+
91
+ plines = ParaLines.new
92
+
93
+ plines.add_static_line 'Gems latest versions'
94
+ plines.add_empty_line
95
+
96
+ gems = %w[sinatra rspec paralines rails hanami]
97
+
98
+ plines.add_static_line '- Random order:'
99
+ threads = gems.map do |name|
100
+ Thread.new do
101
+ plines << name.ljust(15, '.')
102
+ res = `gem list -r #{name} -e`
103
+ plines << 'v' + res[/\((.+)\)/, 1]
104
+ end
105
+ end
106
+ sleep 0.2
107
+ plines.add_empty_line
108
+ plines.add_static_line '- Sorted:'
109
+ threads += gems.sort.map do |name|
110
+ sline = plines.add_shared_line name.ljust(15, '.')
111
+ Thread.new do
112
+ res = `gem list -r #{name} -e`
113
+ sline << 'v' + res[/\((.+)\)/, 1]
114
+ end
115
+ end
116
+
117
+ threads.each &:join
118
+ ```
119
+
120
+ ## Contributing
121
+
122
+ Bug reports and pull requests are welcome on GitHub: https://github.com/Inversion-des/paralines
123
+
124
+ ## License
125
+
126
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/lib/paralines.rb CHANGED
@@ -1,20 +1,10 @@
1
- # frozen_string_literal: true
1
+ # *frozen_string_literal: true — should not be used here to ensure unique object_id for ''
2
2
 
3
3
  class ParaLines
4
- C_mutex = Mutex.new
5
- def C_mutex.sync_if_needed
6
- if owned?
7
- yield
8
- else
9
- synchronize do
10
- yield
11
- end
12
- end
13
- end
14
4
 
15
5
  def initialize
16
6
  set_flags!
17
- @line_by_key = Hash.new {|h, key| h[key] = {line:h.length, col:1, text:''} }
7
+ @line_by_key = Hash.new {|h, key| h[key] = {line:h.length, col:1, text:''.freeze} }
18
8
 
19
9
  # *ensure flush at exit
20
10
  if @f_to_file
@@ -41,7 +31,7 @@ class ParaLines
41
31
  # plines.add_static_line '- 5 workers added'
42
32
  def add_static_line(text)
43
33
  key = text.object_id
44
- C_mutex.synchronize do
34
+ MUTEX.synchronize do
45
35
  d = @line_by_key[key]
46
36
  if @f_to_console
47
37
  puts text
@@ -51,6 +41,11 @@ class ParaLines
51
41
  end
52
42
  end
53
43
 
44
+ # plines.add_empty_line
45
+ def add_empty_line
46
+ add_static_line ''
47
+ end
48
+
54
49
  # done_order_line = plines.add_shared_line 'Done order: '
55
50
  # done_order_line << 'some text'
56
51
  # part = shared_line.part_open "#{n}… " + later: part.close '+'
@@ -73,9 +68,9 @@ class ParaLines
73
68
  d = line_by_key[key]
74
69
  part_col = nil
75
70
 
76
- C_mutex.synchronize do
71
+ MUTEX.synchronize do
77
72
  # *we replace placeholder chars like: … or _ or just the last char (order here needed for priority to be able to have _ in text and use … as a placeholder)
78
- part_col = d[:col] + (text_.index('…') || text_.index('_') || text_.length-1)
73
+ part_col = d[:col] + (text_.index('…'.freeze) || text_.index('_'.freeze) || text_.length-1)
79
74
 
80
75
  rel.send :output, key, text_
81
76
  end
@@ -84,13 +79,15 @@ class ParaLines
84
79
  Object.new.tap do |o|
85
80
  o.define_singleton_method :close do |end_text|
86
81
  # *print the closing chars in the saved position
87
- if f_to_console
88
- rel.send :print_in_line,
89
- lines_up: line_by_key.count - d[:line],
90
- col: part_col,
91
- text: end_text
92
- else # for file
93
- d[:text][part_col-1, end_text.length] = end_text
82
+ MUTEX.synchronize do
83
+ if f_to_console
84
+ rel.send :print_in_line,
85
+ lines_up: line_by_key.count - d[:line],
86
+ col: part_col,
87
+ text: end_text
88
+ else # for file
89
+ d[:text][part_col-1, end_text.length] = end_text
90
+ end
94
91
  end
95
92
  end
96
93
  end
@@ -118,7 +115,7 @@ class ParaLines
118
115
  private \
119
116
  def output(key, text)
120
117
  text = text.to_s
121
- C_mutex.sync_if_needed do
118
+ MUTEX.sync_if_needed do
122
119
 
123
120
  # add line
124
121
  puts if @f_to_console && !@line_by_key.has_key?(key)
@@ -155,4 +152,16 @@ class ParaLines
155
152
  OUT
156
153
  end
157
154
 
155
+
156
+ MUTEX = Mutex.new
157
+ def MUTEX.sync_if_needed
158
+ if owned?
159
+ yield
160
+ else
161
+ synchronize do
162
+ yield
163
+ end
164
+ end
165
+ end
166
+
158
167
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: paralines
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yura Babak
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-27 00:00:00.000000000 Z
11
+ date: 2022-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -31,6 +31,8 @@ executables: []
31
31
  extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
+ - LICENSE.txt
35
+ - README.md
34
36
  - lib/paralines.rb
35
37
  homepage: https://github.com/Inversion-des/paralines
36
38
  licenses:
@@ -44,14 +46,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
44
46
  requirements:
45
47
  - - ">="
46
48
  - !ruby/object:Gem::Version
47
- version: '0'
49
+ version: '2.0'
48
50
  required_rubygems_version: !ruby/object:Gem::Requirement
49
51
  requirements:
50
52
  - - ">="
51
53
  - !ruby/object:Gem::Version
52
54
  version: '0'
53
55
  requirements: []
54
- rubygems_version: 3.2.22
56
+ rubygems_version: 3.3.6
55
57
  signing_key:
56
58
  specification_version: 4
57
59
  summary: Nice output to console/file from concurrent threads.