command_mapper 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog.md +4 -0
- data/README.md +4 -2
- data/{commnad_mapper.gemspec → command_mapper.gemspec} +0 -0
- data/gemspec.yml +2 -2
- data/lib/command_mapper/types/dec.rb +84 -0
- data/lib/command_mapper/types/type.rb +1 -1
- data/lib/command_mapper/types.rb +1 -0
- data/lib/command_mapper/version.rb +1 -1
- data/spec/commnad_spec.rb +5 -5
- data/spec/types/dec_spec.rb +180 -0
- data/spec/types/input_dir_spec.rb +13 -9
- metadata +8 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 254468c58bbee95ac037609a4ddefc34c026240b4933a37038df1bade5b7487e
|
4
|
+
data.tar.gz: 1fe51a7d6ad09b0b51c753bee28632e70292bfa9e9938896e22183c0327f48ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1fc9b041fafa2d92300bcbf312e8b1d848450bd4691b6b0eea57fb401a8d20b8a73613328c69cc5d323e9b42313ecc2f3e66b8bcfff14454a8cdb5bd5db5467
|
7
|
+
data.tar.gz: 62fd74bd469bff9620c94a8c0710f6d309bb0611af7e58664fa7d04808ee40b14d3b076fb8143a6fdbd409a0fd35fb12682e535c30b41ed616200dc7be982bd2
|
data/ChangeLog.md
CHANGED
data/README.md
CHANGED
@@ -10,8 +10,8 @@
|
|
10
10
|
|
11
11
|
## Description
|
12
12
|
|
13
|
-
Command Mapper maps
|
14
|
-
allow safely and securely executing commands.
|
13
|
+
Command Mapper maps an external command's options and arguments to Class
|
14
|
+
attributes to allow safely and securely executing commands.
|
15
15
|
|
16
16
|
## Features
|
17
17
|
|
@@ -20,6 +20,7 @@ allow safely and securely executing commands.
|
|
20
20
|
* Supports common option types:
|
21
21
|
* [Str][CommandMapper::Types::Str]: string values
|
22
22
|
* [Num][CommandMapper::Types::Num]: numeric values
|
23
|
+
* [Dec][CommandMapper::Types::Dec]: decimal values
|
23
24
|
* [Hex][CommandMapper::Types::Hex]: hexadecimal values
|
24
25
|
* [Map][CommandMapper::Types::Map]: maps Ruby values to other String values.
|
25
26
|
* `Map::YesNo`: maps `true`/`false` to `yes`/`no`.
|
@@ -50,6 +51,7 @@ allow safely and securely executing commands.
|
|
50
51
|
|
51
52
|
[CommandMapper::Types::Str]: https://rubydoc.info/gems/command_mapper/CommandMapper/Types/Str
|
52
53
|
[CommandMapper::Types::Num]: https://rubydoc.info/gems/command_mapper/CommandMapper/Types/Num
|
54
|
+
[CommandMapper::Types::Dec]: https://rubydoc.info/gems/command_mapper/CommandMapper/Types/Dec
|
53
55
|
[CommandMapper::Types::Hex]: https://rubydoc.info/gems/command_mapper/CommandMapper/Types/Hex
|
54
56
|
[CommandMapper::Types::Map]: https://rubydoc.info/gems/command_mapper/CommandMapper/Types/Map
|
55
57
|
[CommandMapper::Types::Enum]: https://rubydoc.info/gems/command_mapper/CommandMapper/Types/Enum
|
File without changes
|
data/gemspec.yml
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
name: command_mapper
|
2
2
|
summary: Safe and secure execution of commands.
|
3
3
|
description:
|
4
|
-
Command Mapper maps
|
5
|
-
and securely executing commands.
|
4
|
+
Command Mapper maps an external command's arguments to Class attributes to
|
5
|
+
allow safely and securely executing commands.
|
6
6
|
|
7
7
|
license: MIT
|
8
8
|
authors: Postmodern
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'command_mapper/types/type'
|
2
|
+
|
3
|
+
module CommandMapper
|
4
|
+
module Types
|
5
|
+
#
|
6
|
+
# Represents a decimal value (ex: `1.5`).
|
7
|
+
#
|
8
|
+
# @since 0.3.0
|
9
|
+
#
|
10
|
+
class Dec < Type
|
11
|
+
|
12
|
+
# The optional range of acceptable decimal numbers.
|
13
|
+
#
|
14
|
+
# @return [Range<Float,Float>, nil]
|
15
|
+
#
|
16
|
+
# @api semipublic
|
17
|
+
attr_reader :range
|
18
|
+
|
19
|
+
#
|
20
|
+
# Initializes the decimal type.
|
21
|
+
#
|
22
|
+
# @param [Range<Float,Float>] range
|
23
|
+
# Specifies the range of acceptable numbers.
|
24
|
+
#
|
25
|
+
def initialize(range: nil)
|
26
|
+
@range = range
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Validates a value.
|
31
|
+
#
|
32
|
+
# @param [String, Numeric] value
|
33
|
+
# The given value to validate.
|
34
|
+
#
|
35
|
+
# @return [true, (false, String)]
|
36
|
+
# Returns true if the value is valid, or `false` and a validation error
|
37
|
+
# message if the value is not compatible.
|
38
|
+
#
|
39
|
+
# @api semipublic
|
40
|
+
#
|
41
|
+
def validate(value)
|
42
|
+
case value
|
43
|
+
when Float
|
44
|
+
# no-op
|
45
|
+
when String
|
46
|
+
unless value =~ /\A\d+(?:\.\d+)?\z/
|
47
|
+
return [false, "contains non-decimal characters (#{value.inspect})"]
|
48
|
+
end
|
49
|
+
else
|
50
|
+
unless value.respond_to?(:to_f)
|
51
|
+
return [false, "cannot be converted into a Float (#{value.inspect})"]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
if @range
|
56
|
+
unless @range.include?(value.to_f)
|
57
|
+
return [false, "(#{value.inspect}) not within the range of acceptable values (#{range.inspect})"]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
return true
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# Formats a decimal value.
|
66
|
+
#
|
67
|
+
# @param [String, Float, #to_f] value
|
68
|
+
# The given value to format.
|
69
|
+
#
|
70
|
+
# @return [String]
|
71
|
+
# The formatted decimal value.
|
72
|
+
#
|
73
|
+
# @api semipublic
|
74
|
+
#
|
75
|
+
def format(value)
|
76
|
+
case value
|
77
|
+
when Float, String then value.to_s
|
78
|
+
else value.to_f.to_s
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -58,7 +58,7 @@ module CommandMapper
|
|
58
58
|
# The default `validate` method for all types.
|
59
59
|
#
|
60
60
|
# @param [Object]
|
61
|
-
# The given value to
|
61
|
+
# The given value to validate.
|
62
62
|
#
|
63
63
|
# @return [true, (false, String)]
|
64
64
|
# Returns true if the value is valid, or `false` and a validation error
|
data/lib/command_mapper/types.rb
CHANGED
data/spec/commnad_spec.rb
CHANGED
@@ -808,7 +808,7 @@ describe CommandMapper::Command do
|
|
808
808
|
end
|
809
809
|
|
810
810
|
it "must initialize a new command with the Hash of params and call #run_command" do
|
811
|
-
if RUBY_VERSION < '3.'
|
811
|
+
if RUBY_VERSION < '3.'
|
812
812
|
expect(subject).to receive(:new).with({},params).and_return(command_instance)
|
813
813
|
else
|
814
814
|
expect(subject).to receive(:new).with(params).and_return(command_instance)
|
@@ -846,7 +846,7 @@ describe CommandMapper::Command do
|
|
846
846
|
end
|
847
847
|
|
848
848
|
it "must initialize a new command with the Hash of params and call #spawn_command" do
|
849
|
-
if RUBY_VERSION < '3.'
|
849
|
+
if RUBY_VERSION < '3.'
|
850
850
|
expect(subject).to receive(:new).with({},params).and_return(command_instance)
|
851
851
|
else
|
852
852
|
expect(subject).to receive(:new).with(params).and_return(command_instance)
|
@@ -884,7 +884,7 @@ describe CommandMapper::Command do
|
|
884
884
|
end
|
885
885
|
|
886
886
|
it "must initialize a new command with the Hash of params and call #capture_command" do
|
887
|
-
if RUBY_VERSION < '3.'
|
887
|
+
if RUBY_VERSION < '3.'
|
888
888
|
expect(subject).to receive(:new).with({},params).and_return(command_instance)
|
889
889
|
else
|
890
890
|
expect(subject).to receive(:new).with(params).and_return(command_instance)
|
@@ -922,7 +922,7 @@ describe CommandMapper::Command do
|
|
922
922
|
end
|
923
923
|
|
924
924
|
it "must initialize a new command with the Hash of params and call #popen_command" do
|
925
|
-
if RUBY_VERSION < '3.'
|
925
|
+
if RUBY_VERSION < '3.'
|
926
926
|
expect(subject).to receive(:new).with({},params).and_return(command_instance)
|
927
927
|
else
|
928
928
|
expect(subject).to receive(:new).with(params).and_return(command_instance)
|
@@ -960,7 +960,7 @@ describe CommandMapper::Command do
|
|
960
960
|
end
|
961
961
|
|
962
962
|
it "must initialize a new command with the Hash of params and call #sudo_command" do
|
963
|
-
if RUBY_VERSION < '3.'
|
963
|
+
if RUBY_VERSION < '3.'
|
964
964
|
expect(subject).to receive(:new).with({},params).and_return(command_instance)
|
965
965
|
else
|
966
966
|
expect(subject).to receive(:new).with(params).and_return(command_instance)
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'command_mapper/types/dec'
|
3
|
+
|
4
|
+
describe CommandMapper::Types::Dec do
|
5
|
+
describe "#initialize" do
|
6
|
+
context "when initialized with no keyword arguments" do
|
7
|
+
it "must set #range to nil" do
|
8
|
+
expect(subject.range).to be(nil)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context "when initialized with range: ..." do
|
13
|
+
let(:range) { 1.0..1.5 }
|
14
|
+
|
15
|
+
subject { described_class.new(range: range) }
|
16
|
+
|
17
|
+
it "must set #range" do
|
18
|
+
expect(subject.range).to eq(range)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#validate" do
|
24
|
+
context "when given an Integer" do
|
25
|
+
let(:value) { 1 }
|
26
|
+
|
27
|
+
it "must return true" do
|
28
|
+
expect(subject.validate(value)).to be(true)
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when initialized with range: ..." do
|
32
|
+
let(:range) { 2.0..10.0 }
|
33
|
+
|
34
|
+
subject { described_class.new(range: range) }
|
35
|
+
|
36
|
+
context "and the value is within the range of values" do
|
37
|
+
let(:value) { 4.0 }
|
38
|
+
|
39
|
+
it "must return true" do
|
40
|
+
expect(subject.validate(value)).to be(true)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "but the value is not within the range of values" do
|
45
|
+
let(:value) { 0.0 }
|
46
|
+
|
47
|
+
it "must return [false, \"(...) not within the range of acceptable values (...)\"]" do
|
48
|
+
expect(subject.validate(value)).to eq(
|
49
|
+
[false, "(#{value.inspect}) not within the range of acceptable values (#{range.inspect})"]
|
50
|
+
)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "when given a String" do
|
57
|
+
context "and it contains only digits" do
|
58
|
+
let(:value) { "0123456789" }
|
59
|
+
|
60
|
+
it "must return true" do
|
61
|
+
expect(subject.validate(value)).to be(true)
|
62
|
+
end
|
63
|
+
|
64
|
+
context "when initialized with range: ..." do
|
65
|
+
let(:range) { 2.0..10.0 }
|
66
|
+
|
67
|
+
subject { described_class.new(range: range) }
|
68
|
+
|
69
|
+
context "and the value is within the range of values" do
|
70
|
+
let(:value) { '4.0' }
|
71
|
+
|
72
|
+
it "must return true" do
|
73
|
+
expect(subject.validate(value)).to be(true)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "but the value is not within the range of values" do
|
78
|
+
let(:value) { '0.0' }
|
79
|
+
|
80
|
+
it "must return [false, \"(...) not within the range of acceptable values (...)\"]" do
|
81
|
+
expect(subject.validate(value)).to eq(
|
82
|
+
[false, "(#{value.inspect}) not within the range of acceptable values (#{range.inspect})"]
|
83
|
+
)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context "but the String contains a newline" do
|
89
|
+
let(:value) { "01234.\n56789" }
|
90
|
+
|
91
|
+
it "must return [false, \"contains non-decimal characters (...)\"]" do
|
92
|
+
expect(subject.validate(value)).to eq(
|
93
|
+
[false, "contains non-decimal characters (#{value.inspect})"]
|
94
|
+
)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "but it contains non-digits" do
|
100
|
+
let(:value) { "12.abc34" }
|
101
|
+
|
102
|
+
it "must return [false, \"contains non-decimal characters (...)\"]" do
|
103
|
+
expect(subject.validate(value)).to eq(
|
104
|
+
[false, "contains non-decimal characters (#{value.inspect})"]
|
105
|
+
)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context "when given another type of Object" do
|
111
|
+
context "and it defines a #to_f method" do
|
112
|
+
let(:value) { 1 }
|
113
|
+
|
114
|
+
it "must return true" do
|
115
|
+
expect(subject.validate(value)).to be(true)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "when initialized with range: ..." do
|
120
|
+
let(:range) { 2.0..10.0 }
|
121
|
+
|
122
|
+
subject { described_class.new(range: range) }
|
123
|
+
|
124
|
+
context "and the value is within the range of values" do
|
125
|
+
let(:value) { 4 }
|
126
|
+
|
127
|
+
it "must return true" do
|
128
|
+
expect(subject.validate(value)).to be(true)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
context "but the value is not within the range of values" do
|
133
|
+
let(:value) { 0 }
|
134
|
+
|
135
|
+
it "must return [false, \"(...) not within the range of acceptable values (...)\"]" do
|
136
|
+
expect(subject.validate(value)).to eq(
|
137
|
+
[false, "(#{value.inspect}) not within the range of acceptable values (#{range.inspect})"]
|
138
|
+
)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context "but it does not define a #to_f method" do
|
144
|
+
let(:value) { Object.new }
|
145
|
+
|
146
|
+
it "must return [false, \"value cannot be converted into a Float\"]" do
|
147
|
+
expect(subject.validate(value)).to eq(
|
148
|
+
[false, "cannot be converted into a Float (#{value.inspect})"]
|
149
|
+
)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "#format" do
|
156
|
+
context "when given a String" do
|
157
|
+
let(:value) { "12345.67890" }
|
158
|
+
|
159
|
+
it "must return the same String" do
|
160
|
+
expect(subject.format(value)).to eq(value)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
context "when given an Intger" do
|
165
|
+
let(:value) { 12345.67890 }
|
166
|
+
|
167
|
+
it "must convert the Integer into a String" do
|
168
|
+
expect(subject.format(value)).to eq(value.to_s)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context "when given another type of Object" do
|
173
|
+
let(:value) { 1 }
|
174
|
+
|
175
|
+
it "must call #to_i then #to_s" do
|
176
|
+
expect(subject.format(value)).to eq(value.to_f.to_s)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -3,19 +3,21 @@ require 'command_mapper/types/input_dir'
|
|
3
3
|
|
4
4
|
describe CommandMapper::Types::InputDir do
|
5
5
|
describe "#validate" do
|
6
|
-
context "when given a valid
|
7
|
-
let(:value) {
|
6
|
+
context "when given a valid directory path" do
|
7
|
+
let(:value) { __dir__ }
|
8
8
|
|
9
|
-
it "must return
|
10
|
-
expect(subject.validate(value)).to
|
9
|
+
it "must return true" do
|
10
|
+
expect(subject.validate(value)).to be(true)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
context "when given a valid
|
15
|
-
let(:value) {
|
14
|
+
context "when given a valid file path" do
|
15
|
+
let(:value) { __FILE__ }
|
16
16
|
|
17
|
-
it "must return
|
18
|
-
expect(subject.validate(value)).to eq(
|
17
|
+
it "must return [false, 'directory does not exist (...)']" do
|
18
|
+
expect(subject.validate(value)).to eq(
|
19
|
+
[false, "directory does not exist (#{value.inspect})"]
|
20
|
+
)
|
19
21
|
end
|
20
22
|
end
|
21
23
|
|
@@ -23,7 +25,9 @@ describe CommandMapper::Types::InputDir do
|
|
23
25
|
let(:value) { "/path/does/not/exist" }
|
24
26
|
|
25
27
|
it "must return [false, 'path does not exist (...)']" do
|
26
|
-
expect(subject.validate(value)).to eq(
|
28
|
+
expect(subject.validate(value)).to eq(
|
29
|
+
[false, "path does not exist (#{value.inspect})"]
|
30
|
+
)
|
27
31
|
end
|
28
32
|
end
|
29
33
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: command_mapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Postmodern
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-11-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -24,8 +24,8 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.0'
|
27
|
-
description: Command Mapper maps
|
28
|
-
safely and securely executing commands.
|
27
|
+
description: Command Mapper maps an external command's arguments to Class attributes
|
28
|
+
to allow safely and securely executing commands.
|
29
29
|
email: postmodern.mod3@gmail.com
|
30
30
|
executables: []
|
31
31
|
extensions: []
|
@@ -44,7 +44,7 @@ files:
|
|
44
44
|
- LICENSE.txt
|
45
45
|
- README.md
|
46
46
|
- Rakefile
|
47
|
-
-
|
47
|
+
- command_mapper.gemspec
|
48
48
|
- examples/grep.rb
|
49
49
|
- gemspec.yml
|
50
50
|
- lib/command_mapper.rb
|
@@ -56,6 +56,7 @@ files:
|
|
56
56
|
- lib/command_mapper/option_value.rb
|
57
57
|
- lib/command_mapper/sudo.rb
|
58
58
|
- lib/command_mapper/types.rb
|
59
|
+
- lib/command_mapper/types/dec.rb
|
59
60
|
- lib/command_mapper/types/enum.rb
|
60
61
|
- lib/command_mapper/types/hex.rb
|
61
62
|
- lib/command_mapper/types/input_dir.rb
|
@@ -77,6 +78,7 @@ files:
|
|
77
78
|
- spec/option_value_spec.rb
|
78
79
|
- spec/spec_helper.rb
|
79
80
|
- spec/sudo_spec.rb
|
81
|
+
- spec/types/dec_spec.rb
|
80
82
|
- spec/types/enum_spec.rb
|
81
83
|
- spec/types/hex_spec.rb
|
82
84
|
- spec/types/input_dir_spec.rb
|
@@ -114,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
114
116
|
- !ruby/object:Gem::Version
|
115
117
|
version: '0'
|
116
118
|
requirements: []
|
117
|
-
rubygems_version: 3.
|
119
|
+
rubygems_version: 3.3.7
|
118
120
|
signing_key:
|
119
121
|
specification_version: 4
|
120
122
|
summary: Safe and secure execution of commands.
|