command_lion 1.0.4 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|