command_lion 1.0.4 → 2.0.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 +5 -5
- data/examples/ctrl_c.rb +18 -0
- data/examples/debug.rb +31 -0
- data/examples/error.rb +20 -0
- data/examples/example.rb +1 -0
- data/examples/pcapr.rb +6 -1
- data/examples/readme.rb +13 -10
- data/lib/command_lion/app.rb +35 -126
- data/lib/command_lion/base.rb +1 -1
- data/lib/command_lion/command.rb +18 -290
- data/lib/command_lion/flags.rb +5 -29
- data/lib/command_lion/option.rb +0 -18
- data/lib/command_lion/raw.rb +45 -14
- data/lib/command_lion/version.rb +1 -1
- data/lib/command_lion.rb +12 -2
- metadata +5 -8
- data/examples/example_rainbows.rb +0 -21
- data/examples/flipr.rb +0 -27
- data/examples/flipr2.rb +0 -48
- data/examples/flipr3.rb +0 -31
- data/examples/flipr4.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7831b7dfa26eb6ba19e07b982ec5fa0b32f1340935148718820fa2ba07e719be
|
4
|
+
data.tar.gz: 965035c76c95b12680ca63b9ff36c58a7e46d23869246ef02d97c2770d7f865b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1bdd309f3238c084d791969dedc0248792835ed84ec247bdb7c166b26ec1a07d59245f864edc1404f1300e65c059affd8034c6efb12e95f2e88cbcfb2c517e13
|
7
|
+
data.tar.gz: 4942b2bea29cf5663ea59330ada573370cea73dbcbc2d113087726c0df82a1a68f47982e9402c7e4d0c02a6161f569d3c52b139cef4ccef6428b592d041f48c8
|
data/examples/ctrl_c.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
require 'command_lion'
|
3
|
+
require 'pry'
|
4
|
+
|
5
|
+
CommandLion::App.run do
|
6
|
+
name "Example"
|
7
|
+
|
8
|
+
ctrl_c do
|
9
|
+
puts "Exiting!"
|
10
|
+
exit 0
|
11
|
+
end
|
12
|
+
|
13
|
+
command :example do
|
14
|
+
action do
|
15
|
+
loop { puts "CTL+C to exit!"; sleep 1 }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/examples/debug.rb
CHANGED
@@ -2,4 +2,35 @@ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
|
2
2
|
require 'command_lion'
|
3
3
|
require 'pry'
|
4
4
|
|
5
|
+
|
6
|
+
cmd = CommandLion.command.new do
|
7
|
+
description "This is an example command for debugging!"
|
8
|
+
flags do
|
9
|
+
short "-e"
|
10
|
+
long "--example"
|
11
|
+
end
|
12
|
+
|
13
|
+
before do
|
14
|
+
puts "Before"
|
15
|
+
end
|
16
|
+
|
17
|
+
action do
|
18
|
+
puts "Action"
|
19
|
+
end
|
20
|
+
|
21
|
+
after do
|
22
|
+
puts "After"
|
23
|
+
end
|
24
|
+
|
25
|
+
option :rainbow do
|
26
|
+
flags do
|
27
|
+
short "-r"
|
28
|
+
long "--rainbow"
|
29
|
+
end
|
30
|
+
action do
|
31
|
+
require 'lolize/auto'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
5
36
|
binding.pry
|
data/examples/error.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
require 'command_lion'
|
3
|
+
require 'pry'
|
4
|
+
|
5
|
+
CommandLion::App.run do
|
6
|
+
name "Hello World"
|
7
|
+
|
8
|
+
command :hello_world do
|
9
|
+
flag "--hello-world"
|
10
|
+
action do
|
11
|
+
puts "Hello World!"
|
12
|
+
end
|
13
|
+
option :example do
|
14
|
+
flag "--example"
|
15
|
+
action do
|
16
|
+
puts "Example worked!"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/examples/example.rb
CHANGED
data/examples/pcapr.rb
CHANGED
@@ -9,6 +9,11 @@ CommandLion::App.run do
|
|
9
9
|
version "1.0.0"
|
10
10
|
description "Pcaprub command-line application to capture network traffic."
|
11
11
|
|
12
|
+
ctrl_c do
|
13
|
+
puts "Exiting!"
|
14
|
+
exit 0
|
15
|
+
end
|
16
|
+
|
12
17
|
command :capture do
|
13
18
|
description "Capture from a given network interface ( default: #{Pcap.lookupdev} )."
|
14
19
|
type :string
|
@@ -18,7 +23,7 @@ CommandLion::App.run do
|
|
18
23
|
capture = Pcap.open_live(argument, options[:snaplen].argument, options[:promisc].argument, options[:buffer].argument)
|
19
24
|
loop do
|
20
25
|
if packet = capture.next
|
21
|
-
puts packet
|
26
|
+
puts packet.size
|
22
27
|
end
|
23
28
|
end
|
24
29
|
end
|
data/examples/readme.rb
CHANGED
@@ -2,6 +2,7 @@ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
|
2
2
|
require 'command_lion'
|
3
3
|
require 'pry'
|
4
4
|
|
5
|
+
|
5
6
|
CommandLion::App.run do
|
6
7
|
|
7
8
|
name "Rainbow Hello"
|
@@ -10,26 +11,28 @@ CommandLion::App.run do
|
|
10
11
|
|
11
12
|
command :hello do
|
12
13
|
description "A simple command to say hello!"
|
13
|
-
|
14
|
+
|
14
15
|
type :string
|
15
|
-
|
16
|
-
|
16
|
+
|
17
|
+
flags do
|
18
|
+
short "-h"
|
19
|
+
long "--hello"
|
20
|
+
end
|
21
|
+
|
17
22
|
default "world"
|
18
23
|
|
19
24
|
action do
|
20
25
|
puts "Hello #{argument}!"
|
21
26
|
end
|
22
|
-
|
27
|
+
|
23
28
|
option :rainbow do
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
action do
|
29
|
+
description "STDOUT is much prettier with rainbows!"
|
30
|
+
flag "--rainbow"
|
31
|
+
|
32
|
+
action do
|
29
33
|
require 'lolize/auto'
|
30
34
|
end
|
31
35
|
end
|
32
36
|
end
|
33
37
|
|
34
38
|
end
|
35
|
-
|
data/lib/command_lion/app.rb
CHANGED
@@ -1,86 +1,5 @@
|
|
1
1
|
module CommandLion
|
2
2
|
|
3
|
-
# The App class provides what can be considered the "main" function for the a Command Lion application.
|
4
|
-
#
|
5
|
-
# The App class is primarily used in one of two ways:
|
6
|
-
#
|
7
|
-
# == Building Block
|
8
|
-
# To build an application using the DSL, but not run it right away, the build method block is available.
|
9
|
-
# app = CommandLion::App.build do
|
10
|
-
# # ...
|
11
|
-
# end
|
12
|
-
#
|
13
|
-
# app.run!
|
14
|
-
#
|
15
|
-
# == Run Block
|
16
|
-
# To build, parse, and run everything in one concise block, the run method block is available.
|
17
|
-
# CommandLion::App.run do
|
18
|
-
# # ...
|
19
|
-
# end
|
20
|
-
#
|
21
|
-
# == DSL Keywords:
|
22
|
-
# name::
|
23
|
-
# The name of your application. This is how your application would be referenced in conversation.
|
24
|
-
# It's also going to be used as the defualt banner for the application which will appear at the
|
25
|
-
# top of the help menu.
|
26
|
-
#
|
27
|
-
# == Example
|
28
|
-
# app = CommandLion::App.build do
|
29
|
-
# name "Example"
|
30
|
-
# end
|
31
|
-
#
|
32
|
-
# app.name?
|
33
|
-
# # => true
|
34
|
-
#
|
35
|
-
# app.name = "Changed Name"
|
36
|
-
# # => "Changed Name"
|
37
|
-
#
|
38
|
-
# app.name
|
39
|
-
# # => Changed Name
|
40
|
-
# usage::
|
41
|
-
# Your usage string can be used to help show the basic information for how to use your application.
|
42
|
-
# You can make this as simple or as complex as you like. One will be generated for you by default
|
43
|
-
# when your application runs, but won't be pre-built for you inside the build block for now.
|
44
|
-
#
|
45
|
-
# == Example
|
46
|
-
# app = CommandLion::App.build do
|
47
|
-
# usage "example [commands] [options...]"
|
48
|
-
# end
|
49
|
-
#
|
50
|
-
# app.usage?
|
51
|
-
# # => true
|
52
|
-
#
|
53
|
-
# app.usage = <<USAGE
|
54
|
-
# /|
|
55
|
-
# ~~~/ |~
|
56
|
-
# tsharky [command] [switches] [--] [arguments]
|
57
|
-
# USAGE
|
58
|
-
# # => " /|\n" + "~~~/ |~\n" + "tsharky [command] [switches] [--] [arguments]\n"
|
59
|
-
#
|
60
|
-
# app.usage
|
61
|
-
# # => " /|\n" + "~~~/ |~\n" + "tsharky [command] [switches] [--] [arguments]\n"
|
62
|
-
#
|
63
|
-
# puts app.usage
|
64
|
-
# # /|
|
65
|
-
# # ~~~/ |~
|
66
|
-
# # tsharky [command] [switches] [--] [arguments]
|
67
|
-
# description::
|
68
|
-
# To provide further context for your application's existence, it's fairly nice to have a description.
|
69
|
-
# Like, the usage statement, this can be as complex or as simple as you would like. It isn't required either.
|
70
|
-
#
|
71
|
-
# == Example
|
72
|
-
# app = CommandLion::App.build do
|
73
|
-
# description "Example"
|
74
|
-
# end
|
75
|
-
#
|
76
|
-
# app.description?
|
77
|
-
# # => true
|
78
|
-
#
|
79
|
-
# app.description = "Changed"
|
80
|
-
# # => "Changed"
|
81
|
-
#
|
82
|
-
# app.description
|
83
|
-
# # => Changed
|
84
3
|
class App < Base
|
85
4
|
|
86
5
|
def self.default_help(app)
|
@@ -100,11 +19,11 @@ module CommandLion
|
|
100
19
|
max_flag = flagz.map(&:length).max + 2
|
101
20
|
max_desc = app.commands.values.map(&:description).select{|d| d unless d.nil? }.map(&:length).max
|
102
21
|
puts app.name
|
103
|
-
puts
|
104
22
|
if app.version?
|
23
|
+
puts
|
105
24
|
puts "VERSION"
|
106
25
|
puts app.version
|
107
|
-
puts
|
26
|
+
puts unless app.description?
|
108
27
|
end
|
109
28
|
if app.description?
|
110
29
|
puts
|
@@ -118,6 +37,7 @@ module CommandLion
|
|
118
37
|
puts usage
|
119
38
|
puts
|
120
39
|
end
|
40
|
+
puts unless app.version? || app.description? || app.usage?
|
121
41
|
puts "COMMANDS"
|
122
42
|
app.commands.values.select { |cmd| cmd unless cmd.is_a? CommandLion::Option }.each do |command|
|
123
43
|
if command.flags?
|
@@ -142,12 +62,9 @@ module CommandLion
|
|
142
62
|
end
|
143
63
|
end
|
144
64
|
|
145
|
-
|
146
|
-
#
|
147
|
-
#
|
148
|
-
# this method is then used as the code that is ran in the context of a application
|
149
|
-
# object. So all of those methods will be available.
|
150
|
-
#
|
65
|
+
|
66
|
+
# The run method will run a given block of code using the
|
67
|
+
# Commmand Lion DSL.
|
151
68
|
def self.run(&block)
|
152
69
|
# Initialize an instance of an App object.
|
153
70
|
app = new
|
@@ -162,30 +79,25 @@ module CommandLion
|
|
162
79
|
cmd.before.call if cmd.before?
|
163
80
|
cmd.action.call if cmd.action?
|
164
81
|
cmd.after.call if cmd.after?
|
165
|
-
|
82
|
+
exit 0
|
166
83
|
else
|
167
84
|
# Use the default help menu for the application unless that's been
|
168
85
|
# explictly removed by the author for whatever reason.
|
169
86
|
default_help(app) unless app.default_help_menu_removed?
|
170
87
|
end
|
171
88
|
else
|
172
|
-
threadz = false
|
173
89
|
app.commands.each do |_, cmd|
|
174
90
|
next unless cmd.given?
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
cmd.action.call if cmd.action?
|
185
|
-
cmd.after.call if cmd.after?
|
186
|
-
end
|
91
|
+
cmd.options.each do |_, opt|
|
92
|
+
next unless opt.given?
|
93
|
+
opt.before.call if opt.before?
|
94
|
+
opt.action.call if opt.action?
|
95
|
+
opt.after.call if opt.after?
|
96
|
+
end if cmd.options?
|
97
|
+
cmd.before.call if cmd.before?
|
98
|
+
cmd.action.call if cmd.action?
|
99
|
+
cmd.after.call if cmd.after?
|
187
100
|
end
|
188
|
-
threadz.map(&:join) if threadz
|
189
101
|
end
|
190
102
|
end
|
191
103
|
|
@@ -205,19 +117,6 @@ module CommandLion
|
|
205
117
|
@remove_default_help_menu || false
|
206
118
|
end
|
207
119
|
|
208
|
-
# A tiny bit of rainbow magic is included. You can simple include
|
209
|
-
# this option within your application and, if you have the `lolize` gem
|
210
|
-
# installed, then rainbows will automagically be hooked to STDOUT to make your
|
211
|
-
# application much prettier.
|
212
|
-
#
|
213
|
-
# It'd be funny if this was turned on by default and you had to opt-out of the
|
214
|
-
# rainbows. Good thing I didn't do that, right?
|
215
|
-
def rainbows
|
216
|
-
require 'lolize/auto'
|
217
|
-
rescue
|
218
|
-
raise "The 'lolize' gem is not installed. Install it for rainbow magic!"
|
219
|
-
end
|
220
|
-
|
221
120
|
# Simple attributes for the application. Mostly just metadata to help
|
222
121
|
# provide some context to the application.
|
223
122
|
#
|
@@ -278,11 +177,14 @@ module CommandLion
|
|
278
177
|
cmd
|
279
178
|
end
|
280
179
|
|
180
|
+
def ctrl_c(&block)
|
181
|
+
trap("SIGINT") { block.call }
|
182
|
+
end
|
183
|
+
|
281
184
|
def help(&block)
|
282
185
|
command :help, &block
|
283
186
|
end
|
284
187
|
|
285
|
-
|
286
188
|
# Plugin a command that's probably been built outside of the application's run or build block.
|
287
189
|
# This is helpful for sharing or reusing commands in applications.
|
288
190
|
# @param command [Command]
|
@@ -297,7 +199,7 @@ module CommandLion
|
|
297
199
|
|
298
200
|
# Direct access to the various commands an application has. Helpful for debugging.
|
299
201
|
def commands
|
300
|
-
@commands
|
202
|
+
@commands.reject { |_, v| v.is_a? CommandLion::Option }
|
301
203
|
end
|
302
204
|
|
303
205
|
# Parse arguments off of ARGV.
|
@@ -326,7 +228,7 @@ module CommandLion
|
|
326
228
|
end
|
327
229
|
end
|
328
230
|
|
329
|
-
# Parse a given command with its
|
231
|
+
# Parse a given command with its given flags.
|
330
232
|
# @TODO Re-visit this.
|
331
233
|
def parse_cmd(cmd, flags)
|
332
234
|
if cmd.flags?
|
@@ -337,7 +239,9 @@ module CommandLion
|
|
337
239
|
else
|
338
240
|
args = Raw.arguments_to(cmd.index.to_s, flags)
|
339
241
|
end
|
340
|
-
|
242
|
+
unless cmd.type.to_s =~ /stdin/
|
243
|
+
return nil if args.nil?
|
244
|
+
end
|
341
245
|
case cmd.type
|
342
246
|
when :stdin
|
343
247
|
args = STDIN.gets.strip
|
@@ -374,9 +278,6 @@ module CommandLion
|
|
374
278
|
if cmd.delimiter?
|
375
279
|
if args.count > 1
|
376
280
|
args = args.first.split(cmd.delimiter)
|
377
|
-
#args = args.first.join.split(cmd.delimiter).flatten.select { |arg| arg unless arg.empty? }
|
378
|
-
#args = args.select { |arg| arg if arg.include?(cmd.delimiter) }
|
379
|
-
#args = args.map { |arg| arg.split(cmd.delimiter) }.flatten
|
380
281
|
else
|
381
282
|
args = args.map { |arg| arg.split(cmd.delimiter) }.flatten
|
382
283
|
end
|
@@ -412,10 +313,18 @@ module CommandLion
|
|
412
313
|
nil
|
413
314
|
end
|
414
315
|
|
415
|
-
# @TODO Re-visit this.
|
416
316
|
def run!
|
417
317
|
parse do |cmd|
|
418
|
-
cmd.
|
318
|
+
next unless cmd.given?
|
319
|
+
cmd.options.each do |_, opt|
|
320
|
+
next unless opt.given?
|
321
|
+
opt.before.call if opt.before?
|
322
|
+
opt.action.call if opt.action?
|
323
|
+
opt.after.call if opt.after?
|
324
|
+
end if cmd.options?
|
325
|
+
cmd.before.call if cmd.before?
|
326
|
+
cmd.action.call if cmd.action?
|
327
|
+
cmd.after.call if cmd.after?
|
419
328
|
end
|
420
329
|
end
|
421
330
|
|
data/lib/command_lion/base.rb
CHANGED
data/lib/command_lion/command.rb
CHANGED
@@ -1,290 +1,16 @@
|
|
1
1
|
module CommandLion
|
2
2
|
|
3
|
-
# Every command or option for Command Lion is built on the Command class.
|
4
|
-
#
|
5
|
-
# A Command is typically built using the DSL provided within a build method block:
|
6
|
-
# == ⚙️ Build Block
|
7
|
-
# cmd = CommandLion::Command.build do
|
8
|
-
# # ...
|
9
|
-
# end
|
10
|
-
# This is used under the hood within an Application's DSL run or block:
|
11
|
-
# == ⚙️ Application Build Block
|
12
|
-
# app = CommandLion::App.build do
|
13
|
-
# command :example_index do
|
14
|
-
# # ...
|
15
|
-
# end
|
16
|
-
# end
|
17
|
-
#
|
18
|
-
# The DSL keywords are simple methods provided for any Command object and can be accessed
|
19
|
-
# or modified outside of the DSL building block itself to, for example, query if it exists.
|
20
|
-
#
|
21
|
-
# == 🗣 DSL
|
22
|
-
# Command Lion's DSL is meant to be as flexible as possible without being too compelx.
|
23
|
-
#
|
24
|
-
# ==⚡️ Example
|
25
|
-
# cmd = CommandLion::Command.build do
|
26
|
-
# index :example
|
27
|
-
# flags do
|
28
|
-
# short "-e"
|
29
|
-
# long "--example"
|
30
|
-
# end
|
31
|
-
# type :strings
|
32
|
-
# default ["Jim", "Pam", "Dwight", "Michael"]
|
33
|
-
# before do
|
34
|
-
# unless arguments.count > 2
|
35
|
-
# abort "Must provide more than two arguments!"
|
36
|
-
# end
|
37
|
-
# end
|
38
|
-
# action do
|
39
|
-
# arguments.each do |argument|
|
40
|
-
# puts "Hello #{argument}!"
|
41
|
-
# end
|
42
|
-
# end
|
43
|
-
# after do
|
44
|
-
# exit 0
|
45
|
-
# end
|
46
|
-
# end
|
47
|
-
#
|
48
|
-
# == Keywords
|
49
|
-
# 🔑 description::
|
50
|
-
# To provide further context for your command's existence, it's fairly nice
|
51
|
-
# to have a description.
|
52
|
-
#
|
53
|
-
# == Example
|
54
|
-
# cmd = CommandLion::Command.build do
|
55
|
-
# description "Example"
|
56
|
-
# end
|
57
|
-
#
|
58
|
-
# cmd.description?
|
59
|
-
# # => true
|
60
|
-
#
|
61
|
-
# cmd.description = "Changed"
|
62
|
-
# # => "Changed"
|
63
|
-
#
|
64
|
-
# cmd.description
|
65
|
-
# # => Changed
|
66
|
-
# 🔑 type::
|
67
|
-
# A command may require a specific argument from the command-line. The type
|
68
|
-
# of argument(s) that the command utilizies can be specified with this keyword.
|
69
|
-
# == Example
|
70
|
-
# cmd = CommandLion::Command.build do
|
71
|
-
# type :string
|
72
|
-
# end
|
73
|
-
#
|
74
|
-
# cmd.type?
|
75
|
-
# # => true
|
76
|
-
#
|
77
|
-
# cmd.type = :strings
|
78
|
-
# # => :strings
|
79
|
-
#
|
80
|
-
# cmd.type
|
81
|
-
# # => :strings
|
82
|
-
# 🔑 default::
|
83
|
-
# To specify a command's default arguments, the default keyword can be used.
|
84
|
-
# == Example
|
85
|
-
# cmd = CommandLion::Command.build do
|
86
|
-
# default "example"
|
87
|
-
# end
|
88
|
-
#
|
89
|
-
# cmd.default?
|
90
|
-
# # => true
|
91
|
-
#
|
92
|
-
# cmd.default = "EXAMPLE"
|
93
|
-
# # => "EXAMPLE"
|
94
|
-
#
|
95
|
-
# cmd.default
|
96
|
-
# # => "EXAMPLE"
|
97
|
-
#
|
98
|
-
# cmd.argument
|
99
|
-
# # => "EXAMPLE"
|
100
|
-
# 🔑 delimiter::
|
101
|
-
# In the case of multiple command-line arguments, a custom delimter can be used
|
102
|
-
# to help split up the arguments. Command Lion uses the space betwen arguments as the
|
103
|
-
# default delimter.
|
104
|
-
#
|
105
|
-
# == Example
|
106
|
-
# cmd = CommandLion::Command.build do
|
107
|
-
# delimter ","
|
108
|
-
# end
|
109
|
-
#
|
110
|
-
# cmd.delimter?
|
111
|
-
# # => true
|
112
|
-
#
|
113
|
-
# cmd.delimter = ":"
|
114
|
-
# # => ":"
|
115
|
-
#
|
116
|
-
# cmd.delimter
|
117
|
-
# # => :
|
118
|
-
# 🔑 flag::
|
119
|
-
# If you'd like for one specfic flag to be used for the command, then this keyword is for you!
|
120
|
-
#
|
121
|
-
# == Example
|
122
|
-
# cmd = CommandLion::Command.build do
|
123
|
-
# flag "example"
|
124
|
-
# end
|
125
|
-
#
|
126
|
-
# cmd.flag?
|
127
|
-
# # => true
|
128
|
-
#
|
129
|
-
# cmd.flag = "EXAMPLE"
|
130
|
-
# # => "EXAMPLE"
|
131
|
-
#
|
132
|
-
# cmd.flag
|
133
|
-
# # => "EXAMPLE"
|
134
|
-
# 🔑 flags::
|
135
|
-
# The flags keywords can be used two specify the short and long flags option for a command.
|
136
|
-
#
|
137
|
-
# == Example
|
138
|
-
# cmd = CommandLion::Command.build do
|
139
|
-
# flags do
|
140
|
-
# short "-e"
|
141
|
-
# long "--example
|
142
|
-
# end
|
143
|
-
# end
|
144
|
-
#
|
145
|
-
# cmd.flags?
|
146
|
-
# # => true
|
147
|
-
#
|
148
|
-
# cmd.flags.short?
|
149
|
-
# # => true
|
150
|
-
#
|
151
|
-
# cmd.flags.long?
|
152
|
-
# # => true
|
153
|
-
#
|
154
|
-
# cmd.flags.short = "-E"
|
155
|
-
# # => "-E"
|
156
|
-
#
|
157
|
-
# cmd.flags.long = "--EXAMPLE"
|
158
|
-
# # => "--EXAMPLE"
|
159
|
-
#
|
160
|
-
# cmd.flags.long
|
161
|
-
# # => "--EXAMPLE"
|
162
|
-
#
|
163
|
-
# cmd.flags.short
|
164
|
-
# # => "-E"
|
165
|
-
# 🔑 threaded::
|
166
|
-
# To have your command spawn a thread and have the action block
|
167
|
-
# for your command run in its own background thread.
|
168
|
-
#
|
169
|
-
# == Example
|
170
|
-
# cmd = CommandLion::Command.build do
|
171
|
-
# description "Example"
|
172
|
-
# end
|
173
|
-
#
|
174
|
-
# cmd.description?
|
175
|
-
# # => true
|
176
|
-
#
|
177
|
-
# cmd.description = "Changed"
|
178
|
-
# # => "Changed"
|
179
|
-
#
|
180
|
-
# cmd.description
|
181
|
-
# # => Changed
|
182
|
-
# 🔑 action::
|
183
|
-
# What do you want a command to do when it is used? The action keyword can be used
|
184
|
-
# to capture the block you'd like to run when the command is used.
|
185
|
-
#
|
186
|
-
# == Example
|
187
|
-
# cmd = CommandLion::Command.build do
|
188
|
-
# action do
|
189
|
-
# puts "Hello World!"
|
190
|
-
# end
|
191
|
-
# end
|
192
|
-
#
|
193
|
-
# cmd.action?
|
194
|
-
# # => true
|
195
|
-
#
|
196
|
-
# cmd.action
|
197
|
-
# # => #<Proc:...>
|
198
|
-
#
|
199
|
-
# cmd.action.call
|
200
|
-
# # => Hello World! .. to STDOUT
|
201
|
-
# 🔑 before::
|
202
|
-
# Before the action block is called, you can specify anouther block to be used beforehand
|
203
|
-
# which can be used to help setup or do some custom error checking.
|
204
|
-
#
|
205
|
-
# == Example
|
206
|
-
# cmd = CommandLion::Command.build do
|
207
|
-
# before do
|
208
|
-
# abort "Not on Mondays!" Time.now.monday?
|
209
|
-
# end
|
210
|
-
# action do
|
211
|
-
# puts "Hello World!"
|
212
|
-
# end
|
213
|
-
# end
|
214
|
-
#
|
215
|
-
# cmd.before?
|
216
|
-
# # => true
|
217
|
-
#
|
218
|
-
# cmd.before
|
219
|
-
# # => #<Proc:...>
|
220
|
-
#
|
221
|
-
# cmd.before.call
|
222
|
-
# # aborts application if it's Monday
|
223
|
-
# 🔑 after::
|
224
|
-
# After the action block has been called and completed, anouther optional block
|
225
|
-
# can be used within the block given in the after keyword. This can be used for all sorts
|
226
|
-
# of nifty things: from stopping the application from moving on, to logging, to whatever else.
|
227
|
-
# == Example
|
228
|
-
# cmd = CommandLion::Command.build do
|
229
|
-
# action do
|
230
|
-
# puts "Hello World!"
|
231
|
-
# end
|
232
|
-
# after do
|
233
|
-
# exit 0
|
234
|
-
# end
|
235
|
-
# end
|
236
|
-
#
|
237
|
-
# cmd.after?
|
238
|
-
# # => true
|
239
|
-
#
|
240
|
-
# cmd.after
|
241
|
-
# # => #<Proc:...>
|
242
|
-
#
|
243
|
-
# cmd.after.call
|
244
|
-
# # exits application with successful status code
|
245
|
-
# 🔑 index::
|
246
|
-
# A command's index should be unique. It is used to used to accesses the command amongst other
|
247
|
-
# commands when used within an application. However, this keyword usually isn't used unless being utilized
|
248
|
-
# when using Command Lion's plugin system.
|
249
|
-
# == Example
|
250
|
-
# cmd = CommandLion::Command.build do
|
251
|
-
# index :example
|
252
|
-
# end
|
253
|
-
#
|
254
|
-
# cmd.index?
|
255
|
-
# # => :example
|
256
|
-
#
|
257
|
-
# cmd.index
|
258
|
-
# # => :example
|
259
|
-
# 🔑 option::
|
260
|
-
# a command may have mutiple sub commands or options associated with it. these effectively
|
261
|
-
# work exactly like any other command, but are just started as a leaf under the paren't command's options.
|
262
|
-
# == Example
|
263
|
-
# cmd = CommandLion::Command.build do
|
264
|
-
# # ...
|
265
|
-
# option :example do
|
266
|
-
# action do
|
267
|
-
# puts "hello world!"
|
268
|
-
# end
|
269
|
-
# end
|
270
|
-
# end
|
271
|
-
#
|
272
|
-
# cmd.options?
|
273
|
-
# # => true
|
274
|
-
#
|
275
|
-
# cmd.options[:example]
|
276
|
-
# # => #<proc:...>
|
277
|
-
#
|
278
|
-
# cmd.after.call
|
279
|
-
# # exits the application with successful status code
|
280
|
-
#
|
281
3
|
class Command < Base
|
282
|
-
|
283
|
-
simple_attrs :index, :description, :
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
4
|
+
|
5
|
+
simple_attrs :index, :description, :type,
|
6
|
+
:delimiter, :flags, :arguments,
|
7
|
+
:given, :default, :action,
|
8
|
+
:options, :before, :after
|
9
|
+
|
10
|
+
def initialize(&block)
|
11
|
+
self.instance_eval(&block) if block_given?
|
12
|
+
end
|
13
|
+
|
288
14
|
# @private
|
289
15
|
def option(index, &block)
|
290
16
|
option = Option.new
|
@@ -310,7 +36,7 @@ module CommandLion
|
|
310
36
|
short string.to_s
|
311
37
|
end
|
312
38
|
end
|
313
|
-
|
39
|
+
|
314
40
|
# @private
|
315
41
|
def argument
|
316
42
|
if arguments.respond_to?(:each)
|
@@ -341,6 +67,12 @@ module CommandLion
|
|
341
67
|
arguments.each do |argument|
|
342
68
|
yield argument
|
343
69
|
end
|
70
|
+
elsif @arguments.respond_to?(:readline)
|
71
|
+
until arguments.eof?
|
72
|
+
yield arguments.readline
|
73
|
+
end
|
74
|
+
elsif @arguments.nil? and !@default
|
75
|
+
return
|
344
76
|
else
|
345
77
|
yield @arguments || @default
|
346
78
|
end
|
@@ -360,17 +92,13 @@ module CommandLion
|
|
360
92
|
return @before unless block_given?
|
361
93
|
@before = block
|
362
94
|
end
|
363
|
-
|
95
|
+
|
364
96
|
# @private
|
365
97
|
def after(&block)
|
366
98
|
return @after unless block_given?
|
367
99
|
@after = block
|
368
100
|
end
|
369
101
|
|
370
|
-
# @private
|
371
|
-
def threaded
|
372
|
-
@threaded = true
|
373
|
-
end
|
374
102
|
end
|
375
103
|
|
376
104
|
end
|
data/lib/command_lion/flags.rb
CHANGED
@@ -1,35 +1,11 @@
|
|
1
1
|
module CommandLion
|
2
2
|
|
3
|
-
# The way a user is able to call or access a command or option for
|
4
|
-
# a command-line application is by passing their flags when the application
|
5
|
-
# is run at the command-line.
|
6
|
-
#
|
7
|
-
# == 🗣 DSL
|
8
|
-
# The flags DSL works three different ways.
|
9
|
-
#
|
10
|
-
# == Index as Flag
|
11
|
-
# app = CommandLion::Command.build do
|
12
|
-
# command :hello do
|
13
|
-
# # just use the index as the flag
|
14
|
-
# end
|
15
|
-
# end
|
16
|
-
# == One Flag
|
17
|
-
# app = CommandLion::Command.build do
|
18
|
-
# command :hello do
|
19
|
-
# flag "--hello"
|
20
|
-
# end
|
21
|
-
# end
|
22
|
-
# == Short & Long Flags
|
23
|
-
# app = CommandLion::Command.build do
|
24
|
-
# command :hello do
|
25
|
-
# flags do
|
26
|
-
# short "-e"
|
27
|
-
# long "--example"
|
28
|
-
# end
|
29
|
-
# end
|
30
|
-
# end
|
31
3
|
class Flags < Base
|
32
4
|
simple_attrs :short, :long
|
33
|
-
|
5
|
+
|
6
|
+
def all
|
7
|
+
[@short, @long].reject { |v| v.nil? }
|
8
|
+
end
|
9
|
+
end
|
34
10
|
|
35
11
|
end
|
data/lib/command_lion/option.rb
CHANGED
@@ -1,21 +1,3 @@
|
|
1
1
|
module CommandLion
|
2
|
-
|
3
|
-
# The Option class is a direct sub-class of the Command class. In pretty much
|
4
|
-
# every way it is just a command under the hood. However, instead of being indexed
|
5
|
-
# in an application's commands index, it will be available in whatever command's
|
6
|
-
# options index.
|
7
|
-
#
|
8
|
-
# == Example
|
9
|
-
#
|
10
|
-
# app = CommandLion::App.build do
|
11
|
-
# command :example_command do
|
12
|
-
# # ...
|
13
|
-
# option :example_option do
|
14
|
-
# # ...
|
15
|
-
# end
|
16
|
-
# end
|
17
|
-
# end
|
18
|
-
#
|
19
|
-
# app.commands[:example_command].options[:example_option]
|
20
2
|
class Option < Command; end
|
21
3
|
end
|
data/lib/command_lion/raw.rb
CHANGED
@@ -1,29 +1,60 @@
|
|
1
1
|
module CommandLion
|
2
2
|
|
3
|
+
# Raw command-line option API
|
3
4
|
module Raw
|
4
5
|
|
5
|
-
|
6
|
-
|
6
|
+
@arguments = ARGV
|
7
|
+
|
8
|
+
def self.arguments
|
9
|
+
return @arguments unless block_given?
|
10
|
+
@arguments.each do |argument|
|
11
|
+
yield argument
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.arguments=(args)
|
16
|
+
@arguments = args
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.arguments?
|
20
|
+
arguments.size > 0 ? true : false
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.index_of(flag)
|
24
|
+
arguments.index(flag)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.index_of?(flag)
|
28
|
+
index_of(flag) ? true : false
|
7
29
|
end
|
8
30
|
|
9
31
|
def self.arguments_to(string, flags)
|
10
|
-
return
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
32
|
+
return if string.nil?
|
33
|
+
return if flags.nil?
|
34
|
+
return unless index = index_of(string)
|
35
|
+
if block_given?
|
36
|
+
arguments.drop(index+1).each do |argument|
|
37
|
+
# next if argument == ","
|
38
|
+
break if flags.include?(argument)
|
39
|
+
yield argument
|
40
|
+
end
|
41
|
+
else
|
42
|
+
args = []
|
43
|
+
arguments_to(string, flags) { |arg| args << arg }
|
44
|
+
return args
|
17
45
|
end
|
18
|
-
args
|
19
46
|
end
|
20
47
|
|
21
|
-
def self.arguments_to?(
|
22
|
-
|
48
|
+
def self.arguments_to?(flag)
|
49
|
+
arguments[arguments.index(flag) + 1] ? true : false
|
23
50
|
end
|
24
51
|
|
25
|
-
def self.
|
26
|
-
|
52
|
+
def self.possible_argument_to(string)
|
53
|
+
arguments[arguments.index(string) + 1]
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.clear!
|
57
|
+
@arguments = []
|
27
58
|
end
|
28
59
|
|
29
60
|
end
|
data/lib/command_lion/version.rb
CHANGED
data/lib/command_lion.rb
CHANGED
@@ -1,11 +1,21 @@
|
|
1
1
|
require "command_lion/version"
|
2
2
|
require "command_lion/raw"
|
3
3
|
require "command_lion/base"
|
4
|
-
require "command_lion/flags"
|
5
4
|
require "command_lion/command"
|
6
5
|
require "command_lion/option"
|
6
|
+
require "command_lion/flags"
|
7
7
|
require "command_lion/app"
|
8
8
|
|
9
9
|
module CommandLion
|
10
|
-
|
10
|
+
def self.raw
|
11
|
+
Raw
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.command
|
15
|
+
Command
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.application
|
19
|
+
Application
|
20
|
+
end
|
11
21
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: command_lion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kent 'picat' Gruber
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-04-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -71,14 +71,11 @@ files:
|
|
71
71
|
- bin/console
|
72
72
|
- bin/setup
|
73
73
|
- command_lion.gemspec
|
74
|
+
- examples/ctrl_c.rb
|
74
75
|
- examples/debug.rb
|
76
|
+
- examples/error.rb
|
75
77
|
- examples/example.rb
|
76
78
|
- examples/example2.rb
|
77
|
-
- examples/example_rainbows.rb
|
78
|
-
- examples/flipr.rb
|
79
|
-
- examples/flipr2.rb
|
80
|
-
- examples/flipr3.rb
|
81
|
-
- examples/flipr4.rb
|
82
79
|
- examples/hello_expanded.rb
|
83
80
|
- examples/hello_multi.rb
|
84
81
|
- examples/hello_world.rb
|
@@ -124,7 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
124
121
|
version: '0'
|
125
122
|
requirements: []
|
126
123
|
rubyforge_project:
|
127
|
-
rubygems_version: 2.6
|
124
|
+
rubygems_version: 2.7.6
|
128
125
|
signing_key:
|
129
126
|
specification_version: 4
|
130
127
|
summary: Command-line application framework.
|
@@ -1,21 +0,0 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
-
require 'command_lion'
|
3
|
-
require 'pry'
|
4
|
-
|
5
|
-
CommandLion::App.run do
|
6
|
-
|
7
|
-
name "Rainbow Hello"
|
8
|
-
version "1.0.0"
|
9
|
-
#rainbows
|
10
|
-
|
11
|
-
command "Say Hello" do
|
12
|
-
type :string
|
13
|
-
flag "hello"
|
14
|
-
default "world"
|
15
|
-
|
16
|
-
action do
|
17
|
-
puts "Hello #{argument}!"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
data/examples/flipr.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
-
require 'command_lion'
|
3
|
-
require 'pry'
|
4
|
-
|
5
|
-
|
6
|
-
CommandLion::App.run do
|
7
|
-
|
8
|
-
name "Flipr"
|
9
|
-
version "1.0.0"
|
10
|
-
description "Flipping tables in terminals made easy!"
|
11
|
-
|
12
|
-
command :flip do
|
13
|
-
description "Flip a table."
|
14
|
-
|
15
|
-
flips = ["[ ╯ '□']╯︵┻━┻)", "[ ╯ಠ益ಠ]╯彡┻━┻)", "[ ╯´・ω・]╯︵┸━┸)"]
|
16
|
-
|
17
|
-
flags do
|
18
|
-
short "-f"
|
19
|
-
long "--flip"
|
20
|
-
end
|
21
|
-
|
22
|
-
action do
|
23
|
-
puts flips.sample
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
data/examples/flipr2.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
-
require 'command_lion'
|
3
|
-
require 'pry'
|
4
|
-
|
5
|
-
def random_sleep
|
6
|
-
sleep (0..5).to_a.sample
|
7
|
-
end
|
8
|
-
|
9
|
-
def synchronize(&block)
|
10
|
-
@semaphore ||= Mutex.new
|
11
|
-
@semaphore.synchronize do
|
12
|
-
block.call
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
CommandLion::App.run do
|
17
|
-
|
18
|
-
name "Flipr"
|
19
|
-
version "1.0.0"
|
20
|
-
description "Flipping tables in terminals made easy!"
|
21
|
-
|
22
|
-
command :flip do
|
23
|
-
threaded
|
24
|
-
description "Flip a table."
|
25
|
-
flag "--flip"
|
26
|
-
flips = ["[ ╯ '□']╯︵┻━┻)", "[ ╯ಠ益ಠ]╯彡┻━┻)", "[ ╯´・ω・]╯︵┸━┸)"]
|
27
|
-
action do
|
28
|
-
10.times do
|
29
|
-
random_sleep
|
30
|
-
synchronize { puts flips.sample }
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
command :put do
|
36
|
-
threaded
|
37
|
-
description "Put a table."
|
38
|
-
flag "--put"
|
39
|
-
puts = ["┬──┬ノ['-' ノ ]", "┬──┬ノ[・ω・ ノ ]", "┬──┬ノ['~' ノ ]"]
|
40
|
-
action do
|
41
|
-
10.times do
|
42
|
-
random_sleep
|
43
|
-
synchronize { puts puts.sample }
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
data/examples/flipr3.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
-
require 'command_lion'
|
3
|
-
require 'pry'
|
4
|
-
|
5
|
-
CommandLion::App.run do
|
6
|
-
|
7
|
-
name "Flipr"
|
8
|
-
version "1.0.0"
|
9
|
-
description "Flipping tables in terminals made easy!"
|
10
|
-
|
11
|
-
command :flip do
|
12
|
-
description "Flip a table."
|
13
|
-
flag "--flip"
|
14
|
-
|
15
|
-
flips = ["[ ╯ '□']╯︵┻━┻)", "[ ╯ಠ益ಠ]╯彡┻━┻)", "[ ╯´・ω・]╯︵┸━┸)"]
|
16
|
-
|
17
|
-
action do
|
18
|
-
options[:count].argument.times do
|
19
|
-
puts flips.sample
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
option :count do
|
24
|
-
default 3
|
25
|
-
description "Specify the number of flips ( default: #{default} )"
|
26
|
-
type :integer
|
27
|
-
flag "--count"
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
data/examples/flipr4.rb
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
-
require 'command_lion'
|
3
|
-
require 'pry'
|
4
|
-
|
5
|
-
CommandLion::App.run do
|
6
|
-
|
7
|
-
name "Flipr"
|
8
|
-
version "1.0.0"
|
9
|
-
description "Flipping tables in terminals made easy!"
|
10
|
-
|
11
|
-
command :flip do
|
12
|
-
description "Flip a table."
|
13
|
-
flag "--flip"
|
14
|
-
|
15
|
-
flips = ["[ ╯ '□']╯︵┻━┻)", "[ ╯ಠ益ಠ]╯彡┻━┻)", "[ ╯´・ω・]╯︵┸━┸)"]
|
16
|
-
|
17
|
-
action do
|
18
|
-
options[:count].arguments do |argument|
|
19
|
-
argument.times do
|
20
|
-
puts flips.sample
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
option :count do
|
26
|
-
default 1
|
27
|
-
description "Specify the number of flips ( default: #{default} )"
|
28
|
-
type :stdin_integers
|
29
|
-
flag "--count"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|