tcollier-commando 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +10 -12
- data/bin/commando +3 -1
- data/lib/commando.rb +5 -32
- data/lib/commando/action/help.rb +13 -5
- data/lib/commando/action/history.rb +11 -3
- data/lib/commando/action/quit.rb +2 -2
- data/lib/commando/config.rb +21 -5
- data/lib/commando/interpreter.rb +7 -7
- data/lib/commando/io_handler.rb +8 -8
- data/lib/commando/runner.rb +36 -0
- data/lib/commando/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e2eaeec6ef8a2aa6c50de698bcf97980cecd945
|
4
|
+
data.tar.gz: dfcde5d0c18bbc6c350fcf1fab47a15afb057c84
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 912391da0d11a7d95b3331bfe9d3cdd8b1a0b728d770fb9946f5a7e3940b36e36a1f976a7e0f73d72645922852cf71374af9b4139b126f47af5b576649b71925
|
7
|
+
data.tar.gz: 730b35864936e0960ececea58c3dce1c2fd3f6239d9b95cd65942eed3d6fd295f72dc080451ea6a5b28c4d153b37005a0dc4f450557b2e37f417a19f6fab0f0f
|
data/README.md
CHANGED
@@ -12,6 +12,7 @@ _A command line interface builder with Readline support_
|
|
12
12
|
* `0.2.0` - Persist history across CLI sessions
|
13
13
|
* `0.2.1` - Fix bug when history file doesn't exist
|
14
14
|
* `1.0.0` - Use `ArgumentError` instead of custom error for bad args
|
15
|
+
* `2.0.0` - Remove global config
|
15
16
|
|
16
17
|
## Installation
|
17
18
|
|
@@ -32,10 +33,11 @@ Or install it yourself as:
|
|
32
33
|
## Configuration
|
33
34
|
|
34
35
|
You can configure the start up greeting, the command line prompt, and the set
|
35
|
-
of available commands to use.
|
36
|
+
of available commands to use. To do so, start Commando with the block syntax as
|
37
|
+
follows
|
36
38
|
|
37
39
|
```ruby
|
38
|
-
Commando.
|
40
|
+
Commando.start do |config|
|
39
41
|
# The greeting to print when the CLI is started
|
40
42
|
config.greeting = 'Welcome to my CLI. Type "help" for a list of commands'
|
41
43
|
|
@@ -46,7 +48,8 @@ Commando.configure do |config|
|
|
46
48
|
config.history_file = '/tmp/.commando_history'
|
47
49
|
|
48
50
|
# Register multiple commands
|
49
|
-
config.register 'addfriend', MyApp::AddFriend, 'Adds a friend to your network'
|
51
|
+
config.register 'addfriend', MyApp::AddFriend.new, 'Adds a friend to your network'
|
52
|
+
config.register 'listfriends', MyApp::ListFriends.new, 'List all friends in your network'
|
50
53
|
end
|
51
54
|
```
|
52
55
|
|
@@ -60,11 +63,10 @@ To support a new command, you must register it with
|
|
60
63
|
|
61
64
|
#### Action role
|
62
65
|
|
63
|
-
The `Action` role responds to `perform(args
|
66
|
+
The `Action` role responds to `perform(args:)`, where
|
64
67
|
|
65
68
|
* `args` [`Array<String>`] - the list of the extra words that follow the command
|
66
69
|
(e.g. if the user types `addfriend mary jane`, then the args are `['mary', 'jane']`).
|
67
|
-
* `output` [`IO`] - the IO instance that any messages should be written to.
|
68
70
|
|
69
71
|
If the arguments are not formatted correctly (e.g. the user missed an argument),
|
70
72
|
then method should raise an `ArgumentError` with a descriptive message.
|
@@ -73,14 +75,10 @@ then method should raise an `ArgumentError` with a descriptive message.
|
|
73
75
|
|
74
76
|
A few default actions have been registered
|
75
77
|
|
76
|
-
* help - Prints a help message, including a list of commands
|
77
|
-
* history - Prints the history of commands entered so far
|
78
|
-
* quit - Exits the program
|
78
|
+
* `help` - Prints a help message, including a list of commands
|
79
|
+
* `history` - Prints the history of commands entered so far
|
80
|
+
* `quit` - Exits the program
|
79
81
|
|
80
|
-
## Usage
|
81
|
-
|
82
|
-
Once commando is configured, simply run `Commando.start` to enter the command
|
83
|
-
line interface.
|
84
82
|
|
85
83
|
## Contributing
|
86
84
|
|
data/bin/commando
CHANGED
data/lib/commando.rb
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
require_relative 'commando/config'
|
2
|
-
require_relative 'commando/
|
3
|
-
require_relative 'commando/io_handler'
|
4
|
-
require_relative 'commando/quit_exception'
|
5
|
-
require_relative 'commando/version'
|
2
|
+
require_relative 'commando/runner'
|
6
3
|
|
7
4
|
# Entry point for the Command Line Interface (CLI).
|
8
5
|
#
|
@@ -11,34 +8,10 @@ require_relative 'commando/version'
|
|
11
8
|
# repeated indefinitely until the user give either the "quit" command, or
|
12
9
|
# presses <CMD>+D.
|
13
10
|
module Commando
|
14
|
-
# Initialize and configure the global config object
|
15
|
-
def self.configure(&block)
|
16
|
-
yield config
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.config
|
20
|
-
@config ||= Config.new
|
21
|
-
end
|
22
|
-
|
23
11
|
# Begin the prompt, get input, process loop.
|
24
|
-
def self.start(
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
interpreter = Interpreter.new(output: output)
|
29
|
-
|
30
|
-
loop do
|
31
|
-
begin
|
32
|
-
if line = io.readline
|
33
|
-
# When the user enters a non-empty string, pass the line to the
|
34
|
-
# interpreter and handle the command.
|
35
|
-
interpreter.interpret(line)
|
36
|
-
end
|
37
|
-
rescue ArgumentError => error
|
38
|
-
output.puts "Error: #{error}"
|
39
|
-
rescue QuitException
|
40
|
-
break
|
41
|
-
end
|
42
|
-
end
|
12
|
+
def self.start(&block)
|
13
|
+
config = Config.new
|
14
|
+
yield config if block_given?
|
15
|
+
Runner.new(config: config).start
|
43
16
|
end
|
44
17
|
end
|
data/lib/commando/action/help.rb
CHANGED
@@ -3,14 +3,22 @@ require_relative '../../commando'
|
|
3
3
|
module Commando
|
4
4
|
module Action
|
5
5
|
# Action that prints out all available commands
|
6
|
-
|
7
|
-
def
|
8
|
-
|
9
|
-
|
6
|
+
class Help
|
7
|
+
def initialize(config:)
|
8
|
+
@config = config
|
9
|
+
end
|
10
|
+
|
11
|
+
def perform(args:)
|
12
|
+
config.output.puts "Valid commands are"
|
13
|
+
descriptions = config.descriptions
|
10
14
|
descriptions.sort_by { |cmd, _| cmd }.each do |command, description|
|
11
|
-
output.puts " * #{command} - #{description}"
|
15
|
+
config.output.puts " * #{command} - #{description}"
|
12
16
|
end
|
13
17
|
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
attr_reader :config
|
14
22
|
end
|
15
23
|
end
|
16
24
|
end
|
@@ -3,14 +3,22 @@ require 'readline'
|
|
3
3
|
module Commando
|
4
4
|
module Action
|
5
5
|
# Action that prints out command history
|
6
|
-
|
7
|
-
def
|
6
|
+
class History
|
7
|
+
def initialize(config:)
|
8
|
+
@config = config
|
9
|
+
end
|
10
|
+
|
11
|
+
def perform(args:)
|
8
12
|
max_digits = Math.log(Readline::HISTORY.size, 10).ceil
|
9
13
|
Readline::HISTORY.each.with_index do |history, index|
|
10
14
|
line_no = (index + 1).to_s.rjust(max_digits, ' ')
|
11
|
-
output.puts " #{line_no}\t#{history}"
|
15
|
+
config.output.puts " #{line_no}\t#{history}"
|
12
16
|
end
|
13
17
|
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
attr_reader :config
|
14
22
|
end
|
15
23
|
end
|
16
24
|
end
|
data/lib/commando/action/quit.rb
CHANGED
data/lib/commando/config.rb
CHANGED
@@ -13,16 +13,32 @@ module Commando
|
|
13
13
|
'Welcome to the commando interface. Type "help" to list available commands'
|
14
14
|
|
15
15
|
attr_accessor :history_file
|
16
|
-
|
17
|
-
attr_writer :prompt, :greeting
|
16
|
+
|
17
|
+
attr_writer :prompt, :greeting, :output
|
18
18
|
|
19
19
|
def initialize
|
20
20
|
@mapping = {}
|
21
21
|
|
22
22
|
# Register the default actions
|
23
|
-
register(
|
24
|
-
|
25
|
-
|
23
|
+
register(
|
24
|
+
'help',
|
25
|
+
Commando::Action::Help.new(config: self),
|
26
|
+
'Print this message'
|
27
|
+
)
|
28
|
+
register(
|
29
|
+
'history',
|
30
|
+
Commando::Action::History.new(config: self),
|
31
|
+
'Print the history of commands'
|
32
|
+
)
|
33
|
+
register(
|
34
|
+
'quit',
|
35
|
+
Commando::Action::Quit.new,
|
36
|
+
'Exit the program'
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
def output
|
41
|
+
@output || $stdout
|
26
42
|
end
|
27
43
|
|
28
44
|
def prompt
|
data/lib/commando/interpreter.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
module Commando
|
2
2
|
# Interpret a single command from the user.
|
3
3
|
class Interpreter
|
4
|
-
# @param
|
5
|
-
def initialize(
|
6
|
-
@
|
4
|
+
# @param config [Config] the application configuration
|
5
|
+
def initialize(config:)
|
6
|
+
@config = config
|
7
7
|
end
|
8
8
|
|
9
9
|
# Performs the action (if valid) for the given input command line
|
@@ -12,18 +12,18 @@ module Commando
|
|
12
12
|
def interpret(line)
|
13
13
|
args = line.split(' ')
|
14
14
|
command = args.shift
|
15
|
-
action =
|
15
|
+
action = config.lookup(command)
|
16
16
|
|
17
17
|
if action.nil?
|
18
|
-
output.puts %Q(Unrecognized command: #{command}. Type "help" for a list of valid commands)
|
18
|
+
config.output.puts %Q(Unrecognized command: #{command}. Type "help" for a list of valid commands)
|
19
19
|
else
|
20
|
-
action.perform(args: args
|
20
|
+
action.perform(args: args)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
private
|
25
25
|
|
26
|
-
attr_reader :
|
26
|
+
attr_reader :config
|
27
27
|
end
|
28
28
|
|
29
29
|
private_constant :Interpreter
|
data/lib/commando/io_handler.rb
CHANGED
@@ -5,19 +5,19 @@ require_relative 'quit_exception'
|
|
5
5
|
module Commando
|
6
6
|
# Handle the prompt/input for the command line interface
|
7
7
|
class IOHandler
|
8
|
-
def initialize(
|
9
|
-
@
|
8
|
+
def initialize(config:)
|
9
|
+
@config = config
|
10
10
|
|
11
11
|
configure_readline
|
12
12
|
load_history
|
13
13
|
end
|
14
14
|
|
15
15
|
def readline
|
16
|
-
line = Readline.readline(
|
16
|
+
line = Readline.readline(config.prompt, true)
|
17
17
|
if line.nil?
|
18
18
|
# When the user presses <CMD>+D, this comes through as nil. In that
|
19
19
|
# case we want to exit
|
20
|
-
output.puts
|
20
|
+
config.output.puts
|
21
21
|
raise QuitException
|
22
22
|
elsif line.strip == ''
|
23
23
|
# If the user just hit enter without typing a command, remove that line
|
@@ -32,12 +32,12 @@ module Commando
|
|
32
32
|
|
33
33
|
private
|
34
34
|
|
35
|
-
attr_reader :
|
35
|
+
attr_reader :config
|
36
36
|
|
37
37
|
def configure_readline
|
38
|
-
Readline.output = output
|
38
|
+
Readline.output = config.output
|
39
39
|
Readline.completion_proc =
|
40
|
-
proc { |s|
|
40
|
+
proc { |s| config.commands.grep(/^#{Regexp.escape(s)}/) }
|
41
41
|
end
|
42
42
|
|
43
43
|
def load_history
|
@@ -53,7 +53,7 @@ module Commando
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def history_file
|
56
|
-
|
56
|
+
config.history_file
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative 'interpreter'
|
2
|
+
require_relative 'io_handler'
|
3
|
+
require_relative 'quit_exception'
|
4
|
+
|
5
|
+
module Commando
|
6
|
+
class Runner
|
7
|
+
def initialize(config:)
|
8
|
+
@config = config
|
9
|
+
end
|
10
|
+
|
11
|
+
def start
|
12
|
+
config.output.puts config.greeting
|
13
|
+
|
14
|
+
io = IOHandler.new(config: config)
|
15
|
+
interpreter = Interpreter.new(config: config)
|
16
|
+
|
17
|
+
loop do
|
18
|
+
begin
|
19
|
+
if line = io.readline
|
20
|
+
# When the user enters a non-empty string, pass the line to the
|
21
|
+
# interpreter and handle the command.
|
22
|
+
interpreter.interpret(line)
|
23
|
+
end
|
24
|
+
rescue ArgumentError => error
|
25
|
+
config.output.puts "Error: #{error}"
|
26
|
+
rescue QuitException
|
27
|
+
break
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
attr_reader :config
|
35
|
+
end
|
36
|
+
end
|
data/lib/commando/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tcollier-commando
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Collier
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -78,6 +78,7 @@ files:
|
|
78
78
|
- lib/commando/interpreter.rb
|
79
79
|
- lib/commando/io_handler.rb
|
80
80
|
- lib/commando/quit_exception.rb
|
81
|
+
- lib/commando/runner.rb
|
81
82
|
- lib/commando/version.rb
|
82
83
|
homepage: https://github.com/tcollier/commando
|
83
84
|
licenses:
|