simple-cli 0.2.28 → 0.3.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 +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
|