simple-cli 0.2.28 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/simple/cli/adapter.rb +20 -4
- data/lib/simple/cli/logger/colored_logger.rb +8 -18
- data/lib/simple/cli/runner/command_help.rb +3 -2
- data/lib/simple/cli/runner.rb +25 -15
- data/lib/simple/cli/version.rb +1 -1
- metadata +6 -11
- data/.ruby-version +0 -1
- data/README.md +0 -32
- data/doc/examples/ex1/ex1 +0 -2
- data/doc/examples/ex1/ex1.rb +0 -40
- data/lib/simple/cli/runner/autocompletion.rb +0 -91
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1fdfd698a5315891e4d5dd96e5d3ce07fc075d17d5ced10eb06a9cb5733b4a8a
|
4
|
+
data.tar.gz: 9000f43f3dfceb572aae61b8907216c3dd7c9c4c468374587f56d5c433d84ecd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82f219944dc7ffecac5cae4975749732a6741ee676f5ffd8b4ca862c48717d20a56dfc363dbf7c486e5cb9d48ba376eecb67a7185557547da7824bd201fd524f
|
7
|
+
data.tar.gz: ee581a7eb68e35c9cc8a2560538f709a1c9ce8a90457338c14ef9446875563f6e9f9f4012844c5ada1f96486ef0945e9917cdda0434972b078c9dc22c5f2c9d1
|
data/lib/simple/cli/adapter.rb
CHANGED
@@ -1,8 +1,24 @@
|
|
1
1
|
module Simple::CLI::Adapter
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
# Run a Simple::CLI application
|
3
|
+
#
|
4
|
+
# This is usually called with as either
|
5
|
+
#
|
6
|
+
# - Application::CLI.run!: runs the Application's CLI with subcommand support.
|
7
|
+
#
|
8
|
+
# or
|
9
|
+
#
|
10
|
+
# - Application::CLI.run!("main"): runs the Application's CLI without subcommand support.
|
11
|
+
#
|
12
|
+
def run!(main_command = nil)
|
13
|
+
runner = Simple::CLI::Runner.new(self)
|
14
|
+
|
15
|
+
if main_command && (ARGV.include?("--help") || ARGV.include?("-h"))
|
16
|
+
runner.help(main_command)
|
17
|
+
elsif main_command
|
18
|
+
runner.run(main_command, *ARGV)
|
19
|
+
else
|
20
|
+
runner.run(*ARGV)
|
21
|
+
end
|
6
22
|
end
|
7
23
|
|
8
24
|
def logger=(logger)
|
@@ -56,6 +56,11 @@ module Simple::CLI::Logger::ColoredLogger
|
|
56
56
|
log :error, *args, &block
|
57
57
|
end
|
58
58
|
|
59
|
+
def fatal(*args, &block)
|
60
|
+
log :error, *args, &block
|
61
|
+
exit 1
|
62
|
+
end
|
63
|
+
|
59
64
|
def success(*args, &block)
|
60
65
|
log :success, *args, &block
|
61
66
|
end
|
@@ -118,25 +123,10 @@ module Simple::CLI::Logger::ColoredLogger
|
|
118
123
|
STDERR.puts msg
|
119
124
|
end
|
120
125
|
|
121
|
-
#
|
122
|
-
#
|
126
|
+
# The heuristic used to determine the caller is not perfect, but should
|
127
|
+
# do well in most cases.
|
123
128
|
def source_from_caller
|
124
|
-
source = caller.find
|
125
|
-
# skip this gem
|
126
|
-
next false if loc =~ /\/lib\/simple\/cli\//
|
127
|
-
|
128
|
-
# skip forwardable from Ruby stdlib
|
129
|
-
next false if loc =~ /\/forwardable.rb\:/
|
130
|
-
|
131
|
-
# skip simple-sql
|
132
|
-
next false if loc =~ /\/lib\/simple\/sql\b/
|
133
|
-
|
134
|
-
# skip lib/postjob/queue/postgres/checked_sql.rb
|
135
|
-
next false if loc =~ %r{lib/postjob/queue/postgres/checked_sql.rb}
|
136
|
-
|
137
|
-
true
|
138
|
-
end
|
139
|
-
|
129
|
+
source = caller.find { |loc| loc !~ /simple-cli.*\/lib\/simple\/cli/ }
|
140
130
|
source ||= caller[2]
|
141
131
|
source = source[(wd.length + 1)..-1] if source.start_with?(wd)
|
142
132
|
source
|
@@ -43,7 +43,7 @@ class Simple::CLI::Runner::CommandHelp
|
|
43
43
|
end
|
44
44
|
|
45
45
|
# A help string constructed from the commands method signature.
|
46
|
-
def interface(binary_name, command_name)
|
46
|
+
def interface(binary_name, command_name, include_subcommand: false)
|
47
47
|
args = @method_parameters_ex.map do |mode, name|
|
48
48
|
case mode
|
49
49
|
when :req then "<#{name}>"
|
@@ -66,7 +66,8 @@ class Simple::CLI::Runner::CommandHelp
|
|
66
66
|
end
|
67
67
|
end.compact
|
68
68
|
|
69
|
-
help = "#{binary_name}
|
69
|
+
help = "#{binary_name}"
|
70
|
+
help << " #{command_to_string(command_name)}" if include_subcommand
|
70
71
|
help << " #{options.join(' ')}" unless options.empty?
|
71
72
|
help << " #{args.join(' ')}" unless args.empty?
|
72
73
|
help
|
data/lib/simple/cli/runner.rb
CHANGED
@@ -8,13 +8,10 @@ class Simple::CLI::Runner
|
|
8
8
|
end
|
9
9
|
|
10
10
|
require_relative "runner/command_help"
|
11
|
-
require_relative "runner/autocompletion"
|
12
11
|
|
13
12
|
# A Runner object manages running a CLI application module with a set
|
14
13
|
# of string arguments (usually taken from ARGV)
|
15
14
|
class Simple::CLI::Runner
|
16
|
-
include Autocompletion
|
17
|
-
|
18
15
|
def self.run(app, *args)
|
19
16
|
new(app).run(*args)
|
20
17
|
end
|
@@ -34,6 +31,14 @@ class Simple::CLI::Runner
|
|
34
31
|
|
35
32
|
attr_accessor :subcommand
|
36
33
|
|
34
|
+
def help(command)
|
35
|
+
if command
|
36
|
+
run "help", command
|
37
|
+
else
|
38
|
+
run "help"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
37
42
|
def run(*args)
|
38
43
|
extract_default_flags!(args)
|
39
44
|
|
@@ -43,10 +48,6 @@ class Simple::CLI::Runner
|
|
43
48
|
|
44
49
|
if command == :help
|
45
50
|
do_help!(*args)
|
46
|
-
elsif command == :autocomplete
|
47
|
-
autocomplete(*args)
|
48
|
-
elsif command == :autocomplete_bash
|
49
|
-
autocomplete_bash(*args)
|
50
51
|
elsif commands.include?(command)
|
51
52
|
self.subcommand = command
|
52
53
|
@instance.run! command, *args_with_options(args)
|
@@ -57,6 +58,10 @@ class Simple::CLI::Runner
|
|
57
58
|
on_exception(e)
|
58
59
|
end
|
59
60
|
|
61
|
+
def has_subcommands?
|
62
|
+
commands.length > 1
|
63
|
+
end
|
64
|
+
|
60
65
|
def do_help!(subcommand = nil)
|
61
66
|
if !subcommand
|
62
67
|
help!
|
@@ -72,8 +77,19 @@ class Simple::CLI::Runner
|
|
72
77
|
#{help_for_command(subcommand)}
|
73
78
|
|
74
79
|
#{edoc.full}
|
75
|
-
|
80
|
+
MSG
|
76
81
|
|
82
|
+
unless has_subcommands?
|
83
|
+
|
84
|
+
STDERR.puts <<~MSG
|
85
|
+
|
86
|
+
Default options include:
|
87
|
+
|
88
|
+
#{binary_name} [ --help | -h ] ... print this help
|
89
|
+
#{binary_name} [ --verbose | -v ] ... run on DEBUG log level
|
90
|
+
#{binary_name} [ --quiet | -q ] ... run on WARN log level
|
91
|
+
MSG
|
92
|
+
end
|
77
93
|
exit 1
|
78
94
|
end
|
79
95
|
|
@@ -133,13 +149,8 @@ class Simple::CLI::Runner
|
|
133
149
|
end
|
134
150
|
|
135
151
|
def help_for_command(sym)
|
136
|
-
if sym == "autocomplete"
|
137
|
-
autocomplete_help
|
138
|
-
return
|
139
|
-
end
|
140
|
-
|
141
152
|
cmd = string_to_command(sym)
|
142
|
-
CommandHelp.new(@app, cmd).interface(binary_name, cmd)
|
153
|
+
CommandHelp.new(@app, cmd).interface(binary_name, cmd, include_subcommand: has_subcommands?)
|
143
154
|
end
|
144
155
|
|
145
156
|
def binary_name
|
@@ -194,7 +205,6 @@ class Simple::CLI::Runner
|
|
194
205
|
|
195
206
|
print_help_line.call "#{binary_name} help [ subcommand ]", "print help on a specific subcommand"
|
196
207
|
print_help_line.call "#{binary_name} help -v", "show help for internal commands as well"
|
197
|
-
print_help_line.call "#{binary_name} help autocomplete", "print information on autocompletion."
|
198
208
|
|
199
209
|
STDERR.puts "\n"
|
200
210
|
|
data/lib/simple/cli/version.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- radiospiel
|
8
8
|
- mediapeers GmbH
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2019-11-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -75,13 +75,9 @@ extra_rdoc_files: []
|
|
75
75
|
files:
|
76
76
|
- ".gitignore"
|
77
77
|
- ".rubocop.yml"
|
78
|
-
- ".ruby-version"
|
79
78
|
- Gemfile
|
80
|
-
- README.md
|
81
79
|
- Rakefile
|
82
80
|
- bin/rake
|
83
|
-
- doc/examples/ex1/ex1
|
84
|
-
- doc/examples/ex1/ex1.rb
|
85
81
|
- lib/simple-cli.rb
|
86
82
|
- lib/simple/cli.rb
|
87
83
|
- lib/simple/cli/adapter.rb
|
@@ -91,7 +87,6 @@ files:
|
|
91
87
|
- lib/simple/cli/logger/colored_logger.rb
|
92
88
|
- lib/simple/cli/pp.rb
|
93
89
|
- lib/simple/cli/runner.rb
|
94
|
-
- lib/simple/cli/runner/autocompletion.rb
|
95
90
|
- lib/simple/cli/runner/command_help.rb
|
96
91
|
- lib/simple/cli/runner/module_ex.rb
|
97
92
|
- lib/simple/cli/version.rb
|
@@ -103,7 +98,7 @@ files:
|
|
103
98
|
homepage: http://github.com/radiospiel/simple-cli
|
104
99
|
licenses: []
|
105
100
|
metadata: {}
|
106
|
-
post_install_message:
|
101
|
+
post_install_message:
|
107
102
|
rdoc_options: []
|
108
103
|
require_paths:
|
109
104
|
- lib
|
@@ -118,8 +113,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
118
113
|
- !ruby/object:Gem::Version
|
119
114
|
version: '0'
|
120
115
|
requirements: []
|
121
|
-
rubygems_version: 3.
|
122
|
-
signing_key:
|
116
|
+
rubygems_version: 3.0.4
|
117
|
+
signing_key:
|
123
118
|
specification_version: 4
|
124
119
|
summary: Simple CLI builder for ruby
|
125
120
|
test_files:
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
2.7.2
|
data/README.md
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
# simple-cli
|
2
|
-
|
3
|
-
Building Ruby CLIs with easy.
|
4
|
-
|
5
|
-
## Philosophy
|
6
|
-
|
7
|
-
Building a command line could be much easier than what ruby provides with its standard library. In general, between the invocation of a tool from the command line and the actual running of whatever code the user intends to run really should disappear.
|
8
|
-
|
9
|
-
Ideally a developer would only have to build the implementation of whatever logic should be provided by the tool; everything else - parsing arguments, calling the tool's implementation, printing help - should happen automatically.
|
10
|
-
|
11
|
-
This is roughly what sinmple-sql provides.
|
12
|
-
|
13
|
-
## On versions
|
14
|
-
|
15
|
-
`simple-cli` is still on a 0.x.x version, and, generally, a 0.x.y version is not compatible with a 0.x+1.y version.
|
16
|
-
|
17
|
-
These are the follow
|
18
|
-
|
19
|
-
- The 0.2.x versions are tracked in the [`stable`](https://github.com/radiospiel/simple-cli/tree/stable) branch
|
20
|
-
- The 0.3.x versions are tracked in the [`master`](https://github.com/radiospiel/simple-cli/tree/stable) branch
|
21
|
-
|
22
|
-
## Basic features
|
23
|
-
|
24
|
-
- build command line features in a number of modules;
|
25
|
-
- public methods in these modules provide a subcommand for the CLI;
|
26
|
-
- `"_"` in the method name are being mapped to `":"` in the CLI;
|
27
|
-
- CLI provides a help subcommand. help texts are derived from the methods over a subcommand implementation:
|
28
|
-
- The first line determines the "short help" message, to be included in the `$CMD help` command list;
|
29
|
-
- The remaining lines determines the full help message, to be included in the `$CMD help subcommand` message.
|
30
|
-
|
31
|
-
## Example
|
32
|
-
|
data/doc/examples/ex1/ex1
DELETED
data/doc/examples/ex1/ex1.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
require 'bundler/inline'
|
3
|
-
|
4
|
-
gemfile do
|
5
|
-
source 'https://rubygems.org'
|
6
|
-
gem "simple-cli", '~> 0.2', path: "../../.."
|
7
|
-
end
|
8
|
-
|
9
|
-
module Ex1; end
|
10
|
-
module Ex1::CLI
|
11
|
-
include Simple::CLI
|
12
|
-
|
13
|
-
# Command without arguments
|
14
|
-
#
|
15
|
-
# Example:
|
16
|
-
#
|
17
|
-
# ./ex1 hello:world
|
18
|
-
#
|
19
|
-
def hello_world
|
20
|
-
puts "Hello from #{__FILE__}"
|
21
|
-
end
|
22
|
-
|
23
|
-
# Command with arguments
|
24
|
-
#
|
25
|
-
# This implements a command with arguments
|
26
|
-
#
|
27
|
-
# Examples:
|
28
|
-
#
|
29
|
-
# ./ex1 hello --name=user "what's up"
|
30
|
-
#
|
31
|
-
def hello(message, name: nil)
|
32
|
-
if name
|
33
|
-
puts "Hello #{name}: #{message}!"
|
34
|
-
else
|
35
|
-
puts "Hello, #{message}!"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
Ex1::CLI.run!(*ARGV)
|
@@ -1,91 +0,0 @@
|
|
1
|
-
module Simple::CLI::Runner::Autocompletion
|
2
|
-
CommandHelp = Simple::CLI::Runner::CommandHelp
|
3
|
-
|
4
|
-
def autocomplete(subcommand = nil, cur = nil)
|
5
|
-
puts completions(subcommand, cur).join("\n")
|
6
|
-
end
|
7
|
-
|
8
|
-
def completions(subcommand = nil, cur = nil)
|
9
|
-
if !cur
|
10
|
-
autocomplete_subcommands(subcommand)
|
11
|
-
else
|
12
|
-
autocomplete_subcommand_options(subcommand, cur)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def filter_completions(completions, prefix:)
|
17
|
-
completions.select do |completion|
|
18
|
-
!prefix || completion.start_with?(prefix)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def autocomplete_subcommands(cur)
|
23
|
-
commands = self.commands.map { |cmd| cmd.to_s.tr("_", ":") }
|
24
|
-
commands << "help"
|
25
|
-
completions = filter_completions commands, prefix: cur
|
26
|
-
if completions == [cur]
|
27
|
-
autocomplete_subcommand_options(cur, nil)
|
28
|
-
else
|
29
|
-
completions
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
DEFAULT_OPTIONS = %w(--verbose -v --quiet -q)
|
34
|
-
|
35
|
-
def autocomplete_subcommand_options(subcommand, cur)
|
36
|
-
if subcommand == "help"
|
37
|
-
completions = commands.map(&:to_s).map { |s| s.tr("_", ":") } + ["autocomplete"]
|
38
|
-
filter_completions completions, prefix: cur
|
39
|
-
elsif cur && cur[0, 1] == "-"
|
40
|
-
completions = CommandHelp.option_names(@app, string_to_command(subcommand))
|
41
|
-
completions += DEFAULT_OPTIONS
|
42
|
-
|
43
|
-
filter_completions completions, prefix: cur
|
44
|
-
else
|
45
|
-
Dir.glob "#{cur}*"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def autocomplete_help
|
50
|
-
STDERR.puts <<~DOC
|
51
|
-
#{binary_name} supports autocompletion. To enable autocompletion please run
|
52
|
-
|
53
|
-
eval "$(#{$0} autocomplete:bash)"
|
54
|
-
DOC
|
55
|
-
|
56
|
-
exit 1
|
57
|
-
end
|
58
|
-
|
59
|
-
def autocomplete_bash
|
60
|
-
puts AUTOCOMPLETE_SHELL_CODE.gsub(/{{BINARY}}/, binary_name)
|
61
|
-
end
|
62
|
-
|
63
|
-
# The shell function function is executed in the current shell environment.
|
64
|
-
# When it is executed,
|
65
|
-
#
|
66
|
-
# - $1 is the name of the command whose arguments are being completed,
|
67
|
-
# - $2 is the word being completed, and
|
68
|
-
# - $3 is the word preceding the word being completed
|
69
|
-
#
|
70
|
-
# When it finishes, the possible completions are retrieved from the value of the COMPREPLY array variable.
|
71
|
-
#
|
72
|
-
# see https://www.gnu.org/software/bash/manual/html_node/Programmable-Completion-Builtins.html
|
73
|
-
#
|
74
|
-
AUTOCOMPLETE_SHELL_CODE = <<~BASH
|
75
|
-
_{{BINARY}}()
|
76
|
-
{
|
77
|
-
local cmd=$1
|
78
|
-
local cur=$2
|
79
|
-
|
80
|
-
if [[ $COMP_CWORD == 1 ]]; then
|
81
|
-
COMPREPLY=( $("$cmd" autocomplete "$cur" ))
|
82
|
-
else
|
83
|
-
local subcommand=${COMP_WORDS[1]}
|
84
|
-
COMPREPLY=( $("$cmd" autocomplete "$subcommand" "$cur" ))
|
85
|
-
fi
|
86
|
-
|
87
|
-
return 0
|
88
|
-
}
|
89
|
-
complete -F _{{BINARY}} {{BINARY}}
|
90
|
-
BASH
|
91
|
-
end
|