clif 0.1.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.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.markdown +106 -0
- data/Rakefile +62 -0
- data/VERSION +1 -0
- data/lib/clif.rb +9 -0
- data/lib/clif/helper.rb +50 -0
- data/lib/clif/questioner.rb +45 -0
- data/test/clif_test.rb +185 -0
- data/test/test_helper.rb +41 -0
- metadata +86 -0
data/.document
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 jameswilding
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
# clif
|
2
|
+
|
3
|
+
clif is a ready-made interface between your library and the command-line. Write less code, get more done.
|
4
|
+
|
5
|
+
## Why clif?
|
6
|
+
|
7
|
+
clif will ask questions, get answers, convert yes/no responses into true/false values, and more. Use clif to run an installation procedure, explain build steps, get user input for a command line script: anywhere your library needs to interact with the use on the command line, clif can help.
|
8
|
+
|
9
|
+
## Some examples
|
10
|
+
|
11
|
+
In the following examples, the output of methods like <code>ask</code>, <code>say</code>, and <code>perform_action</code> is displayed on the command-line (and input from the command line is passed back to your code, where appropriate).
|
12
|
+
|
13
|
+
### Setup
|
14
|
+
|
15
|
+
Clif respects the :quiet and :pretend options:
|
16
|
+
|
17
|
+
Clif.new # speaks messages, performs action
|
18
|
+
Clif.new(:quiet => true) # performs actions silently (will still ask questions)
|
19
|
+
Clif.new(:pretend => true) # speaks but doesn't act (useful for dry runs)
|
20
|
+
|
21
|
+
# Let's go
|
22
|
+
@clif = Clif.new
|
23
|
+
|
24
|
+
### Speaking
|
25
|
+
|
26
|
+
# Clif can speak
|
27
|
+
@clif.say "Hello world!" # => 'Hello world!'
|
28
|
+
|
29
|
+
# Set :quiet to true to supress messages (questions will still be spoken)
|
30
|
+
Clif.new(:quiet => true).say('Hello world!') # => nil
|
31
|
+
|
32
|
+
### Asking Questions
|
33
|
+
|
34
|
+
Ask a question on the command line and get a response from the user:
|
35
|
+
|
36
|
+
user_status = @clif.ask('How are you?')
|
37
|
+
|
38
|
+
Yes/no ('boolean') questions return true or false:
|
39
|
+
|
40
|
+
hungry = @clif.ask('Are you hungry?', :boolean => true) # "Are you hungry? [y/n]:"
|
41
|
+
|
42
|
+
And as a convenience, clif provide <code>yes?</code> and <code>no?</code> methods:
|
43
|
+
|
44
|
+
hungry = @clif.yes?('Are you hungry?')
|
45
|
+
thirsty = @clif.no?('Have you drunk?')
|
46
|
+
|
47
|
+
### Prompt for responses
|
48
|
+
|
49
|
+
name = @clif.prompt('Your name, please') # "Your name, please: "
|
50
|
+
puts "Your name is #{name}"
|
51
|
+
|
52
|
+
### Perform Actions
|
53
|
+
|
54
|
+
The <code>perform_action</code> and <code>explain</code> methods are intended to talk the user through a serious of related steps: an installation, a plugin generation process, etc.
|
55
|
+
|
56
|
+
The <code>perform_action</code> method explains an action to the user, and then performs the action. This next example outputs "install: some/file.rb" and runs <code>FileUtils.install</code>:
|
57
|
+
|
58
|
+
@clif.perform_action(:install, 'some/file.rb') do
|
59
|
+
FileUtils.install('some/file.rb', '/usr/local/lib')
|
60
|
+
end
|
61
|
+
|
62
|
+
When you use <code>:pretend => true</code>, clif will explain actions but won't actually perform them. This is useful for dry runs:
|
63
|
+
|
64
|
+
file = 'some/file.rb'
|
65
|
+
|
66
|
+
Clif.new(:pretend => true).perform_action(:create, file) do
|
67
|
+
FileUtils.touch(file) # won't run
|
68
|
+
end
|
69
|
+
|
70
|
+
File.file?(file) # => false
|
71
|
+
|
72
|
+
Use <code>explain</code> to comment on steps that don't require any actions:
|
73
|
+
|
74
|
+
@clif.explain(:exists, 'app/views') # => "exists: app/views"
|
75
|
+
|
76
|
+
### Mixin!
|
77
|
+
|
78
|
+
Mix in the <code>Clif::Helper</code> module to use clif's methods in your own classes:
|
79
|
+
|
80
|
+
class Butler
|
81
|
+
include Clif::Helper
|
82
|
+
end
|
83
|
+
|
84
|
+
Butler.new.ask('May I take your coat?')
|
85
|
+
|
86
|
+
<code>Clif::Helper</code> assumes that you have an instance variable called <code>@options</code> available in your objects.
|
87
|
+
|
88
|
+
## TODO
|
89
|
+
|
90
|
+
* Cleaner testing of output to $stdout and input from $stdin
|
91
|
+
* Persistently ask yes/no questions until the response is some variant of 'y', 'yes, 'n', or 'no'
|
92
|
+
|
93
|
+
## Note on Patches/Pull Requests
|
94
|
+
|
95
|
+
* Fork the project.
|
96
|
+
* Make your feature addition or bug fix.
|
97
|
+
* Add tests for it. This is important so I don't break it in a
|
98
|
+
future version unintentionally.
|
99
|
+
* Commit: do not mess with rakefile, version, or history.
|
100
|
+
(if you want to have your own version, that is fine but
|
101
|
+
bump version in a commit by itself I can ignore when I pull)
|
102
|
+
* Send me a pull request. Bonus points for topic branches.
|
103
|
+
|
104
|
+
== Copyright
|
105
|
+
|
106
|
+
Copyright (c) 2009 James Wilding. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
|
7
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
8
|
+
Jeweler::Tasks.new do |gem|
|
9
|
+
gem.name = "clif"
|
10
|
+
gem.summary = %Q{Ready-made command line interface for ruby libraries}
|
11
|
+
gem.description = %Q{clif (Command Line InterFace) acts as a bridge between your code and the command line}
|
12
|
+
gem.email = "james@jameswilding.net"
|
13
|
+
gem.homepage = "http://github.com/jameswilding/clif"
|
14
|
+
gem.authors = ["jameswilding"]
|
15
|
+
gem.add_development_dependency "thoughtbot-shoulda"
|
16
|
+
gem.add_development_dependency "redgreen"
|
17
|
+
end
|
18
|
+
|
19
|
+
# Releases go to gemcutter.org
|
20
|
+
Jeweler::GemcutterTasks.new
|
21
|
+
rescue LoadError
|
22
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'rake/testtask'
|
26
|
+
Rake::TestTask.new(:test) do |test|
|
27
|
+
test.libs << 'lib' << 'test'
|
28
|
+
test.pattern = 'test/**/*_test.rb'
|
29
|
+
test.verbose = true
|
30
|
+
end
|
31
|
+
|
32
|
+
begin
|
33
|
+
require 'rcov/rcovtask'
|
34
|
+
Rcov::RcovTask.new do |test|
|
35
|
+
test.libs << 'test'
|
36
|
+
test.pattern = 'test/**/*_test.rb'
|
37
|
+
test.rcov_opts = ['--exclude /Library'] # otherwise depandencies are analysed, too
|
38
|
+
test.verbose = true
|
39
|
+
end
|
40
|
+
rescue LoadError
|
41
|
+
task :rcov do
|
42
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
#task :test => :check_dependencies # => "don't know how to build task'check_dependencies'"
|
47
|
+
|
48
|
+
task :default => :test
|
49
|
+
|
50
|
+
require 'rake/rdoctask'
|
51
|
+
Rake::RDocTask.new do |rdoc|
|
52
|
+
if File.exist?('VERSION')
|
53
|
+
version = File.read('VERSION')
|
54
|
+
else
|
55
|
+
version = ""
|
56
|
+
end
|
57
|
+
|
58
|
+
rdoc.rdoc_dir = 'rdoc'
|
59
|
+
rdoc.title = "clif #{version}"
|
60
|
+
rdoc.rdoc_files.include('README*')
|
61
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
62
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/lib/clif.rb
ADDED
data/lib/clif/helper.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'clif/questioner'
|
2
|
+
|
3
|
+
class Clif
|
4
|
+
module Helper
|
5
|
+
|
6
|
+
def say(message)
|
7
|
+
$stdout.puts(message) unless quiet?
|
8
|
+
end
|
9
|
+
|
10
|
+
def no?(question)
|
11
|
+
!yes?(question)
|
12
|
+
end
|
13
|
+
|
14
|
+
def yes?(question)
|
15
|
+
!!ask(question)
|
16
|
+
end
|
17
|
+
|
18
|
+
def ask(question, options = {})
|
19
|
+
::Clif::Questioner.new(options).ask(question)
|
20
|
+
end
|
21
|
+
alias :prompt :ask
|
22
|
+
|
23
|
+
def perform_action(action, message, &block)
|
24
|
+
explain(action, message)
|
25
|
+
yield unless pretend?
|
26
|
+
end
|
27
|
+
|
28
|
+
def explain(action, message)
|
29
|
+
say "#{title_for_action(action)}: #{message}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def quiet?
|
33
|
+
@options[:quiet] || false
|
34
|
+
end
|
35
|
+
|
36
|
+
def pretend?
|
37
|
+
@options[:pretend] || false
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
def title_for_action(action)
|
42
|
+
action.to_s.rjust(indent)
|
43
|
+
end
|
44
|
+
|
45
|
+
def indent
|
46
|
+
@options[:indent] || 8
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class Clif
|
2
|
+
class Questioner
|
3
|
+
|
4
|
+
def initialize(options = {})
|
5
|
+
@options = options
|
6
|
+
end
|
7
|
+
|
8
|
+
def ask(question)
|
9
|
+
@question = question
|
10
|
+
ask_question
|
11
|
+
get_response
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def ask_question
|
16
|
+
$stdout.print(formatted_question + " ")
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_response
|
20
|
+
response = ($stdin.gets || '').chomp
|
21
|
+
|
22
|
+
if boolean_question?
|
23
|
+
boolean_response(response)
|
24
|
+
else
|
25
|
+
response
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def boolean_response(response)
|
30
|
+
%w(y yes).include?(response.downcase) ? true : false
|
31
|
+
end
|
32
|
+
|
33
|
+
def formatted_question
|
34
|
+
if boolean_question?
|
35
|
+
"#{@question} [y/n]:"
|
36
|
+
else
|
37
|
+
@question =~ /\?$/ ? "#{@question}" : "#{@question}:"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def boolean_question?
|
42
|
+
@options[:boolean] || false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/test/clif_test.rb
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'clif'
|
3
|
+
|
4
|
+
class ClifTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@real_stdout, $stdout = $stdout, StringIO.new
|
8
|
+
@real_stdin, $stdin = $stdin, StringIO.new
|
9
|
+
|
10
|
+
def $stdin.gets
|
11
|
+
$stdin.string
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def teardown
|
16
|
+
$stdout = @real_stdout
|
17
|
+
$stdin = @real_stdin
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'a Clif::CLI instance' do
|
21
|
+
|
22
|
+
setup { @cli = new_clif }
|
23
|
+
|
24
|
+
should 'be able to say things' do
|
25
|
+
expected = "Hello world"
|
26
|
+
|
27
|
+
assert_stdout(expected) { @cli.say 'Hello world' }
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'when initialized with :quiet => true' do
|
31
|
+
|
32
|
+
setup { @cli = new_clif(:quiet => true) }
|
33
|
+
|
34
|
+
should 'communicate whether it should be quiet' do
|
35
|
+
assert @cli.quiet?
|
36
|
+
end
|
37
|
+
|
38
|
+
should 'not say things when asked to' do
|
39
|
+
expected = ''
|
40
|
+
|
41
|
+
assert_stdout(expected) { @cli.say 'Nothing' }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'when initialized without :quiet' do
|
46
|
+
|
47
|
+
setup { @cli = new_clif }
|
48
|
+
|
49
|
+
should 'return false when asked if it should be quiet' do
|
50
|
+
assert_equal false, @cli.quiet?
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when initialized with :pretend => true' do
|
55
|
+
|
56
|
+
setup { @cli = new_clif(:pretend => true, :quiet => true) }
|
57
|
+
|
58
|
+
should 'not actually do things when asked to' do
|
59
|
+
expected = nil
|
60
|
+
actual = @cli.perform_action(:add, '1 plus 1') { destroy_the_city }
|
61
|
+
|
62
|
+
assert_equal expected, actual
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
should 'be able to do things' do
|
67
|
+
expected = 2
|
68
|
+
actual = new_clif(:quiet => true).perform_action(:add, '1 plus 1') { 1 + 1 }
|
69
|
+
end
|
70
|
+
|
71
|
+
should 'explain its action before performing them' do
|
72
|
+
expected = ' add: 1 plus 1'
|
73
|
+
|
74
|
+
assert_stdout(expected) do
|
75
|
+
new_clif.perform_action(:add, '1 plus 1') { 1 + 1 }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
should 'just explain things with no action' do
|
80
|
+
expected = ' skip: something'
|
81
|
+
|
82
|
+
assert_stdout(expected) do
|
83
|
+
new_clif.explain(:skip, 'something')
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
should 'not explain things when :quiet => true' do
|
88
|
+
expected = ''
|
89
|
+
|
90
|
+
assert_stdout(expected) do
|
91
|
+
new_clif(:quiet => true).explain(:do, 'something')
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
should 'allow for setting of indent level in explanations' do
|
96
|
+
expected = 'do: something'
|
97
|
+
|
98
|
+
assert_stdout(expected) do
|
99
|
+
new_clif(:indent => 0).explain(:do, 'something')
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
should 'be able to ask nicely formatted questions, without indenting' do
|
104
|
+
expected = formatted_question_for("What's your name?")
|
105
|
+
|
106
|
+
assert_stdout expected do
|
107
|
+
new_clif.ask("What's your name?")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
should 'alias :ask as :prompt' do
|
112
|
+
expected = formatted_question_for('Your name')
|
113
|
+
|
114
|
+
assert_stdout expected do
|
115
|
+
new_clif.prompt('Your name')
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
should 'ask nicely formatted yes/no questions, if :boolean => true' do
|
120
|
+
expected = formatted_question_for('Launch rockets?', :boolean => true)
|
121
|
+
|
122
|
+
assert_stdout expected do
|
123
|
+
new_clif.ask('Launch rockets?', :boolean => true)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
should 'have a shortcut for getting a yes? answer' do
|
128
|
+
expected = formatted_question_for('Do something?')
|
129
|
+
|
130
|
+
assert_stdout expected do
|
131
|
+
assert_respond_to @cli, :yes?
|
132
|
+
@cli.yes?('Do something?')
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
should 'have a shortcut for getting a no? answer' do
|
137
|
+
expected = formatted_question_for('Do something?')
|
138
|
+
|
139
|
+
assert_stdout expected do
|
140
|
+
assert_respond_to @cli, :no?
|
141
|
+
@cli.no?('Do something?')
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
context 'asking boolean questions' do
|
146
|
+
should 'turn Y into true' do
|
147
|
+
expected = true
|
148
|
+
|
149
|
+
with_input('Y') do
|
150
|
+
actual = @cli.ask('Are you there?', :boolean => true)
|
151
|
+
assert_equal expected, actual, "Expected 'Y' to produce #{expected} (got #{actual})"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
should 'turn y into true' do
|
156
|
+
expected = true
|
157
|
+
|
158
|
+
with_input('y') do
|
159
|
+
actual = @cli.ask('Are you there?', :boolean => true)
|
160
|
+
assert_equal expected, actual, "Expected 'y' to produce #{expected} (got #{actual})"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
should 'turn N into false' do
|
165
|
+
expected = false
|
166
|
+
|
167
|
+
with_input('N') do
|
168
|
+
actual = @cli.ask('Are you there?', :boolean => true)
|
169
|
+
assert_equal expected, actual, "Expected 'N' to produce #{expected} (got #{actual})"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
should 'turn n into false' do
|
174
|
+
expected = false
|
175
|
+
|
176
|
+
with_input('n') do
|
177
|
+
actual = @cli.ask('Are you there?', :boolean => true)
|
178
|
+
assert_equal expected, actual, "Expected 'n' to produce #{expected} (got #{actual})"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
require 'redgreen'
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
|
+
require 'clif'
|
9
|
+
|
10
|
+
class Test::Unit::TestCase
|
11
|
+
|
12
|
+
def new_clif(options = {})
|
13
|
+
Clif.new(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def formatted_question_for(message, options = {})
|
17
|
+
if options[:boolean]
|
18
|
+
"#{message} [y/n]: "
|
19
|
+
else
|
20
|
+
message =~ /\?$/ ? "#{message} " : "#{message}: "
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def assert_stdout(expected, &block)
|
25
|
+
result = silently(&block)
|
26
|
+
assert_equal expected, result
|
27
|
+
end
|
28
|
+
|
29
|
+
def with_input(text, &block)
|
30
|
+
silently do
|
31
|
+
$stdin.write(text); yield
|
32
|
+
end
|
33
|
+
ensure
|
34
|
+
$stdin.string.replace('')
|
35
|
+
end
|
36
|
+
|
37
|
+
def silently(&block)
|
38
|
+
yield; $stdout.string.chomp
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: clif
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- jameswilding
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-21 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: thoughtbot-shoulda
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: redgreen
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
description: clif (Command Line InterFace) acts as a bridge between your code and the command line
|
36
|
+
email: james@jameswilding.net
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- LICENSE
|
43
|
+
- README.markdown
|
44
|
+
files:
|
45
|
+
- .document
|
46
|
+
- .gitignore
|
47
|
+
- LICENSE
|
48
|
+
- README.markdown
|
49
|
+
- Rakefile
|
50
|
+
- VERSION
|
51
|
+
- lib/clif.rb
|
52
|
+
- lib/clif/helper.rb
|
53
|
+
- lib/clif/questioner.rb
|
54
|
+
- test/clif_test.rb
|
55
|
+
- test/test_helper.rb
|
56
|
+
has_rdoc: true
|
57
|
+
homepage: http://github.com/jameswilding/clif
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options:
|
62
|
+
- --charset=UTF-8
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: "0"
|
70
|
+
version:
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: "0"
|
76
|
+
version:
|
77
|
+
requirements: []
|
78
|
+
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.3.5
|
81
|
+
signing_key:
|
82
|
+
specification_version: 3
|
83
|
+
summary: Ready-made command line interface for ruby libraries
|
84
|
+
test_files:
|
85
|
+
- test/clif_test.rb
|
86
|
+
- test/test_helper.rb
|