long-command-runner 0.1.4 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f6d2038cb89e937c4338cb47e4e3cbbd63e6df288ce146c56cdedaf9cd4e669
4
- data.tar.gz: 12dae9fedb930a911813dd69aa06efc30d6beda0f70c3a5ed902afd657818923
3
+ metadata.gz: 732ddcf74afb4d4a3f7e5990e4761e4fabbea37824890c98e8cc236c3339a317
4
+ data.tar.gz: 3209440517bcfcb93e020e01a3484e029487af1e61b95e86d932db6c27b30c7e
5
5
  SHA512:
6
- metadata.gz: 66a47ff6f6de3d987b5192aad839b2dccf44c5f132c6066e9430e0b0ea8ef8598bb84644936bf7b7c61c166367493a6b06d8a17ae020104a8c2d85168df24a1c
7
- data.tar.gz: 230c0b1ad2803be4f3b267f6724482715bf4bc8403dbe45d3731aa156289c26dff61e73df93c62913e6aa38a106150c45bf9723773c0ef467c53c2ba1b417294
6
+ metadata.gz: ac8cc65bf6dfc634469ca90d9312183aa17c7ec3d7d6649bddfc505879babbf0adadc503124a384d6fe3d78aa335d2d90e230bdfb7cf1d8670bfae04496efd6e
7
+ data.tar.gz: 004ca4095874c144356593c7ceedef1c8a3983b2f6a5fbf18cfd0da5ca154fac670bc64cc81acf22644a5e5603e47a026fb1231c96b69c0cfdf1bf4644e86f19
data/README.md CHANGED
@@ -12,8 +12,7 @@ the CPU usage and the progression of the program.
12
12
  ## Currently (what we have)
13
13
  - monitoring of the progression of the application through the output of the app
14
14
  (I don't think that we can do better)
15
- - get the real/user/sys time usage of the application by using the output of the `time` `bash` function.
16
- (This make it incompatible with system that doesn't support ouput redirections and bash itself)
15
+ - get the real/user/sys time usage of the application by using the lib Benchmark of ruby.
17
16
 
18
17
  ## v1 goal
19
18
 
@@ -5,6 +5,9 @@ require 'open3'
5
5
  module LCR
6
6
  # This class aims to contain the runing script.
7
7
  class Container
8
+ # The expected Language environment:
9
+ ENVIRONMENT = 'LANGUAGE=en'
10
+
8
11
  # Get the standard input IO of the process.
9
12
  #
10
13
  # @note Be aware that it may be closed by the process (on exit), or by you.
@@ -34,7 +37,8 @@ module LCR
34
37
  # @param [String] command The command to execute.
35
38
  # @param [Hash] opts The option to pass to Open3.popen3.
36
39
  def initialize(command, opts = {})
37
- @stdin, @stdout, @stderr, @wait_thr = Open3.popen3(command, opts)
40
+ safe_command = quote_sanitize(command)
41
+ @stdin, @stdout, @stderr, @wait_thr = Open3.popen3("#{ENVIRONMENT} bash -c \"#{safe_command}\"", opts)
38
42
  end
39
43
 
40
44
  # Is the last launched command is still running.
@@ -64,5 +68,11 @@ module LCR
64
68
  def pid
65
69
  @wait_thr.pid
66
70
  end
71
+
72
+ private
73
+
74
+ def quote_sanitize(cmd)
75
+ cmd.gsub(/(["])/, '\\"')
76
+ end
67
77
  end
68
78
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'open3'
4
+ require 'benchmark'
4
5
 
5
6
  module LCR
6
7
  # This class aims to manage an external process through a parallele excecution thread.
@@ -14,15 +15,11 @@ module LCR
14
15
  class Runner
15
16
  # The constant used to get the percetange of completion of the command.
16
17
  PERCENT_INDICATOR = /(.*\s|^)((\d+)([,.]\d*)?)%.*/.freeze
17
- # The constant to match a `time -p` output:
18
- TIMES_INDICATORS = /\A(real|user|sys)\s+(\d+[\.,]\d\d)\z/.freeze
19
- # The expected Language environment:
20
- ENVIRONMENT = 'LC_ALL=C.UTF-8 LANGUAGE=en'
21
18
 
22
19
  # Get the mesured progress in percentage.
23
20
  # This is just the result of parsing stdout lines with {PERCENT_INDICATOR}.
24
21
  # So this percentage is comming from the thread not this library.
25
- attr_reader :progress
22
+ attr_reader :progress, :tms
26
23
 
27
24
  # Initializer takes the command as a plain string.
28
25
  # You can optionaly pass a block that will be called when the command generate
@@ -39,7 +36,7 @@ module LCR
39
36
  @launch_lock = Mutex.new
40
37
  @on_input = on_input
41
38
  @progress = 0.0
42
- @times = { real: nil, user: nil, sys: nil }
39
+ @tms = nil
43
40
  end
44
41
 
45
42
  # Is the last launched command is still running.
@@ -56,13 +53,17 @@ module LCR
56
53
 
57
54
  # Actually launch the process.
58
55
  def launch
59
- stderr, stderr_in = IO.pipe
60
- @container = Container.new("#{ENVIRONMENT} bash -c 'time -p #{@command} 2>&3'", 3 => stderr_in)
61
- @line_reader = LineReader.new([@container.stdout, stderr, @container.stderr]) do |*new_lines|
56
+ @bench_thread = Thread.new do
57
+ @tms = Benchmark.measure do
58
+ @container = Container.new(@command)
59
+ @container.wait
60
+ end
61
+ end
62
+ Thread.pass while @container.nil?
63
+ @line_reader = LineReader.new([@container.stdout, @container.stderr]) do |*new_lines|
62
64
  on_newline(*new_lines)
63
65
  end
64
66
  @reader_thr = Thread.new { @line_reader.read }
65
- stderr_in.close
66
67
  Thread.pass
67
68
  end
68
69
 
@@ -98,9 +99,10 @@ module LCR
98
99
  #
99
100
  # @return [Process::Status]
100
101
  def wait
101
- p = @container.wait
102
+ @bench_thread.join
103
+ @reader_thr.join
102
104
  sleep 0.01 until @line_reader.streams.all?(&:eof?)
103
- p
105
+ @container.status
104
106
  end
105
107
 
106
108
  # Get the status of the process without blocking.
@@ -125,35 +127,37 @@ module LCR
125
127
  nil
126
128
  end
127
129
 
128
- # Get the time really spend ('real' part of `time` command)
129
- #
130
- # @return [Float | nil] The elapsed seconds (using POSIX.2 standard see `time -p` for more information)
131
- # if the Process isn't finished it return nil.
130
+ # Old get the time really spend ('real' part of `time` command)
131
+ # DEPRECATED: use tms access now.
132
132
  def time_real
133
- @times[:real]
133
+ warn '[DEPRECATION] use :tms instead of :time_real'
134
+ return nil if @tms.nil?
135
+
136
+ @tms.real
134
137
  end
135
138
 
136
- # Get the time in user space spend ('user' part of `time` command)
137
- #
138
- # @return [Float | nil] The elapsed seconds (using POSIX.2 standard see `time -p` for more information)
139
- # if the Process isn't finished it return nil.
139
+ # Old get the time in user space spend ('user' part of `time` command)
140
+ # DEPRECATED: use tms access now.
140
141
  def time_user
141
- @times[:user]
142
+ warn '[DEPRECATION] use :tms instead of :time_user'
143
+ return nil if @tms.nil?
144
+
145
+ @tms.cutime + @tms.utime
142
146
  end
143
147
 
144
- # Get the time system space spend ('sys' part of `time` command)
145
- #
146
- # @return [Float | nil] The elapsed seconds (using POSIX.2 standard see `time -p` for more information)
147
- # if the Process isn't finished it return nil.
148
+ # old get the time system space spend ('sys' part of `time` command)
149
+ # DEPRECATED: use tms access now.
148
150
  def time_sys
149
- @times[:sys]
151
+ warn '[DEPRECATION] use :tms instead of :time_user'
152
+ return nil if @tms.nil?
153
+
154
+ @tms.cstime + @tms.stime
150
155
  end
151
156
 
152
157
  private
153
158
 
154
- def on_newline(nl_stdout, nl_stderr, nl_time)
159
+ def on_newline(nl_stdout, nl_stderr)
155
160
  manage_progress(nl_stdout) unless nl_stdout.nil?
156
- manage_time(nl_time) unless nl_time.nil?
157
161
  @on_input&.call(nl_stdout, nl_stderr)
158
162
  end
159
163
 
@@ -163,12 +167,5 @@ module LCR
163
167
 
164
168
  @progress = match[2].to_f
165
169
  end
166
-
167
- def manage_time(new_line)
168
- match = new_line.match TIMES_INDICATORS
169
- return unless match
170
-
171
- @times[match[1].to_sym] = match[2].to_f
172
- end
173
170
  end
174
171
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module LCR
4
4
  # Version of the library.
5
- VERSION = '0.1.4'
5
+ VERSION = '0.2.0'
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: long-command-runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roland Laurès
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-28 00:00:00.000000000 Z
11
+ date: 2019-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry