shell_adapter 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +29 -0
- data/README.md +16 -0
- data/lib/cmd_failed_error.rb +2 -0
- data/lib/shell_adapter.rb +56 -0
- metadata +50 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9c604c28773fc260835782f25225dbe53a33c2aed6d1669ed1fbb76c5c733372
|
4
|
+
data.tar.gz: 2d43317111952fa08514ab52265a43f35202a47f33c167891b0b87d97b67e5b2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ad20f71921312ba70e5c2c6ae6bf402e950947261b4ea8c7f10011600c153daeaaa9281a6c8fa45a11cb19b630c771457c31c1eda87605f39d99fdd2d8d3e322
|
7
|
+
data.tar.gz: 6d0afb18e383e315e9d7f617b5648c5603031aa05fcab9f0f8f77e6b9a7c2ff9ff5edcbe1c1b85146bde080dcdb4ca7b7112ec191aa033611d2bf4c5d26a5205
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.3)
|
5
|
+
rspec (3.8.0)
|
6
|
+
rspec-core (~> 3.8.0)
|
7
|
+
rspec-expectations (~> 3.8.0)
|
8
|
+
rspec-mocks (~> 3.8.0)
|
9
|
+
rspec-core (3.8.0)
|
10
|
+
rspec-support (~> 3.8.0)
|
11
|
+
rspec-expectations (3.8.3)
|
12
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
13
|
+
rspec-support (~> 3.8.0)
|
14
|
+
rspec-mocks (3.8.0)
|
15
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
16
|
+
rspec-support (~> 3.8.0)
|
17
|
+
rspec-support (3.8.0)
|
18
|
+
|
19
|
+
PLATFORMS
|
20
|
+
ruby
|
21
|
+
|
22
|
+
DEPENDENCIES
|
23
|
+
rspec
|
24
|
+
|
25
|
+
RUBY VERSION
|
26
|
+
ruby 2.6.0p0
|
27
|
+
|
28
|
+
BUNDLED WITH
|
29
|
+
2.0.1
|
data/README.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Shell Adapter
|
2
|
+
|
3
|
+
A very simpler wrapper around the fiddliness of interacting with shell commands
|
4
|
+
in Ruby. Extracted from [Ministry of Justice's "FormBuilder Publisher"](https://github.com/ministryofjustice/fb-publisher).
|
5
|
+
|
6
|
+
# Usage
|
7
|
+
|
8
|
+
Commands executed with ShellAdapter will inherit the environment of their
|
9
|
+
parent process (i.e. the running Ruby process), including PATH.
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
# run a command with arguments, discarding the output:
|
13
|
+
ShellAdapter.exec(cmd, arg1, arg2, ....)
|
14
|
+
# e.g.
|
15
|
+
ShellAdapter.exec('cp', file_path_1, file_path_2)
|
16
|
+
```
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
require_relative 'cmd_failed_error'
|
5
|
+
|
6
|
+
class ShellAdapter
|
7
|
+
# run the given binary with the given arguments,
|
8
|
+
# discarding the output
|
9
|
+
def self.exec(binary, *args)
|
10
|
+
cmd_line = build_cmd( executable: binary, args: args )
|
11
|
+
log "executing cmd #{cmd_line}"
|
12
|
+
# TODO: maybe use Open3.popen2e instead, so that we
|
13
|
+
# can get streaming output as well as exit code?
|
14
|
+
result = Kernel.system(cmd_line)
|
15
|
+
raise CmdFailedError.new(cause: "#{$?}", message: "failing cmd: #{cmd_line}") unless result
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.output_of(*args)
|
19
|
+
capture_with_stdin(cmd: args).strip
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.capture_with_stdin(cmd: [], stdin: nil)
|
23
|
+
cmd_line = build_cmd( executable: cmd[0], args: cmd[1..-1] )
|
24
|
+
|
25
|
+
stdout_str, status = Open3.capture2(cmd_line, stdin_data: stdin)
|
26
|
+
unless status.success?
|
27
|
+
raise CmdFailedError.new(cause: "#{$?}", message: "failing cmd: #{cmd_line}")
|
28
|
+
end
|
29
|
+
stdout_str
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.build_cmd(executable:, args: [], redirect_to: nil, pipe_to: nil)
|
33
|
+
line = [executable, args].flatten.compact.join(' ')
|
34
|
+
line = add_pipe(cmd: line, to: pipe_to) if pipe_to
|
35
|
+
line = add_redirect(cmd: line, to: redirect_to) if redirect_to
|
36
|
+
line
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.add_redirect(cmd:, to:, operator: '>>')
|
40
|
+
[cmd, operator, to].join(' ')
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.add_pipe(cmd:, to:, operator: '|')
|
44
|
+
[cmd, operator, to].join(' ')
|
45
|
+
end
|
46
|
+
|
47
|
+
protected
|
48
|
+
|
49
|
+
def self.log(string, level: :info)
|
50
|
+
self.logger.send(level, string)
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.logger
|
54
|
+
@logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
|
55
|
+
end
|
56
|
+
end
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: shell_adapter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Al Davidson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-04-26 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |
|
14
|
+
A simple wrapper around the fiddliness of interacting with the shell in Ruby.
|
15
|
+
Extracted from Ministry of Justice's "FormBuilder Publisher"
|
16
|
+
(https://github.com/ministryofjustice/fb-publisher)
|
17
|
+
email: apdavidson at gmail.com
|
18
|
+
executables: []
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- Gemfile
|
23
|
+
- Gemfile.lock
|
24
|
+
- README.md
|
25
|
+
- lib/cmd_failed_error.rb
|
26
|
+
- lib/shell_adapter.rb
|
27
|
+
homepage: http://rubygems.org/gems/shelladapter
|
28
|
+
licenses:
|
29
|
+
- MIT
|
30
|
+
metadata: {}
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
requirements: []
|
46
|
+
rubygems_version: 3.0.1
|
47
|
+
signing_key:
|
48
|
+
specification_version: 4
|
49
|
+
summary: Shell Adapter
|
50
|
+
test_files: []
|