eksek 0.1.0 → 0.2.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
  SHA256:
3
- metadata.gz: 38c99ca643c947821f164f389981a9958424ede39ba1aeea5ba956265291d0ff
4
- data.tar.gz: bc09955bf615924204cad88a4a7b840826633184b6830207cb1193e71f132346
3
+ metadata.gz: 0c7830e5e5d0a88f9ecc26668684d1f14c5f8a4a0144268d52d9099fb6443db1
4
+ data.tar.gz: adbfab80da9e0a617fccd0f3afd7908009274e4ea88a407b0b95bdf921fad00d
5
5
  SHA512:
6
- metadata.gz: a91f53242d38998a7b2ab739050379b07108697c488f9dc69120e8538c6ee1299a66cc07ea203bca54aa76341d8c817f107af365cbaa669f6c365704ca780757
7
- data.tar.gz: 2918aa0f4ecea9affba5a6d531a7fa7cfd89ae2186ae30f033efda40e9480a91157afe4d20879591e7e8013a92a19adea79284dcc8cbc966737d6b6624080f7f
6
+ metadata.gz: cfcf19d51d3ee081739ecb55fb6d0572f07e8865953fe6cd90cc910d0bd453990344dc7df6988e2e30a1b7e799f68e70e6909ad59b1350b6a22c730233677c88
7
+ data.tar.gz: cc6e0f4ccb882adab62d699d7c5b7b5fe010dd6dc4d48c96828a9adf3de1f2e2eb6435261fd23ab1805f8800bc44693d3f4c7bd0f9732f269ba0c1920df81afe
data/.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'eksek'
3
- s.version = '0.1.0'
3
+ s.version = '0.2.0'
4
4
  s.authors = ['Johnny Lee-Othon', 'Thomas Bretzke']
5
5
  s.homepage = 'https://github.com/taccon/eksek'
6
6
  s.summary = 'A better backticks'
@@ -13,6 +13,5 @@ Gem::Specification.new do |s|
13
13
 
14
14
  s.required_ruby_version = '~> 2.3'
15
15
  s.add_development_dependency 'rspec','~> 3'
16
- s.add_development_dependency 'rubocop', '~> 0'
17
- s.add_development_dependency 'bundler', '~> 1.0'
16
+ s.add_development_dependency 'rubocop', '~> 0.49.0'
18
17
  end
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # eksek
2
2
 
3
- [![Travis](https://img.shields.io/travis/jleeothon/eksek.svg)](https://travis-ci.org/jleeothon/eksek)
3
+ [![Travis](https://img.shields.io/travis/taccon/eksek.svg)](https://travis-ci.org/taccon/eksek)
4
+ [![Coverage Status](https://coveralls.io/repos/github/taccon/eksek/badge.svg?branch=coveralls)](https://coveralls.io/github/taccon/eksek?branch=coveralls)
4
5
 
5
6
  `eksek` is a library to run shell commands synchronously and obtain any of the standard output, standard error, and exit code with flexibility.
6
7
 
@@ -8,17 +9,23 @@
8
9
 
9
10
  ### Basic usage
10
11
 
11
- Use the `eksek` to execute a command:
12
+ Use the `eksek` method to execute a command:
12
13
 
13
14
  ```ruby
14
15
  eksek 'echo Hello'
15
16
  ```
16
17
 
17
- This returns an `EksekResult` object providing the following methods:
18
+ or the `kapture` method to execute a command but "capture" the standard output and standard error in a fashion similar to `Kernel#\`` (backticks) or `%x()`.
19
+
20
+ ```ruby
21
+ kapture 'echo Hello'
22
+ ```
23
+
24
+ These methods return an `EksekResult` object providing the following methods:
18
25
 
19
26
  - `exit` returns the exit code.
20
- - `stdout` returns the standard output as a string.
21
- - `stderr` returns the standard error as a string.
27
+ - `stdout` returns the standard output as a string if `kapture` was called.
28
+ - `stderr` returns the standard error as a string if `kapture` was called.
22
29
  - `success?` returns `true` or `false` depending of the exit code (`0` for `true`).
23
30
  - `success!` throws an exception if the command exited with a non-0 code.
24
31
 
@@ -32,25 +39,6 @@ puts eksek!('echo Hello').stdout # Hello
32
39
  puts eksek('echo Hello').success!.stdout
33
40
  ```
34
41
 
35
- ### Writing to stdin
36
-
37
- To write into the standard input a block can be used:
38
-
39
- ```ruby
40
- r = eksek('read A; echo $A') { |stdin| stdin.write "Hello" }
41
- r.success!
42
- ```
43
-
44
- If the block returns a `String` or `IO`, it will be written into the stdio.
45
-
46
- ```ruby
47
- r = eksek('read A; echo $A') { "Hello" }
48
- r.success!
49
-
50
- r = eksek('read A; echo $A') { File.open('myfile.txt') }
51
- r.success!
52
- ```
53
-
54
42
  ### Passing other options
55
43
 
56
44
  `eksek` has the same signature as `Process#spawn`. This means that:
@@ -78,7 +66,10 @@ In case you prefer an object oriented method, you can also use the `Eksekuter` c
78
66
 
79
67
  ```ruby
80
68
  # With eksek
81
- eksek 'echo Hello' { 'This goes to stdin.' }
69
+ eksek 'echo Hello'
70
+ kapture 'echo Hello'
71
+
82
72
  # With Eksekuter
83
- Eksekuter.new('echo Hello').run { 'This goes to stdin.' }
73
+ Eksekuter.new.exec('echo Hello')
74
+ Eksekuter.new.capture('echo Hello')
84
75
  ```
data/lib/eksek.rb CHANGED
@@ -9,10 +9,18 @@ module Kernel
9
9
  private
10
10
 
11
11
  def eksek *args, **opts, &block
12
- Eksekuter.new(*args, **opts).run(&block)
12
+ Eksekuter.new.exec(*args, **opts, &block)
13
13
  end
14
14
 
15
15
  def eksek! *args, **opts, &block
16
16
  eksek(*args, **opts, &block).success!
17
17
  end
18
+
19
+ def kapture *args, **opts, &block
20
+ Eksekuter.new.capture(*args, **opts, &block)
21
+ end
22
+
23
+ def kapture! *args, **opts, &block
24
+ kapture(*args, **opts, &block).success!
25
+ end
18
26
  end
data/lib/eksek_result.rb CHANGED
@@ -5,21 +5,27 @@ require_relative 'eksek_error'
5
5
  # Describes a result object to be used for evaluating
6
6
  # return values from a command
7
7
  class EksekResult
8
- # rubocop:disable Metrics/ParameterLists
9
- def initialize env, cmd, exit_code, success, stdout, stderr
8
+ def initialize env, cmd, exit_code, out_stream, err_stream
10
9
  @env = env
11
10
  @cmd = cmd
12
11
  @exit_code = exit_code
13
- @success = success
14
- @stdout = stdout
15
- @stderr = stderr
12
+ @out_stream = out_stream
13
+ @err_stream = err_stream
16
14
  end
17
15
  # rubocop:enable Metrics/ParameterLists
18
16
 
19
- attr_reader :exit_code, :stdout, :stderr
17
+ attr_reader :exit_code
18
+
19
+ def stdout
20
+ @stdout ||= @out_stream&.read
21
+ end
22
+
23
+ def stderr
24
+ @stderr ||= @err_stream&.read
25
+ end
20
26
 
21
27
  def success?
22
- @success
28
+ @exit_code.zero?
23
29
  end
24
30
 
25
31
  def success!
data/lib/eksekuter.rb CHANGED
@@ -6,75 +6,66 @@ require_relative 'eksek_result'
6
6
 
7
7
  # Class that command execution is delegated to by Eksek.
8
8
  class Eksekuter
9
- def initialize *args, **opts
10
- @env = args[0].is_a?(Hash) ? args.shift : {}
11
- @env = @env.each_with_object({}) { |(k, v), o| o[k.to_s] = v }
12
- @cmd = args.size == 1 ? args.first : args
13
- @opts = opts
9
+ # @param {Logger} logger
10
+ def initialize logger: nil
11
+ @logger = logger
12
+ @stdout_buffer = nil
13
+ @stderr_buffer = nil
14
+ @stdin_buffer = nil
14
15
  end
15
16
 
16
- def run &block
17
- spawn_process
18
- write_and_close_stdin(&block)
19
- wait
20
- read_and_close_stdout_stderr
21
- assemble_result
17
+ # Wraps around Kernel#spawn so that the return value is an EksekResult.
18
+ # @return EksekResult
19
+ def exec *args, **opts
20
+ env, cmd = split_env_and_cmd(args)
21
+ params = { env: env, cmd: cmd, opts: opts }
22
+ process_status = spawn_and_get_status(params)
23
+ assemble_result(params, process_status)
22
24
  end
23
25
 
24
- private
25
-
26
- attr_reader(
27
- :cmd,
28
- :env,
29
- :err_str,
30
- :opts,
31
- :out_str,
32
- :process_status,
33
- :stdin,
34
- :wait_thr,
35
- )
36
-
37
- def stdout
38
- @stdout ||= StringIO.new('', 'r')
39
- end
40
-
41
- def stderr
42
- @stderr ||= StringIO.new('', 'r')
26
+ # Like Eksekuter#exec but the :out and :err options are ignored; instead
27
+ # the output is attached to the EksekResult object returned.
28
+ # Returns an EksekResult object which getters :stdout and :stderr containing
29
+ # the corresponding output of the spawned process.
30
+ # @return EksekResult
31
+ def capture *args, **opts
32
+ env, cmd = split_env_and_cmd(args)
33
+ out_read, out_write = IO.pipe
34
+ err_read, err_write = IO.pipe
35
+ opts2 = opts.merge(out: out_write, err: err_write)
36
+ params = { env: env, cmd: cmd, opts: opts2 }
37
+ process_status = spawn_and_get_status(params)
38
+ out_write.close
39
+ err_write.close
40
+ assemble_result(params, process_status, out_read, err_read)
43
41
  end
44
42
 
45
- def spawn_process
46
- @stdin, @stdout, @stderr, @wait_thr = Open3.popen3(env, *cmd, opts)
47
- nil
48
- end
49
-
50
- def write_and_close_stdin
51
- return if stdin.closed? || !block_given?
52
- block_result = yield stdin
53
- block_result = StringIO.new(block_result) if block_result.is_a? String
54
- IO.copy_stream(block_result, stdin) if block_result.respond_to? :read
55
- stdin.close
56
- nil
57
- end
43
+ private
58
44
 
59
- def wait
60
- @process_status = wait_thr.value
45
+ def split_env_and_cmd args
46
+ cmd_args = args.clone
47
+ env = cmd_args.first.is_a?(Hash) ? cmd_args.shift : {}
48
+ env = env.each_with_object({}) { |(k, v), o| o[k.to_s] = v }
49
+ cmd = cmd_args.size == 1 ? cmd_args.first : cmd_args
50
+ [env, cmd]
61
51
  end
62
52
 
63
- def read_and_close_stdout_stderr
64
- streams = [stdout, stderr]
65
- @out_str, @err_str = streams.map(&:read).map(&:chomp)
66
- streams.each(&:close)
67
- nil
53
+ def spawn_and_get_status params
54
+ env = params.fetch(:env)
55
+ cmd = params.fetch(:cmd)
56
+ opts = params.fetch(:opts)
57
+ pid = spawn(env, *cmd, opts)
58
+ _, process_status = Process.wait2(pid)
59
+ process_status
68
60
  end
69
61
 
70
- def assemble_result
62
+ def assemble_result params, process_status, out_stream = nil, err_stream = nil
71
63
  EksekResult.new(
72
- env,
73
- cmd,
64
+ params.fetch(:env),
65
+ params.fetch(:cmd),
74
66
  process_status.exitstatus,
75
- process_status.success?,
76
- out_str,
77
- err_str,
67
+ out_stream,
68
+ err_stream,
78
69
  )
79
70
  end
80
71
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eksek
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Johnny Lee-Othon
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-04-01 00:00:00.000000000 Z
12
+ date: 2019-03-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -31,28 +31,14 @@ dependencies:
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: '0'
34
+ version: 0.49.0
35
35
  type: :development
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: '0'
42
- - !ruby/object:Gem::Dependency
43
- name: bundler
44
- requirement: !ruby/object:Gem::Requirement
45
- requirements:
46
- - - "~>"
47
- - !ruby/object:Gem::Version
48
- version: '1.0'
49
- type: :development
50
- prerelease: false
51
- version_requirements: !ruby/object:Gem::Requirement
52
- requirements:
53
- - - "~>"
54
- - !ruby/object:Gem::Version
55
- version: '1.0'
41
+ version: 0.49.0
56
42
  description: 'Execute shell commands and easily get stdout, stderr, exit code, and
57
43
  more
58
44