gli 1.6.0 → 2.0.0.rc3
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.
- data/.gitignore +11 -0
- data/.rvmrc +1 -0
- data/.travis.yml +10 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +201 -0
- data/ObjectModel.graffle +1191 -0
- data/README.rdoc +60 -10
- data/Rakefile +145 -0
- data/bin/gli +12 -30
- data/bin/report_on_rake_results +10 -0
- data/bin/test_all_rubies.sh +6 -0
- data/features/gli_executable.feature +84 -0
- data/features/gli_init.feature +219 -0
- data/features/step_definitions/gli_executable_steps.rb +12 -0
- data/features/step_definitions/gli_init_steps.rb +11 -0
- data/features/step_definitions/todo_steps.rb +69 -0
- data/features/support/env.rb +49 -0
- data/features/todo.feature +182 -0
- data/gli.cheat +95 -0
- data/gli.gemspec +34 -0
- data/lib/gli.rb +11 -571
- data/lib/gli/app.rb +184 -0
- data/lib/gli/app_support.rb +226 -0
- data/lib/gli/command.rb +107 -95
- data/lib/gli/command_line_option.rb +34 -0
- data/lib/gli/command_line_token.rb +13 -9
- data/lib/gli/command_support.rb +200 -0
- data/lib/gli/commands/compound_command.rb +42 -0
- data/lib/gli/commands/help.rb +63 -0
- data/lib/gli/commands/help_modules/command_help_format.rb +134 -0
- data/lib/gli/commands/help_modules/global_help_format.rb +61 -0
- data/lib/gli/commands/help_modules/list_formatter.rb +22 -0
- data/lib/gli/commands/help_modules/options_formatter.rb +50 -0
- data/lib/gli/commands/help_modules/text_wrapper.rb +53 -0
- data/lib/gli/commands/initconfig.rb +67 -0
- data/lib/{support → gli/commands}/scaffold.rb +150 -34
- data/lib/gli/dsl.rb +194 -0
- data/lib/gli/exceptions.rb +13 -4
- data/lib/gli/flag.rb +30 -41
- data/lib/gli/gli_option_parser.rb +98 -0
- data/lib/gli/option_parser_factory.rb +44 -0
- data/lib/gli/options.rb +2 -1
- data/lib/gli/switch.rb +19 -51
- data/lib/gli/terminal.rb +30 -20
- data/lib/gli/version.rb +5 -0
- data/test/apps/README.md +2 -0
- data/test/apps/todo/Gemfile +2 -0
- data/test/apps/todo/README.rdoc +6 -0
- data/test/apps/todo/Rakefile +23 -0
- data/test/apps/todo/bin/todo +52 -0
- data/test/apps/todo/lib/todo/commands/create.rb +22 -0
- data/test/apps/todo/lib/todo/commands/list.rb +53 -0
- data/test/apps/todo/lib/todo/commands/ls.rb +47 -0
- data/test/apps/todo/lib/todo/version.rb +3 -0
- data/test/apps/todo/test/tc_nothing.rb +14 -0
- data/test/apps/todo/todo.gemspec +23 -0
- data/test/apps/todo/todo.rdoc +5 -0
- data/test/config.yaml +10 -0
- data/test/fake_std_out.rb +30 -0
- data/test/gli.reek +122 -0
- data/test/init_simplecov.rb +8 -0
- data/test/option_test_helper.rb +13 -0
- data/test/roodi.yaml +18 -0
- data/test/tc_command.rb +260 -0
- data/test/tc_compount_command.rb +22 -0
- data/test/tc_flag.rb +56 -0
- data/test/tc_gli.rb +611 -0
- data/test/tc_help.rb +223 -0
- data/test/tc_options.rb +31 -0
- data/test/tc_subcommands.rb +162 -0
- data/test/tc_switch.rb +57 -0
- data/test/tc_terminal.rb +97 -0
- data/test/test_helper.rb +13 -0
- metadata +318 -49
- data/lib/gli_version.rb +0 -3
- data/lib/support/help.rb +0 -179
- data/lib/support/initconfig.rb +0 -34
- data/lib/support/rdoc.rb +0 -119
data/lib/gli_version.rb
DELETED
data/lib/support/help.rb
DELETED
@@ -1,179 +0,0 @@
|
|
1
|
-
require 'gli'
|
2
|
-
require 'gli/command'
|
3
|
-
require 'gli/terminal'
|
4
|
-
|
5
|
-
module GLI
|
6
|
-
class DefaultHelpCommand < Command #:nodoc:
|
7
|
-
@@output = $stdout
|
8
|
-
@@skips_pre = true
|
9
|
-
@@skips_post = true
|
10
|
-
|
11
|
-
# Exposed for testing
|
12
|
-
def self.output_device=(o); @@output = o; end
|
13
|
-
|
14
|
-
# To override the default behavior of the help command, which is
|
15
|
-
# to NOT run the pre block, use this.
|
16
|
-
def self.skips_pre=(skips_pre)
|
17
|
-
@@skips_pre = skips_pre
|
18
|
-
end
|
19
|
-
|
20
|
-
# To override the default behavior of the help command, which is
|
21
|
-
# to NOT run the post block, use this.
|
22
|
-
def self.skips_post=(skips_post)
|
23
|
-
@@skips_post = skips_post
|
24
|
-
end
|
25
|
-
|
26
|
-
def initialize(version,*omit_from_list)
|
27
|
-
@omit_from_list = omit_from_list
|
28
|
-
@version = version
|
29
|
-
super(:help,
|
30
|
-
'Shows list of commands or help for one command',
|
31
|
-
'[command]',
|
32
|
-
'Gets help for the application or its commands. Can also list the commands in a way helpful to creating a bash-style completion function')
|
33
|
-
self.desc 'List all commands one line at a time, for use with shell completion ([command] argument is partial command to match)'
|
34
|
-
self.switch [:c,:completion]
|
35
|
-
end
|
36
|
-
|
37
|
-
def skips_pre; @@skips_pre; end
|
38
|
-
def skips_post; @@skips_post; end
|
39
|
-
|
40
|
-
def execute(global_options,options,arguments)
|
41
|
-
if options[:c]
|
42
|
-
names = commands_to_show.reduce([]) do |memo,obj|
|
43
|
-
memo << obj[0]
|
44
|
-
memo << obj[1].aliases
|
45
|
-
memo = memo.flatten
|
46
|
-
end
|
47
|
-
names.map! { |name| name.to_s }
|
48
|
-
if arguments && arguments.size > 0
|
49
|
-
names = names.select { |name| name =~ /^#{arguments[0]}/ }
|
50
|
-
end
|
51
|
-
names.sort.each do |command|
|
52
|
-
next if command.empty?
|
53
|
-
@@output.puts command
|
54
|
-
end
|
55
|
-
else
|
56
|
-
if arguments.empty?
|
57
|
-
list_global_flags
|
58
|
-
list_commands
|
59
|
-
else
|
60
|
-
list_one_command_help(arguments[0])
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
private
|
66
|
-
|
67
|
-
def list_global_flags
|
68
|
-
if GLI.program_desc
|
69
|
-
@@output.puts wrap(GLI.program_desc,0)
|
70
|
-
@@output.puts
|
71
|
-
end
|
72
|
-
usage = "usage: #{GLI.program_name} "
|
73
|
-
all_options = GLI.switches.merge(GLI.flags)
|
74
|
-
if !all_options.empty?
|
75
|
-
usage += "[global options] "
|
76
|
-
end
|
77
|
-
usage += "command"
|
78
|
-
usage += ' [command options]'
|
79
|
-
@@output.puts usage
|
80
|
-
@@output.puts
|
81
|
-
if @version
|
82
|
-
@@output.puts "Version: #{@version}"
|
83
|
-
@@output.puts
|
84
|
-
end
|
85
|
-
@@output.puts 'Global Options:' if !all_options.empty?
|
86
|
-
output_command_tokens_for_help(all_options)
|
87
|
-
@@output.puts if !all_options.empty?
|
88
|
-
end
|
89
|
-
|
90
|
-
def list_commands
|
91
|
-
@@output.puts 'Commands:'
|
92
|
-
output_command_tokens_for_help(commands_to_show,:names)
|
93
|
-
end
|
94
|
-
|
95
|
-
def commands_to_show
|
96
|
-
GLI.commands.reject{ |name,c| @omit_from_list.include?(c) }
|
97
|
-
end
|
98
|
-
|
99
|
-
def list_one_command_help(command_name)
|
100
|
-
command = GLI.find_command(command_name)
|
101
|
-
if command
|
102
|
-
@@output.puts command.usage
|
103
|
-
description = wrap(command.description,4)
|
104
|
-
@@output.puts " #{description}"
|
105
|
-
if command.long_description
|
106
|
-
@@output.puts
|
107
|
-
@@output.puts " #{wrap(command.long_description,4)}"
|
108
|
-
end
|
109
|
-
all_options = command.switches.merge(command.flags)
|
110
|
-
if !all_options.empty?
|
111
|
-
@@output.puts
|
112
|
-
@@output.puts "Command Options:"
|
113
|
-
output_command_tokens_for_help(all_options)
|
114
|
-
end
|
115
|
-
else
|
116
|
-
@@output.puts "No such command #{command_name}"
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
def output_command_tokens_for_help(tokens,usage_name=:usage)
|
121
|
-
max = 0
|
122
|
-
tokens.values.each do |token|
|
123
|
-
len = token.send(usage_name).length
|
124
|
-
if len > max
|
125
|
-
max = len
|
126
|
-
end
|
127
|
-
end
|
128
|
-
names = tokens.keys.sort { |x,y| x.to_s <=> y.to_s }
|
129
|
-
names.each do |name|
|
130
|
-
token = tokens[name]
|
131
|
-
description = token.description || ''
|
132
|
-
if token.kind_of? Flag
|
133
|
-
description += " (default: #{token.default_value})" if token.default_value
|
134
|
-
end
|
135
|
-
description = wrap(description,max+7)
|
136
|
-
string = sprintf " %-#{max}s - %s",token.send(usage_name),description
|
137
|
-
@@output.puts string
|
138
|
-
end
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
private
|
143
|
-
|
144
|
-
# Wraps the line at the given column length, using the given line padding.
|
145
|
-
# Assumes that the first line doesn't need the padding, as its filled
|
146
|
-
# up with other stuff
|
147
|
-
def wrap(line,pad_length=0,line_length=nil)
|
148
|
-
line ||= ''
|
149
|
-
if line_length.nil?
|
150
|
-
line_length = Terminal.instance.size[0]
|
151
|
-
end
|
152
|
-
line_padding = sprintf("%#{pad_length}s",'')
|
153
|
-
paragraphs = line.split("\n\n").map { |l| l.chomp }.reject { |l| l.empty? }
|
154
|
-
wrapped = paragraphs.map do |para|
|
155
|
-
paragraph_lines(para, line_length - pad_length).join("\n#{line_padding}")
|
156
|
-
end
|
157
|
-
wrapped.join("\n\n#{line_padding}")
|
158
|
-
end
|
159
|
-
|
160
|
-
# Creates lines of the given column length using the words from the
|
161
|
-
# provided paragraph.
|
162
|
-
def paragraph_lines(paragraph,line_length)
|
163
|
-
lines = []
|
164
|
-
this_line = ''
|
165
|
-
|
166
|
-
paragraph.split(/\s+/).each do |word|
|
167
|
-
if this_line.length + word.length + 1 > line_length
|
168
|
-
lines << this_line
|
169
|
-
this_line = word
|
170
|
-
else
|
171
|
-
this_line += ' ' unless this_line.empty?
|
172
|
-
this_line += word
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
lines << this_line
|
177
|
-
end
|
178
|
-
|
179
|
-
end
|
data/lib/support/initconfig.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'gli'
|
2
|
-
require 'gli/command'
|
3
|
-
require 'yaml'
|
4
|
-
|
5
|
-
module GLI
|
6
|
-
class InitConfig < Command # :nodoc:
|
7
|
-
COMMANDS_KEY = 'commands'
|
8
|
-
|
9
|
-
def initialize(config_file_name)
|
10
|
-
@filename = config_file_name
|
11
|
-
super(:initconfig,"Initialize the config file using current global options",nil,'Initializes a configuration file where you can set default options for command line flags, both globally and on a per-command basis. These defaults override the built-in defaults and allow you to omit commonly-used command line flags when invoking this program')
|
12
|
-
|
13
|
-
self.desc 'force overwrite of existing config file'
|
14
|
-
self.switch :force
|
15
|
-
end
|
16
|
-
|
17
|
-
def execute(global_options,options,arguments)
|
18
|
-
if options[:force] || !File.exist?(@filename)
|
19
|
-
config = global_options
|
20
|
-
config[COMMANDS_KEY] = {}
|
21
|
-
GLI.commands.each do |name,command|
|
22
|
-
if (command != self) && (name != :rdoc) && (name != :help)
|
23
|
-
config[COMMANDS_KEY][name.to_sym] = {} if command != self
|
24
|
-
end
|
25
|
-
end
|
26
|
-
File.open(@filename,'w', 0600) do |file|
|
27
|
-
YAML.dump(config,file)
|
28
|
-
end
|
29
|
-
else
|
30
|
-
raise "Not overwriting existing config file #{@filename}, use --force to override"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
data/lib/support/rdoc.rb
DELETED
@@ -1,119 +0,0 @@
|
|
1
|
-
require 'gli'
|
2
|
-
require 'fileutils'
|
3
|
-
|
4
|
-
module GLI
|
5
|
-
class RDocCommand < Command # :nodoc:
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
super(:rdoc,'Generates RDoc (and other types of documentation) for your command line interface')
|
9
|
-
self.desc 'Create a very basic scaffold for a cheat-style cheatsheet, in addition to rdoc'
|
10
|
-
self.switch 'cheatsheet'
|
11
|
-
self.desc 'Include a manapage suitable for gem man, in addition to rdoc'
|
12
|
-
self.switch 'manpage'
|
13
|
-
self.desc 'Do not create rdoc'
|
14
|
-
self.switch 'no-rdoc'
|
15
|
-
end
|
16
|
-
|
17
|
-
def execute(g,options,a)
|
18
|
-
create_rdoc unless options[:'no-rdoc']
|
19
|
-
create_manpage if options[:manpage]
|
20
|
-
create_cheatsheet if options[:cheatsheet]
|
21
|
-
end
|
22
|
-
|
23
|
-
def create_cheatsheet
|
24
|
-
File.open("#{GLI.program_name}.cheat",'w') do |file|
|
25
|
-
file << GLI.program_name
|
26
|
-
file << "\n"
|
27
|
-
file << GLI.program_name.length.times.inject("") { |a,x| a + "=" }
|
28
|
-
file << "\n"
|
29
|
-
file << "\n"
|
30
|
-
file << "Installation:\n"
|
31
|
-
file << "$ gem install #{GLI.program_name}\n\n"
|
32
|
-
GLI.commands.values.sort.each do |command|
|
33
|
-
next if command == self
|
34
|
-
file << command.description
|
35
|
-
file << "\n"
|
36
|
-
[command.name,command.aliases].flatten.each do |name|
|
37
|
-
next unless name
|
38
|
-
file << "$ #{GLI.program_name} #{name} #{command.arguments_description}\n"
|
39
|
-
end
|
40
|
-
file << "\n"
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def create_manpage
|
46
|
-
end
|
47
|
-
|
48
|
-
def create_rdoc
|
49
|
-
File.open("#{GLI.program_name}.rdoc",'w') do |file|
|
50
|
-
file << "= <tt>#{GLI.program_name}</tt>\n\n"
|
51
|
-
if GLI.program_desc
|
52
|
-
file << GLI.program_desc
|
53
|
-
file << "\n\n"
|
54
|
-
end
|
55
|
-
file << " "
|
56
|
-
file << GLI.program_name
|
57
|
-
file << " "
|
58
|
-
global_options = GLI.switches.merge(GLI.flags)
|
59
|
-
if (global_options && global_options.length > 0)
|
60
|
-
file << "[global options] "
|
61
|
-
end
|
62
|
-
file << "command_name"
|
63
|
-
file << " [command-specific options]"
|
64
|
-
file << " [--] arguments...\n\n"
|
65
|
-
file << "* Use the command +help+ to get a summary of commands\n"
|
66
|
-
file << "* Use the command <tt>help command_name</tt> to get a help for +command_name+\n"
|
67
|
-
file << "* Use <tt>--</tt> to stop command line argument processing; useful if your arguments have dashes in them\n"
|
68
|
-
file << "\n"
|
69
|
-
if (global_options && global_options.length > 0)
|
70
|
-
file << "== Global Options\n"
|
71
|
-
file << "These options are available for any command and are specified before the name of the command\n\n"
|
72
|
-
output_flags(file,global_options)
|
73
|
-
end
|
74
|
-
file << "== Commands\n"
|
75
|
-
GLI.commands.values.sort.each do |command|
|
76
|
-
next if command == self
|
77
|
-
file << "[<tt>#{command.name}</tt>] #{command.description}\n"
|
78
|
-
end
|
79
|
-
file << "\n"
|
80
|
-
|
81
|
-
GLI.commands.values.sort.each do |command|
|
82
|
-
next if command == self
|
83
|
-
file << "=== <tt>#{command.name} #{command.arguments_description}</tt>\n\n"
|
84
|
-
file << "#{command.description}\n\n"
|
85
|
-
if command.aliases
|
86
|
-
file << "*Aliases*\n"
|
87
|
-
command.aliases.each do |al|
|
88
|
-
file << "* <tt><b>#{al}</b></tt>\n"
|
89
|
-
end
|
90
|
-
file << "\n"
|
91
|
-
end
|
92
|
-
all_options = command.switches.merge(command.flags)
|
93
|
-
file << "#{command.long_description}\n\n" if command.long_description
|
94
|
-
if (all_options && all_options.length > 0)
|
95
|
-
file << "==== Options\n"
|
96
|
-
file << "These options are specified *after* the command.\n\n"
|
97
|
-
output_flags(file,all_options)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
def output_flags(file,flags)
|
104
|
-
flags.values.sort.each do |flag|
|
105
|
-
file << "[<tt>#{flag.usage}</tt>] #{flag.description}"
|
106
|
-
if flag.kind_of? Flag
|
107
|
-
file << " <i>( default: <tt>#{flag.default_value}</tt>)</i>" if flag.default_value
|
108
|
-
end
|
109
|
-
file << "\n"
|
110
|
-
if flag.long_description
|
111
|
-
file << "\n"
|
112
|
-
# 12 is: 4 for tt, 5 for /tt, 2 for the brackets and 1 for spacing
|
113
|
-
(flag.usage.length + 12).times { file << " " }
|
114
|
-
file << "#{flag.long_description}\n\n"
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|