rubyshell 1.1.0 → 1.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 +124 -19
- data/lib/rubyshell/chain_context.rb +4 -3
- data/lib/rubyshell/chainer.rb +7 -8
- data/lib/rubyshell/command.rb +19 -11
- data/lib/rubyshell/executor.rb +16 -3
- data/lib/rubyshell/version.rb +1 -1
- data/lib/rubyshell.rb +2 -22
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3dc52bfe0cf67de6392904a19c61eecd1ba03d309ed0b71fe7c9f62c43a99389
|
4
|
+
data.tar.gz: 99ec7930b2fb5223efe6533fee5357ea1a18ee8501267479157d533e9be687e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f44145f622774e54812697bb03a16e06f5b1a5f4dedbe3832879af9f500144a1b81a67424a0567b0a738efa713c5d849321f58ba6281fe8c2d573e53d04343b3
|
7
|
+
data.tar.gz: 6b213e46dd112c32449cfab374cafefaa41265dfdc4b32152bfeac6757757266bdb56e81dc975f9c816c8818edc1d5533e28bebacdda510310f2fb43c7a2b83b
|
data/README.md
CHANGED
@@ -11,41 +11,39 @@
|
|
11
11
|
<a href="https://rubygems.org/gems/rubyshell">
|
12
12
|
<img src="https://img.shields.io/gem/dt/rubyshell.svg?label=Downloads&colorA=004d99&colorB=0073e6" alt="Gem Version">
|
13
13
|
</a>
|
14
|
-
<a href="https://github.com/albertalef/
|
15
|
-
<img src="https://github.com/albertalef/
|
14
|
+
<a href="https://github.com/albertalef/rubyshell/actions/workflows/main.yml">
|
15
|
+
<img src="https://github.com/albertalef/rubyshell/actions/workflows/main.yml/badge.svg" alt="Build Status">
|
16
16
|
</a>
|
17
17
|
<a href="https://opensource.org/licenses/MIT">
|
18
18
|
<img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License">
|
19
19
|
</a>
|
20
20
|
|
21
21
|
<p align="center">
|
22
|
-
<a href="
|
22
|
+
<a href="#installation">Installation</a>
|
23
23
|
·
|
24
|
-
<a href="
|
24
|
+
<a href="#usage">Usage</a>
|
25
25
|
·
|
26
|
-
<a href="
|
26
|
+
<a href="#complete-example">Examples</a>
|
27
27
|
·
|
28
|
-
<a href="
|
28
|
+
<a href="#contributing">Contributing</a>
|
29
|
+
·
|
30
|
+
<a href="#sponsors">Sponsors</a>
|
29
31
|
</p>
|
30
32
|
</p>
|
31
33
|
<br />
|
32
34
|
<br />
|
33
35
|
|
34
36
|
```ruby
|
35
|
-
cd "/log" do
|
36
|
-
|
37
|
-
|
37
|
+
cd "/log" do
|
38
|
+
ls.each_line do |line|
|
39
|
+
puts cat(line)
|
40
|
+
end
|
38
41
|
end
|
39
|
-
end
|
40
42
|
```
|
41
43
|
|
42
44
|
Yes, that’s valid Ruby!
|
43
45
|
`ls` and `cat` are just shell commands, but **RubyShell** makes them behave like Ruby methods.
|
44
46
|
|
45
|
-
## Usage
|
46
|
-
|
47
|
-
|
48
|
-
|
49
47
|
## Installation
|
50
48
|
|
51
49
|
Install the gem and add to the application's Gemfile by executing:
|
@@ -56,12 +54,119 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
56
54
|
|
57
55
|
$ gem install rubyshell
|
58
56
|
|
59
|
-
##
|
57
|
+
## Usage
|
58
|
+
|
59
|
+
### Calling a shell command
|
60
|
+
With RubyShell, every shell command can be used inside the ruby, you just need to call
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
sh do
|
64
|
+
puts pwd # => /Users/albertalef/projects/rubyshell
|
65
|
+
end
|
66
|
+
```
|
67
|
+
|
68
|
+
### Passing arguments
|
69
|
+
Here we have different ways to pass arguments to a command.
|
70
|
+
You can separate strings, use only one, use hashes, anyway will work
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
sh do
|
74
|
+
docker("ps", all: true) # Using hash syntax = docker ps --all
|
75
|
+
|
76
|
+
docker("ps", a: true) # Using hash syntax = docker ps -a
|
77
|
+
|
78
|
+
docker("ps", '-a') # Passing multiple strings = docker ps -a
|
79
|
+
|
80
|
+
docker("ps -a") # Passing one string = docker ps -a
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
### Changing folder
|
85
|
+
Has two possible ways, changing the folder of the code, or running code only inside a folder
|
86
|
+
|
87
|
+
##### Chaging code folder
|
88
|
+
```ruby
|
89
|
+
sh do
|
90
|
+
puts pwd # => /Users/albertalef/projects/rubyshell
|
91
|
+
|
92
|
+
cd 'examples'
|
93
|
+
|
94
|
+
puts pwd # => /Users/albertalef/projects/rubyshell/examples
|
95
|
+
end
|
96
|
+
```
|
97
|
+
|
98
|
+
##### Executing code inside another folder
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
sh do
|
102
|
+
cd 'examples' do
|
103
|
+
puts pwd # => /Users/albertalef/projects/rubyshell/examples
|
104
|
+
end
|
105
|
+
|
106
|
+
puts pwd # => /Users/albertalef/projects/rubyshell
|
107
|
+
end
|
108
|
+
```
|
109
|
+
|
110
|
+
### Chaining commands
|
111
|
+
The `chain` method make possible we use shell operators inside the ruby, like `& && | > >> < <<`
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
sh do
|
115
|
+
chain { echo "Dummy text" >> "dummy.txt" }
|
116
|
+
|
117
|
+
puts cat("dummy.txt") # => "Dummy text"
|
118
|
+
end
|
119
|
+
|
120
|
+
sh do
|
121
|
+
number_of_files = chain { ls | wc('-l') }.chomp
|
122
|
+
|
123
|
+
puts number_of_files # => 5
|
124
|
+
end
|
125
|
+
```
|
126
|
+
|
127
|
+
## Complete example
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
#!/usr/bin/env ruby
|
131
|
+
|
132
|
+
require "rubyshell"
|
133
|
+
require "securerandom"
|
134
|
+
|
135
|
+
sh do
|
136
|
+
mkdir "files"
|
137
|
+
|
138
|
+
cd "files" do
|
139
|
+
5.times do |i|
|
140
|
+
chain do
|
141
|
+
echo(SecureRandom.alphanumeric(16)) >> "#{i}.txt"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
puts "Number of Files: #{ls.lines.count}"
|
146
|
+
|
147
|
+
ls.each_line do |filename|
|
148
|
+
puts cat(filename)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
ensure
|
152
|
+
rm "-rf files"
|
153
|
+
end
|
154
|
+
|
155
|
+
# Running:
|
156
|
+
#
|
157
|
+
# ❯ ./examples/example1.rb
|
158
|
+
#
|
159
|
+
# Number of Files: 5
|
160
|
+
# o6Kw8KHvWJnLGSeQ
|
161
|
+
# qkRKcZHqu2Moq1se
|
162
|
+
# nUPluln9GM1ydtoz
|
163
|
+
# rkdYsc1RBhkeN1dq
|
164
|
+
# ZPXZMqzYfyFfjPHF
|
165
|
+
```
|
166
|
+
|
167
|
+
## Coming
|
60
168
|
|
61
|
-
-
|
62
|
-
- [ ] More examples
|
63
|
-
- [ ] Tests
|
64
|
-
- [ ] Github Action
|
169
|
+
- Support to Streams
|
65
170
|
|
66
171
|
## Development
|
67
172
|
|
@@ -1,11 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
module RubyShell
|
3
4
|
class ChainContext
|
4
|
-
def self.method_missing(method_name, *args, &)
|
5
|
-
RubyShell::Chainer.new(RubyShell::Command.new(method_name, *(args << {_manual: true}), &))
|
5
|
+
def self.method_missing(method_name, *args, &block)
|
6
|
+
RubyShell::Chainer.new(RubyShell::Command.new(method_name, *(args << { _manual: true }), &block))
|
6
7
|
end
|
7
8
|
|
8
|
-
def self.respond_to_missing?(
|
9
|
+
def self.respond_to_missing?(_name, _include_private)
|
9
10
|
false
|
10
11
|
end
|
11
12
|
end
|
data/lib/rubyshell/chainer.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
module RubyShell
|
3
4
|
class Chainer
|
5
|
+
attr_reader :parts
|
6
|
+
|
4
7
|
def initialize(command)
|
5
8
|
@parts = [command]
|
6
9
|
end
|
@@ -9,13 +12,13 @@ module RubyShell
|
|
9
12
|
@parts = [
|
10
13
|
*@parts,
|
11
14
|
operator.to_s,
|
12
|
-
*(chainer.is_a?(RubyShell::Chainer) ? chainer.parts : chainer)
|
15
|
+
*(chainer.is_a?(RubyShell::Chainer) ? chainer.parts : chainer)
|
13
16
|
]
|
14
17
|
|
15
18
|
self
|
16
19
|
end
|
17
20
|
|
18
|
-
def method_missing(method_name, *args, &)
|
21
|
+
def method_missing(method_name, *args, &block)
|
19
22
|
if method_name.start_with?(/[^A-Za-z0-9]/)
|
20
23
|
handle_chain(method_name, args.first)
|
21
24
|
else
|
@@ -23,16 +26,12 @@ module RubyShell
|
|
23
26
|
end
|
24
27
|
end
|
25
28
|
|
26
|
-
def respond_to_missing?(
|
29
|
+
def respond_to_missing?(_name, _include_private)
|
27
30
|
false
|
28
31
|
end
|
29
32
|
|
30
33
|
def exec_commands
|
31
|
-
|
32
|
-
end
|
33
|
-
|
34
|
-
def parts
|
35
|
-
@parts
|
34
|
+
`#{to_shell}`.chomp
|
36
35
|
end
|
37
36
|
|
38
37
|
def to_shell
|
data/lib/rubyshell/command.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RubyShell
|
2
4
|
class Command
|
3
5
|
def initialize(command_name, *args, &block)
|
@@ -22,21 +24,27 @@ module RubyShell
|
|
22
24
|
@args.map do |arg|
|
23
25
|
case arg
|
24
26
|
when Hash
|
25
|
-
arg
|
26
|
-
next if k.start_with?("_")
|
27
|
-
|
28
|
-
key = if k.length == 1
|
29
|
-
"-#{k}"
|
30
|
-
else
|
31
|
-
"--#{k}"
|
32
|
-
end
|
33
|
-
|
34
|
-
[key, v.is_a?(TrueClass) ? nil : v].compact.join(" ")
|
35
|
-
end.compact
|
27
|
+
map_hash_arg(arg)
|
36
28
|
else
|
37
29
|
arg.to_s
|
38
30
|
end
|
39
31
|
end.flatten
|
40
32
|
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def map_hash_arg(arg)
|
37
|
+
arg.map do |k, v|
|
38
|
+
next if k.start_with?("_")
|
39
|
+
|
40
|
+
key = if k.length == 1
|
41
|
+
"-#{k}"
|
42
|
+
else
|
43
|
+
"--#{k}"
|
44
|
+
end
|
45
|
+
|
46
|
+
[key, v.is_a?(TrueClass) ? nil : v].compact.join(" ")
|
47
|
+
end.compact
|
48
|
+
end
|
41
49
|
end
|
42
50
|
end
|
data/lib/rubyshell/executor.rb
CHANGED
@@ -1,11 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
module RubyShell
|
3
4
|
class Executor
|
4
|
-
def self.
|
5
|
-
|
5
|
+
def self.cd(path, &block)
|
6
|
+
Dir.chdir(path, &block)
|
6
7
|
end
|
7
8
|
|
8
|
-
def self.
|
9
|
+
def self.chain(&block)
|
10
|
+
result = RubyShell::ChainContext.class_eval(&block).exec_commands
|
11
|
+
|
12
|
+
raise "Command Failed" unless $?.success?
|
13
|
+
|
14
|
+
result
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.method_missing(method_name, *args)
|
18
|
+
RubyShell::Command.new(method_name, *args).exec_command
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.respond_to_missing?(_name, _include_private)
|
9
22
|
false
|
10
23
|
end
|
11
24
|
end
|
data/lib/rubyshell/version.rb
CHANGED
data/lib/rubyshell.rb
CHANGED
@@ -8,30 +8,10 @@ require_relative "rubyshell/executor"
|
|
8
8
|
|
9
9
|
module Kernel
|
10
10
|
def sh(&block)
|
11
|
-
if
|
12
|
-
RubyShell::Executor.class_eval(&block)
|
13
|
-
else
|
11
|
+
if block.nil?
|
14
12
|
RubyShell::Executor
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def sh_unsafe_mode(value)
|
19
|
-
@sh_unsafe_mode = value
|
20
|
-
end
|
21
|
-
|
22
|
-
def cd(path, &)
|
23
|
-
Dir.chdir(path, &)
|
24
|
-
end
|
25
|
-
|
26
|
-
def method_missing(method_name, *args, &)
|
27
|
-
if @sh_unsafe_mode
|
28
|
-
RubyShell::Executor.send(method_name.to_s.gsub('!', ''), *args, &)
|
29
13
|
else
|
30
|
-
|
14
|
+
RubyShell::Executor.class_eval(&block)
|
31
15
|
end
|
32
16
|
end
|
33
|
-
|
34
|
-
def chain(&)
|
35
|
-
RubyShell::ChainContext.class_eval(&).exec_commands
|
36
|
-
end
|
37
17
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubyshell
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- albertalef
|
@@ -33,6 +33,7 @@ metadata:
|
|
33
33
|
homepage_uri: https://github.com/albertalef/rubyshell
|
34
34
|
source_code_uri: https://github.com/albertalef/rubyshell
|
35
35
|
changelog_uri: https://github.com/albertalef/rubyshell
|
36
|
+
rubygems_mfa_required: 'true'
|
36
37
|
rdoc_options: []
|
37
38
|
require_paths:
|
38
39
|
- lib
|