coglius 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. data/Cogfile +15 -0
  2. data/LICENSE +201 -0
  3. data/lib/coglius.rb +29 -0
  4. data/lib/coglius/app.rb +250 -0
  5. data/lib/coglius/app_support.rb +284 -0
  6. data/lib/coglius/command.rb +149 -0
  7. data/lib/coglius/command_line_option.rb +34 -0
  8. data/lib/coglius/command_line_token.rb +62 -0
  9. data/lib/coglius/command_support.rb +214 -0
  10. data/lib/coglius/commands/compound_command.rb +42 -0
  11. data/lib/coglius/commands/doc.rb +215 -0
  12. data/lib/coglius/commands/help.rb +73 -0
  13. data/lib/coglius/commands/help_modules/arg_name_formatter.rb +20 -0
  14. data/lib/coglius/commands/help_modules/command_finder.rb +60 -0
  15. data/lib/coglius/commands/help_modules/command_help_format.rb +138 -0
  16. data/lib/coglius/commands/help_modules/global_help_format.rb +70 -0
  17. data/lib/coglius/commands/help_modules/help_completion_format.rb +31 -0
  18. data/lib/coglius/commands/help_modules/list_formatter.rb +23 -0
  19. data/lib/coglius/commands/help_modules/one_line_wrapper.rb +18 -0
  20. data/lib/coglius/commands/help_modules/options_formatter.rb +49 -0
  21. data/lib/coglius/commands/help_modules/text_wrapper.rb +53 -0
  22. data/lib/coglius/commands/help_modules/tty_only_wrapper.rb +23 -0
  23. data/lib/coglius/commands/help_modules/verbatim_wrapper.rb +16 -0
  24. data/lib/coglius/commands/initconfig.rb +69 -0
  25. data/lib/coglius/commands/rdoc_document_listener.rb +116 -0
  26. data/lib/coglius/commands/scaffold.rb +401 -0
  27. data/lib/coglius/copy_options_to_aliases.rb +33 -0
  28. data/lib/coglius/dsl.rb +221 -0
  29. data/lib/coglius/exceptions.rb +54 -0
  30. data/lib/coglius/flag.rb +68 -0
  31. data/lib/coglius/gli_option_parser.rb +124 -0
  32. data/lib/coglius/option_parser_factory.rb +45 -0
  33. data/lib/coglius/options.rb +23 -0
  34. data/lib/coglius/switch.rb +35 -0
  35. data/lib/coglius/terminal.rb +94 -0
  36. data/lib/coglius/version.rb +5 -0
  37. data/templates/coglius/generator.rb.erb +26 -0
  38. metadata +208 -0
@@ -0,0 +1,53 @@
1
+ module Coglius
2
+ module Commands
3
+ module HelpModules
4
+ # Handles wrapping text
5
+ class TextWrapper
6
+ # Create a text_wrapper wrapping at the given width,
7
+ # and indent.
8
+ def initialize(width,indent)
9
+ @width = width
10
+ @indent = indent
11
+ end
12
+
13
+ # Return a wrapped version of text, assuming that the first line has already been
14
+ # indented by @indent characters. Resulting text does NOT have a newline in it.
15
+ def wrap(text)
16
+ return text if text.nil?
17
+ wrapped_text = ''
18
+ current_graf = ''
19
+
20
+ paragraphs = text.split(/\n\n+/)
21
+ paragraphs.each do |graf|
22
+ current_line = ''
23
+ current_line_length = @indent
24
+
25
+ words = graf.split(/\s+/)
26
+ current_line = words.shift || ''
27
+ current_line_length += current_line.length
28
+
29
+ words.each do |word|
30
+ if current_line_length + word.length + 1 > @width
31
+ current_graf << current_line << "\n"
32
+ current_line = ''
33
+ current_line << ' ' * @indent << word
34
+ current_line_length = @indent + word.length
35
+ else
36
+ if current_line == ''
37
+ current_line << word
38
+ else
39
+ current_line << ' ' << word
40
+ end
41
+ current_line_length += (word.length + 1)
42
+ end
43
+ end
44
+ current_graf << current_line
45
+ wrapped_text << current_graf << "\n\n" << ' ' * @indent
46
+ current_graf = ''
47
+ end
48
+ wrapped_text.gsub(/[\n\s]*\Z/,'')
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,23 @@
1
+ module Coglius
2
+ module Commands
3
+ module HelpModules
4
+ # Formats text in one line, stripping newlines and NOT wrapping
5
+ class TTYOnlyWrapper
6
+ # Args are ignored entirely; this keeps it consistent with the TextWrapper interface
7
+ def initialize(width,indent)
8
+ @proxy = if STDOUT.tty?
9
+ TextWrapper.new(width,indent)
10
+ else
11
+ OneLineWrapper.new(width,indent)
12
+ end
13
+ end
14
+
15
+ # Return a wrapped version of text, assuming that the first line has already been
16
+ # indented by @indent characters. Resulting text does NOT have a newline in it.
17
+ def wrap(text)
18
+ @proxy.wrap(text)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ module Coglius
2
+ module Commands
3
+ module HelpModules
4
+ # Leaves text formatting exactly as it was received. Doesn't strip anything.
5
+ class VerbatimWrapper
6
+ # Args are ignored entirely; this keeps it consistent with the TextWrapper interface
7
+ def initialize(width,indent)
8
+ end
9
+
10
+ def wrap(text)
11
+ return String(text)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,69 @@
1
+ require 'coglius'
2
+ require 'coglius/command'
3
+ require 'yaml'
4
+
5
+ module Coglius
6
+ # Command that initializes the configuration file for apps that use it.
7
+ class InitConfig < Command # :nodoc:
8
+ COMMANDS_KEY = 'commands'
9
+
10
+ def initialize(config_file_name,commands,flags,switches)
11
+ @filename = config_file_name
12
+ super(:names => :initconfig,
13
+ :description => "Initialize the config file using current global options",
14
+ :long_desc => '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',
15
+ :skips_pre => true,:skips_post => true, :skips_around => true)
16
+
17
+ @app_commands = commands
18
+ @app_flags = flags
19
+ @app_switches = switches
20
+
21
+ self.desc 'force overwrite of existing config file'
22
+ self.switch :force
23
+
24
+ action do |global_options,options,arguments|
25
+ if options[:force] || !File.exist?(@filename)
26
+ create_config(global_options,options,arguments)
27
+ else
28
+ raise "Not overwriting existing config file #{@filename}, use --force to override"
29
+ end
30
+ end
31
+ end
32
+
33
+
34
+ private
35
+
36
+ def create_config(global_options,options,arguments)
37
+ config = Hash[global_options.map { |option_name,option_value|
38
+ if option_value.kind_of?(String) && option_value.respond_to?(:force_encoding)
39
+ [option_name,option_value.force_encoding("utf-8")]
40
+ else
41
+ [option_name,option_value]
42
+ end
43
+ }]
44
+ config[COMMANDS_KEY] = {}
45
+ @app_commands.each do |name,command|
46
+ if (command != self) && (name != :rdoc) && (name != :help)
47
+ if command != self
48
+ config[COMMANDS_KEY][name.to_sym] = config_for_command(@app_commands,name.to_sym)
49
+ end
50
+ end
51
+ end
52
+ File.open(@filename,'w', 0600) do |file|
53
+ YAML.dump(config,file)
54
+ end
55
+ end
56
+
57
+ def config_for_command(commands,command_name)
58
+ {}.tap do |hash|
59
+ subcommands = commands[command_name].commands
60
+ subcommands.each do |name,subcommand|
61
+ next unless name.kind_of? Symbol
62
+ hash[COMMANDS_KEY] ||= {}
63
+ puts "#{command_name}:#{name}"
64
+ hash[COMMANDS_KEY][name.to_sym] = config_for_command(subcommands,name)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,116 @@
1
+ require 'stringio'
2
+ require 'coglius/commands/help_modules/arg_name_formatter'
3
+ module Coglius
4
+ module Commands
5
+ class RdocDocumentListener
6
+
7
+ def initialize(global_options,options,arguments)
8
+ @io = File.new(File.basename($0) + ".rdoc",'w')
9
+ @nest = ''
10
+ @arg_name_formatter = Coglius::Commands::HelpModules::ArgNameFormatter.new
11
+ end
12
+
13
+ def beginning
14
+ end
15
+
16
+ # Called when processing has completed
17
+ def ending
18
+ @io.close
19
+ end
20
+
21
+ # Gives you the program description
22
+ def program_desc(desc)
23
+ @io.puts "== #{File.basename($0)} - #{desc}"
24
+ @io.puts
25
+ end
26
+
27
+ def program_long_desc(desc)
28
+ @io.puts desc
29
+ @io.puts
30
+ end
31
+
32
+ # Gives you the program version
33
+ def version(version)
34
+ @io.puts "v#{version}"
35
+ @io.puts
36
+ end
37
+
38
+ def options
39
+ if @nest.size == 0
40
+ @io.puts "=== Global Options"
41
+ else
42
+ @io.puts "#{@nest}=== Options"
43
+ end
44
+ end
45
+
46
+ # Gives you a flag in the current context
47
+ def flag(name,aliases,desc,long_desc,default_value,arg_name,must_match,type)
48
+ invocations = ([name] + Array(aliases)).map { |_| add_dashes(_) }.join('|')
49
+ usage = "#{invocations} #{arg_name || 'arg'}"
50
+ @io.puts "#{@nest}=== #{usage}"
51
+ @io.puts
52
+ @io.puts String(desc).strip
53
+ @io.puts
54
+ @io.puts "[Default Value] #{default_value || 'None'}"
55
+ @io.puts "[Must Match] #{must_match.to_s}" unless must_match.nil?
56
+ @io.puts String(long_desc).strip
57
+ @io.puts
58
+ end
59
+
60
+ # Gives you a switch in the current context
61
+ def switch(name,aliases,desc,long_desc,negetable)
62
+ if negetable
63
+ name = "[no-]#{name}" if name.to_s.length > 1
64
+ aliases = aliases.map { |_| _.to_s.length > 1 ? "[no-]#{_}" : _ }
65
+ end
66
+ invocations = ([name] + aliases).map { |_| add_dashes(_) }.join('|')
67
+ @io.puts "#{@nest}=== #{invocations}"
68
+ @io.puts String(desc).strip
69
+ @io.puts
70
+ @io.puts String(long_desc).strip
71
+ @io.puts
72
+ end
73
+
74
+ def end_options
75
+ end
76
+
77
+ def commands
78
+ @io.puts "#{@nest}=== Commands"
79
+ @nest = "#{@nest}="
80
+ end
81
+
82
+ # Gives you a command in the current context and creates a new context of this command
83
+ def command(name,aliases,desc,long_desc,arg_name,arg_options)
84
+ @io.puts "#{@nest}=== Command: <tt>#{([name] + aliases).join('|')} #{@arg_name_formatter.format(arg_name,arg_options)}</tt>"
85
+ @io.puts String(desc).strip
86
+ @io.puts
87
+ @io.puts String(long_desc).strip
88
+ @nest = "#{@nest}="
89
+ end
90
+
91
+ # Ends a command, and "pops" you back up one context
92
+ def end_command(name)
93
+ @nest.gsub!(/=$/,'')
94
+ end
95
+
96
+ # Gives you the name of the current command in the current context
97
+ def default_command(name)
98
+ @io.puts "[Default Command] #{name}" unless name.nil?
99
+ end
100
+
101
+ def end_commands
102
+ @nest.gsub!(/=$/,'')
103
+ end
104
+
105
+ private
106
+
107
+ def add_dashes(name)
108
+ name = "-#{name}"
109
+ name = "-#{name}" if name.length > 2
110
+ name
111
+ end
112
+
113
+
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,401 @@
1
+ require 'coglius'
2
+ require 'fileutils'
3
+
4
+ module Coglius
5
+ module Commands
6
+ class Scaffold #:nodoc:
7
+
8
+ def self.create_scaffold(root_dir,
9
+ create_test_dir,
10
+ create_ext_dir,
11
+ project_name,
12
+ commands,
13
+ force=false,
14
+ dry_run=false,
15
+ create_rvmrc=false)
16
+ dirs = [File.join(root_dir,project_name,'lib')]
17
+ dirs << File.join(root_dir,project_name,'bin')
18
+ dirs << File.join(root_dir,project_name,'test') if create_test_dir
19
+ dirs << File.join(root_dir,project_name,'ext') if create_ext_dir
20
+
21
+ if mkdirs(dirs,force,dry_run)
22
+ mk_binfile(root_dir,create_ext_dir,force,dry_run,project_name,commands)
23
+ mk_readme(root_dir,dry_run,project_name)
24
+ mk_gemspec(root_dir,dry_run,project_name)
25
+ mk_rakefile(root_dir,dry_run,project_name,create_test_dir)
26
+ mk_lib_files(root_dir,dry_run,project_name)
27
+ if create_rvmrc
28
+ rvmrc = File.join(root_dir,project_name,".rvmrc")
29
+ File.open(rvmrc,'w') do |file|
30
+ file.puts "rvm use #{ENV['rvm_ruby_string']}@#{project_name} --create"
31
+ end
32
+ puts "Created #{rvmrc}"
33
+ end
34
+ end
35
+ end
36
+
37
+ def self.mk_readme(root_dir,dry_run,project_name)
38
+ return if dry_run
39
+ File.open("#{root_dir}/#{project_name}/README.rdoc",'w') do |file|
40
+ file << "= #{project_name}\n\n"
41
+ file << "Describe your project here\n\n"
42
+ file << ":include:#{project_name}.rdoc\n\n"
43
+ end
44
+ puts "Created #{root_dir}/#{project_name}/README.rdoc"
45
+ File.open("#{root_dir}/#{project_name}/#{project_name}.rdoc",'w') do |file|
46
+ file << "= #{project_name}\n\n"
47
+ file << "Generate this with\n #{project_name} rdoc\nAfter you have described your command line interface"
48
+ end
49
+ puts "Created #{root_dir}/#{project_name}/#{project_name}.rdoc"
50
+ end
51
+
52
+ def self.mk_gemspec(root_dir,dry_run,project_name)
53
+ return if dry_run
54
+ File.open("#{root_dir}/#{project_name}/#{project_name}.gemspec",'w') do |file|
55
+ file.puts <<EOS
56
+ # Ensure we require the local version and not one we might have installed already
57
+ require File.join([File.dirname(__FILE__),'lib','#{project_name}','version.rb'])
58
+ spec = Gem::Specification.new do |s|
59
+ s.name = '#{project_name}'
60
+ s.version = #{project_name_as_module_name(project_name)}::VERSION
61
+ s.author = 'Your Name Here'
62
+ s.email = 'your@email.address.com'
63
+ s.homepage = 'http://your.website.com'
64
+ s.platform = Gem::Platform::RUBY
65
+ s.summary = 'A description of your project'
66
+ # Add your other files here if you make them
67
+ s.files = %w(
68
+ bin/#{project_name}
69
+ lib/#{project_name}/version.rb
70
+ lib/#{project_name}.rb
71
+ )
72
+ s.require_paths << 'lib'
73
+ s.has_rdoc = true
74
+ s.extra_rdoc_files = ['README.rdoc','#{project_name}.rdoc']
75
+ s.rdoc_options << '--title' << '#{project_name}' << '--main' << 'README.rdoc' << '-ri'
76
+ s.bindir = 'bin'
77
+ s.executables << '#{project_name}'
78
+ s.add_development_dependency('rake')
79
+ s.add_development_dependency('rdoc')
80
+ s.add_development_dependency('aruba')
81
+ s.add_runtime_dependency('coglius','#{Coglius::VERSION}')
82
+ end
83
+ EOS
84
+ end
85
+ puts "Created #{root_dir}/#{project_name}/#{project_name}.gemspec"
86
+ end
87
+
88
+ def self.project_name_as_module_name(project_name)
89
+ project_name.split(/[_-]/).map { |part| part[0..0].upcase + part[1..-1] }.join('')
90
+ end
91
+
92
+ def self.mk_lib_files(root_dir,dry_run,project_name)
93
+ return if dry_run
94
+ FileUtils.mkdir("#{root_dir}/#{project_name}/lib/#{project_name}")
95
+ File.open("#{root_dir}/#{project_name}/lib/#{project_name}/version.rb",'w') do |file|
96
+ file.puts <<EOS
97
+ module #{project_name_as_module_name(project_name)}
98
+ VERSION = '0.0.1'
99
+ end
100
+ EOS
101
+ end
102
+ puts "Created #{root_dir}/#{project_name}/lib/#{project_name}/version.rb"
103
+ File.open("#{root_dir}/#{project_name}/lib/#{project_name}.rb",'w') do |file|
104
+ file.puts <<EOS
105
+ require '#{project_name}/version.rb'
106
+
107
+ # Add requires for other files you add to your project here, so
108
+ # you just need to require this one file in your bin file
109
+ EOS
110
+ end
111
+ puts "Created #{root_dir}/#{project_name}/lib/#{project_name}.rb"
112
+ end
113
+ def self.mk_rakefile(root_dir,dry_run,project_name,create_test_dir)
114
+ return if dry_run
115
+ File.open("#{root_dir}/#{project_name}/Rakefile",'w') do |file|
116
+ file.puts <<EOS
117
+ require 'rake/clean'
118
+ require 'rubygems'
119
+ require 'rubygems/package_task'
120
+ require 'rdoc/task'
121
+ EOS
122
+ if create_test_dir
123
+ file.puts <<EOS
124
+ require 'cucumber'
125
+ require 'cucumber/rake/task'
126
+ EOS
127
+ end
128
+ file.puts <<EOS
129
+ Rake::RDocTask.new do |rd|
130
+ rd.main = "README.rdoc"
131
+ rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
132
+ rd.title = 'Your application title'
133
+ end
134
+
135
+ spec = eval(File.read('#{project_name}.gemspec'))
136
+
137
+ Gem::PackageTask.new(spec) do |pkg|
138
+ end
139
+ EOS
140
+ if create_test_dir
141
+ file.puts <<EOS
142
+ CUKE_RESULTS = 'results.html'
143
+ CLEAN << CUKE_RESULTS
144
+ desc 'Run features'
145
+ Cucumber::Rake::Task.new(:features) do |t|
146
+ opts = "features --format html -o \#{CUKE_RESULTS} --format progress -x"
147
+ opts += " --tags \#{ENV['TAGS']}" if ENV['TAGS']
148
+ t.cucumber_opts = opts
149
+ t.fork = false
150
+ end
151
+
152
+ desc 'Run features tagged as work-in-progress (@wip)'
153
+ Cucumber::Rake::Task.new('features:wip') do |t|
154
+ tag_opts = ' --tags ~@pending'
155
+ tag_opts = ' --tags @wip'
156
+ t.cucumber_opts = "features --format html -o \#{CUKE_RESULTS} --format pretty -x -s\#{tag_opts}"
157
+ t.fork = false
158
+ end
159
+
160
+ task :cucumber => :features
161
+ task 'cucumber:wip' => 'features:wip'
162
+ task :wip => 'features:wip'
163
+ EOS
164
+ end
165
+ if create_test_dir
166
+ file.puts <<EOS
167
+ require 'rake/testtask'
168
+ Rake::TestTask.new do |t|
169
+ t.libs << "test"
170
+ t.test_files = FileList['test/*_test.rb']
171
+ end
172
+
173
+ task :default => [:test,:features]
174
+ EOS
175
+ File.open("#{root_dir}/#{project_name}/test/default_test.rb",'w') do |test_file|
176
+ test_file.puts <<EOS
177
+ require 'test_helper'
178
+
179
+ class DefaultTest < Test::Unit::TestCase
180
+
181
+ def setup
182
+ end
183
+
184
+ def teardown
185
+ end
186
+
187
+ def test_the_truth
188
+ assert true
189
+ end
190
+ end
191
+ EOS
192
+ end
193
+ puts "Created #{root_dir}/#{project_name}/test/default_test.rb"
194
+ File.open("#{root_dir}/#{project_name}/test/test_helper.rb",'w') do |test_file|
195
+ test_file.puts <<EOS
196
+ require 'test/unit'
197
+
198
+ # Add test libraries you want to use here, e.g. mocha
199
+
200
+ class Test::Unit::TestCase
201
+
202
+ # Add global extensions to the test case class here
203
+
204
+ end
205
+ EOS
206
+ end
207
+ puts "Created #{root_dir}/#{project_name}/test/test_helper.rb"
208
+ else
209
+ file.puts "task :default => :package\n"
210
+ end
211
+ end
212
+ puts "Created #{root_dir}/#{project_name}/Rakefile"
213
+ File.open("#{root_dir}/#{project_name}/Gemfile",'w') do |bundler_file|
214
+ bundler_file.puts "source :rubygems"
215
+ bundler_file.puts "gemspec"
216
+ end
217
+ puts "Created #{root_dir}/#{project_name}/Gemfile"
218
+ if create_test_dir
219
+ features_dir = File.join(root_dir,project_name,'features')
220
+ FileUtils.mkdir features_dir
221
+ FileUtils.mkdir File.join(features_dir,"step_definitions")
222
+ FileUtils.mkdir File.join(features_dir,"support")
223
+ File.open(File.join(features_dir,"#{project_name}.feature"),'w') do |file|
224
+ file.puts <<EOS
225
+ Feature: My bootstrapped app kinda works
226
+ In order to get going on coding my awesome app
227
+ I want to have aruba and cucumber setup
228
+ So I don't have to do it myself
229
+
230
+ Scenario: App just runs
231
+ When I get help for "#{project_name}"
232
+ Then the exit status should be 0
233
+ EOS
234
+ end
235
+ File.open(File.join(features_dir,"step_definitions","#{project_name}_steps.rb"),'w') do |file|
236
+ file.puts <<EOS
237
+ When /^I get help for "([^"]*)"$/ do |app_name|
238
+ @app_name = app_name
239
+ step %(I run `\#{app_name} help`)
240
+ end
241
+
242
+ # Add more step definitions here
243
+ EOS
244
+ end
245
+ File.open(File.join(features_dir,"support","env.rb"),'w') do |file|
246
+ file.puts <<EOS
247
+ require 'aruba/cucumber'
248
+
249
+ ENV['PATH'] = "\#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}\#{File::PATH_SEPARATOR}\#{ENV['PATH']}"
250
+ LIB_DIR = File.join(File.expand_path(File.dirname(__FILE__)),'..','..','lib')
251
+
252
+ Before do
253
+ # Using "announce" causes massive warnings on 1.9.2
254
+ @puts = true
255
+ @original_rubylib = ENV['RUBYLIB']
256
+ ENV['RUBYLIB'] = LIB_DIR + File::PATH_SEPARATOR + ENV['RUBYLIB'].to_s
257
+ end
258
+
259
+ After do
260
+ ENV['RUBYLIB'] = @original_rubylib
261
+ end
262
+ EOS
263
+ end
264
+ puts "Created #{features_dir}"
265
+ end
266
+ end
267
+
268
+ def self.mk_binfile(root_dir,create_ext_dir,force,dry_run,project_name,commands)
269
+ bin_file = File.join(root_dir,project_name,'bin',project_name)
270
+ if !File.exist?(bin_file) || force
271
+ if !dry_run
272
+ File.open(bin_file,'w') do |file|
273
+ file.chmod(0755)
274
+ file.puts '#!/usr/bin/env ruby'
275
+ file.puts <<EOS
276
+ require 'coglius'
277
+ begin # XXX: Remove this begin/rescue before distributing your app
278
+ require '#{project_name}'
279
+ rescue LoadError
280
+ STDERR.puts "In development, you need to use `bundle exec bin/#{project_name}` to run your app"
281
+ STDERR.puts "At install-time, RubyGems will make sure lib, etc. are in the load path"
282
+ STDERR.puts "Feel free to remove this message from bin/#{project_name} now"
283
+ exit 64
284
+ end
285
+
286
+ include Coglius::App
287
+
288
+ program_desc 'Describe your application here'
289
+
290
+ version #{project_name_as_module_name(project_name)}::VERSION
291
+
292
+ desc 'Describe some switch here'
293
+ switch [:s,:switch]
294
+
295
+ desc 'Describe some flag here'
296
+ default_value 'the default'
297
+ arg_name 'The name of the argument'
298
+ flag [:f,:flagname]
299
+ EOS
300
+ first = true
301
+ commands.each do |command|
302
+ file.puts <<EOS
303
+
304
+ desc 'Describe #{command} here'
305
+ arg_name 'Describe arguments to #{command} here'
306
+ EOS
307
+ if first
308
+ file.puts <<EOS
309
+ command :#{command} do |c|
310
+ c.desc 'Describe a switch to #{command}'
311
+ c.switch :s
312
+
313
+ c.desc 'Describe a flag to #{command}'
314
+ c.default_value 'default'
315
+ c.flag :f
316
+ c.action do |global_options,options,args|
317
+
318
+ # Your command logic here
319
+
320
+ # If you have any errors, just raise them
321
+ # raise "that command made no sense"
322
+
323
+ puts "#{command} command ran"
324
+ end
325
+ end
326
+ EOS
327
+ else
328
+ file.puts <<EOS
329
+ command :#{command} do |c|
330
+ c.action do |global_options,options,args|
331
+ puts "#{command} command ran"
332
+ end
333
+ end
334
+ EOS
335
+ end
336
+ first = false
337
+ end
338
+ file.puts <<EOS
339
+
340
+ pre do |global,command,options,args|
341
+ # Pre logic here
342
+ # Return true to proceed; false to abort and not call the
343
+ # chosen command
344
+ # Use skips_pre before a command to skip this block
345
+ # on that command only
346
+ true
347
+ end
348
+
349
+ post do |global,command,options,args|
350
+ # Post logic here
351
+ # Use skips_post before a command to skip this
352
+ # block on that command only
353
+ end
354
+
355
+ on_error do |exception|
356
+ # Error logic here
357
+ # return false to skip default error handling
358
+ true
359
+ end
360
+
361
+ exit run(ARGV)
362
+ EOS
363
+ puts "Created #{bin_file}"
364
+ end
365
+ end
366
+ else
367
+ puts bin_file + " exists; use --force to override"
368
+ return false
369
+ end
370
+ true
371
+ end
372
+
373
+ def self.mkdirs(dirs,force,dry_run)
374
+ exists = false
375
+ if !force
376
+ dirs.each do |dir|
377
+ if File.exist? dir
378
+ raise "#{dir} exists; use --force to override"
379
+ exists = true
380
+ end
381
+ end
382
+ end
383
+ if !exists
384
+ dirs.each do |dir|
385
+ puts "Creating dir #{dir}..."
386
+ if dry_run
387
+ puts "dry-run; #{dir} not created"
388
+ else
389
+ FileUtils.mkdir_p dir
390
+ end
391
+ end
392
+ else
393
+ puts "Exiting..."
394
+ return false
395
+ end
396
+ true
397
+ end
398
+
399
+ end
400
+ end
401
+ end