clino 0.1.2 → 0.1.3
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/CODE_OF_CONDUCT.md +1 -1
- data/README.md +5 -13
- data/lib/clino/common/utils.rb +5 -0
- data/lib/clino/domain/input_parser.rb +22 -19
- data/lib/clino/domain/result_obtainer.rb +5 -1
- data/lib/clino/domain/signature/base.rb +2 -2
- data/lib/clino/domain/signature/cli_signature.rb +32 -3
- data/lib/clino/interfaces/base/base_cli.rb +19 -5
- data/lib/clino/interfaces/cli.rb +10 -3
- data/lib/clino/interfaces/min.rb +1 -1
- data/lib/clino/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df8da7e0b98d842743ff6574a23b88f48382faa9ccc218734b9696db55758799
|
4
|
+
data.tar.gz: ec26f662643aa566eaf2572d79a0d50dbb96a1d23550899329967a3299708b1f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1accf77eb7242b41b00a9b19cedecb00a6116d429016123714a9bc0f08dc82d371216b9bfbe733ee411a18da97074c0e919f1e5b88248f5786293003be8ec695
|
7
|
+
data.tar.gz: b96437b5d23babb6a6749e23414ed5aef3bc3effe2690399ccb22136a5e686f3be8ec9f97a8bdd419ef66e69c993495bf4baeb25aac121c40d9f678cb094f9eb
|
data/CODE_OF_CONDUCT.md
CHANGED
@@ -39,7 +39,7 @@ This Code of Conduct applies within all community spaces, and also applies when
|
|
39
39
|
|
40
40
|
## Enforcement
|
41
41
|
|
42
|
-
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at
|
42
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at snusmumrmail@gmail.com. All complaints will be reviewed and investigated promptly and fairly.
|
43
43
|
|
44
44
|
All community leaders are obligated to respect the privacy and security of the reporter of any incident.
|
45
45
|
|
data/README.md
CHANGED
@@ -48,14 +48,10 @@ Let's write a simple script that takes a name as an argument and prints a greeti
|
|
48
48
|
|
49
49
|
require "clino/interfaces/min"
|
50
50
|
|
51
|
-
|
52
|
-
"Hello, #{name}!"
|
53
|
-
end
|
54
|
-
|
55
|
-
Min.new(:hello).start
|
51
|
+
Min.new(->(name) { "Hello, #{name}!" }).start
|
56
52
|
```
|
57
53
|
|
58
|
-
Writing
|
54
|
+
Writing lambda containing only business logic is enough, as the input and output handling is done by the `Min` interface.
|
59
55
|
|
60
56
|
Run the script with the following command:
|
61
57
|
|
@@ -72,7 +68,7 @@ ruby hello.rb --help
|
|
72
68
|
or
|
73
69
|
|
74
70
|
```bash
|
75
|
-
ruby hello.rb
|
71
|
+
ruby hello.rb -h
|
76
72
|
```
|
77
73
|
|
78
74
|
It will print the following output:
|
@@ -85,7 +81,6 @@ Arguments:
|
|
85
81
|
<name> [string]
|
86
82
|
|
87
83
|
Usage: hello.rb [arguments] [options]
|
88
|
-
Use --h, --help to print this help message.
|
89
84
|
```
|
90
85
|
#### Randomizer Minimalistic Example
|
91
86
|
|
@@ -140,7 +135,7 @@ ruby min_randomizer.rb --help
|
|
140
135
|
or
|
141
136
|
|
142
137
|
```bash
|
143
|
-
ruby min_randomizer.rb
|
138
|
+
ruby min_randomizer.rb -h
|
144
139
|
```
|
145
140
|
|
146
141
|
It will print the following output:
|
@@ -163,7 +158,6 @@ Options:
|
|
163
158
|
[--incl] [string] [default: unknown]
|
164
159
|
|
165
160
|
Usage: min_randomizer.rb [arguments] [options]
|
166
|
-
Use --h, --help to print this help message.
|
167
161
|
```
|
168
162
|
|
169
163
|
As we can see, ruby's metaprogramming capabilities allow us to create a simple CLI, however it doesn't provide a way to handle complex input.
|
@@ -232,7 +226,7 @@ ruby randomizer.rb --help
|
|
232
226
|
or
|
233
227
|
|
234
228
|
```bash
|
235
|
-
ruby randomizer.rb
|
229
|
+
ruby randomizer.rb -h
|
236
230
|
```
|
237
231
|
|
238
232
|
It will print the following output:
|
@@ -260,7 +254,6 @@ Options:
|
|
260
254
|
[--incl] (-i) [bool] [default: false]
|
261
255
|
|
262
256
|
Usage: randomizer.rb [arguments] [options]
|
263
|
-
Use --h, --help to print this help message.
|
264
257
|
```
|
265
258
|
|
266
259
|
As we can see, all the default values, helping notes, and types are written out, and the input validation is handled automatically.
|
@@ -314,7 +307,6 @@ Arguments:
|
|
314
307
|
<height> [positive_integer]
|
315
308
|
|
316
309
|
Usage: weight_calculator.rb [arguments] [options]
|
317
|
-
Use --h, --help to print this help message.
|
318
310
|
```
|
319
311
|
|
320
312
|
## Improvements
|
data/lib/clino/common/utils.rb
CHANGED
@@ -4,10 +4,18 @@ require "optparse"
|
|
4
4
|
|
5
5
|
module InputParser
|
6
6
|
def parse_input(args_and_opts, signature)
|
7
|
+
args_and_opts = args_and_opts.map do |arg|
|
8
|
+
idx = 0
|
9
|
+
idx += 1 while arg[idx..].start_with?("-") && idx < arg.length
|
10
|
+
part_to_replace = arg[idx..].gsub("-", "_")
|
11
|
+
arg[0...idx] + part_to_replace
|
12
|
+
end
|
13
|
+
|
7
14
|
input = {}
|
8
15
|
pos_args = []
|
16
|
+
allowed_options = signature.allowed_options
|
9
17
|
args_and_opts.each do |arg|
|
10
|
-
break if
|
18
|
+
break if allowed_options.include?(arg)
|
11
19
|
|
12
20
|
pos_args << arg
|
13
21
|
end
|
@@ -19,25 +27,20 @@ module InputParser
|
|
19
27
|
input[arg.name] = load_input arg.type, val if arg
|
20
28
|
end
|
21
29
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
input[name] = load_input signature.opts[name].type, v
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
opt.on("--h", "--help", "Prints this help") do
|
38
|
-
input[:help] = true
|
30
|
+
prev_opt_name = nil
|
31
|
+
allowed_option_to_name = signature.allowed_option_to_name
|
32
|
+
opts.each do |opt|
|
33
|
+
if allowed_options.include?(opt)
|
34
|
+
prev_opt_name = allowed_option_to_name[opt]
|
35
|
+
input[prev_opt_name] = true
|
36
|
+
elsif input[prev_opt_name] == true
|
37
|
+
input[prev_opt_name] = load_input signature.opts[prev_opt_name].type, opt
|
38
|
+
prev_opt_name = nil
|
39
|
+
else
|
40
|
+
raise ArgumentError, "Can't parse #{opt} option"
|
39
41
|
end
|
40
|
-
end
|
42
|
+
end
|
43
|
+
|
41
44
|
input
|
42
45
|
end
|
43
46
|
end
|
@@ -16,8 +16,10 @@ module ResultObtainer
|
|
16
16
|
end
|
17
17
|
|
18
18
|
signature.opts.each do |opt_name, opt|
|
19
|
+
next if opt.exec_skip
|
20
|
+
|
19
21
|
if opt.required?
|
20
|
-
keyword_values[opt_name] = input[opt_name]
|
22
|
+
keyword_values[opt_name] = input[opt_name] if input.key?(opt_name)
|
21
23
|
else
|
22
24
|
keyword_values[opt_name] = input[opt_name] unless input[opt_name].nil?
|
23
25
|
end
|
@@ -25,6 +27,8 @@ module ResultObtainer
|
|
25
27
|
|
26
28
|
default_opts = signature.default_opts
|
27
29
|
default_opts.each do |opt_name, opt|
|
30
|
+
next if signature.opts[opt_name].exec_skip
|
31
|
+
|
28
32
|
keyword_values[opt_name] = opt unless keyword_values.key?(opt_name) || opt == :unknown
|
29
33
|
end
|
30
34
|
|
@@ -33,9 +33,9 @@ module Base
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
OptSignature = Struct.new(*BaseSignatureStruct.members, :aliases) do
|
36
|
+
OptSignature = Struct.new(*BaseSignatureStruct.members, :aliases, :exec_skip) do
|
37
37
|
include BaseSignature
|
38
|
-
def initialize(name:, type: :string, default: :none, desc: nil, aliases: [])
|
38
|
+
def initialize(name:, type: :string, default: :none, desc: nil, aliases: [], exec_skip: false)
|
39
39
|
super
|
40
40
|
end
|
41
41
|
end
|
@@ -10,7 +10,16 @@ class CliSignature
|
|
10
10
|
def initialize
|
11
11
|
@args = {}
|
12
12
|
@args_arr = []
|
13
|
-
@opts = {
|
13
|
+
@opts = {
|
14
|
+
help: Base::OptSignature.new(
|
15
|
+
name: :help,
|
16
|
+
type: :bool,
|
17
|
+
desc: "Prints this help message",
|
18
|
+
aliases: %w[-h],
|
19
|
+
default: false,
|
20
|
+
exec_skip: true
|
21
|
+
)
|
22
|
+
}
|
14
23
|
@description = nil
|
15
24
|
@help = nil
|
16
25
|
end
|
@@ -63,8 +72,6 @@ class CliSignature
|
|
63
72
|
|
64
73
|
@help += "\nUsage: #{program_name} [arguments] [options]"
|
65
74
|
|
66
|
-
@help += "\nUse --h, --help to print this help message.\n"
|
67
|
-
|
68
75
|
@help
|
69
76
|
end
|
70
77
|
|
@@ -107,4 +114,26 @@ class CliSignature
|
|
107
114
|
end
|
108
115
|
args
|
109
116
|
end
|
117
|
+
|
118
|
+
def allowed_options
|
119
|
+
if @allowed_options.nil?
|
120
|
+
@allowed_options = Set.new
|
121
|
+
@allowed_option_to_name = {}
|
122
|
+
@opts.each_value do |opt|
|
123
|
+
long_opt = "--#{opt.name}"
|
124
|
+
@allowed_options.add(long_opt)
|
125
|
+
@allowed_option_to_name[long_opt] = opt.name
|
126
|
+
opt.aliases.each do |alias_|
|
127
|
+
@allowed_options.add(alias_)
|
128
|
+
@allowed_option_to_name[alias_] = opt.name
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
@allowed_options
|
133
|
+
end
|
134
|
+
|
135
|
+
def allowed_option_to_name
|
136
|
+
allowed_options if @allowed_option_to_name.nil?
|
137
|
+
@allowed_option_to_name
|
138
|
+
end
|
110
139
|
end
|
@@ -5,14 +5,28 @@ module BaseCli
|
|
5
5
|
include ResultObtainer
|
6
6
|
|
7
7
|
def start(args = ARGV)
|
8
|
-
input =
|
8
|
+
input = parse_args_by_signature args
|
9
|
+
return if input.nil?
|
9
10
|
|
11
|
+
print_result run_instance input
|
12
|
+
end
|
13
|
+
|
14
|
+
def start_raw(args)
|
15
|
+
input = parse_args_by_signature args
|
16
|
+
return if input.nil?
|
17
|
+
|
18
|
+
run_instance input
|
19
|
+
end
|
20
|
+
|
21
|
+
def parse_args_by_signature(args)
|
22
|
+
parse_input args, @signature
|
23
|
+
end
|
24
|
+
|
25
|
+
def run_instance(input)
|
10
26
|
if input[:help]
|
11
|
-
|
12
|
-
return
|
27
|
+
return @signature.help
|
13
28
|
end
|
14
|
-
|
15
|
-
print_result call_method_with_args @signature, @method, input
|
29
|
+
call_method_with_args @signature, @method, input
|
16
30
|
end
|
17
31
|
|
18
32
|
def print_help
|
data/lib/clino/interfaces/cli.rb
CHANGED
@@ -8,7 +8,14 @@ require_relative "base/base_cli"
|
|
8
8
|
|
9
9
|
class Cli
|
10
10
|
class << self
|
11
|
-
attr_reader :
|
11
|
+
attr_reader :description
|
12
|
+
def opt_buffer
|
13
|
+
@opt_buffer || {}
|
14
|
+
end
|
15
|
+
|
16
|
+
def arg_buffer
|
17
|
+
@arg_buffer || {}
|
18
|
+
end
|
12
19
|
|
13
20
|
def desc(description)
|
14
21
|
@description = description
|
@@ -16,7 +23,7 @@ class Cli
|
|
16
23
|
|
17
24
|
def opt(name, type: :string, desc: nil, aliases: [], default: :none)
|
18
25
|
@opt_buffer ||= {}
|
19
|
-
aliases = aliases.map { |a| "
|
26
|
+
aliases = aliases.map { |a| "-#{general_strip a, "-"}" }
|
20
27
|
default = load_input type, default unless default == :none
|
21
28
|
@opt_buffer[name] = Base::OptSignature.new(name: name, type: type, default: default, desc: desc,
|
22
29
|
aliases: aliases)
|
@@ -38,7 +45,7 @@ class Cli
|
|
38
45
|
end
|
39
46
|
|
40
47
|
@signature.opts.each_key do |name|
|
41
|
-
@signature.add_opt(self.class.opt_buffer[name])
|
48
|
+
@signature.add_opt(self.class.opt_buffer[name]) if self.class.opt_buffer.key? name
|
42
49
|
end
|
43
50
|
|
44
51
|
@signature.description = self.class.description
|
data/lib/clino/interfaces/min.rb
CHANGED
data/lib/clino/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clino
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tikhon Zaikin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-02-
|
11
|
+
date: 2024-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |-
|
14
14
|
clino is a minimalistic CLI generator
|