kommando 0.0.22 → 0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5d04e223cee14a391a08470955f57eaa63009148
4
- data.tar.gz: 58629080acfb3bc56c0f071283a652ea90ebacd5
3
+ metadata.gz: 06f39743982905083dccf326b8edd83f882cefa4
4
+ data.tar.gz: f7eb8a290c764606b716c2b15a451179502eb716
5
5
  SHA512:
6
- metadata.gz: bebe0fa396b5e2be603e7454550e11a1098135df56c0e9529bd7bc6a0a2213789146147d36043eff7877a0ff8080fb4d0ec2c2b7dacff2202862d57b45f4d348
7
- data.tar.gz: 5b6f6f11dae84848a166d9b9ee76150659d1d29feda6f91263b4e3c394e9e92d174a395c94f3ccd8cb3ef66479b8dde9c4a41c5797904b98ee58be66781443f5
6
+ metadata.gz: c913d9b57655dfd1768c682cba99f0f0109c8cad22d2eff6a024c68c1b85e75672fab5449295f4ce9cfee0917994507f76bf338ecfdcbc21e79cd3aa3b523814
7
+ data.tar.gz: 2fead68560757c6bad67aa22d663fa59cce61587bab9b52ed7e01f7ea6b71d379c468e230f0549bbe5e7c2963ab5eeac1cf1668aa492c6648e74b2811ccd859f
data/.gitignore CHANGED
@@ -9,3 +9,4 @@
9
9
  /tmp/
10
10
  *.gem
11
11
  .byebug_history
12
+ /profiles
@@ -1 +1 @@
1
- 2.3.3
1
+ 2.4.1
@@ -1,4 +1,16 @@
1
+ dist: trusty
1
2
  language: ruby
2
3
  rvm:
3
- - 2.3.0
4
- before_install: gem install bundler -v 1.11.2
4
+ - 2.4
5
+ - 2.3
6
+ - 2.2
7
+ - 2.1
8
+ before_install:
9
+ - sudo apt-get update -qq
10
+ - sudo apt-get install -yqq nano
11
+ - gem install bundler
12
+ install:
13
+ - bundle
14
+ script:
15
+ - rake
16
+ - bin/e2e
@@ -1,5 +1,16 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.1.0
4
+ - DOCS: `demos/ping_monitor.rb`
5
+ - FEAT: `k.out.once` can chain `k.out.every` (`k.out.once(/smth/).every(/aftersmth/)`
6
+ - FEAT: `k.out.every` can chain `k.out.once` (`k.out.every(/smth/).once(/aftersmth/)`
7
+ - FEAT: MatchData will be passed as the first argument of the proc on `k.once` and `k.every`
8
+ - FEAT: `k.out.every` matching with chaining
9
+ - FEAT: `k.out.once` matching with chaining (will deprecate `k.on`)
10
+ - FEAT: Ruby 2.1 compatibility
11
+ - FEAT: `k.when` returns `k` so when's can be defined as a chain
12
+ - FIX: Ruby 2.4 Fixnum deprecation warning
13
+
3
14
  ## 0.0.22
4
15
  - FEAT: Global whens with `Kommando.when :timeout block` and clearing with `Kommando.when = nil`
5
16
  - FEAT: Context available with `k.when :timeout do |kontextual_k|` and `Kommando.when :timeout |kontextual_k|`
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # Kommando
2
+ [![Build Status](https://travis-ci.org/matti/kommando.svg?branch=master)](https://travis-ci.org/matti/kommando)
2
3
 
3
4
  Command runner with expect-like features. Great for integration testing.
4
5
 
@@ -115,6 +116,14 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
115
116
 
116
117
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bin/release`, which will run all tests, create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
117
118
 
119
+ ### Notes
120
+
121
+ ```
122
+ RSPEC_PROFILE=each rake spec
123
+ RSPEC_PROFILE=all rake spec
124
+ # --> profiles directory
125
+ ```
126
+
118
127
  ## Contributing
119
128
 
120
129
  Bug reports and pull requests are welcome on GitHub at https://github.com/matti/kommando.
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env sh
2
+
3
+ while true; do
4
+ rake
5
+ read input
6
+ done
data/bin/e2e CHANGED
@@ -6,7 +6,7 @@ require 'tempfile'
6
6
  find_examples = Kommando.new "find examples -type f -name *"
7
7
  find_examples.run
8
8
 
9
- e2e_output = Tempfile.new
9
+ e2e_output = Tempfile.new "test"
10
10
 
11
11
  for example in find_examples.out.split("\r\n") do
12
12
  print "Running #{example} ".ljust(74, ".")
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "./lib/kommando"
4
+ require "yaml"
5
+
6
+ docker_compose=YAML.load(File.read("docker-compose.yml"))
7
+ services = docker_compose["services"].keys
8
+
9
+ Kommando.run("docker-compose build", {
10
+ output: true
11
+ }).when(:failed) {
12
+ raise "build failed"
13
+ }
14
+
15
+ ks = []
16
+ for service in services
17
+ k = Kommando.new "docker-compose up #{service}"
18
+ k.run_async
19
+ ks << k
20
+ end
21
+
22
+ loop do
23
+ for k in ks do
24
+ cmd=k.instance_variable_get(:@cmd)
25
+ puts "#{cmd} (#{(k.code ? "STOP" : "RUNNING")})"
26
+
27
+ if k.code
28
+ puts k.out
29
+ exit 1
30
+ end
31
+ end
32
+
33
+ print "-"*20; puts " #{DateTime.now.to_s}"
34
+ sleep 2
35
+ end
@@ -9,7 +9,8 @@ set -e
9
9
 
10
10
  rake; rake; rake
11
11
  bin/e2e
12
- #bin/stress 2 10
12
+ #bin/matrix
13
+ bin/stress 2 10
13
14
 
14
15
  echo
15
16
  head CHANGELOG.md
@@ -0,0 +1,19 @@
1
+ require "./lib/kommando"
2
+
3
+ k = Kommando.new "ping -i 0.2 127.0.0.1"
4
+
5
+ k.out.every /time=(\d+\.\d+)\s/ do |m|
6
+ time = m[1].to_f
7
+ print "#{time} ".ljust(6)
8
+ puts "x" * (time*300.to_i)
9
+ end
10
+
11
+ k.out.once(/^PING.+\n$/).every(/^(.+)\r\n/) do |m|
12
+ unless m[1].start_with? "64 bytes from"
13
+ puts "ERR: unexpected reply: #{m[1]}"
14
+ exit 1
15
+ end
16
+ end
17
+
18
+
19
+ k.run
@@ -0,0 +1,27 @@
1
+ version: '2.1'
2
+
3
+ services:
4
+ alpine:
5
+ build:
6
+ context: .
7
+ dockerfile: docker/Dockerfile.alpine
8
+
9
+ debian:
10
+ build:
11
+ context: .
12
+ dockerfile: docker/Dockerfile.debian
13
+
14
+ alpine-2.1:
15
+ build:
16
+ context: .
17
+ dockerfile: docker/Dockerfile.alpine-2.1
18
+
19
+ alpine-2.2:
20
+ build:
21
+ context: .
22
+ dockerfile: docker/Dockerfile.alpine-2.2
23
+
24
+ alpine-2.3:
25
+ build:
26
+ context: .
27
+ dockerfile: docker/Dockerfile.alpine-2.3
@@ -0,0 +1,14 @@
1
+ FROM ruby:2.4.1-alpine
2
+
3
+ RUN apk add --no-cache \
4
+ git build-base \
5
+ nano bash
6
+
7
+ WORKDIR /app
8
+
9
+ COPY Gemfile Gemfile.lock kommando.gemspec ./
10
+ COPY lib/kommando/version.rb ./lib/kommando/
11
+ RUN bundle install
12
+
13
+ COPY . .
14
+ ENTRYPOINT docker/entrypoint.sh
@@ -0,0 +1,14 @@
1
+ FROM ruby:2.1-alpine
2
+
3
+ RUN apk add --no-cache \
4
+ git build-base \
5
+ nano bash
6
+
7
+ WORKDIR /app
8
+
9
+ COPY Gemfile Gemfile.lock kommando.gemspec ./
10
+ COPY lib/kommando/version.rb ./lib/kommando/
11
+ RUN bundle install
12
+
13
+ COPY . .
14
+ ENTRYPOINT docker/entrypoint.sh
@@ -0,0 +1,14 @@
1
+ FROM ruby:2.2-alpine
2
+
3
+ RUN apk add --no-cache \
4
+ git build-base \
5
+ nano bash
6
+
7
+ WORKDIR /app
8
+
9
+ COPY Gemfile Gemfile.lock kommando.gemspec ./
10
+ COPY lib/kommando/version.rb ./lib/kommando/
11
+ RUN bundle install
12
+
13
+ COPY . .
14
+ ENTRYPOINT docker/entrypoint.sh
@@ -0,0 +1,14 @@
1
+ FROM ruby:2.3-alpine
2
+
3
+ RUN apk add --no-cache \
4
+ git build-base \
5
+ nano bash
6
+
7
+ WORKDIR /app
8
+
9
+ COPY Gemfile Gemfile.lock kommando.gemspec ./
10
+ COPY lib/kommando/version.rb ./lib/kommando/
11
+ RUN bundle install
12
+
13
+ COPY . .
14
+ ENTRYPOINT docker/entrypoint.sh
@@ -0,0 +1,13 @@
1
+ FROM ruby:2.4.1
2
+ ENV DEBIAN_FRONTEND=noninteractive
3
+
4
+ RUN apt-get update && apt-get install -y nano
5
+
6
+ WORKDIR /app
7
+
8
+ COPY Gemfile Gemfile.lock kommando.gemspec ./
9
+ COPY lib/kommando/version.rb ./lib/kommando/
10
+ RUN bundle install
11
+
12
+ COPY . .
13
+ ENTRYPOINT docker/entrypoint.sh
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env sh
2
+ set -e
3
+
4
+ while true; do
5
+ rake
6
+ done
@@ -0,0 +1,23 @@
1
+ require "./lib/kommando"
2
+
3
+ calls = []
4
+ calls_chained = []
5
+
6
+ k = Kommando.new("$ echo hello hello hello hell", {
7
+ output: false
8
+ })
9
+
10
+ k.out.every("hello") do
11
+ calls << :got_hello
12
+ end
13
+
14
+ k.out.every("hello") do
15
+ calls_chained << :got_hello
16
+ end.every("hell") do
17
+ calls_chained << :got_hell
18
+ end
19
+
20
+ k.run
21
+
22
+ raise "err" unless calls == [:got_hello, :got_hello, :got_hello]
23
+ raise "err chained" unless calls_chained == [:got_hello, :got_hell, :got_hello, :got_hell, :got_hello, :got_hell]
@@ -0,0 +1,15 @@
1
+ require "./lib/kommando"
2
+
3
+ calls = []
4
+
5
+ k = Kommando.new("ping -c 2 -i 0.2 127.0.0.1", {
6
+ output: false
7
+ })
8
+
9
+ k.out.every(/from (\d+\.\d+\.\d+\.\d+):/) do |m|
10
+ calls << m[1]
11
+ end
12
+
13
+ k.run
14
+
15
+ raise "err" unless calls == ["127.0.0.1", "127.0.0.1"]
@@ -0,0 +1,15 @@
1
+ require "./lib/kommando"
2
+
3
+ k_in_when, k_in_out_on = nil, nil
4
+
5
+ k = Kommando.new "$ echo something"
6
+ k.when(:exit) do #NOTE: no |k| needed (naturally)
7
+ k_in_when = true if k
8
+ end
9
+ k.out.on("something") do
10
+ k_in_out_on = true if k
11
+ end
12
+
13
+ k.run
14
+
15
+ raise "err" unless k_in_when && k_in_out_on
@@ -2,7 +2,7 @@ require "./lib/kommando"
2
2
 
3
3
  k = Kommando.run_async "sleep 10"
4
4
 
5
- sleep 1
5
+ sleep 0.1
6
6
  k.kill
7
7
  puts "..killed."
8
8
 
@@ -1,5 +1,5 @@
1
1
  require "./lib/kommando"
2
2
 
3
- Kommando.run "ping -c 3 127.0.0.1", {
3
+ Kommando.run "ping -c 3 -i 0.2 127.0.0.1", {
4
4
  output: true
5
5
  }
@@ -1,7 +1,7 @@
1
1
  require "./lib/kommando"
2
2
  require "tempfile"
3
3
 
4
- scratch = Tempfile.new
4
+ scratch = Tempfile.new "test"
5
5
 
6
6
  k = Kommando.new "nano #{scratch.path}", {
7
7
  output: true
@@ -1,7 +1,7 @@
1
1
  require "./lib/kommando"
2
2
  require "tempfile"
3
3
 
4
- scratch = Tempfile.new
4
+ scratch = Tempfile.new "test"
5
5
 
6
6
  k = Kommando.new "nano #{scratch.path}", {
7
7
  output: true
@@ -0,0 +1,21 @@
1
+ require "./lib/kommando"
2
+
3
+ calls = []
4
+ calls_matchdata = []
5
+
6
+ k = Kommando.new("ping -c 3 -i 0.2 127.0.0.1", {
7
+ output: false
8
+ })
9
+
10
+ k.out.once("bytes") do
11
+ calls << :first
12
+ end
13
+
14
+ k.out.once(/from (\d+)\./) do |m|
15
+ calls_matchdata << m[1]
16
+ end
17
+
18
+ k.run
19
+
20
+ raise "err" unless calls == [:first]
21
+ raise "err matchdata" unless calls_matchdata == ["127"]
@@ -0,0 +1,29 @@
1
+ require "./lib/kommando"
2
+
3
+ calls_bytes = []
4
+ calls_icmp = []
5
+ calls_ttl_then_time = []
6
+
7
+ k = Kommando.new("ping -c 3 -i 0.2 127.0.0.1", {
8
+ output: true
9
+ })
10
+
11
+ k.out.on("bytes") do
12
+ calls_bytes << :only_bytes
13
+ end
14
+
15
+ k.out.once("icmp_seq") do
16
+ calls_icmp << :first_icmp
17
+ end.once("icmp_seq") do
18
+ calls_icmp << :second_icmp
19
+ end
20
+
21
+ k.out.once("ttl").once("time") do
22
+ calls_ttl_then_time << :only_ttl_then_time
23
+ end
24
+
25
+ k.run
26
+
27
+ raise "err icmp" unless calls_icmp == [:first_icmp, :second_icmp]
28
+ raise "err bytes" unless calls_bytes == [:only_bytes]
29
+ raise "err ttl_then_time" unless calls_ttl_then_time == [:only_ttl_then_time]
@@ -1,9 +1,9 @@
1
1
  require "./lib/kommando"
2
2
  require "tempfile"
3
3
 
4
- outfile = Tempfile.new
4
+ outfile = Tempfile.new "test"
5
5
 
6
- k = Kommando.new "ping -c 3 127.0.0.1", {
6
+ k = Kommando.new "ping -c 3 -i 0.2 127.0.0.1", {
7
7
  output: outfile.path
8
8
  }
9
9
 
@@ -1,10 +1,10 @@
1
1
  require "./lib/kommando"
2
2
 
3
3
  k = Kommando.new "sleep 2", {
4
- timeout: 0.5
4
+ timeout: 0.1
5
5
  }
6
6
  k2 = Kommando.new "sleep 2", {
7
- timeout: 0.5
7
+ timeout: 0.1
8
8
  }
9
9
 
10
10
  did_run_timeout_callback = false
@@ -0,0 +1,15 @@
1
+ require "./lib/kommando"
2
+
3
+ calls = []
4
+ k = Kommando.new("$ exit 0")
5
+ k.when(:success) do
6
+ calls << :success
7
+ end.when(:failed) do
8
+ calls << :failed # should never happen
9
+ end.when(:exit) do
10
+ calls << :exit
11
+ end
12
+
13
+ k.run
14
+
15
+ raise "err" unless calls == [:exit, :success]
@@ -14,7 +14,9 @@ Gem::Specification.new do |spec|
14
14
  spec.homepage = "http://github.com/matti/kommando"
15
15
  spec.license = "MIT"
16
16
 
17
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ if Dir.exist? ".git"
18
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
19
+ end
18
20
  spec.bindir = "exe"
19
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
22
  spec.require_paths = ["lib"]
@@ -27,4 +29,5 @@ Gem::Specification.new do |spec|
27
29
  spec.add_development_dependency "byebug"
28
30
  spec.add_development_dependency "stackprof"
29
31
  spec.add_development_dependency "trapper"
32
+ spec.add_development_dependency "rspec-prof"
30
33
  end
@@ -1,10 +1,15 @@
1
1
  require "pty"
2
2
  require "timeout"
3
3
 
4
+ class Kommando
5
+ end
6
+
4
7
  require_relative "kommando/error"
5
8
  require_relative "kommando/version"
6
- require_relative "kommando/buffer"
7
9
  require_relative "kommando/when"
10
+ require_relative "kommando/stdout"
11
+ require_relative "kommando/stdin"
12
+ require_relative "kommando/matchers"
8
13
 
9
14
  class Kommando
10
15
  class << self
@@ -38,7 +43,6 @@ class Kommando
38
43
  @@timeout=value
39
44
  end
40
45
 
41
-
42
46
  def when(event_name, &block)
43
47
  @@whens ||= Kommando::When.new
44
48
  @@whens.register event_name, block
@@ -53,8 +57,9 @@ class Kommando
53
57
  Thread.abort_on_exception=true
54
58
 
55
59
  @cmd = cmd
56
- @stdout = Buffer.new
57
- @stdin = Buffer.new
60
+ @shell = @cmd.start_with? "$"
61
+ @stdout = Kommando::Stdout.new @shell
62
+ @stdin = Kommando::Stdin.new
58
63
 
59
64
  @output_stdout = opts[:output] == true
60
65
  @output_file = if opts[:output].class == String
@@ -63,7 +68,7 @@ class Kommando
63
68
 
64
69
  @timeout = if opts[:timeout].class == Float
65
70
  opts[:timeout]
66
- elsif opts[:timeout].class == Fixnum
71
+ elsif opts[:timeout].class.to_s == "Integer" || opts[:timeout].class.to_s == "Fixnum"
67
72
  opts[:timeout].to_f
68
73
  else
69
74
  @timeout = @@timeout
@@ -94,11 +99,6 @@ class Kommando
94
99
  @thread = nil
95
100
  @pid = nil
96
101
 
97
- @shell = false
98
-
99
- @matchers = {}
100
- @matcher_buffer = ""
101
-
102
102
  @whens = {}
103
103
  @when = When.new(self)
104
104
 
@@ -138,8 +138,7 @@ class Kommando
138
138
  return false if @executed
139
139
  @executed = true
140
140
 
141
- command, *args = if @cmd.start_with? "$"
142
- @shell = true
141
+ command, *args = if @shell
143
142
  trash, line = @cmd.split "$", 2
144
143
  line.lstrip!
145
144
  ["bash", "-c", line]
@@ -270,16 +269,16 @@ class Kommando
270
269
  137
271
270
  else
272
271
  begin
273
- Timeout.timeout(0.1) do
274
- Process.wait @pid if @pid
275
- end
272
+ Process.wait @pid if @pid
276
273
  rescue Errno::ECHILD => ex
277
274
  # safe to supress, I guess
278
- rescue Timeout::Error => ex
279
- # seems to be okay...
280
275
  end
281
276
 
282
- $?.exitstatus
277
+ if $?
278
+ $?.exitstatus
279
+ else
280
+ 137 # sometimes with ruby2.1 ? (maybefix now?)
281
+ end
283
282
  end
284
283
 
285
284
  @when.fire :error if @rescue_happened
@@ -298,19 +297,7 @@ class Kommando
298
297
  end
299
298
 
300
299
  def out
301
- string = if @shell
302
- @stdout.to_s.strip
303
- else
304
- @stdout.to_s
305
- end
306
-
307
- kommando = self
308
- string.define_singleton_method(:on) do |matcher, &block|
309
- matchers = kommando.instance_variable_get(:@matchers)
310
- matchers[matcher] = block
311
- end
312
-
313
- string
300
+ @stdout.to_s
314
301
  end
315
302
 
316
303
  def code
@@ -333,6 +320,7 @@ class Kommando
333
320
 
334
321
  def when(event, &block)
335
322
  @when.register event, block
323
+ self
336
324
  end
337
325
 
338
326
  private
@@ -375,21 +363,9 @@ class Kommando
375
363
  break if flushing == true && c == nil
376
364
  next unless c
377
365
 
378
- @stdout.append c if c
366
+ @stdout << c
379
367
  print c if @output_stdout
380
368
  stdout_file.write c if @output_file
381
-
382
- if c
383
- @matcher_buffer << c
384
-
385
- matchers_copy = @matchers.clone # blocks can insert to @matchers while iteration is undergoing
386
- matchers_copy.each_pair do |matcher,block|
387
- if @matcher_buffer.match matcher
388
- block.call
389
- @matchers.delete matcher # do not match again TODO: is this safe?
390
- end
391
- end
392
- end
393
369
  end
394
370
  end
395
371
 
@@ -0,0 +1,6 @@
1
+ module Kommando::Matchers
2
+ end
3
+
4
+ require_relative "matchers/base"
5
+ require_relative "matchers/once"
6
+ require_relative "matchers/every"
@@ -0,0 +1,31 @@
1
+ class Kommando::Matchers::Base
2
+ attr_reader :nested_matchers
3
+
4
+ def initialize(regexp, block)
5
+ @regexp = regexp
6
+ @block = block
7
+
8
+ @nested_matchers = []
9
+ end
10
+
11
+ def match(string)
12
+ raise "#match not implemented"
13
+ end
14
+
15
+ def call(match_data=nil)
16
+ return unless @block
17
+ @block.call match_data
18
+ end
19
+
20
+ def once(regexp, &block)
21
+ m = Kommando::Matchers::Once.new regexp, block
22
+ @nested_matchers << m
23
+ m
24
+ end
25
+
26
+ def every(regexp, &block)
27
+ m = Kommando::Matchers::Every.new regexp, block
28
+ @nested_matchers << m
29
+ m
30
+ end
31
+ end
@@ -0,0 +1,16 @@
1
+ class Kommando::Matchers::Every < Kommando::Matchers::Base
2
+ def initialize(regexp, block)
3
+ super regexp, block
4
+ @cursor = 0
5
+ end
6
+
7
+ def match(string)
8
+ match_data = string[@cursor..-1].match(@regexp)
9
+ @cursor = string.length if match_data
10
+ match_data
11
+ end
12
+
13
+ def skip_by(string)
14
+ @cursor = string.length
15
+ end
16
+ end
@@ -0,0 +1,5 @@
1
+ class Kommando::Matchers::Once < Kommando::Matchers::Base
2
+ def match(string)
3
+ string.match(@regexp)
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ class Kommando; class Stdin
2
+ def initialize
3
+ @buffer = []
4
+ end
5
+
6
+ def getc
7
+ @buffer.shift
8
+ end
9
+
10
+ def <<(string)
11
+ @buffer << string
12
+ end
13
+
14
+ def write(string)
15
+ self << string
16
+ end
17
+
18
+ def writeln(string)
19
+ self << string << "\r"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,61 @@
1
+ class Kommando; class Stdout
2
+ def initialize(shell)
3
+ @buffer = []
4
+ @matchers = []
5
+ @matcher_buffer = ""
6
+
7
+ @shell = shell
8
+ end
9
+
10
+ def <<(c)
11
+ @buffer << c
12
+ @matcher_buffer << c
13
+
14
+ matchers_copy = @matchers.clone # blocks can insert to @matchers while iteration is undergoing
15
+ matchers_copy.each do |matcher|
16
+ if (match_data = matcher.match @matcher_buffer)
17
+ matcher.call match_data
18
+ unless matcher.class == Kommando::Matchers::Every
19
+ @matchers.delete matcher #TODO: is this safe?
20
+ end
21
+
22
+ matcher.nested_matchers.each do |nested_matcher|
23
+ if nested_matcher.class == Kommando::Matchers::Every
24
+ nested_matcher.skip_by(@matcher_buffer)
25
+ end
26
+ @matchers = @matchers + [nested_matcher] #TODO: is this safe?
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ def to_s
33
+ string = @buffer.join ""
34
+
35
+ #TODO: this behaviour maybe makes no sense?
36
+ string.strip! if @shell
37
+
38
+ matchers = @matchers
39
+ #TODO: deprecate .on
40
+ string.define_singleton_method(:on) do |regexp, &block|
41
+ m = Kommando::Matchers::Once.new regexp, block
42
+ matchers << m
43
+ m
44
+ end
45
+
46
+ string.define_singleton_method(:once) do |regexp, &block|
47
+ m = Kommando::Matchers::Once.new regexp, block
48
+ matchers << m
49
+ m
50
+ end
51
+
52
+ string.define_singleton_method(:every) do |regexp, &block|
53
+ m = Kommando::Matchers::Every.new regexp, block
54
+ matchers << m
55
+ m
56
+ end
57
+
58
+ string
59
+ end
60
+
61
+ end; end
@@ -1,3 +1,3 @@
1
1
  class Kommando
2
- VERSION = "0.0.22"
2
+ VERSION = "0.1.0"
3
3
  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.22
4
+ version: 0.1.0
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-12-07 00:00:00.000000000 Z
11
+ date: 2017-04-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec-prof
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
125
139
  description: Great for integration testing.
126
140
  email:
127
141
  - matti.paksula@iki.fi
@@ -139,23 +153,38 @@ files:
139
153
  - LICENSE.txt
140
154
  - README.md
141
155
  - Rakefile
156
+ - bin/autotest
142
157
  - bin/console
143
158
  - bin/e2e
144
159
  - bin/loop
160
+ - bin/matrix
145
161
  - bin/reinstall
146
162
  - bin/release
147
163
  - bin/setup
148
164
  - bin/stress
149
165
  - bin/version
166
+ - demos/ping_monitor.rb
167
+ - docker-compose.yml
168
+ - docker/Dockerfile.alpine
169
+ - docker/Dockerfile.alpine-2.1
170
+ - docker/Dockerfile.alpine-2.2
171
+ - docker/Dockerfile.alpine-2.3
172
+ - docker/Dockerfile.debian
173
+ - docker/entrypoint.sh
150
174
  - examples/async.rb
151
175
  - examples/env.rb
176
+ - examples/every.rb
177
+ - examples/every_ping.rb
152
178
  - examples/exit.rb
153
179
  - examples/in.rb
154
180
  - examples/in_shell.rb
181
+ - examples/k_visibility.rb
155
182
  - examples/kill.rb
156
183
  - examples/live_output.rb
157
184
  - examples/nano.rb
158
185
  - examples/nano_match.rb
186
+ - examples/out_once.rb
187
+ - examples/out_once_chaining.rb
159
188
  - examples/passwd.rb
160
189
  - examples/ping.rb
161
190
  - examples/shell.rb
@@ -168,10 +197,16 @@ files:
168
197
  - examples/uptime.rb
169
198
  - examples/wait.rb
170
199
  - examples/when.rb
200
+ - examples/when_chaining.rb
171
201
  - kommando.gemspec
172
202
  - lib/kommando.rb
173
- - lib/kommando/buffer.rb
174
203
  - lib/kommando/error.rb
204
+ - lib/kommando/matchers.rb
205
+ - lib/kommando/matchers/base.rb
206
+ - lib/kommando/matchers/every.rb
207
+ - lib/kommando/matchers/once.rb
208
+ - lib/kommando/stdin.rb
209
+ - lib/kommando/stdout.rb
175
210
  - lib/kommando/version.rb
176
211
  - lib/kommando/when.rb
177
212
  - tests/forever_true.rb
@@ -197,7 +232,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
197
232
  version: '0'
198
233
  requirements: []
199
234
  rubyforge_project:
200
- rubygems_version: 2.5.2
235
+ rubygems_version: 2.6.11
201
236
  signing_key:
202
237
  specification_version: 4
203
238
  summary: Command runner with expect-like features
@@ -1,36 +0,0 @@
1
- class Kommando::Buffer
2
-
3
- def initialize
4
- @buffer = []
5
-
6
- @matchers = {}
7
- end
8
-
9
- def append(string)
10
- @buffer << string
11
- end
12
-
13
- def to_s
14
- @buffer.join ""
15
- end
16
-
17
- def <<(string)
18
- @buffer << string
19
- end
20
-
21
- def write(string)
22
- self << string
23
- end
24
-
25
- def writeln(string)
26
- self.write "#{string}\r"
27
- end
28
-
29
- def getc
30
- @buffer.shift
31
- end
32
-
33
- def on(matcher, &block)
34
- @matchers[matcher] = block
35
- end
36
- end