gli 1.6.0 → 2.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/.gitignore +11 -0
  2. data/.rvmrc +1 -0
  3. data/.travis.yml +10 -0
  4. data/Gemfile +8 -0
  5. data/LICENSE.txt +201 -0
  6. data/ObjectModel.graffle +1191 -0
  7. data/README.rdoc +60 -10
  8. data/Rakefile +145 -0
  9. data/bin/gli +12 -30
  10. data/bin/report_on_rake_results +10 -0
  11. data/bin/test_all_rubies.sh +6 -0
  12. data/features/gli_executable.feature +84 -0
  13. data/features/gli_init.feature +219 -0
  14. data/features/step_definitions/gli_executable_steps.rb +12 -0
  15. data/features/step_definitions/gli_init_steps.rb +11 -0
  16. data/features/step_definitions/todo_steps.rb +69 -0
  17. data/features/support/env.rb +49 -0
  18. data/features/todo.feature +182 -0
  19. data/gli.cheat +95 -0
  20. data/gli.gemspec +34 -0
  21. data/lib/gli.rb +11 -571
  22. data/lib/gli/app.rb +184 -0
  23. data/lib/gli/app_support.rb +226 -0
  24. data/lib/gli/command.rb +107 -95
  25. data/lib/gli/command_line_option.rb +34 -0
  26. data/lib/gli/command_line_token.rb +13 -9
  27. data/lib/gli/command_support.rb +200 -0
  28. data/lib/gli/commands/compound_command.rb +42 -0
  29. data/lib/gli/commands/help.rb +63 -0
  30. data/lib/gli/commands/help_modules/command_help_format.rb +134 -0
  31. data/lib/gli/commands/help_modules/global_help_format.rb +61 -0
  32. data/lib/gli/commands/help_modules/list_formatter.rb +22 -0
  33. data/lib/gli/commands/help_modules/options_formatter.rb +50 -0
  34. data/lib/gli/commands/help_modules/text_wrapper.rb +53 -0
  35. data/lib/gli/commands/initconfig.rb +67 -0
  36. data/lib/{support → gli/commands}/scaffold.rb +150 -34
  37. data/lib/gli/dsl.rb +194 -0
  38. data/lib/gli/exceptions.rb +13 -4
  39. data/lib/gli/flag.rb +30 -41
  40. data/lib/gli/gli_option_parser.rb +98 -0
  41. data/lib/gli/option_parser_factory.rb +44 -0
  42. data/lib/gli/options.rb +2 -1
  43. data/lib/gli/switch.rb +19 -51
  44. data/lib/gli/terminal.rb +30 -20
  45. data/lib/gli/version.rb +5 -0
  46. data/test/apps/README.md +2 -0
  47. data/test/apps/todo/Gemfile +2 -0
  48. data/test/apps/todo/README.rdoc +6 -0
  49. data/test/apps/todo/Rakefile +23 -0
  50. data/test/apps/todo/bin/todo +52 -0
  51. data/test/apps/todo/lib/todo/commands/create.rb +22 -0
  52. data/test/apps/todo/lib/todo/commands/list.rb +53 -0
  53. data/test/apps/todo/lib/todo/commands/ls.rb +47 -0
  54. data/test/apps/todo/lib/todo/version.rb +3 -0
  55. data/test/apps/todo/test/tc_nothing.rb +14 -0
  56. data/test/apps/todo/todo.gemspec +23 -0
  57. data/test/apps/todo/todo.rdoc +5 -0
  58. data/test/config.yaml +10 -0
  59. data/test/fake_std_out.rb +30 -0
  60. data/test/gli.reek +122 -0
  61. data/test/init_simplecov.rb +8 -0
  62. data/test/option_test_helper.rb +13 -0
  63. data/test/roodi.yaml +18 -0
  64. data/test/tc_command.rb +260 -0
  65. data/test/tc_compount_command.rb +22 -0
  66. data/test/tc_flag.rb +56 -0
  67. data/test/tc_gli.rb +611 -0
  68. data/test/tc_help.rb +223 -0
  69. data/test/tc_options.rb +31 -0
  70. data/test/tc_subcommands.rb +162 -0
  71. data/test/tc_switch.rb +57 -0
  72. data/test/tc_terminal.rb +97 -0
  73. data/test/test_helper.rb +13 -0
  74. metadata +318 -49
  75. data/lib/gli_version.rb +0 -3
  76. data/lib/support/help.rb +0 -179
  77. data/lib/support/initconfig.rb +0 -34
  78. data/lib/support/rdoc.rb +0 -119
data/lib/gli_version.rb DELETED
@@ -1,3 +0,0 @@
1
- module GLI
2
- VERSION = '1.6.0'
3
- end
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
@@ -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