kommando 0.0.22 → 0.1.0

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