komenda 0.0.4 → 0.1.1
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 +4 -4
- data/README.md +5 -2
- data/lib/komenda.rb +1 -3
- data/lib/komenda/process.rb +58 -41
- data/lib/komenda/process_builder.rb +30 -8
- data/lib/komenda/result.rb +0 -2
- metadata +34 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1dc95e01539e2ccbbc00044df4c47da92578c9c3
|
4
|
+
data.tar.gz: 72b97381c230e7bb19d7507c495c6c3abc311a57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d2edf563c747a5816d878a0a972880a1da1b27275ba54bbbf9c3432841532aba04fbffce3f0da2d68ac35fdd4a6c1e697f9bac1b5560ae35c15f73b6bf97796
|
7
|
+
data.tar.gz: 440e085f88b4324f055ce0b5a222e6efd083acaf01efa6b83fae13be65067509b0d380e16bcd158e118ee87ad3d7b7fe02e81f4c92f02005e835c84299853d4f
|
data/README.md
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
-
Komenda
|
1
|
+
Komenda
|
2
2
|
=======
|
3
|
-
Komenda is a convenience wrapper
|
3
|
+
Komenda is a convenience wrapper to run shell commands in Ruby.
|
4
|
+
|
5
|
+
[](https://travis-ci.org/cargomedia/komenda)
|
6
|
+
[](https://rubygems.org/gems/komenda)
|
4
7
|
|
5
8
|
Usage
|
6
9
|
-----
|
data/lib/komenda.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
require 'open3'
|
2
|
-
require '
|
2
|
+
require 'events'
|
3
3
|
|
4
4
|
require 'komenda/process_builder'
|
5
5
|
require 'komenda/process'
|
6
6
|
require 'komenda/result'
|
7
7
|
|
8
8
|
module Komenda
|
9
|
-
|
10
9
|
# @param [String] command
|
11
10
|
# @param [Hash] options
|
12
11
|
# @return [Komenda::Process]
|
@@ -22,5 +21,4 @@ module Komenda
|
|
22
21
|
process_builder = Komenda::ProcessBuilder.new(command, options)
|
23
22
|
process_builder.create.run
|
24
23
|
end
|
25
|
-
|
26
24
|
end
|
data/lib/komenda/process.rb
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
module Komenda
|
2
2
|
class Process
|
3
|
-
|
4
3
|
attr_reader :output
|
5
4
|
|
6
|
-
include
|
5
|
+
include Events::Emitter
|
7
6
|
|
8
7
|
# @param [ProcessBuilder] process_builder
|
9
8
|
def initialize(process_builder)
|
10
9
|
@process_builder = process_builder
|
11
|
-
@output = {:
|
12
|
-
@exit_status = nil
|
13
|
-
@thread = nil
|
10
|
+
@output = { stdout: '', stderr: '', combined: '' }
|
11
|
+
@exit_status = @thread = @pid = nil
|
14
12
|
|
15
13
|
on(:stdout) { |data| @output[:stdout] += data }
|
16
14
|
on(:stderr) { |data| @output[:stderr] += data }
|
@@ -22,88 +20,107 @@ module Komenda
|
|
22
20
|
|
23
21
|
# @return [Thread]
|
24
22
|
def start
|
25
|
-
|
23
|
+
fail 'Already started' if started?
|
26
24
|
@thread = Thread.new { run_process(@process_builder) }
|
27
25
|
end
|
28
26
|
|
29
27
|
# @return [Komenda::Result]
|
30
28
|
def wait_for
|
31
|
-
|
29
|
+
fail 'Process not started' unless started?
|
32
30
|
@thread.join
|
33
31
|
result
|
34
32
|
end
|
35
33
|
|
36
34
|
# @return [Komenda::Result]
|
37
35
|
def run
|
38
|
-
start unless
|
36
|
+
start unless started?
|
39
37
|
wait_for
|
40
38
|
end
|
41
39
|
|
40
|
+
# @return [Integer]
|
41
|
+
def pid
|
42
|
+
fail 'No PID available' if @pid.nil?
|
43
|
+
@pid
|
44
|
+
end
|
45
|
+
|
46
|
+
# @param [Integer, String]
|
47
|
+
def kill(signal = 'TERM')
|
48
|
+
::Process.kill(signal, pid)
|
49
|
+
end
|
50
|
+
|
42
51
|
# @return [TrueClass, FalseClass]
|
43
52
|
def running?
|
44
|
-
|
45
|
-
@thread.alive?
|
53
|
+
started? && !@pid.nil? && @thread.alive?
|
46
54
|
end
|
47
55
|
|
48
56
|
# @return [Komenda::Result]
|
49
57
|
def result
|
50
|
-
|
51
|
-
|
58
|
+
fail 'Process not started' unless started?
|
59
|
+
fail 'Process not finished' unless finished?
|
52
60
|
Komenda::Result.new(@output, @exit_status)
|
53
61
|
end
|
54
62
|
|
55
63
|
private
|
56
64
|
|
57
65
|
# @return [TrueClass, FalseClass]
|
58
|
-
def
|
66
|
+
def started?
|
59
67
|
!@thread.nil?
|
60
68
|
end
|
61
69
|
|
62
70
|
# @return [TrueClass, FalseClass]
|
63
|
-
def
|
71
|
+
def finished?
|
64
72
|
!@exit_status.nil?
|
65
73
|
end
|
66
74
|
|
67
75
|
# @param [ProcessBuilder] process_builder
|
68
76
|
def run_process(process_builder)
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
Dir.chdir(process_builder.cwd) { run_popen3(process_builder) }
|
74
|
-
end
|
75
|
-
rescue Exception => exception
|
76
|
-
emit(:error, exception)
|
77
|
-
raise exception
|
77
|
+
if process_builder.cwd.nil?
|
78
|
+
run_popen3(process_builder)
|
79
|
+
else
|
80
|
+
Dir.chdir(process_builder.cwd) { run_popen3(process_builder) }
|
78
81
|
end
|
82
|
+
rescue Exception => exception
|
83
|
+
emit(:error, exception)
|
84
|
+
raise exception
|
79
85
|
end
|
80
86
|
|
81
87
|
# @param [ProcessBuilder] process_builder
|
82
88
|
def run_popen3(process_builder)
|
83
89
|
Open3.popen3(process_builder.env, *process_builder.command) do |stdin, stdout, stderr, wait_thr|
|
90
|
+
@pid = wait_thr.pid
|
84
91
|
stdin.close
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
streams_read_available.each do |stream|
|
91
|
-
if stream.eof?
|
92
|
-
stream.close
|
93
|
-
streams_read_open.delete(stream)
|
94
|
-
else
|
95
|
-
data = stream.readpartial(4096)
|
96
|
-
emit(:stdout, data) if stdout === stream
|
97
|
-
emit(:stderr, data) if stderr === stream
|
98
|
-
emit(:output, data)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end until streams_read_open.empty?
|
102
|
-
|
92
|
+
read_streams([stdout, stderr]) do |data, stream|
|
93
|
+
emit(:output, data)
|
94
|
+
emit(:stdout, data) if stdout == stream
|
95
|
+
emit(:stderr, data) if stderr == stream
|
96
|
+
end
|
103
97
|
@exit_status = wait_thr.value
|
104
98
|
emit(:exit, result)
|
105
99
|
end
|
106
100
|
end
|
107
101
|
|
102
|
+
# @param [Array<IO>] streams
|
103
|
+
def read_streams(streams)
|
104
|
+
select_streams(streams) do |stream|
|
105
|
+
if stream.eof?
|
106
|
+
stream.close
|
107
|
+
else
|
108
|
+
data = stream.readpartial(4096)
|
109
|
+
yield(data, stream)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# @param [Array<IO>] streams
|
115
|
+
def select_streams(streams)
|
116
|
+
loop do
|
117
|
+
streams_available, = IO.select(streams)
|
118
|
+
streams_available.each do |stream|
|
119
|
+
yield(stream)
|
120
|
+
end
|
121
|
+
streams.reject!(&:closed?)
|
122
|
+
break if streams.empty?
|
123
|
+
end
|
124
|
+
end
|
108
125
|
end
|
109
126
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module Komenda
|
2
2
|
class ProcessBuilder
|
3
|
-
|
4
3
|
attr_reader :command
|
5
4
|
attr_reader :env
|
6
5
|
attr_reader :cwd
|
@@ -10,16 +9,16 @@ module Komenda
|
|
10
9
|
# @param [Hash] options
|
11
10
|
def initialize(command, options = {})
|
12
11
|
defaults = {
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
12
|
+
env: ENV.to_hash,
|
13
|
+
cwd: nil,
|
14
|
+
events: {}
|
16
15
|
}
|
17
16
|
options = defaults.merge(options)
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
18
|
+
self.command = command
|
19
|
+
self.env = options[:env]
|
20
|
+
self.cwd = options[:cwd]
|
21
|
+
self.events = options[:events]
|
23
22
|
end
|
24
23
|
|
25
24
|
# @return [Komenda::Process]
|
@@ -27,5 +26,28 @@ module Komenda
|
|
27
26
|
Komenda::Process.new(self)
|
28
27
|
end
|
29
28
|
|
29
|
+
# @param [String, Array<String>] command
|
30
|
+
def command=(command)
|
31
|
+
if command.is_a?(Array)
|
32
|
+
@command = command.map { |v| String(v) }
|
33
|
+
else
|
34
|
+
@command = String(command)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# @param [Hash] env
|
39
|
+
def env=(env)
|
40
|
+
@env = Hash[env.to_hash.map { |k, v| [String(k), String(v)] }]
|
41
|
+
end
|
42
|
+
|
43
|
+
# @param [String] cwd
|
44
|
+
def cwd=(cwd = nil)
|
45
|
+
@cwd = cwd.nil? ? nil : String(cwd)
|
46
|
+
end
|
47
|
+
|
48
|
+
# @param [Hash<Symbol, Proc>]
|
49
|
+
def events=(events)
|
50
|
+
@events = Hash[events.to_hash.map { |k, v| [k.to_sym, v.to_proc] }]
|
51
|
+
end
|
30
52
|
end
|
31
53
|
end
|
data/lib/komenda/result.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: komenda
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cargo Media
|
@@ -9,22 +9,22 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-12-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: events
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
18
|
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version:
|
20
|
+
version: 0.9.8
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version:
|
27
|
+
version: 0.9.8
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: bundler
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,6 +67,34 @@ dependencies:
|
|
67
67
|
- - "~>"
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '2.0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rspec-wait
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 0.0.8
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 0.0.8
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: rubocop
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0.35'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - "~>"
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0.35'
|
70
98
|
description: Convenience wrapper around `Open3` to run shell commands in Ruby.
|
71
99
|
email: hello@cargomedia.ch
|
72
100
|
executables: []
|
@@ -99,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
127
|
version: '0'
|
100
128
|
requirements: []
|
101
129
|
rubyforge_project:
|
102
|
-
rubygems_version: 2.
|
130
|
+
rubygems_version: 2.5.0
|
103
131
|
signing_key:
|
104
132
|
specification_version: 4
|
105
133
|
summary: Convenience wrapper around `Open3` to run shell commands in Ruby.
|