gli_aziz_light 2.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (104) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +17 -0
  6. data/CONTRIBUTING.md +23 -0
  7. data/Gemfile +8 -0
  8. data/LICENSE.txt +201 -0
  9. data/ObjectModel.graffle +1191 -0
  10. data/README.rdoc +109 -0
  11. data/Rakefile +126 -0
  12. data/bin/gli +59 -0
  13. data/bin/report_on_rake_results +10 -0
  14. data/bin/test_all_rubies.sh +6 -0
  15. data/features/gli_executable.feature +90 -0
  16. data/features/gli_init.feature +232 -0
  17. data/features/step_definitions/gli_executable_steps.rb +18 -0
  18. data/features/step_definitions/gli_init_steps.rb +11 -0
  19. data/features/step_definitions/todo_steps.rb +88 -0
  20. data/features/support/env.rb +53 -0
  21. data/features/todo.feature +413 -0
  22. data/features/todo_legacy.feature +128 -0
  23. data/gli.cheat +95 -0
  24. data/gli.gemspec +34 -0
  25. data/gli.rdoc +73 -0
  26. data/lib/gli.rb +35 -0
  27. data/lib/gli/app.rb +286 -0
  28. data/lib/gli/app_support.rb +341 -0
  29. data/lib/gli/command.rb +171 -0
  30. data/lib/gli/command_finder.rb +41 -0
  31. data/lib/gli/command_line_option.rb +34 -0
  32. data/lib/gli/command_line_token.rb +63 -0
  33. data/lib/gli/command_support.rb +181 -0
  34. data/lib/gli/commands/compound_command.rb +42 -0
  35. data/lib/gli/commands/doc.rb +231 -0
  36. data/lib/gli/commands/help.rb +95 -0
  37. data/lib/gli/commands/help_modules/arg_name_formatter.rb +20 -0
  38. data/lib/gli/commands/help_modules/command_finder.rb +60 -0
  39. data/lib/gli/commands/help_modules/command_help_format.rb +156 -0
  40. data/lib/gli/commands/help_modules/global_help_format.rb +70 -0
  41. data/lib/gli/commands/help_modules/help_completion_format.rb +31 -0
  42. data/lib/gli/commands/help_modules/list_formatter.rb +23 -0
  43. data/lib/gli/commands/help_modules/one_line_wrapper.rb +18 -0
  44. data/lib/gli/commands/help_modules/options_formatter.rb +49 -0
  45. data/lib/gli/commands/help_modules/text_wrapper.rb +53 -0
  46. data/lib/gli/commands/help_modules/tty_only_wrapper.rb +23 -0
  47. data/lib/gli/commands/help_modules/verbatim_wrapper.rb +16 -0
  48. data/lib/gli/commands/initconfig.rb +74 -0
  49. data/lib/gli/commands/rdoc_document_listener.rb +116 -0
  50. data/lib/gli/commands/scaffold.rb +401 -0
  51. data/lib/gli/dsl.rb +226 -0
  52. data/lib/gli/exceptions.rb +71 -0
  53. data/lib/gli/flag.rb +68 -0
  54. data/lib/gli/gli_option_block_parser.rb +84 -0
  55. data/lib/gli/gli_option_parser.rb +156 -0
  56. data/lib/gli/option_parser_factory.rb +81 -0
  57. data/lib/gli/option_parsing_result.rb +21 -0
  58. data/lib/gli/options.rb +23 -0
  59. data/lib/gli/switch.rb +35 -0
  60. data/lib/gli/terminal.rb +101 -0
  61. data/lib/gli/version.rb +5 -0
  62. data/test/apps/README.md +2 -0
  63. data/test/apps/todo/Gemfile +2 -0
  64. data/test/apps/todo/README.rdoc +6 -0
  65. data/test/apps/todo/Rakefile +23 -0
  66. data/test/apps/todo/bin/todo +63 -0
  67. data/test/apps/todo/lib/todo/commands/create.rb +24 -0
  68. data/test/apps/todo/lib/todo/commands/list.rb +63 -0
  69. data/test/apps/todo/lib/todo/commands/ls.rb +47 -0
  70. data/test/apps/todo/lib/todo/commands/make.rb +52 -0
  71. data/test/apps/todo/lib/todo/version.rb +3 -0
  72. data/test/apps/todo/test/tc_nothing.rb +14 -0
  73. data/test/apps/todo/todo.gemspec +23 -0
  74. data/test/apps/todo/todo.rdoc +5 -0
  75. data/test/apps/todo_legacy/Gemfile +2 -0
  76. data/test/apps/todo_legacy/README.rdoc +6 -0
  77. data/test/apps/todo_legacy/Rakefile +23 -0
  78. data/test/apps/todo_legacy/bin/todo +61 -0
  79. data/test/apps/todo_legacy/lib/todo/commands/create.rb +24 -0
  80. data/test/apps/todo_legacy/lib/todo/commands/list.rb +63 -0
  81. data/test/apps/todo_legacy/lib/todo/commands/ls.rb +47 -0
  82. data/test/apps/todo_legacy/lib/todo/version.rb +3 -0
  83. data/test/apps/todo_legacy/test/tc_nothing.rb +14 -0
  84. data/test/apps/todo_legacy/todo.gemspec +23 -0
  85. data/test/apps/todo_legacy/todo.rdoc +5 -0
  86. data/test/apps/todo_plugins/commands/third.rb +1 -0
  87. data/test/config.yaml +10 -0
  88. data/test/fake_std_out.rb +30 -0
  89. data/test/init_simplecov.rb +8 -0
  90. data/test/option_test_helper.rb +13 -0
  91. data/test/tc_command.rb +508 -0
  92. data/test/tc_compound_command.rb +22 -0
  93. data/test/tc_doc.rb +325 -0
  94. data/test/tc_flag.rb +62 -0
  95. data/test/tc_gli.rb +773 -0
  96. data/test/tc_help.rb +387 -0
  97. data/test/tc_options.rb +43 -0
  98. data/test/tc_subcommand_parsing.rb +104 -0
  99. data/test/tc_subcommands.rb +260 -0
  100. data/test/tc_switch.rb +55 -0
  101. data/test/tc_terminal.rb +100 -0
  102. data/test/tc_verbatim_wrapper.rb +36 -0
  103. data/test/test_helper.rb +20 -0
  104. metadata +330 -0
@@ -0,0 +1,128 @@
1
+ Feature: The todo app is backwards compatible with legacy subcommand parsing
2
+ As a user of GLI
3
+ My apps with subcommands should support the old, legacy way, by default
4
+
5
+ Background:
6
+ Given I have GLI installed
7
+ And GLI's libs are in my path
8
+ And my terminal size is "80x24"
9
+ And todo_legacy's bin directory is in my path
10
+
11
+ Scenario: Help completion mode for subcommands
12
+ When I successfully run `todo help -c list`
13
+ Then the output should contain:
14
+ """
15
+ contexts
16
+ tasks
17
+ """
18
+
19
+ Scenario: Help completion mode partial match for subcommands
20
+ When I successfully run `todo help -c list con`
21
+ Then the output should contain:
22
+ """
23
+ contexts
24
+ """
25
+
26
+ Scenario Outline: Getting Help for a top level command of todo
27
+ When I successfully run `todo <help_invocation>`
28
+ Then the output should contain:
29
+ """
30
+ NAME
31
+ list - List things, such as tasks or contexts
32
+
33
+ SYNOPSIS
34
+ todo [global options] list [command options] [--flag arg] [-x arg] [tasks]
35
+ todo [global options] list [command options] [--otherflag arg] [-b] [-f|--foobar] contexts
36
+
37
+ DESCRIPTION
38
+ List a whole lot of things that you might be keeping track of in your
39
+ overall todo list.
40
+
41
+ This is your go-to place or finding all of the things that you might have
42
+ stored in your todo databases.
43
+
44
+ COMMAND OPTIONS
45
+ -l, --[no-]long - Show long form
46
+
47
+ COMMANDS
48
+ contexts - List contexts
49
+ tasks - List tasks (default)
50
+ """
51
+
52
+ Examples:
53
+ | help_invocation |
54
+ | help list |
55
+ | list -h |
56
+ | list --help |
57
+
58
+
59
+ Scenario: Getting Help for a sub command of todo list
60
+ When I successfully run `todo help list tasks`
61
+ Then the output should contain:
62
+ """
63
+ NAME
64
+ tasks - List tasks
65
+
66
+ SYNOPSIS
67
+ todo [global options] list tasks [command options]
68
+ todo [global options] list tasks [command options] open
69
+
70
+ DESCRIPTION
71
+ Lists all of your tasks that you have, in varying orders, and all that
72
+ stuff. Yes, this is long, but I need a long description.
73
+
74
+ COMMAND OPTIONS
75
+ --flag=arg - (default: none)
76
+ -x arg - blah blah crud x whatever (default: none)
77
+
78
+ COMMANDS
79
+ <default> - list all tasks
80
+ open - list open tasks
81
+ """
82
+
83
+ Scenario: Getting Help for a sub command with no command options
84
+ When I successfully run `todo help new`
85
+ Then the output should contain:
86
+ """
87
+ NAME
88
+ create - Create a new task or context
89
+
90
+ SYNOPSIS
91
+ todo [global options] create
92
+ todo [global options] create contexts [context_name]
93
+ todo [global options] create tasks task_name[, task_name]*
94
+
95
+ COMMANDS
96
+ <default> - Makes a new task
97
+ contexts - Make a new context
98
+ tasks - Make a new task
99
+ """
100
+ And the output should not contain "COMMAND OPTIONS"
101
+
102
+ Scenario: Running ls w/out subcommand shows help and an error
103
+ When I run `todo ls`
104
+ Then the exit status should not be 0
105
+ And the stderr should contain "error: Command 'ls' requires a subcommand"
106
+ And the stdout should contain:
107
+ """
108
+ NAME
109
+ ls - LS things, such as tasks or contexts
110
+
111
+ SYNOPSIS
112
+ todo [global options] ls [command options] [-b] [-f|--foobar] contexts
113
+ todo [global options] ls [command options] [-x arg] tasks
114
+
115
+ DESCRIPTION
116
+ List a whole lot of things that you might be keeping track of in your
117
+ overall todo list.
118
+
119
+ This is your go-to place or finding all of the things that you might have
120
+ stored in your todo databases.
121
+
122
+ COMMAND OPTIONS
123
+ -l, --[no-]long - Show long form
124
+
125
+ COMMANDS
126
+ contexts - List contexts
127
+ tasks - List tasks
128
+ """
@@ -0,0 +1,95 @@
1
+ gli - create command-suite apps, a la git, using this awesome Ruby DSL
2
+ ======================================================================
3
+
4
+ Setup and Usage
5
+ ---------------
6
+
7
+ Installation:
8
+ $ gem install gli
9
+
10
+ Show list of commands
11
+ $ gli help [command]
12
+
13
+ Show help for one command
14
+ $ gli help init
15
+
16
+ Create a new GLI-based project with the commands foo and bar
17
+ $ gli init project_name foo bar
18
+
19
+ Create a new GLI-based project with an ext directory
20
+ $ gli init -e project_name foo bar
21
+
22
+ Create a new GLI-based project without a test directory (bad!)
23
+ $ gli init --notest project_name foo bar
24
+
25
+ Create a new GLI-based project somewhere else than .
26
+ $ gli -r /tmp init project_name foo bar
27
+
28
+ Just see what GLI would create
29
+ $ gli -n init -e project_name foo bar
30
+
31
+
32
+ Using GLI's DSL
33
+ ---------------
34
+
35
+ Create a switch (option that takes no args)
36
+
37
+ desc 'Dry-run; don't change the disk
38
+ switch [:n,'dry-run']
39
+ # Both -n and --dry-run will work
40
+ * --no-dry-run will set the switch to false
41
+ # Access in code via global_options[:n]
42
+ # or global_options[:'dry-run']
43
+
44
+ Create it on one line
45
+ switch :n,'dry-run', :desc => 'Dry-run; don't change the disk
46
+
47
+ Don't create a negatable version
48
+ switch :n,'dry-run', :negatable => false, :desc => 'Dry-run; don't change the disk
49
+ # --no-dry-run is not accepted
50
+
51
+ Create a flag (option that takes an argument)
52
+
53
+ desc 'Location of the config file'
54
+ arg_name 'path_to_file'
55
+ default_value '~/.glirc'
56
+ flag [:c,:conf], :must_match => /^\..*rc$/
57
+ # Both -c and --conf work, if this flag is omitted
58
+ # then the default of ~/.glirc is avaialble to the code
59
+ # The argument must match the given regex
60
+ # Access in code via global_options[:c] (or :conf)
61
+
62
+ Create a flag in a more compact style
63
+
64
+ flag :c,:conf, :desc => 'Location of the config file',
65
+ :arg_name => 'path_to_file', :default_value => '~/.glirc'
66
+
67
+ Create a command
68
+
69
+ desc 'Get the list of open tickets'
70
+ command [:tickets] do |c|
71
+ c.desc 'Only assigned to me'
72
+ c.switch [:m,:me]
73
+
74
+ c.desc 'Show only tickets for one project'
75
+ c.flag [:p,:project,'only-project']
76
+
77
+ c.action do |global_options,options,args|
78
+ # global_options has the global options as a hash
79
+ # options are the command specific ones (e.g. options[:p])
80
+ # args are the command line arguments that weren't parsed
81
+ # raise an exception or exit_now! if things go wrong
82
+ end
83
+ end
84
+
85
+ Set up stuff ahead of time
86
+
87
+ pre do |global_options,command,options,args|
88
+ return true if things_are_ok
89
+ return false if we_should_abort_the_command
90
+ end
91
+
92
+ Use GLI
93
+
94
+ exit run(ARGV)
95
+ # run returns a suitable exit status
@@ -0,0 +1,34 @@
1
+ # Make sure we get the gli that's local
2
+ require File.join([File.dirname(__FILE__),'lib','gli','version.rb'])
3
+
4
+ spec = Gem::Specification.new do |s|
5
+ s.name = 'gli_aziz_light'
6
+ s.version = GLI::VERSION
7
+ s.authors = ['David Copeland', 'Aziz Light']
8
+ s.email = 'davidcopeland@naildrivin5.com'
9
+ s.homepage = 'http://davetron5000.github.com/gli'
10
+ s.platform = Gem::Platform::RUBY
11
+ s.summary = 'Build command-suite CLI apps that are awesome.'
12
+ s.description = 'Build command-suite CLI apps that are awesome. Bootstrap your app, add commands, options and documentation while maintaining a well-tested idiomatic command-line app'
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = 'gli'
17
+ s.require_paths = ["lib"]
18
+
19
+ s.has_rdoc = true
20
+ s.extra_rdoc_files = ['README.rdoc', 'gli.rdoc']
21
+ s.rdoc_options << '--title' << 'Git Like Interface' << '--main' << 'README.rdoc'
22
+ s.bindir = 'bin'
23
+ s.rubyforge_project = 'gli'
24
+ s.add_development_dependency('rake', '~> 0.9.2.2')
25
+ s.add_development_dependency('rdoc', '~> 3.11')
26
+ s.add_development_dependency('rainbow', '~> 1.1.1')
27
+ s.add_development_dependency('clean_test')
28
+ s.add_development_dependency('cucumber', '1.2.3')
29
+ s.add_development_dependency('gherkin', '<= 2.11.6')
30
+ s.add_development_dependency('aruba', '0.5.1') # 0.5.3 randomly breaks with "LaunchError: no such file or directory" and only sometimes.
31
+ s.add_development_dependency('sdoc')
32
+ s.add_development_dependency('faker','1.0.0')
33
+ end
34
+
@@ -0,0 +1,73 @@
1
+ == gli - create scaffolding for a GLI-powered application
2
+
3
+ v2.2.1
4
+
5
+ === Global Options
6
+ === -r|--root arg
7
+
8
+ Root dir of project
9
+
10
+ [Default Value] .
11
+ This is the directory where the project''s directory will be made, so if you
12
+ specify a project name ''foo'' and the root dir of ''.'', the directory
13
+ ''./foo'' will be created'
14
+
15
+ === --help
16
+ Show this message
17
+
18
+
19
+
20
+ === -n
21
+ Dry run; dont change the disk
22
+
23
+
24
+
25
+ === -v
26
+ Be verbose
27
+
28
+
29
+
30
+ === --version
31
+
32
+
33
+
34
+
35
+ === Commands
36
+ ==== Command: <tt>help command</tt>
37
+ Shows a list of commands or help for one command
38
+
39
+ Gets help for the application or its commands. Can also list the commands in a way helpful to creating a bash-style completion function
40
+ ===== Options
41
+ ===== -c
42
+ List commands one per line, to assist with shell completion
43
+
44
+
45
+
46
+ ==== Command: <tt>init|scaffold project_name [command[ command]*]</tt>
47
+ Create a new GLI-based project
48
+
49
+ This will create a scaffold command line project that uses GLI
50
+ for command line processing. Specifically, this will create
51
+ an executable ready to go, as well as a lib and test directory, all
52
+ inside the directory named for your project
53
+ ===== Options
54
+ ===== -e|--[no-]ext
55
+ Create an ext dir
56
+
57
+
58
+
59
+ ===== --[no-]force
60
+ Overwrite/ignore existing files and directories
61
+
62
+
63
+
64
+ ===== --notest
65
+ Do not create a test or features dir
66
+
67
+
68
+
69
+ ===== --[no-]rvmrc
70
+ Create an .rvmrc based on your current RVM setup
71
+
72
+
73
+
@@ -0,0 +1,35 @@
1
+ require 'gli/command_finder.rb'
2
+ require 'gli/gli_option_block_parser.rb'
3
+ require 'gli/option_parser_factory.rb'
4
+ require 'gli/option_parsing_result.rb'
5
+ require 'gli/gli_option_parser.rb'
6
+ require 'gli/app_support.rb'
7
+ require 'gli/app.rb'
8
+ require 'gli/command_support.rb'
9
+ require 'gli/command.rb'
10
+ require 'gli/command_line_token.rb'
11
+ require 'gli/command_line_option.rb'
12
+ require 'gli/exceptions.rb'
13
+ require 'gli/flag.rb'
14
+ require 'gli/options.rb'
15
+ require 'gli/switch.rb'
16
+ require 'gli/dsl.rb'
17
+ require 'gli/version.rb'
18
+ require 'gli/commands/help'
19
+ require 'gli/commands/compound_command'
20
+ require 'gli/commands/initconfig'
21
+ require 'gli/commands/rdoc_document_listener'
22
+ require 'gli/commands/doc'
23
+
24
+ module GLI
25
+ include GLI::App
26
+ def self.included(klass)
27
+ warn "You should include GLI::App instead"
28
+ end
29
+
30
+ def self.run(*args)
31
+ warn "GLI.run no longer works for GLI-2, you must just call `run(ARGV)' instead"
32
+ warn "either fix your app, or use the latest GLI in the 1.x family"
33
+ 1
34
+ end
35
+ end
@@ -0,0 +1,286 @@
1
+ require 'etc'
2
+ require 'optparse'
3
+ require 'gli/dsl'
4
+ require 'pathname'
5
+
6
+ module GLI
7
+ # A means to define and parse a command line interface that works as
8
+ # Git's does, in that you specify global options, a command name, command
9
+ # specific options, and then command arguments.
10
+ module App
11
+ include DSL
12
+ include AppSupport
13
+
14
+ # Loads ruby files in the load path that start with
15
+ # +path+, which are presumed to be commands for your executable.
16
+ # This is useful for decomposing your bin file into different classes, but
17
+ # can also be used as a plugin mechanism, allowing users to provide additional
18
+ # commands for your app at runtime. All that being said, it's basically
19
+ # a glorified +require+.
20
+ #
21
+ # path:: a path from which to load <code>.rb</code> files that, presumably, contain commands. If this is an absolute path,
22
+ # any files in that path are loaded. If not, it is interpretted as relative to somewhere
23
+ # in the <code>LOAD_PATH</code>.
24
+ #
25
+ # == Example:
26
+ #
27
+ # # loads *.rb from your app's install - great for decomposing your bin file
28
+ # commands_from "my_app/commands"
29
+ #
30
+ # # loads *.rb files from the user's home dir - great and an extension/plugin mechanism
31
+ # commands_from File.join(ENV["HOME"],".my_app","plugins")
32
+ def commands_from(path)
33
+ if Pathname.new(path).absolute? and File.exists?(path)
34
+ load_commands(path)
35
+ else
36
+ $LOAD_PATH.each do |load_path|
37
+ commands_path = File.join(load_path,path)
38
+ load_commands(commands_path)
39
+ end
40
+ end
41
+ end
42
+
43
+ # Describe the overall application/programm. This should be a one-sentence summary
44
+ # of what your program does that will appear in the help output.
45
+ #
46
+ # +description+:: A String of the short description of your program's purpose
47
+ def program_desc(description=nil)
48
+ if description
49
+ @program_desc = description
50
+ end
51
+ @program_desc
52
+ end
53
+
54
+ # Provide a longer description of the program. This can be as long as needed, and use double-newlines
55
+ # for paragraphs. This will show up in the help output.
56
+ #
57
+ # description:: A String for the description
58
+ def program_long_desc(description=nil)
59
+ if description
60
+ @program_long_desc = description
61
+ end
62
+ @program_long_desc
63
+ end
64
+
65
+ # Use this if the following command should not have the pre block executed.
66
+ # By default, the pre block is executed before each command and can result in
67
+ # aborting the call. Using this will avoid that behavior for the following command
68
+ def skips_pre
69
+ @skips_pre = true
70
+ end
71
+
72
+ # Use this if the following command should not have the post block executed.
73
+ # By default, the post block is executed after each command.
74
+ # Using this will avoid that behavior for the following command
75
+ def skips_post
76
+ @skips_post = true
77
+ end
78
+
79
+ # Use this if the following command should not have the around block executed.
80
+ # By default, the around block is executed, but for commands that might not want the
81
+ # setup to happen, this can be handy
82
+ def skips_around
83
+ @skips_around = true
84
+ end
85
+
86
+ # Sets that this app uses a config file as well as the name of the config file.
87
+ #
88
+ # +filename+:: A String representing the path to the file to use for the config file. If it's an absolute
89
+ # path, this is treated as the path to the file. If it's *not*, it's treated as relative to the user's home
90
+ # directory as produced by <code>File.expand_path('~')</code>.
91
+ def config_file(filename)
92
+ if filename =~ /^\//
93
+ @config_file = filename
94
+ else
95
+ @config_file = File.join(File.expand_path(ENV['HOME']),filename)
96
+ end
97
+ commands[:initconfig] = InitConfig.new(@config_file,commands,flags,switches)
98
+ @commands_declaration_order << commands[:initconfig]
99
+ @config_file
100
+ end
101
+
102
+ # Define a block to run after command line arguments are parsed
103
+ # but before any command is run. If this block raises an exception
104
+ # the command specified will not be executed.
105
+ # The block will receive the global-options,command,options, and arguments
106
+ # If this block evaluates to true, the program will proceed; otherwise
107
+ # the program will end immediately and exit nonzero
108
+ def pre(&a_proc)
109
+ @pre_block = a_proc
110
+ end
111
+
112
+ # Define a block to run after the command was executed, <b>only
113
+ # if there was not an error</b>.
114
+ # The block will receive the global-options,command,options, and arguments
115
+ def post(&a_proc)
116
+ @post_block = a_proc
117
+ end
118
+
119
+ # This inverts the pre/post concept. This is useful when you have a global shared resource that is governed by a block
120
+ # instead of separate open/close methods. The block you pass here will be given four parameters:
121
+ #
122
+ # global options:: the parsed global options
123
+ # command:: The GLI::Command that the user is going to invoke
124
+ # options:: the command specific options
125
+ # args:: unparsed command-line args
126
+ # code:: a block that you must +call+ to execute the command.
127
+ #
128
+ # #help_now! and #exit_now! work as expected; you can abort the command call by simply not calling it.
129
+ #
130
+ # You can declare as many #around blocks as you want. They will be called in the order in which they are defined.
131
+ #
132
+ # Note that if you declare #around blocks, #pre and #post blocks will still work. The #pre is called first, followed by
133
+ # the around, followed by the #post.
134
+ #
135
+ # Call #skips_around before a command that should not have this hook fired
136
+ def around(&a_proc)
137
+ @around_blocks ||= []
138
+ @around_blocks << a_proc
139
+ end
140
+
141
+ # Define a block to run if an error occurs.
142
+ # The block will receive any Exception that was caught.
143
+ # It should evaluate to false to avoid the built-in error handling (which basically just
144
+ # prints out a message). GLI uses a variety of exceptions that you can use to find out what
145
+ # errors might've occurred during command-line parsing:
146
+ # * GLI::CustomExit
147
+ # * GLI::UnknownCommandArgument
148
+ # * GLI::UnknownGlobalArgument
149
+ # * GLI::UnknownCommand
150
+ # * GLI::BadCommandLine
151
+ def on_error(&a_proc)
152
+ @error_block = a_proc
153
+ end
154
+
155
+ # Indicate the version of your application
156
+ #
157
+ # +version+:: String containing the version of your application.
158
+ def version(version)
159
+ @version = version
160
+ desc 'Display the program version'
161
+ switch :version, :negatable => false
162
+ end
163
+
164
+ # By default, GLI mutates the argument passed to it. This is
165
+ # consistent with +OptionParser+, but be less than ideal. Since
166
+ # that value, for scaffolded apps, is +ARGV+, you might want to
167
+ # refer to the entire command-line via +ARGV+ and thus not want it mutated.
168
+ def preserve_argv(preserve=true)
169
+ @preserve_argv = preserve
170
+ end
171
+
172
+ # Call this with +true+ will cause the +global_options+ and
173
+ # +options+ passed to your code to be wrapped in
174
+ # Options, which is a subclass of +OpenStruct+ that adds
175
+ # <tt>[]</tt> and <tt>[]=</tt> methods.
176
+ #
177
+ # +use_openstruct+:: a Boolean indicating if we should use OpenStruct instead of Hashes
178
+ def use_openstruct(use_openstruct)
179
+ @use_openstruct = use_openstruct
180
+ end
181
+
182
+ # Configure a type conversion not already provided by the underlying OptionParser.
183
+ # This works more or less like the OptionParser version.
184
+ #
185
+ # object:: the class (or whatever) that triggers the type conversion
186
+ # block:: the block that will be given the string argument and is expected
187
+ # to return the converted value
188
+ #
189
+ # Example
190
+ #
191
+ # accept(Hash) do |value|
192
+ # result = {}
193
+ # value.split(/,/) do |pair|
194
+ # k,v = pair.split(/:/)
195
+ # result[k] = v
196
+ # end
197
+ # result
198
+ # end
199
+ #
200
+ # flag :properties, :type => Hash
201
+ def accept(object,&block)
202
+ accepts[object] = block
203
+ end
204
+
205
+ # Simpler means of exiting with a custom exit code. This will
206
+ # raise a CustomExit with the given message and exit code, which will ultimatley
207
+ # cause your application to exit with the given exit_code as its exit status
208
+ # Use #help_now! if you want to show the help in addition to the error message
209
+ #
210
+ # message:: message to show the user
211
+ # exit_code:: exit code to exit as, defaults to 1
212
+ def exit_now!(message,exit_code=1)
213
+ raise CustomExit.new(message,exit_code)
214
+ end
215
+
216
+ # Exit now, showing the user help for the command they executed. Use #exit_now! to just show the error message
217
+ #
218
+ # message:: message to indicate how the user has messed up the CLI invocation or nil to just simply show help
219
+ def help_now!(message=nil)
220
+ exception = OptionParser::ParseError.new(message)
221
+ class << exception
222
+ def exit_code; 64; end
223
+ end
224
+ raise exception
225
+ end
226
+
227
+ # Control how commands and options are sorted in help output. By default, they are sorted alphabetically.
228
+ #
229
+ # sort_type:: How you want help commands/options sorted:
230
+ # +:manually+:: help commands/options are ordered in the order declared.
231
+ # +:alpha+:: sort alphabetically (default)
232
+ def sort_help(sort_type)
233
+ @help_sort_type = sort_type
234
+ end
235
+
236
+ # Set how help text is wrapped.
237
+ #
238
+ # wrap_type:: Symbol indicating how you'd like text wrapped:
239
+ # +:to_terminal+:: Wrap text based on the width of the terminal (default)
240
+ # +:verbatim+:: Format text exactly as it was given to the various methods. This is useful if your output has
241
+ # formatted output, e.g. ascii tables and you don't want it messed with.
242
+ # +:one_line+:: Do not wrap text at all. This will bring all help content onto one line, removing any newlines
243
+ # +:tty_only+:: Wrap like +:to_terminal+ if this output is going to a TTY, otherwise don't wrap (like +:one_line+)
244
+ def wrap_help_text(wrap_type)
245
+ @help_text_wrap_type = wrap_type
246
+ end
247
+
248
+ def program_name(override=nil) #:nodoc:
249
+ warn "#program_name has been deprecated"
250
+ end
251
+
252
+ # Sets a default command to run when none is specified on the command line. Note that
253
+ # if you use this, you won't be able to pass arguments, flags, or switches
254
+ # to the command when run in default mode. All flags and switches are treated
255
+ # as global, and any argument will be interpretted as the command name and likely
256
+ # fail.
257
+ #
258
+ # +command+:: Command as a Symbol to run as default
259
+ def default_command(command)
260
+ @default_command = command.to_sym
261
+ end
262
+
263
+ # How to handle subcommand options. In general, you want to set this to +:normal+, which
264
+ # treats each subcommand as establishing its own namespace for options. This is what
265
+ # the scaffolding should generate, but it is *not* what GLI 2.5.x and lower apps had as a default.
266
+ # To maintain backwards compatibility, the default is +:legacy+, which is that all subcommands of
267
+ # a particular command share a namespace for options, making it impossible for two subcommands
268
+ # to have options of the same name.
269
+ def subcommand_option_handling(handling_strategy)
270
+ @subcommand_option_handling_strategy = handling_strategy
271
+ end
272
+
273
+ private
274
+
275
+ def load_commands(path)
276
+ if File.exists? path
277
+ Dir.entries(path).sort.each do |entry|
278
+ file = File.join(path,entry)
279
+ if file =~ /\.rb$/
280
+ require file
281
+ end
282
+ end
283
+ end
284
+ end
285
+ end
286
+ end