command_mapper 0.2.1 → 0.3.0
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/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.
|