optparse-plus 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -0
- data/CHANGES.md +66 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +201 -0
- data/README.rdoc +173 -0
- data/Rakefile +94 -0
- data/bin/optparse_plus +130 -0
- data/fix.rb +29 -0
- data/lib/optparse-plus.rb +1 -0
- data/lib/optparse_plus.rb +15 -0
- data/lib/optparse_plus/argv_parser.rb +50 -0
- data/lib/optparse_plus/cli.rb +116 -0
- data/lib/optparse_plus/cli_logger.rb +133 -0
- data/lib/optparse_plus/cli_logging.rb +138 -0
- data/lib/optparse_plus/cucumber.rb +119 -0
- data/lib/optparse_plus/error.rb +32 -0
- data/lib/optparse_plus/execution_strategy/base.rb +34 -0
- data/lib/optparse_plus/execution_strategy/jvm.rb +37 -0
- data/lib/optparse_plus/execution_strategy/mri.rb +16 -0
- data/lib/optparse_plus/execution_strategy/open_3.rb +16 -0
- data/lib/optparse_plus/execution_strategy/open_4.rb +22 -0
- data/lib/optparse_plus/execution_strategy/rbx_open_4.rb +12 -0
- data/lib/optparse_plus/exit_now.rb +40 -0
- data/lib/optparse_plus/main.rb +603 -0
- data/lib/optparse_plus/process_status.rb +45 -0
- data/lib/optparse_plus/sh.rb +223 -0
- data/lib/optparse_plus/test/base_integration_test.rb +31 -0
- data/lib/optparse_plus/test/integration_test_assertions.rb +65 -0
- data/lib/optparse_plus/version.rb +3 -0
- data/optparse_plus.gemspec +28 -0
- data/templates/full/.gitignore.erb +4 -0
- data/templates/full/README.rdoc.erb +24 -0
- data/templates/full/Rakefile.erb +71 -0
- data/templates/full/_license_head.txt.erb +2 -0
- data/templates/full/apache_LICENSE.txt.erb +203 -0
- data/templates/full/bin/executable.erb +45 -0
- data/templates/full/custom_LICENSE.txt.erb +0 -0
- data/templates/full/gplv2_LICENSE.txt.erb +14 -0
- data/templates/full/gplv3_LICENSE.txt.erb +14 -0
- data/templates/full/mit_LICENSE.txt.erb +7 -0
- data/templates/rspec/spec/something_spec.rb.erb +5 -0
- data/templates/test_unit/test/integration/test_cli.rb.erb +11 -0
- data/templates/test_unit/test/unit/test_something.rb.erb +7 -0
- data/test/integration/base_integration_test.rb +60 -0
- data/test/integration/test_bootstrap.rb +150 -0
- data/test/integration/test_cli.rb +21 -0
- data/test/integration/test_license.rb +56 -0
- data/test/integration/test_readme.rb +53 -0
- data/test/integration/test_rspec.rb +28 -0
- data/test/integration/test_version.rb +21 -0
- data/test/unit/base_test.rb +19 -0
- data/test/unit/command_for_tests.sh +7 -0
- data/test/unit/execution_strategy/test_base.rb +24 -0
- data/test/unit/execution_strategy/test_jvm.rb +77 -0
- data/test/unit/execution_strategy/test_mri.rb +32 -0
- data/test/unit/execution_strategy/test_open_3.rb +70 -0
- data/test/unit/execution_strategy/test_open_4.rb +86 -0
- data/test/unit/execution_strategy/test_rbx_open_4.rb +25 -0
- data/test/unit/test/test_integration_test_assertions.rb +211 -0
- data/test/unit/test_cli_logger.rb +219 -0
- data/test/unit/test_cli_logging.rb +243 -0
- data/test/unit/test_exit_now.rb +37 -0
- data/test/unit/test_main.rb +840 -0
- data/test/unit/test_sh.rb +404 -0
- metadata +260 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
module OptparsePlus
|
2
|
+
# <b>OptparsePlus Internal - treat as private</b>
|
3
|
+
#
|
4
|
+
# A wrapper/enhancement of Process::Status that handles coersion and expected
|
5
|
+
# nonzero statuses
|
6
|
+
class ProcessStatus
|
7
|
+
|
8
|
+
# The exit status, either directly from a Process::Status or derived from a non-Int value.
|
9
|
+
attr_reader :exitstatus
|
10
|
+
|
11
|
+
# Create the ProcessStatus with the given status.
|
12
|
+
#
|
13
|
+
# status:: if this responds to #exitstatus, that method is used to extract the exit code. If it's
|
14
|
+
# and Int, that is used as the exit code. Otherwise,
|
15
|
+
# it's truthiness is used: 0 for truthy, 1 for falsey.
|
16
|
+
# expected:: an Int or Array of Int representing the expected exit status, other than zero,
|
17
|
+
# that represent "success".
|
18
|
+
def initialize(status,expected)
|
19
|
+
@exitstatus = derive_exitstatus(status)
|
20
|
+
@success = ([0] + Array(expected)).include?(@exitstatus)
|
21
|
+
end
|
22
|
+
|
23
|
+
# True if the exit status was a successul (i.e. expected) one.
|
24
|
+
def success?
|
25
|
+
@success
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def derive_exitstatus(status)
|
31
|
+
status = if status.respond_to? :exitstatus
|
32
|
+
status.exitstatus
|
33
|
+
else
|
34
|
+
status
|
35
|
+
end
|
36
|
+
if status.kind_of? Integer
|
37
|
+
status
|
38
|
+
elsif status
|
39
|
+
0
|
40
|
+
else
|
41
|
+
1
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
if RUBY_PLATFORM == 'java'
|
2
|
+
require 'java'
|
3
|
+
require 'ostruct'
|
4
|
+
elsif RUBY_VERSION =~ /^1.8/
|
5
|
+
begin
|
6
|
+
require 'open4'
|
7
|
+
rescue LoadError
|
8
|
+
warn "For Ruby #{RUBY_VERSION}, the open4 library must be installed or SH won't work"
|
9
|
+
end
|
10
|
+
else
|
11
|
+
require 'open3'
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'optparse_plus/process_status'
|
15
|
+
|
16
|
+
module OptparsePlus
|
17
|
+
# Module with various helper methods for executing external commands.
|
18
|
+
# In most cases, you can use #sh to run commands and have decent logging
|
19
|
+
# done. You will likely use this in a class that also mixes-in
|
20
|
+
# OptparsePlus::CLILogging (remembering that OptparsePlus::Main mixes this in for you).
|
21
|
+
# If you <b>don't</b>, you must provide a logger via #set_sh_logger.
|
22
|
+
#
|
23
|
+
# == Examples
|
24
|
+
#
|
25
|
+
# include OptparsePlus::SH
|
26
|
+
#
|
27
|
+
# sh 'cp foo.txt /tmp'
|
28
|
+
# # => logs the command to DEBUG, executes the command, logs its output to DEBUG and its
|
29
|
+
# # error output to WARN, returns 0
|
30
|
+
#
|
31
|
+
# sh 'cp non_existent_file.txt /nowhere_good'
|
32
|
+
# # => logs the command to DEBUG, executes the command, logs its output to INFO and
|
33
|
+
# # its error output to WARN, returns the nonzero exit status of the underlying command
|
34
|
+
#
|
35
|
+
# sh! 'cp non_existent_file.txt /nowhere_good'
|
36
|
+
# # => same as above, EXCEPT, raises a OptparsePlus::FailedCommandError
|
37
|
+
#
|
38
|
+
# sh 'cp foo.txt /tmp' do
|
39
|
+
# # Behaves exactly as before, but this block is called after
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# sh 'cp non_existent_file.txt /nowhere_good' do
|
43
|
+
# # This block isn't called, since the command failed
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# sh 'ls -l /tmp/' do |stdout|
|
47
|
+
# # stdout contains the output of the command
|
48
|
+
# end
|
49
|
+
# sh 'ls -l /tmp/ /non_existent_dir' do |stdout,stderr|
|
50
|
+
# # stdout contains the output of the command,
|
51
|
+
# # stderr contains the standard error output.
|
52
|
+
# end
|
53
|
+
#
|
54
|
+
# == Handling process execution
|
55
|
+
#
|
56
|
+
# In order to work on as many Rubies as possible, this class defers the actual execution
|
57
|
+
# to an execution strategy. See #set_execution_strategy if you think you'd like to override
|
58
|
+
# that, or just want to know how it works.
|
59
|
+
#
|
60
|
+
# == More complex execution and subprocess management
|
61
|
+
#
|
62
|
+
# This is not intended to be a complete replacement for Open3 or an enhanced means of managing subprocesses.
|
63
|
+
# This is to make it easy for you to shell-out to external commands and have your app be robust and
|
64
|
+
# easy to maintain.
|
65
|
+
module SH
|
66
|
+
def self.included(k)
|
67
|
+
k.extend(self)
|
68
|
+
end
|
69
|
+
# Run a shell command, capturing and logging its output.
|
70
|
+
# If the command completed successfully, it's output is logged at DEBUG.
|
71
|
+
# If not, its output as logged at INFO. In either case, its
|
72
|
+
# error output is logged at WARN.
|
73
|
+
#
|
74
|
+
# command:: the command to run as a String or Array of String. The String form is simplest, but
|
75
|
+
# is open to injection. If you need to execute a command that is assembled from some portion
|
76
|
+
# of user input, consider using an Array of String. This form prevents tokenization that occurs
|
77
|
+
# in the String form. The first element is the command to execute,
|
78
|
+
# and the remainder are the arguments. See OptparsePlus::ExecutionStrategy::Base for more info.
|
79
|
+
# options:: options to control the call. Currently responds to:
|
80
|
+
# +:expected+:: an Int or Array of Int representing error codes, <b>in addition to 0</b>, that are
|
81
|
+
# expected and therefore constitute success. Useful for commands that don't use
|
82
|
+
# exit codes the way you'd like
|
83
|
+
# block:: if provided, will be called if the command exited nonzero. The block may take 0, 1, 2, or 3 arguments.
|
84
|
+
# The arguments provided are the standard output as a string, standard error as a string, and
|
85
|
+
# the exitstatus as an Int.
|
86
|
+
# You should be safe to pass in a lambda instead of a block, as long as your
|
87
|
+
# lambda doesn't take more than three arguments
|
88
|
+
#
|
89
|
+
# Example
|
90
|
+
#
|
91
|
+
# sh "cp foo /tmp"
|
92
|
+
# sh "ls /tmp" do |stdout|
|
93
|
+
# # stdout contains the output of ls /tmp
|
94
|
+
# end
|
95
|
+
# sh "ls -l /tmp foobar" do |stdout,stderr|
|
96
|
+
# # ...
|
97
|
+
# end
|
98
|
+
#
|
99
|
+
# Returns the exit status of the command. Note that if the command doesn't exist, this returns 127.
|
100
|
+
def sh(command,options={},&block)
|
101
|
+
sh_logger.debug("Executing '#{command}'")
|
102
|
+
|
103
|
+
stdout,stderr,status = execution_strategy.run_command(command)
|
104
|
+
process_status = OptparsePlus::ProcessStatus.new(status,options[:expected])
|
105
|
+
|
106
|
+
sh_logger.warn("stderr output of '#{command}': #{stderr}") unless stderr.strip.length == 0
|
107
|
+
|
108
|
+
if process_status.success?
|
109
|
+
sh_logger.debug("stdout output of '#{command}': #{stdout}") unless stdout.strip.length == 0
|
110
|
+
call_block(block,stdout,stderr,process_status.exitstatus) unless block.nil?
|
111
|
+
else
|
112
|
+
sh_logger.info("stdout output of '#{command}': #{stdout}") unless stdout.strip.length == 0
|
113
|
+
sh_logger.warn("Error running '#{command}'")
|
114
|
+
end
|
115
|
+
|
116
|
+
process_status.exitstatus
|
117
|
+
rescue *exception_meaning_command_not_found => ex
|
118
|
+
sh_logger.error("Error running '#{command}': #{ex.message}")
|
119
|
+
127
|
120
|
+
end
|
121
|
+
|
122
|
+
# Run a command, throwing an exception if the command exited nonzero.
|
123
|
+
# Otherwise, behaves exactly like #sh.
|
124
|
+
#
|
125
|
+
# options:: options hash, responding to:
|
126
|
+
# <tt>:expected</tt>:: same as for #sh
|
127
|
+
# <tt>:on_fail</tt>:: a custom error message. This allows you to have your
|
128
|
+
# app exit on shell command failures, but customize the error
|
129
|
+
# message that they see.
|
130
|
+
#
|
131
|
+
# Raises OptparsePlus::FailedCommandError if the command exited nonzero.
|
132
|
+
#
|
133
|
+
# Examples:
|
134
|
+
#
|
135
|
+
# sh!("rsync foo bar")
|
136
|
+
# # => if command fails, app exits and user sees: "error: Command 'rsync foo bar' exited 12"
|
137
|
+
# sh!("rsync foo bar", :on_fail => "Couldn't rsync, check log for details")
|
138
|
+
# # => if command fails, app exits and user sees: "error: Couldn't rsync, check log for details
|
139
|
+
def sh!(command,options={},&block)
|
140
|
+
sh(command,options,&block).tap do |exitstatus|
|
141
|
+
process_status = OptparsePlus::ProcessStatus.new(exitstatus,options[:expected])
|
142
|
+
unless process_status.success?
|
143
|
+
raise OptparsePlus::FailedCommandError.new(exitstatus,command,options[:on_fail])
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# Override the default logger (which is the one provided by CLILogging).
|
149
|
+
# You would do this if you want a custom logger or you aren't mixing-in
|
150
|
+
# CLILogging.
|
151
|
+
#
|
152
|
+
# Note that this method is *not* called <tt>sh_logger=</tt> to avoid annoying situations
|
153
|
+
# where Ruby thinks you are setting a local variable
|
154
|
+
def set_sh_logger(logger)
|
155
|
+
@sh_logger = logger
|
156
|
+
end
|
157
|
+
|
158
|
+
# Set the strategy to use for executing commands. In general, you don't need to set this
|
159
|
+
# since this module chooses an appropriate implementation based on your Ruby platform:
|
160
|
+
#
|
161
|
+
# 1.8 Rubies, including 1.8, and REE:: Open4 is used via OptparsePlus::ExecutionStrategy::Open_4. <b><tt>open4</tt> will not be
|
162
|
+
# installed as a dependency</b>. RubyGems doesn't allow conditional dependencies,
|
163
|
+
# so make sure that your app declares it as a dependency if you think you'll be
|
164
|
+
# running on 1.8 or REE.
|
165
|
+
# Rubinius:: Open4 is used, but we handle things a bit differently; see OptparsePlus::ExecutionStrategy::RBXOpen_4.
|
166
|
+
# Same warning on dependencies applies.
|
167
|
+
# JRuby:: Use JVM calls to +Runtime+ via OptparsePlus::ExecutionStrategy::JVM
|
168
|
+
# Windows:: Currently no support for Windows
|
169
|
+
# All others:: we use Open3 from the standard library, via OptparsePlus::ExecutionStrategy::Open_3
|
170
|
+
#
|
171
|
+
# See OptparsePlus::ExecutionStrategy::Base for how to implement your own.
|
172
|
+
def set_execution_strategy(strategy)
|
173
|
+
@execution_strategy = strategy
|
174
|
+
end
|
175
|
+
|
176
|
+
private
|
177
|
+
|
178
|
+
def exception_meaning_command_not_found
|
179
|
+
execution_strategy.exception_meaning_command_not_found
|
180
|
+
end
|
181
|
+
|
182
|
+
def self.default_execution_strategy_class
|
183
|
+
if RUBY_PLATFORM == 'java'
|
184
|
+
OptparsePlus::ExecutionStrategy::JVM
|
185
|
+
elsif defined?(RUBY_ENGINE) && RUBY_ENGINE == 'rbx'
|
186
|
+
OptparsePlus::ExecutionStrategy::RBXOpen_4
|
187
|
+
elsif RUBY_VERSION =~ /^1.8/
|
188
|
+
OptparsePlus::ExecutionStrategy::Open_4
|
189
|
+
else
|
190
|
+
OptparsePlus::ExecutionStrategy::Open_3
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def execution_strategy
|
195
|
+
@execution_strategy ||= SH.default_execution_strategy_class.new
|
196
|
+
end
|
197
|
+
|
198
|
+
def sh_logger
|
199
|
+
@sh_logger ||= begin
|
200
|
+
raise StandardError, "No logger set! Please include OptparsePlus::CLILogging or provide your own via #set_sh_logger." unless self.respond_to?(:logger)
|
201
|
+
self.logger
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# Safely call our block, even if the user passed in a lambda
|
206
|
+
def call_block(block,stdout,stderr,exitstatus)
|
207
|
+
# blocks that take no arguments have arity -1. Or 0. Ugh.
|
208
|
+
if block.arity > 0
|
209
|
+
case block.arity
|
210
|
+
when 1
|
211
|
+
block.call(stdout)
|
212
|
+
when 2
|
213
|
+
block.call(stdout,stderr)
|
214
|
+
else
|
215
|
+
# Let it fail for lambdas
|
216
|
+
block.call(stdout,stderr,exitstatus)
|
217
|
+
end
|
218
|
+
else
|
219
|
+
block.call
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "fileutils"
|
3
|
+
require "pathname"
|
4
|
+
require "tmpdir"
|
5
|
+
require "open3"
|
6
|
+
|
7
|
+
require_relative "integration_test_assertions"
|
8
|
+
|
9
|
+
# Clean test should be setting this
|
10
|
+
$FOR_TESTING_ONLY_SKIP_STDERR = false
|
11
|
+
|
12
|
+
module OptparsePlus
|
13
|
+
end
|
14
|
+
class OptparsePlus::BaseIntegrationTest < Test::Unit::TestCase
|
15
|
+
include FileUtils
|
16
|
+
include OptparsePlus::IntegrationTestAssertions
|
17
|
+
|
18
|
+
# Run your app, capturing stdout, stderr, and process status.
|
19
|
+
# app_name:: Your bin name, without `bin/`
|
20
|
+
# args:: CLI args as a string
|
21
|
+
# allow_failure:: if true, this will return even if the app invocation fails. If false (the default), blows up if things go
|
22
|
+
# wrong.
|
23
|
+
def run_app(app_name, args, allow_failure: false)
|
24
|
+
command = "bin/#{app_name} #{args}"
|
25
|
+
stdout,stderr,results = Open3.capture3(command)
|
26
|
+
if @allow_failure && !results.success?
|
27
|
+
raise "'#{command}' failed!: #{results.inspect}\n\nSTDOUT {\n#{stdout}\n} STDERR {\n#{stderr}\n} END"
|
28
|
+
end
|
29
|
+
[stdout,stderr,results]
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module OptparsePlus
|
2
|
+
end
|
3
|
+
module OptparsePlus::IntegrationTestAssertions
|
4
|
+
# Assert that a file's contents contains one or more regexps
|
5
|
+
#
|
6
|
+
# filename:: The file whose contents to check
|
7
|
+
# contains:: either a regexp or array of regexpts that the file's contents must match
|
8
|
+
def assert_file(filename, contains:)
|
9
|
+
contents = File.read(filename)
|
10
|
+
Array(contains).each do |regexp|
|
11
|
+
assert_match(regexp,contents,"Expected #{filename} to contain #{regexp}")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Assert that the stdout contains an appropriate banner for your app
|
16
|
+
#
|
17
|
+
# stdout:: The standard out, presumably of running `«your-app» --help`
|
18
|
+
# bin_name:: The binary name of your app
|
19
|
+
# takes_options:: set this to true if your app should take options
|
20
|
+
# takes_arguments:: set this to a hash of the arguments your app should take, with the key being the arg name and the value
|
21
|
+
# being either `:required` or `:optional`
|
22
|
+
def assert_banner(stdout, bin_name, takes_options: , takes_arguments: {})
|
23
|
+
if takes_options
|
24
|
+
assert_match(/Options/, stdout)
|
25
|
+
if takes_arguments == false || takes_arguments.empty?
|
26
|
+
assert_match(/Usage: #{Regexp.escape(bin_name)}.*\[options\]\s*$/,stdout)
|
27
|
+
else
|
28
|
+
expected_args = takes_arguments.map { |arg, required|
|
29
|
+
if required == :required
|
30
|
+
arg.to_s
|
31
|
+
else
|
32
|
+
"[#{arg}]"
|
33
|
+
end
|
34
|
+
}.join(" ")
|
35
|
+
|
36
|
+
assert_match(/Usage: #{Regexp.escape(bin_name)}.*\[options\]\s*#{Regexp.escape(expected_args)}$/,stdout)
|
37
|
+
end
|
38
|
+
else
|
39
|
+
assert_match(/Usage: #{Regexp.escape(bin_name)}\s*$/,stdout)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Assert that your app takes the given option(s)
|
44
|
+
#
|
45
|
+
# stdout:: The standard out, presumably of running `«your-app» --help`
|
46
|
+
# options:: options your app should take. Put the literal value in here e.g. `--foo` or `--[no-]bar`. The array form is to
|
47
|
+
# allow you to assert long and short options for readable tests:
|
48
|
+
#
|
49
|
+
# assert_option(stdout, "--version")
|
50
|
+
# assert_option(stdout, "-h", "--help")
|
51
|
+
def assert_option(stdout, *options)
|
52
|
+
options.each do |option|
|
53
|
+
assert_match(/#{Regexp.escape(option)}/,stdout)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Assert that your app has a one-line summary
|
58
|
+
# stdout:: The standard out, presumably of running `«your-app» --help`
|
59
|
+
def assert_oneline_summary(stdout)
|
60
|
+
output = stdout.split(/\n/)
|
61
|
+
assert output.size >= 3, "Expected 3 or more lines:\n#{stdout}"
|
62
|
+
assert_match(/^\s*$/,output[1],"Should be a blank line after the banner")
|
63
|
+
assert_match(/^\w+\s+\w+/,output[2],"Should be at least two words describing your app")
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "optparse_plus/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "optparse-plus"
|
7
|
+
s.version = OptparsePlus::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["davetron5000"]
|
10
|
+
s.email = ["davetron5000 at gmail.com"]
|
11
|
+
s.homepage = "http://github.com/davetron5000/optparse-plus"
|
12
|
+
s.summary = %q{Wrapper around the Standard Library's Option Parser to make CLIs Easier}
|
13
|
+
s.description = %q{OptparsePlus provides a lot of small but useful features for developing a command-line app, including an opinionated bootstrapping process, some helpful integration test support, and some classes to bridge logging and output into a simple, unified, interface}
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
s.add_dependency("bundler")
|
20
|
+
s.add_development_dependency("rake")
|
21
|
+
s.add_development_dependency("rdoc","~> 6.0")
|
22
|
+
s.add_development_dependency("sdoc")
|
23
|
+
s.add_development_dependency("simplecov", "~> 0.5")
|
24
|
+
s.add_development_dependency("clean_test", "~> 1.0.1")
|
25
|
+
s.add_development_dependency("mocha")
|
26
|
+
s.add_development_dependency("rspec") # needed for testing the generated tests
|
27
|
+
s.add_development_dependency("i18n")
|
28
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
= <%= gemname %> - DESCRIBE YOUR GEM
|
2
|
+
|
3
|
+
Author:: YOUR NAME (YOUR EMAIL)
|
4
|
+
Copyright:: Copyright (c) <%= Time.now.year %> YOUR NAME
|
5
|
+
<% if license %>
|
6
|
+
<% if license == 'custom' %>
|
7
|
+
License:: INSERT LICENSE HERE
|
8
|
+
<% else %>
|
9
|
+
License:: <%= license %>, see LICENSE.txt
|
10
|
+
<% end %>
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
DESCRIBE YOUR GEM HERE
|
14
|
+
|
15
|
+
== Links
|
16
|
+
|
17
|
+
* {Source on Github}[LINK TO GITHUB]
|
18
|
+
* RDoc[LINK TO RDOC.INFO]
|
19
|
+
|
20
|
+
== Install
|
21
|
+
|
22
|
+
== Examples
|
23
|
+
|
24
|
+
== Contributing
|
@@ -0,0 +1,71 @@
|
|
1
|
+
def dump_load_path
|
2
|
+
puts $LOAD_PATH.join("\n")
|
3
|
+
found = nil
|
4
|
+
$LOAD_PATH.each do |path|
|
5
|
+
if File.exists?(File.join(path,"rspec"))
|
6
|
+
puts "Found rspec in #{path}"
|
7
|
+
if File.exists?(File.join(path,"rspec","core"))
|
8
|
+
puts "Found core"
|
9
|
+
if File.exists?(File.join(path,"rspec","core","rake_task"))
|
10
|
+
puts "Found rake_task"
|
11
|
+
found = path
|
12
|
+
else
|
13
|
+
puts "!! no rake_task"
|
14
|
+
end
|
15
|
+
else
|
16
|
+
puts "!!! no core"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
if found.nil?
|
21
|
+
puts "Didn't find rspec/core/rake_task anywhere"
|
22
|
+
else
|
23
|
+
puts "Found in #{path}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
require 'bundler'
|
27
|
+
require 'rake/clean'
|
28
|
+
<% if rspec %>
|
29
|
+
begin
|
30
|
+
require 'rspec/core/rake_task'
|
31
|
+
rescue LoadError
|
32
|
+
dump_load_path
|
33
|
+
raise
|
34
|
+
end
|
35
|
+
<% else %>
|
36
|
+
require 'rake/testtask'
|
37
|
+
<% end %>
|
38
|
+
gem 'rdoc' # we need the installed RDoc gem, not the system one
|
39
|
+
require 'rdoc/task'
|
40
|
+
|
41
|
+
include Rake::DSL
|
42
|
+
|
43
|
+
Bundler::GemHelper.install_tasks
|
44
|
+
|
45
|
+
<% if rspec %>
|
46
|
+
RSpec::Core::RakeTask.new do |t|
|
47
|
+
# Put spec opts in a file named .rspec in root
|
48
|
+
end
|
49
|
+
<% else %>
|
50
|
+
Rake::TestTask.new do |t|
|
51
|
+
t.pattern = 'test/unit/test_*.rb'
|
52
|
+
end
|
53
|
+
|
54
|
+
Rake::TestTask.new("test:integration") do |t|
|
55
|
+
t.pattern = 'test/integration/test_*.rb'
|
56
|
+
end
|
57
|
+
<% end %>
|
58
|
+
|
59
|
+
Rake::RDocTask.new do |rd|
|
60
|
+
<% if using_readme %>
|
61
|
+
rd.main = "README.rdoc"
|
62
|
+
rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
|
63
|
+
<% else %>
|
64
|
+
rd.rdoc_files.include("lib/**/*.rb","bin/**/*")
|
65
|
+
<% end %>
|
66
|
+
end
|
67
|
+
<% if rspec %>
|
68
|
+
task :default => [:spec]
|
69
|
+
<% else %>
|
70
|
+
task :default => [:test,"test:integration"]
|
71
|
+
<% end %>
|