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 +4 -4
- data/.gitignore +1 -0
- data/.ruby-version +1 -1
- data/.travis.yml +14 -2
- data/CHANGELOG.md +11 -0
- data/README.md +9 -0
- data/bin/autotest +6 -0
- data/bin/e2e +1 -1
- data/bin/matrix +35 -0
- data/bin/release +2 -1
- data/demos/ping_monitor.rb +19 -0
- data/docker-compose.yml +27 -0
- data/docker/Dockerfile.alpine +14 -0
- data/docker/Dockerfile.alpine-2.1 +14 -0
- data/docker/Dockerfile.alpine-2.2 +14 -0
- data/docker/Dockerfile.alpine-2.3 +14 -0
- data/docker/Dockerfile.debian +13 -0
- data/docker/entrypoint.sh +6 -0
- data/examples/every.rb +23 -0
- data/examples/every_ping.rb +15 -0
- data/examples/k_visibility.rb +15 -0
- data/examples/kill.rb +1 -1
- data/examples/live_output.rb +1 -1
- data/examples/nano.rb +1 -1
- data/examples/nano_match.rb +1 -1
- data/examples/out_once.rb +21 -0
- data/examples/out_once_chaining.rb +29 -0
- data/examples/stdout_to_file.rb +2 -2
- data/examples/timeout.rb +2 -2
- data/examples/when_chaining.rb +15 -0
- data/kommando.gemspec +4 -1
- data/lib/kommando.rb +20 -44
- data/lib/kommando/matchers.rb +6 -0
- data/lib/kommando/matchers/base.rb +31 -0
- data/lib/kommando/matchers/every.rb +16 -0
- data/lib/kommando/matchers/once.rb +5 -0
- data/lib/kommando/stdin.rb +22 -0
- data/lib/kommando/stdout.rb +61 -0
- data/lib/kommando/version.rb +1 -1
- metadata +39 -4
- data/lib/kommando/buffer.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 06f39743982905083dccf326b8edd83f882cefa4
|
4
|
+
data.tar.gz: f7eb8a290c764606b716c2b15a451179502eb716
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c913d9b57655dfd1768c682cba99f0f0109c8cad22d2eff6a024c68c1b85e75672fab5449295f4ce9cfee0917994507f76bf338ecfdcbc21e79cd3aa3b523814
|
7
|
+
data.tar.gz: 2fead68560757c6bad67aa22d663fa59cce61587bab9b52ed7e01f7ea6b71d379c468e230f0549bbe5e7c2963ab5eeac1cf1668aa492c6648e74b2811ccd859f
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.4.1
|
data/.travis.yml
CHANGED
@@ -1,4 +1,16 @@
|
|
1
|
+
dist: trusty
|
1
2
|
language: ruby
|
2
3
|
rvm:
|
3
|
-
- 2.
|
4
|
-
|
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
|
data/CHANGELOG.md
CHANGED
@@ -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.
|
data/bin/autotest
ADDED
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, ".")
|
data/bin/matrix
ADDED
@@ -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
|
data/bin/release
CHANGED
@@ -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
|
data/docker-compose.yml
ADDED
@@ -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
|
data/examples/every.rb
ADDED
@@ -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
|
data/examples/kill.rb
CHANGED
data/examples/live_output.rb
CHANGED
data/examples/nano.rb
CHANGED
data/examples/nano_match.rb
CHANGED
@@ -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]
|
data/examples/stdout_to_file.rb
CHANGED
data/examples/timeout.rb
CHANGED
@@ -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]
|
data/kommando.gemspec
CHANGED
@@ -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
|
-
|
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
|
data/lib/kommando.rb
CHANGED
@@ -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
|
-
@
|
57
|
-
@
|
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 @
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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,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,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
|
data/lib/kommando/version.rb
CHANGED
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
|
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:
|
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.
|
235
|
+
rubygems_version: 2.6.11
|
201
236
|
signing_key:
|
202
237
|
specification_version: 4
|
203
238
|
summary: Command runner with expect-like features
|
data/lib/kommando/buffer.rb
DELETED
@@ -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
|