kommando 0.0.19 → 0.0.21

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9bb1a31b4636721369778e57590b0bcff594d8e8
4
- data.tar.gz: 3ce37c43a206f0b87a7ec360102023395e69fa6b
3
+ metadata.gz: 28bb48c41521e414b25f99f504388d7f487540e7
4
+ data.tar.gz: c5a621a4d4e123a1e384662d8beac09eafd3c289
5
5
  SHA512:
6
- metadata.gz: 9e67343a7db57fd787b81efd27eba7632e7da95533a5fe909c4dcef57f6b221012e10f51fd3330aa0f99fdb976bedcbb18b2dc47aeb3845d72c6edfab77ec79e
7
- data.tar.gz: c040fe6fd13d9053589d84df59406d619585ad3d65302b73a6346348419cbe53bd4b535530a98a8bfb4a87797e8f71049992dc025a9316a548b5ceb0012d1936
6
+ metadata.gz: dac7252e7d4af6dc8ceeeff7c53a2b087e193ca2f9a87c2a5b44d9287bf3a65a883495845e87122ce9860e574e72a90722017264c5885af520087457a124ff85
7
+ data.tar.gz: 36802a54834ad364b2addabf3ea8679c801c82b3f68090c129cd5b9a0b32ddad8d198b35b229143619df6072e91995b1625601a2cee997886195afeab5d39d02
@@ -1,5 +1,12 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.0.21
4
+ - FEAT: `k.in.write` as an alias for `k.in <<`
5
+ - FEAT: `k.in.writeln` as an shorthand for `k.in.write "lol\r"`
6
+
7
+ ## 0.0.20
8
+ - FEAT: Run when callbacks immediately if the event already fired.
9
+
3
10
  ## 0.0.19
4
11
  Fixes Linux
5
12
 
data/README.md CHANGED
@@ -2,6 +2,94 @@
2
2
 
3
3
  Command runner with expect-like features. Great for integration testing.
4
4
 
5
+ ## Usage
6
+
7
+ ### Automating GNU nano:
8
+
9
+ ```
10
+ require "./lib/kommando"
11
+ require "tempfile"
12
+
13
+ scratch = Tempfile.new
14
+
15
+ k = Kommando.new "nano #{scratch.path}", {
16
+ output: true
17
+ }
18
+ k.out.on "GNU nano" do
19
+ k.in << "hello\r"
20
+ k.in << "\x1B\x1Bx"
21
+
22
+ k.out.on "Save modified buffer" do
23
+ sleep 1
24
+ k.in << "y"
25
+
26
+ k.out.on "File Name to Write" do
27
+ sleep 1
28
+ k.in << "\r"
29
+ end
30
+ end
31
+ end
32
+
33
+ k.when "start" do
34
+ puts "Kommando started running nano"
35
+ sleep 2
36
+ end
37
+
38
+ k.when "exit" do
39
+ puts "Kommando finished"
40
+ sleep 1
41
+ end
42
+
43
+ k.run
44
+ ```
45
+
46
+ ### Shell scripting
47
+
48
+ ```
49
+ require "./lib/kommando"
50
+
51
+ script = '
52
+ printf "new password: "
53
+ read input1
54
+ printf "password again: "
55
+ read input2
56
+
57
+ if [ "$input1" == "$input2" ]; then
58
+ printf "Are you sure that you want to change it? (y/N): "
59
+ read input3
60
+ if [ "$input3" == "y" ]; then
61
+ echo "changed"
62
+ else
63
+ echo "not changed"
64
+ fi
65
+ else
66
+ echo "Passwords did not match"
67
+ fi
68
+ '
69
+
70
+ k = Kommando.new "$ #{script}", {
71
+ output: true
72
+ }
73
+
74
+ k.out.on "new password:" do
75
+ k.in.write "lol\r"
76
+
77
+ k.out.on "password again:" do
78
+ k.in.writeln "lol"
79
+
80
+ k.out.on /want to change it\?/ do
81
+ k.in << "y\r"
82
+ end
83
+
84
+ k.out.on /Passwords did not match/ do
85
+ raise "this should never happen with that script."
86
+ end
87
+ end
88
+ end
89
+
90
+ k.run
91
+ ```
92
+
5
93
  ## Installation
6
94
 
7
95
  Add this line to your application's Gemfile:
@@ -18,9 +106,6 @@ Or install it yourself as:
18
106
 
19
107
  $ gem install kommando
20
108
 
21
- ## Usage
22
-
23
- TODO: Write usage instructions here
24
109
 
25
110
  ## Development
26
111
 
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "./lib/kommando"
4
+
5
+ while true do
6
+ k = Kommando.new "rake", {
7
+ timeout: 5
8
+ }
9
+
10
+ k.when :timeout do
11
+ print "t"
12
+ puts k.out
13
+ end
14
+ k.when :error do
15
+ print "e"
16
+ end
17
+
18
+ k.run
19
+
20
+ if k.code == 0
21
+ print "."
22
+ end
23
+ end
@@ -0,0 +1,42 @@
1
+ require "./lib/kommando"
2
+
3
+ script = '
4
+ printf "new password: "
5
+ read input1
6
+ printf "password again: "
7
+ read input2
8
+
9
+ if [ "$input1" == "$input2" ]; then
10
+ printf "Are you sure that you want to change it? (y/N): "
11
+ read input3
12
+ if [ "$input3" == "y" ]; then
13
+ echo "changed"
14
+ else
15
+ echo "not changed"
16
+ fi
17
+ else
18
+ echo "Passwords did not match"
19
+ fi
20
+ '
21
+
22
+ k = Kommando.new "$ #{script}", {
23
+ output: true
24
+ }
25
+
26
+ k.out.on "new password:" do
27
+ k.in.write "lol\r"
28
+
29
+ k.out.on "password again:" do
30
+ k.in.writeln "lol"
31
+
32
+ k.out.on /want to change it\?/ do
33
+ k.in << "y\r"
34
+ end
35
+
36
+ k.out.on /Passwords did not match/ do
37
+ raise "this should never happen with that script."
38
+ end
39
+ end
40
+ end
41
+
42
+ k.run
@@ -0,0 +1,18 @@
1
+ require "./lib/kommando"
2
+ require 'stackprof'
3
+
4
+
5
+ profile = StackProf.run(mode: :wall, out: 'tmp/stackprof-wall.dump', interval: 100) do
6
+ 100.times {
7
+ Kommando.run "uptime"
8
+ }
9
+ end
10
+
11
+ profile = StackProf.run(mode: :cpu, out: 'tmp/stackprof-cpu.dump', interval: 100) do
12
+ 100.times {
13
+ Kommando.run "uptime"
14
+ }
15
+ end
16
+
17
+ Kommando.puts "stackprof tmp/stackprof-wall.dump --text"
18
+ Kommando.puts "stackprof tmp/stackprof-cpu.dump --text"
@@ -1,10 +1,22 @@
1
1
  require "./lib/kommando"
2
2
 
3
+ last_k = nil
3
4
  100.times do
4
- k = Kommando.run "uptime"
5
+ last_k = Kommando.run "uptime", {
6
+ timeout: 0.1
7
+ }
8
+ last_k.when :timeout do
9
+ print "t"
10
+ puts last_k.out
11
+ end
5
12
  print "."
6
13
  end
7
- sleep 0.25
8
14
 
9
- raise "Thread leak" unless Thread.list.count == 1
15
+ puts ""
16
+ unless Thread.list.count == 1
17
+ puts Thread.list.map(&:inspect).join("\n")
18
+ puts last_k.out
19
+ raise "Thread leak"
20
+
21
+ end
10
22
  puts "ok"
@@ -25,4 +25,6 @@ Gem::Specification.new do |spec|
25
25
  spec.add_development_dependency "rspec-autotest", "~> 1.0"
26
26
  spec.add_development_dependency "ZenTest", "~> 4.11"
27
27
  spec.add_development_dependency "byebug"
28
+ spec.add_development_dependency "stackprof"
29
+ spec.add_development_dependency "trapper"
28
30
  end
@@ -88,7 +88,7 @@ class Kommando
88
88
  begin
89
89
  Process.kill('KILL', @pid)
90
90
  rescue Errno::ESRCH => ex
91
- raise ex # see if happens
91
+ #raise ex # see if happens
92
92
  end
93
93
 
94
94
  @kill_happened = true
@@ -145,7 +145,10 @@ class Kommando
145
145
  end
146
146
 
147
147
  begin
148
+ debug "pty before spawn"
148
149
  make_pty_testable.spawn(command, *interpolated_args) do |stdout, stdin, pid|
150
+ debug "pty in spawn"
151
+
149
152
  @pid = pid
150
153
 
151
154
  if @output_file
@@ -153,25 +156,36 @@ class Kommando
153
156
  stdout_file.sync = true
154
157
  end
155
158
 
156
- thread_stdin = Thread.new do
157
- sleep 0.1 # allow program to start, do not write "in terminal"
158
- while true do
159
- break if @process_completed
160
- # c = nil
161
- # Timeout.timeout(1) do
162
- c = @stdin.getc
163
- #end
164
-
165
- unless c
166
- sleep 0.01
167
- next
159
+ thread_stdin = nil
160
+ self.when :start do
161
+ thread_stdin = Thread.new do
162
+ while true do
163
+ break if @process_completed
164
+ # c = nil
165
+ # Timeout.timeout(1) do
166
+ c = @stdin.getc
167
+ #end
168
+
169
+ unless c
170
+ sleep 0.01
171
+ next
172
+ end
173
+
174
+ stdin.write c
168
175
  end
169
-
170
- stdin.write c
171
176
  end
172
177
  end
173
178
 
174
- @when.fire :start unless @start_fired
179
+
180
+ debug "thread_stdin started"
181
+
182
+ unless @start_fired
183
+ debug "when :start firing"
184
+ @when.fire :start
185
+ debug "when :start fired"
186
+ else
187
+ debug "when :start NOT fired, as :start has already been fired"
188
+ end
175
189
 
176
190
  if @timeout
177
191
  begin
@@ -186,7 +200,9 @@ class Kommando
186
200
  process_stdout(pid, stdout, stdout_file)
187
201
  end
188
202
  @process_completed = true
189
-
203
+ debug "thread_stdin joining"
204
+ thread_stdin.join
205
+ debug "thread_stdin joined"
190
206
  stdout_file.close if @output_file
191
207
  end
192
208
 
@@ -239,6 +255,7 @@ class Kommando
239
255
  @when.fire :timeout if @timeout_happened
240
256
  @when.fire :exit
241
257
 
258
+ debug "run returning true"
242
259
  true
243
260
  end
244
261
 
@@ -267,7 +284,13 @@ class Kommando
267
284
  end
268
285
 
269
286
  def wait
270
- sleep 0.001 until @code
287
+ debug "k.wait starting"
288
+ exited = false
289
+ self.when :exit do
290
+ exited = true
291
+ end
292
+ sleep 0.0001 until exited
293
+ debug "k.wait done"
271
294
  end
272
295
 
273
296
  def when(event, &block)
@@ -276,6 +299,11 @@ class Kommando
276
299
 
277
300
  private
278
301
 
302
+ def debug(msg)
303
+ return unless ENV["DEBUG"]
304
+ print "|#{msg}"
305
+ end
306
+
279
307
  def raise_after_callbacks(exception)
280
308
  @when.fire :error
281
309
  @when.fire :exit
@@ -289,6 +317,7 @@ class Kommando
289
317
  def process_stdout(pid, stdout, stdout_file)
290
318
  flushing = false
291
319
  while true do
320
+ debug "process_stdout started"
292
321
  begin
293
322
  Process.getpgid(pid)
294
323
  rescue Errno::ESRCH => ex
@@ -18,6 +18,14 @@ class Kommando::Buffer
18
18
  @buffer << string
19
19
  end
20
20
 
21
+ def write(string)
22
+ self << string
23
+ end
24
+
25
+ def writeln(string)
26
+ self.write "#{string}\r"
27
+ end
28
+
21
29
  def getc
22
30
  @buffer.shift
23
31
  end
@@ -1,3 +1,3 @@
1
1
  class Kommando
2
- VERSION = "0.0.19"
2
+ VERSION = "0.0.21"
3
3
  end
@@ -3,6 +3,7 @@ class Kommando::When
3
3
 
4
4
  def initialize
5
5
  @whens = {}
6
+ @fired = []
6
7
  end
7
8
 
8
9
  def register(event_name, block)
@@ -14,16 +15,32 @@ class Kommando::When
14
15
  else
15
16
  [block]
16
17
  end
18
+
19
+ if @fired.include? event_name_as_sym
20
+ debug "cb firing as #{event_name_as_sym} already fired."
21
+ block.call
22
+ debug "cb fired as #{event_name_as_sym} already fired."
23
+ else
24
+ debug "cb for #{event_name_as_sym} registered, not fired."
25
+ end
17
26
  end
18
27
 
19
28
  def fire(event_name)
20
29
  event_name_as_sym = event_name.to_sym
21
30
  validate_event_name(event_name_as_sym)
22
31
 
23
- return unless blocks = @whens[event_name]
32
+ @fired << event_name_as_sym
33
+ debug "set #{event_name_as_sym} as fired"
24
34
 
25
- blocks.each do |block|
26
- block.call
35
+ if blocks = @whens[event_name]
36
+ debug "firing cbs for #{event_name_as_sym}"
37
+ blocks.each do |block|
38
+ debug "firing cb for #{event_name_as_sym}"
39
+ block.call
40
+ debug "fired cb for #{event_name_as_sym}"
41
+ end
42
+ else
43
+ debug "no cbs for #{event_name_as_sym}"
27
44
  end
28
45
  end
29
46
 
@@ -31,4 +48,9 @@ class Kommando::When
31
48
  def validate_event_name(event_name_as_sym)
32
49
  raise Kommando::Error, "When '#{event_name_as_sym}' is not known." unless VALID_EVENTS.include? event_name_as_sym
33
50
  end
51
+
52
+ def debug(msg)
53
+ return unless ENV["DEBUG"]
54
+ print "W#{msg}"
55
+ end
34
56
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kommando
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.19
4
+ version: 0.0.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matti Paksula
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-07-21 00:00:00.000000000 Z
11
+ date: 2016-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -94,6 +94,34 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: stackprof
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: trapper
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
97
125
  description: Great for integration testing.
98
126
  email:
99
127
  - matti.paksula@iki.fi
@@ -113,6 +141,7 @@ files:
113
141
  - Rakefile
114
142
  - bin/console
115
143
  - bin/e2e
144
+ - bin/loop
116
145
  - bin/reinstall
117
146
  - bin/release
118
147
  - bin/setup
@@ -127,9 +156,11 @@ files:
127
156
  - examples/live_output.rb
128
157
  - examples/nano.rb
129
158
  - examples/nano_match.rb
159
+ - examples/passwd.rb
130
160
  - examples/ping.rb
131
161
  - examples/shell.rb
132
162
  - examples/shorthands.rb
163
+ - examples/stackprof.rb
133
164
  - examples/stderr_to_out.rb
134
165
  - examples/stdout_to_file.rb
135
166
  - examples/thread_leak.rb
@@ -145,6 +176,7 @@ files:
145
176
  - lib/kommando/when.rb
146
177
  - tests/forever_true.rb
147
178
  - tests/forever_uptime.rb
179
+ - tmp/.gitkeep
148
180
  homepage: http://github.com/matti/kommando
149
181
  licenses:
150
182
  - MIT