optparse-plus 3.0.0
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.
- 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 %>
|