kommando 0.0.19 → 0.0.21

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
  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