my 0.3.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/LICENSE +20 -0
- data/Manifest +26 -0
- data/README.rdoc +37 -0
- data/Rakefile +41 -0
- data/VERSION +1 -0
- data/bin/my +5 -0
- data/features/advanced.feature +29 -0
- data/features/aliases.feature +20 -0
- data/features/files.feature +37 -0
- data/features/folder.feature +13 -0
- data/features/questions.feature +43 -0
- data/features/sinatra.feature +72 -0
- data/features/support/env.rb +9 -0
- data/features/support/hooks.rb +8 -0
- data/features/support/interactive_steps.rb +41 -0
- data/features/support/steps.rb +22 -0
- data/features/usage.feature +20 -0
- data/lib/my.rb +13 -0
- data/lib/my/config.rb +39 -0
- data/lib/my/runner.rb +120 -0
- data/lib/my/script.rb +177 -0
- data/my.gemspec +41 -0
- data/spec/config_spec.rb +30 -0
- data/spec/runner_spec.rb +110 -0
- data/spec/script_spec.rb +149 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +27 -0
- metadata +141 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Kevin W. Gisi
|
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/Manifest
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
LICENSE
|
2
|
+
README.rdoc
|
3
|
+
Rakefile
|
4
|
+
VERSION
|
5
|
+
bin/my
|
6
|
+
features/advanced.feature
|
7
|
+
features/aliases.feature
|
8
|
+
features/files.feature
|
9
|
+
features/folder.feature
|
10
|
+
features/questions.feature
|
11
|
+
features/sinatra.feature
|
12
|
+
features/support/env.rb
|
13
|
+
features/support/hooks.rb
|
14
|
+
features/support/interactive_steps.rb
|
15
|
+
features/support/steps.rb
|
16
|
+
features/usage.feature
|
17
|
+
lib/my.rb
|
18
|
+
lib/my/config.rb
|
19
|
+
lib/my/runner.rb
|
20
|
+
lib/my/script.rb
|
21
|
+
spec/config_spec.rb
|
22
|
+
spec/runner_spec.rb
|
23
|
+
spec/script_spec.rb
|
24
|
+
spec/spec.opts
|
25
|
+
spec/spec_helper.rb
|
26
|
+
Manifest
|
data/README.rdoc
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
= My
|
2
|
+
|
3
|
+
My is a configuration and template manager written in Ruby, designed to provide a DSL for managing file and folder dependencies.
|
4
|
+
|
5
|
+
== Installation and Usage
|
6
|
+
|
7
|
+
In order to use My, simply install the gem:
|
8
|
+
|
9
|
+
gem install my
|
10
|
+
|
11
|
+
Then to run a My script, just run:
|
12
|
+
|
13
|
+
my [FILE|URL]
|
14
|
+
|
15
|
+
== My Scripts
|
16
|
+
|
17
|
+
My uses a Ruby script syntax to specify actions, like in the following example script:
|
18
|
+
|
19
|
+
# Sinatra My Script
|
20
|
+
|
21
|
+
file "app.rb" => "http://pastie.org/944315.txt"
|
22
|
+
file "config.ru" => "http://pastie.org/994640.txt"
|
23
|
+
|
24
|
+
ask "Will you be using external views?"
|
25
|
+
yes do
|
26
|
+
folder "views"
|
27
|
+
file "views/index.html" => "http://pastie.org/944311.txt"
|
28
|
+
end
|
29
|
+
|
30
|
+
ask "Will you be using an external stylesheet?"
|
31
|
+
yes do
|
32
|
+
folder "views"
|
33
|
+
file "views/style.sass" => "http://pastie.org/944313.txt"
|
34
|
+
end
|
35
|
+
|
36
|
+
== Copyright
|
37
|
+
Copyright (c) 2010 Kevin W. Gisi. Released under the MIT License
|
data/Rakefile
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'echoe'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
require 'cucumber/rake/task'
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
|
6
|
+
Echoe.new "my", File.read("VERSION").chomp do |m|
|
7
|
+
m.author = "Kevin W. Gisi"
|
8
|
+
m.email = "kevin@kevingisi.com"
|
9
|
+
m.summary = "Ruby template and configuration manager"
|
10
|
+
m.url = "http://gisikw.github.com/my"
|
11
|
+
m.development_dependencies << "cucumber >=0.7.2"
|
12
|
+
m.development_dependencies << "aruba >=0.1.9"
|
13
|
+
m.development_dependencies << "rspec >=1.3.0"
|
14
|
+
end
|
15
|
+
|
16
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
17
|
+
spec.libs << 'lib' << 'spec'
|
18
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
19
|
+
end
|
20
|
+
|
21
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
22
|
+
spec.libs << 'lib' << 'spec'
|
23
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
24
|
+
spec.rcov = true
|
25
|
+
spec.rcov_opts = ["-T"]
|
26
|
+
end
|
27
|
+
|
28
|
+
Cucumber::Rake::Task.new do |t|
|
29
|
+
t.cucumber_opts = %w{--format pretty}
|
30
|
+
end
|
31
|
+
|
32
|
+
Rake::RDocTask.new do |rdoc|
|
33
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
34
|
+
rdoc.rdoc_dir = 'rdoc'
|
35
|
+
rdoc.title = "My #{version}"
|
36
|
+
rdoc.main = 'README.rdoc'
|
37
|
+
rdoc.rdoc_files.include('README.rdoc')
|
38
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
39
|
+
end
|
40
|
+
|
41
|
+
task :default => :spec
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|
data/bin/my
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
Feature: Advanced scripting
|
2
|
+
|
3
|
+
As a My script writer
|
4
|
+
I want to nest tasks inside of questions
|
5
|
+
So I can respond dynamically to the user's needs
|
6
|
+
|
7
|
+
Scenario: Nesting questions
|
8
|
+
Given a file named "yes.template" with:
|
9
|
+
"""
|
10
|
+
The user picked yes
|
11
|
+
"""
|
12
|
+
And a file named "script.rb" with:
|
13
|
+
"""
|
14
|
+
ask "Are you sure you would like to apply this script?"
|
15
|
+
yes do
|
16
|
+
folder "foo"
|
17
|
+
file "foo.txt" => "yes.template"
|
18
|
+
ask "Would you like to create bar.txt?"
|
19
|
+
yes do
|
20
|
+
file "bar.txt" => "yes.template"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
"""
|
24
|
+
When I run "../../bin/my script.rb" interactively
|
25
|
+
And I type "y"
|
26
|
+
And I type "y"
|
27
|
+
And the program completes
|
28
|
+
Then the file "foo.txt" should contain "The user picked yes"
|
29
|
+
Then the file "bar.txt" should contain "The user picked yes"
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: Script aliases
|
2
|
+
|
3
|
+
As a user of the My gem
|
4
|
+
I want to register shortname for scripts
|
5
|
+
So I can save time
|
6
|
+
|
7
|
+
Scenario: Adding an alias
|
8
|
+
Given there are no scripts installed
|
9
|
+
And I run "../../bin/my add sinatra"
|
10
|
+
Then I should see "The sinatra script has been registered"
|
11
|
+
|
12
|
+
Scenario: Removing an alias
|
13
|
+
Given there is a "sinatra" script installed
|
14
|
+
And I run "../../bin/my rm sinatra"
|
15
|
+
Then I should see "The sinatra script has been removed"
|
16
|
+
|
17
|
+
Scenario: Listing aliases
|
18
|
+
Given there is a "sinatra" script installed
|
19
|
+
And I run "../../bin/my help"
|
20
|
+
Then I should see "sinatra"
|
@@ -0,0 +1,37 @@
|
|
1
|
+
Feature: File commands with My scripts
|
2
|
+
|
3
|
+
As a user of the My gem
|
4
|
+
I want to specify files in scripts
|
5
|
+
So that I can download them automatically
|
6
|
+
|
7
|
+
Scenario: Requiring files
|
8
|
+
Given a file named "test.txt.template" with:
|
9
|
+
"""
|
10
|
+
My script test content
|
11
|
+
"""
|
12
|
+
And a file named "test2.txt.template" with:
|
13
|
+
"""
|
14
|
+
My script test2 content
|
15
|
+
"""
|
16
|
+
And a file named "script.rb" with:
|
17
|
+
"""
|
18
|
+
file "test.txt" => "test.txt.template"
|
19
|
+
file "test2.txt" => "test2.txt.template"
|
20
|
+
"""
|
21
|
+
When I run "../../bin/my script.rb"
|
22
|
+
Then the file "test.txt" should contain "My script test content"
|
23
|
+
And the file "test2.txt" should contain "My script test2 content"
|
24
|
+
|
25
|
+
Scenario: Requiring a file with template options
|
26
|
+
Given a file named "test.txt.template" with:
|
27
|
+
"""
|
28
|
+
My script injected content: <%= @content %>
|
29
|
+
"""
|
30
|
+
And a file named "script.rb" with:
|
31
|
+
"""
|
32
|
+
file "test.txt" => "test.txt.template" do
|
33
|
+
@content = "injection"
|
34
|
+
end
|
35
|
+
"""
|
36
|
+
When I run "../../bin/my script.rb"
|
37
|
+
Then the file "test.txt" should contain "My script injected content: injection"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Feature: Folder commands with My scripts
|
2
|
+
|
3
|
+
As a user of the My gem
|
4
|
+
I want to specify folders in create
|
5
|
+
So that I can create them automatically
|
6
|
+
|
7
|
+
Scenario: Requiring a folder
|
8
|
+
Given a file named "script.rb" with:
|
9
|
+
"""
|
10
|
+
folder "foo"
|
11
|
+
"""
|
12
|
+
When I run "../../bin/my script.rb"
|
13
|
+
Then the "foo" directory should exist
|
@@ -0,0 +1,43 @@
|
|
1
|
+
Feature: Prompt the user for information with My scripts
|
2
|
+
|
3
|
+
As a user of the My gem
|
4
|
+
I want to optionally run tasks
|
5
|
+
So that I can be explicit
|
6
|
+
|
7
|
+
Scenario: Accepting a prompt
|
8
|
+
Given a file named "yes.txt.template" with:
|
9
|
+
"""
|
10
|
+
The user picked yes
|
11
|
+
"""
|
12
|
+
And a file named "script.rb" with:
|
13
|
+
"""
|
14
|
+
ask "Would you like to add a file?"
|
15
|
+
yes do
|
16
|
+
file "yes.txt" => "yes.txt.template"
|
17
|
+
end
|
18
|
+
"""
|
19
|
+
When I run "../../bin/my script.rb" interactively
|
20
|
+
Then the program should prompt "Would you like to add a file? [y/N]"
|
21
|
+
|
22
|
+
When I type "y"
|
23
|
+
And the program completes
|
24
|
+
Then the file "yes.txt" should contain "The user picked yes"
|
25
|
+
|
26
|
+
Scenario: Declining a prompt
|
27
|
+
Given a file named "no.txt.template" with:
|
28
|
+
"""
|
29
|
+
The user picked no
|
30
|
+
"""
|
31
|
+
And a file named "script.rb" with:
|
32
|
+
"""
|
33
|
+
ask "Would you like to add a file?"
|
34
|
+
no do
|
35
|
+
file "no.txt" => "no.txt.template"
|
36
|
+
end
|
37
|
+
"""
|
38
|
+
When I run "../../bin/my script.rb" interactively
|
39
|
+
Then the program should prompt "Would you like to add a file? [y/N]"
|
40
|
+
|
41
|
+
When I type "n"
|
42
|
+
And the program completes
|
43
|
+
Then the file "no.txt" should contain "The user picked no"
|
@@ -0,0 +1,72 @@
|
|
1
|
+
Feature: Ensuring README examples
|
2
|
+
|
3
|
+
As a My project maintainer
|
4
|
+
I want to ensure my Sinatra example works
|
5
|
+
So I that I avoid humiliation
|
6
|
+
|
7
|
+
Background:
|
8
|
+
Given a file named "script.rb" with:
|
9
|
+
"""
|
10
|
+
# Sinatra My Script
|
11
|
+
|
12
|
+
file "app.rb" => "http://pastie.org/944315.txt"
|
13
|
+
file "config.ru" => "http://pastie.org/994640.txt"
|
14
|
+
|
15
|
+
ask "Will you be using external views?"
|
16
|
+
yes do
|
17
|
+
folder "views"
|
18
|
+
file "views/index.html" => "http://pastie.org/944311.txt"
|
19
|
+
end
|
20
|
+
|
21
|
+
ask "Will you be using an external stylesheet?"
|
22
|
+
yes do
|
23
|
+
folder "views"
|
24
|
+
file "views/style.sass" => "http://pastie.org/944313.txt"
|
25
|
+
end
|
26
|
+
"""
|
27
|
+
|
28
|
+
Scenario: Answering yes and yes
|
29
|
+
When I run "../../bin/my script.rb" interactively
|
30
|
+
And I type "y"
|
31
|
+
And I type "y"
|
32
|
+
And the program completes
|
33
|
+
Then the following files should exist:
|
34
|
+
| app.rb |
|
35
|
+
| config.ru |
|
36
|
+
| views/index.html |
|
37
|
+
| views/style.sass |
|
38
|
+
|
39
|
+
Scenario: Answering yes and no
|
40
|
+
When I run "../../bin/my script.rb" interactively
|
41
|
+
And I type "y"
|
42
|
+
And I type "n"
|
43
|
+
And the program completes
|
44
|
+
Then the following files should exist:
|
45
|
+
| app.rb |
|
46
|
+
| config.ru |
|
47
|
+
| views/index.html |
|
48
|
+
And the following files should not exist:
|
49
|
+
| views/style.sass |
|
50
|
+
|
51
|
+
Scenario: Answering no and yes
|
52
|
+
When I run "../../bin/my script.rb" interactively
|
53
|
+
And I type "n"
|
54
|
+
And I type "y"
|
55
|
+
And the program completes
|
56
|
+
Then the following files should exist:
|
57
|
+
| app.rb |
|
58
|
+
| config.ru |
|
59
|
+
| views/style.sass |
|
60
|
+
And the following files should not exist:
|
61
|
+
| views/index.html |
|
62
|
+
|
63
|
+
Scenario: Answering no and no
|
64
|
+
When I run "../../bin/my script.rb" interactively
|
65
|
+
And I type "n"
|
66
|
+
And I type "n"
|
67
|
+
And the program completes
|
68
|
+
Then the following files should exist:
|
69
|
+
| app.rb |
|
70
|
+
| config.ru |
|
71
|
+
And the following folders should not exist:
|
72
|
+
| views |
|
@@ -0,0 +1,8 @@
|
|
1
|
+
Before do
|
2
|
+
FileUtils.mv("~/.my_scripts","~/.my_scripts_backup") if File.exist? "~/.my_scripts"
|
3
|
+
File.open(File.expand_path("~/.my_scripts"),"w"){|f|f.write({}.to_yaml)}
|
4
|
+
end
|
5
|
+
|
6
|
+
After do
|
7
|
+
FileUtils.mv("~/.my_scripts_backup","~/.my_scripts") if File.exist? "~/.my_scripts_backup"
|
8
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
@interactive_history = []
|
4
|
+
|
5
|
+
def run_interactive_program
|
6
|
+
old_dir = Dir.pwd
|
7
|
+
Dir.chdir("tmp/aruba") unless Dir.pwd.split('/')[-1] == "aruba"
|
8
|
+
@stdin, @stdout, @stderr = Open3.popen3(@interactive_prog)
|
9
|
+
@interactive_history.each do |input|
|
10
|
+
@stdin.puts input
|
11
|
+
end
|
12
|
+
@output = ""
|
13
|
+
begin
|
14
|
+
loop do
|
15
|
+
Timeout::timeout(1) do
|
16
|
+
@output << @stdout.readpartial(1)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
rescue Timeout::Error
|
20
|
+
rescue EOFError
|
21
|
+
end
|
22
|
+
Dir.chdir(old_dir)
|
23
|
+
end
|
24
|
+
|
25
|
+
When /^I run "([^\"]*)" interactively$/ do |arg1|
|
26
|
+
@interactive_prog = arg1
|
27
|
+
@interactive_history = []
|
28
|
+
end
|
29
|
+
|
30
|
+
Then /^the program should prompt "([^\"]*)"$/ do |arg1|
|
31
|
+
run_interactive_program
|
32
|
+
@output.should include(arg1)
|
33
|
+
end
|
34
|
+
|
35
|
+
When /^I type "([^\"]*)"/ do |arg1|
|
36
|
+
@interactive_history << arg1
|
37
|
+
end
|
38
|
+
|
39
|
+
When /^the program completes$/ do
|
40
|
+
run_interactive_program
|
41
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
Then /^I debug$/ do
|
2
|
+
end
|
3
|
+
|
4
|
+
Given /^there are no scripts installed$/ do
|
5
|
+
File.open(My::Config.scripts,"w"){|f|f.write({}.to_yaml)}
|
6
|
+
end
|
7
|
+
|
8
|
+
Given /^there is a "([^\"]*)" script installed$/ do |arg1|
|
9
|
+
scripts = {}
|
10
|
+
scripts[arg1] = {:url => "http://pastie.org/944311.txt"}
|
11
|
+
File.open(My::Config.scripts,"w"){|f|f.write(scripts.to_yaml)}
|
12
|
+
end
|
13
|
+
|
14
|
+
Then /^the "([^\"]*)" directory should exist$/ do |arg1|
|
15
|
+
File.directory?("tmp/aruba/#{arg1}").should be_true
|
16
|
+
end
|
17
|
+
|
18
|
+
Then /^the following folders should (not )?exist:$/ do |negation,table|
|
19
|
+
table.raw.flatten.each do |folder|
|
20
|
+
File.exist?(folder).should == !negation
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: Help
|
2
|
+
As a user of the My gem
|
3
|
+
I want to view the usage information
|
4
|
+
So I can use the gem effectively
|
5
|
+
|
6
|
+
Scenario: Viewing the usage information implicitly
|
7
|
+
Given there are no scripts installed
|
8
|
+
And I run "../../bin/my"
|
9
|
+
Then I should see "My"
|
10
|
+
And I should see "USAGE: my [NAME|URL]"
|
11
|
+
And I should see "Additional commands:"
|
12
|
+
And I should see "Registered scripts:"
|
13
|
+
|
14
|
+
Scenario: Viewing the usage information explicitly
|
15
|
+
Given there are no scripts installed
|
16
|
+
And I run "../../bin/my help"
|
17
|
+
Then I should see "My v."
|
18
|
+
And I should see "USAGE: my [NAME|URL]"
|
19
|
+
And I should see "Additional commands:"
|
20
|
+
And I should see "Registered scripts:"
|
data/lib/my.rb
ADDED
data/lib/my/config.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Author:: Kevin W. Gisi (mailto:kevin@kevingisi.com)
|
2
|
+
# Copyright:: Copyright (c) 2010 Kevin W. Gisi
|
3
|
+
# License:: Distributed under the MIT License
|
4
|
+
|
5
|
+
module My
|
6
|
+
# My::Config is the wrapper around all configurable options
|
7
|
+
# within the My gem. It tracks the version of the My gem,
|
8
|
+
# the environment in which My has been run, and the
|
9
|
+
# location of the My script registry.
|
10
|
+
module Config
|
11
|
+
extend self
|
12
|
+
|
13
|
+
@version = File.read(File.dirname(__FILE__)+"/../../VERSION").chomp
|
14
|
+
|
15
|
+
attr_accessor :environment,:version
|
16
|
+
|
17
|
+
# Returns the location of the My script registry,
|
18
|
+
# depending on the current environment.
|
19
|
+
#
|
20
|
+
# My::Config.environment = 'production'
|
21
|
+
# My::Config.scripts
|
22
|
+
# # => "/home/gisikw/.my_scripts"
|
23
|
+
#
|
24
|
+
# My::Config.environment = 'test'
|
25
|
+
# My::Config.scripts
|
26
|
+
# # => "/home/gisikw/.rvm/gems/ruby-1.8.7-p249/gems/my-0.3.0/test.yml"
|
27
|
+
def scripts
|
28
|
+
case self.environment||='production'
|
29
|
+
when /^production$/
|
30
|
+
return File.expand_path("~/.my_scripts")
|
31
|
+
when /^test$/
|
32
|
+
return File.expand_path(File.join(File.dirname(__FILE__),'../../test.yml'))
|
33
|
+
when /^cucumber$/
|
34
|
+
return File.expand_path(File.join(File.dirname(__FILE__),'../../test.yml'))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
data/lib/my/runner.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
# Author:: Kevin W. Gisi (mailto:kevin@kevingisi.com)
|
2
|
+
# Copyright:: Copyright (c) 2010 Kevin W. Gisi
|
3
|
+
# License:: Distributed under the MIT License
|
4
|
+
|
5
|
+
module My
|
6
|
+
# The My::Runner module is called directly whenever the My binary is run.
|
7
|
+
# It handles basic tasks like adding and removing script aliases
|
8
|
+
# and delegating what gets run.
|
9
|
+
module Runner
|
10
|
+
extend self
|
11
|
+
|
12
|
+
# Registers an alias to a script URL or file path, specified
|
13
|
+
# by <em>args[0]</em> as an alias name, and <em>args[1]</em>
|
14
|
+
# as a path.
|
15
|
+
#
|
16
|
+
# My::Runner.add(['google','http://www.google.com'])
|
17
|
+
def add(args)
|
18
|
+
scripts = YAML::load(File.read(My::Config.scripts))
|
19
|
+
unless scripts[args[0]]
|
20
|
+
scripts[args[0]] = {:url => args[1]}
|
21
|
+
File.open(My::Config.scripts,'w'){|f|f.write(scripts.to_yaml)}
|
22
|
+
puts "The #{args[0]} script has been registered"
|
23
|
+
else
|
24
|
+
puts "The #{args[0]} script is already registered. Please remove it first."
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Removes a registered script alias, specified by
|
29
|
+
# <em>args[0]</em> as the alias name.
|
30
|
+
#
|
31
|
+
# My::Runner.rm(['google'])
|
32
|
+
def rm(args)
|
33
|
+
scripts = YAML::load(File.read(My::Config.scripts))
|
34
|
+
if scripts[args[0]]
|
35
|
+
scripts.delete(args[0])
|
36
|
+
File.open(My::Config.scripts,'w'){|f|f.write(scripts.to_yaml)}
|
37
|
+
puts "The #{args[0]} script has been removed"
|
38
|
+
else
|
39
|
+
puts "No #{args[0]} script has been registered"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Displays the My version information and basic usage
|
44
|
+
# information, along with a list of registered script
|
45
|
+
# aliases.
|
46
|
+
#
|
47
|
+
# My::Runner.help
|
48
|
+
#
|
49
|
+
# <em>produces (for example):</em>
|
50
|
+
#
|
51
|
+
# My v.0.3.0
|
52
|
+
# USAGE: my [NAME|URL]
|
53
|
+
#
|
54
|
+
# Additional commands:
|
55
|
+
# my add NAME URL # Add NAME as an alias to a script at URL
|
56
|
+
# my rm NAME # Remove the NAME alias
|
57
|
+
#
|
58
|
+
# Registered scripts:
|
59
|
+
# sinatra
|
60
|
+
# rails
|
61
|
+
# gem
|
62
|
+
def help
|
63
|
+
puts <<-END
|
64
|
+
My v.#{My::Config.version}
|
65
|
+
USAGE: my [NAME|URL]
|
66
|
+
|
67
|
+
Additional commands:
|
68
|
+
my add NAME URL # Add NAME as an alias to a script at URL
|
69
|
+
my rm NAME # Remove the NAME alias
|
70
|
+
|
71
|
+
Registered scripts:
|
72
|
+
END
|
73
|
+
|
74
|
+
YAML::load(File.read(My::Config.scripts)).each do |name,params|
|
75
|
+
puts "#{name.ljust(30)}#{params[:description]}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Runs an appropriate task based on the <em>command</em>
|
80
|
+
# argument passed. In order, execute will try to:
|
81
|
+
# * Run My::Runner#<em>command</em>
|
82
|
+
# * Run a registered script, whose alias is <em>command</em>
|
83
|
+
# * Run a script located at <em>command</em>
|
84
|
+
# * Run My::Runner#help
|
85
|
+
#
|
86
|
+
# My::Runner.execute('add',['google','http://www.google.com'])
|
87
|
+
# # Executes My::Runner.add(['google','http://www.google.com'])
|
88
|
+
#
|
89
|
+
# My::Runner.execute('google')
|
90
|
+
# # Executes a registered script named 'google'
|
91
|
+
#
|
92
|
+
# My::Runner.execute('http://www.google.com')
|
93
|
+
# # Executes a script located at 'http://www.google.com'
|
94
|
+
#
|
95
|
+
# My::Runner.execute('flibbitijibbet')
|
96
|
+
# # Executes My::Runner.help
|
97
|
+
def execute(command=nil,args=[])
|
98
|
+
if command
|
99
|
+
if respond_to?(command)
|
100
|
+
begin
|
101
|
+
self.send(command,args)
|
102
|
+
rescue
|
103
|
+
self.send(command)
|
104
|
+
end
|
105
|
+
elsif (scripts=YAML::load(File.read(My::Config.scripts))).keys.include?(command)
|
106
|
+
My::Script.new(open(scripts[command][:url]).read).run
|
107
|
+
else
|
108
|
+
begin
|
109
|
+
script = open(command)
|
110
|
+
rescue
|
111
|
+
help
|
112
|
+
end
|
113
|
+
My::Script.new(script.read).run if script
|
114
|
+
end
|
115
|
+
else
|
116
|
+
help
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
data/lib/my/script.rb
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
# Author:: Kevin W. Gisi (mailto:kevin@kevingisi.com)
|
2
|
+
# Copyright:: Copyright (c) 2010 Kevin W. Gisi
|
3
|
+
# License:: Distributed under the MIT License
|
4
|
+
|
5
|
+
module My
|
6
|
+
# The My::Script class acts as a wrapper around
|
7
|
+
# the My script DSL. A My::Script instance is created
|
8
|
+
# with a string or a Proc argument, which is instantly
|
9
|
+
# evaluated, converting the standard script syntax:
|
10
|
+
#
|
11
|
+
# file "app.rb" => "http://pastie.org/994577.txt"
|
12
|
+
# folder "views"
|
13
|
+
# folder "lib"
|
14
|
+
#
|
15
|
+
# To a My::Script instance with a registered queue of
|
16
|
+
# files and folders to be created when run.
|
17
|
+
class Script
|
18
|
+
|
19
|
+
# Creates a new Script and calls <code>instance_eval</code>
|
20
|
+
# on the <em>script</em> argument, either as a string or
|
21
|
+
# as a Proc.
|
22
|
+
#
|
23
|
+
# My::Script.new("file 'app.rb' => 'http://pastie.org/994577.txt'")
|
24
|
+
# # => #<My::Script:0x7fc5aef84398 @folders=[], @files=[{:proc=>nil, :to=>"app.rb", :from=>"http://pastie.org/994577.txt"}], @questions=[]>
|
25
|
+
#
|
26
|
+
# My::Script.new(Proc.new{file "app.rb" => "http://pastie.org/994577.txt"})
|
27
|
+
# # => #<My::Script:0x7fc5aef84398 @folders=[], @files=[{:proc=>nil, :to=>"app.rb", :from=>"http://pastie.org/994577.txt"}], @questions=[]>
|
28
|
+
def initialize(script)
|
29
|
+
@files = []
|
30
|
+
@folders = []
|
31
|
+
@questions = []
|
32
|
+
if script.class == Proc
|
33
|
+
instance_eval &script
|
34
|
+
else
|
35
|
+
instance_eval script
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the binding for the Script object.
|
40
|
+
#
|
41
|
+
# s = My::Script.new('')
|
42
|
+
# s.get_binding
|
43
|
+
# # => #<Binding:0x7fc5aef7fc80>
|
44
|
+
def get_binding
|
45
|
+
return binding
|
46
|
+
end
|
47
|
+
|
48
|
+
# Registers a file to be created, using the first key in
|
49
|
+
# the <em>args</em> hash as the <code>:to</code> attribute
|
50
|
+
# and the first value as the <code>:from</code> attribute.
|
51
|
+
# Optionally, a block can be passed to specify a context
|
52
|
+
# for populating variables, if the file specified is an
|
53
|
+
# ERB-templated file.
|
54
|
+
#
|
55
|
+
# s = My::Script.new('')
|
56
|
+
# s.file("app.rb" => "http://pastie.org/994577.txt")
|
57
|
+
#
|
58
|
+
# s = My::Script.new('')
|
59
|
+
# s.file("app.rb" => "http://pastie.org/994577.txt") do
|
60
|
+
# @app_name = "AwesomeApp"
|
61
|
+
# end
|
62
|
+
def file(args,&block)
|
63
|
+
@files << {:from => args.values[0], :to => args.keys[0], :proc => block}
|
64
|
+
end
|
65
|
+
|
66
|
+
# Registers a folder to be created, using the <em>name</em>
|
67
|
+
# as the path to the folder.
|
68
|
+
#
|
69
|
+
# s = My::Script.new('')
|
70
|
+
# s.folder "views"
|
71
|
+
#
|
72
|
+
# s = My::Script.new('')
|
73
|
+
# s.folder "/home/gisikw/.vim"
|
74
|
+
def folder(name)
|
75
|
+
@folders << name
|
76
|
+
end
|
77
|
+
|
78
|
+
# Registers a new question, with the <em>query</em>
|
79
|
+
# parameter as the prompt for the user.
|
80
|
+
#
|
81
|
+
# s = My::Script.new('')
|
82
|
+
# s.ask("Would you like to use HAML instead of ERB?")
|
83
|
+
def ask(query)
|
84
|
+
@questions << {:query => query}
|
85
|
+
end
|
86
|
+
|
87
|
+
# Registers a Proc to be used with the most recent
|
88
|
+
# question, should the user respond affirmatively.
|
89
|
+
# The block passed in will be evaluated in the context
|
90
|
+
# of an empty script, and so can make use of any My::Script
|
91
|
+
# functionality.
|
92
|
+
#
|
93
|
+
# s = My::Script.new('')
|
94
|
+
# s.ask("Would you like to use HAML instead of ERB?")
|
95
|
+
# s.yes do
|
96
|
+
# file "views/index.haml" => "http://pastie.org/994577.txt"
|
97
|
+
# end
|
98
|
+
def yes(&block)
|
99
|
+
unless @questions.empty?
|
100
|
+
@questions.last[:yes] = block
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Registers a Proc to be used with the most recent
|
105
|
+
# question, should the user respond negatively.
|
106
|
+
# The block passed in will be evaluated in the context
|
107
|
+
# of an empty script, and so can make use of any My::Script
|
108
|
+
# functionality.
|
109
|
+
#
|
110
|
+
# s = My::Script.new('')
|
111
|
+
# s.ask("Would you like to use HAML instead of ERB?")
|
112
|
+
# s.no do
|
113
|
+
# file "views/index.erb" => "http://pastie.org/994577.txt"
|
114
|
+
# end
|
115
|
+
def no(&block)
|
116
|
+
unless @questions.empty?
|
117
|
+
@questions.last[:no] = block
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# The run command does several tasks in executing the script
|
122
|
+
# in the following order:
|
123
|
+
# * Create all registered folders
|
124
|
+
# * Create all registered files, evaluating them with ERB if a block was passed
|
125
|
+
# * Ask all questions, spawning and executing a new script, using a Proc that corresponds to the user's answer.
|
126
|
+
#
|
127
|
+
# s = Script.new %Q{
|
128
|
+
# ask "Are you sure you would like to apply this script?"
|
129
|
+
# yes do
|
130
|
+
# file "app.rb" => "http://pastie.org/994577.txt"
|
131
|
+
# folder "lib"
|
132
|
+
# folder "views"
|
133
|
+
# ask "Would you like to use HAML instead of ERB?"
|
134
|
+
# yes do
|
135
|
+
# file => "views/index.haml" => "http://pastie.org/994577.txt"
|
136
|
+
# end
|
137
|
+
# no do
|
138
|
+
# file => "views/index.erb" => "http://pastie.org/994577.txt"
|
139
|
+
# end
|
140
|
+
# end
|
141
|
+
# }
|
142
|
+
# s.run
|
143
|
+
#
|
144
|
+
# <em>produces:</em>
|
145
|
+
#
|
146
|
+
# Are you sure you would like to apply this script? [y/N]
|
147
|
+
# # The user types "y\n"
|
148
|
+
# Would you like to use HAML instead of ERB?
|
149
|
+
# # The user types "n\n"
|
150
|
+
#
|
151
|
+
# # folders ["lib","views"] have been created
|
152
|
+
# # files ["app.rb","views/index.erb"] have been created
|
153
|
+
def run
|
154
|
+
@folders.each do |folder|
|
155
|
+
FileUtils.mkdir_p(folder)
|
156
|
+
end
|
157
|
+
@files.each do |file|
|
158
|
+
$stdout.puts "Writing file!"
|
159
|
+
FileUtils.mkdir_p(File.dirname(file[:to]))
|
160
|
+
if file[:proc]
|
161
|
+
open(file[:to],'w').write(ERB.new(open(file[:from]).read).result(My::Script.new(file[:proc]).get_binding))
|
162
|
+
else
|
163
|
+
open(file[:to],'w').write(open(file[:from]).read)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
@questions.each do |question|
|
167
|
+
$stdout.print "#{question[:query]} [y/N] "
|
168
|
+
if $stdin.gets.chomp.downcase =~ /^y(?:es)?$/
|
169
|
+
My::Script.new(question[:yes]||Proc.new{}).run
|
170
|
+
else
|
171
|
+
My::Script.new(question[:no]||Proc.new{}).run
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
end
|
data/my.gemspec
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{my}
|
5
|
+
s.version = "0.3.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Kevin W. Gisi"]
|
9
|
+
s.date = %q{2010-06-07}
|
10
|
+
s.default_executable = %q{my}
|
11
|
+
s.description = %q{Ruby template and configuration manager}
|
12
|
+
s.email = %q{kevin@kevingisi.com}
|
13
|
+
s.executables = ["my"]
|
14
|
+
s.extra_rdoc_files = ["LICENSE", "README.rdoc", "bin/my", "lib/my.rb", "lib/my/config.rb", "lib/my/runner.rb", "lib/my/script.rb"]
|
15
|
+
s.files = ["LICENSE", "README.rdoc", "Rakefile", "VERSION", "bin/my", "features/advanced.feature", "features/aliases.feature", "features/files.feature", "features/folder.feature", "features/questions.feature", "features/sinatra.feature", "features/support/env.rb", "features/support/hooks.rb", "features/support/interactive_steps.rb", "features/support/steps.rb", "features/usage.feature", "lib/my.rb", "lib/my/config.rb", "lib/my/runner.rb", "lib/my/script.rb", "spec/config_spec.rb", "spec/runner_spec.rb", "spec/script_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "Manifest", "my.gemspec"]
|
16
|
+
s.homepage = %q{http://gisikw.github.com/my}
|
17
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "My", "--main", "README.rdoc"]
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
s.rubyforge_project = %q{my}
|
20
|
+
s.rubygems_version = %q{1.3.6}
|
21
|
+
s.summary = %q{Ruby template and configuration manager}
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
25
|
+
s.specification_version = 3
|
26
|
+
|
27
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
28
|
+
s.add_development_dependency(%q<cucumber>, [">= 0.7.2"])
|
29
|
+
s.add_development_dependency(%q<aruba>, [">= 0.1.9"])
|
30
|
+
s.add_development_dependency(%q<rspec>, [">= 1.3.0"])
|
31
|
+
else
|
32
|
+
s.add_dependency(%q<cucumber>, [">= 0.7.2"])
|
33
|
+
s.add_dependency(%q<aruba>, [">= 0.1.9"])
|
34
|
+
s.add_dependency(%q<rspec>, [">= 1.3.0"])
|
35
|
+
end
|
36
|
+
else
|
37
|
+
s.add_dependency(%q<cucumber>, [">= 0.7.2"])
|
38
|
+
s.add_dependency(%q<aruba>, [">= 0.1.9"])
|
39
|
+
s.add_dependency(%q<rspec>, [">= 1.3.0"])
|
40
|
+
end
|
41
|
+
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe My::Config do
|
4
|
+
describe "scripts" do
|
5
|
+
describe "in the production environment" do
|
6
|
+
it "should return the .my_scripts file" do
|
7
|
+
My::Config.stubs(:environment).returns("production")
|
8
|
+
My::Config.scripts.should == File.expand_path("~/.my_scripts")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
describe "in the test environment" do
|
12
|
+
it "should return the test.yml file" do
|
13
|
+
My::Config.stubs(:environment).returns("test")
|
14
|
+
My::Config.scripts.should == File.expand_path("test.yml")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
describe "in the cucumber environment" do
|
18
|
+
it "should return the test.yml file" do
|
19
|
+
My::Config.stubs(:environment).returns("cucumber")
|
20
|
+
My::Config.scripts.should == File.expand_path("test.yml")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "version" do
|
26
|
+
it "should return the version in the VERSION file" do
|
27
|
+
My::Config.version.should == File.read("VERSION").chomp
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/spec/runner_spec.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe My::Runner do
|
4
|
+
describe "#add" do
|
5
|
+
describe "when the script name does not exist" do
|
6
|
+
it "adds an entry to the script registry" do
|
7
|
+
scripts = YAML::load(File.read(My::Config.scripts))
|
8
|
+
My::Runner.add(["google","http://google.com"])
|
9
|
+
(YAML::load(File.read(My::Config.scripts)).keys.size-scripts.keys.size).should == 1
|
10
|
+
end
|
11
|
+
it "informs the user the script has been registered" do
|
12
|
+
My::Runner.add(["google","http://google.com"])
|
13
|
+
@stdout.string.should =~ /The google script has been registered/
|
14
|
+
end
|
15
|
+
end
|
16
|
+
describe "when the script name does exist" do
|
17
|
+
before :each do
|
18
|
+
My::Runner.add(["google","http://google.com"])
|
19
|
+
end
|
20
|
+
it "does not overwrite the existing entry" do
|
21
|
+
scripts = File.read(My::Config.scripts)
|
22
|
+
My::Runner.add(["google","https://google.com"])
|
23
|
+
File.read(My::Config.scripts).should == scripts
|
24
|
+
end
|
25
|
+
it "prompts the user to remove the original script" do
|
26
|
+
My::Runner.add(["google","https://google.com"])
|
27
|
+
@stdout.string.should =~ /The google script is already registered\. Please remove it first\./
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#rm" do
|
33
|
+
describe "when the script has been registered" do
|
34
|
+
before :each do
|
35
|
+
My::Runner.add(["google","http://google.com"])
|
36
|
+
end
|
37
|
+
it "removes an entry from the script registry" do
|
38
|
+
scripts = YAML::load(File.read(My::Config.scripts))
|
39
|
+
scripts.size.should == 1
|
40
|
+
My::Runner.rm(["google"])
|
41
|
+
YAML::load(File.read(My::Config.scripts)).size.should == 0
|
42
|
+
(YAML::load(File.read(My::Config.scripts)).keys.size-scripts.keys.size).should == -1
|
43
|
+
end
|
44
|
+
end
|
45
|
+
describe "when the script has not been registered" do
|
46
|
+
it "does not modify the script registry" do
|
47
|
+
scripts = File.read(My::Config.scripts)
|
48
|
+
My::Runner.rm(["google"])
|
49
|
+
File.read(My::Config.scripts).should == scripts
|
50
|
+
end
|
51
|
+
it "informs the user no script exists" do
|
52
|
+
My::Runner.rm(["google"])
|
53
|
+
@stdout.string.should =~ /No google script has been registered/
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#help" do
|
59
|
+
it "parses the script registry" do
|
60
|
+
YAML.expects(:load).with(File.read(My::Config.scripts)).returns({})
|
61
|
+
My::Runner.help
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#execute" do
|
66
|
+
describe "when a command is passed" do
|
67
|
+
describe "and the method exists" do
|
68
|
+
it "runs the method" do
|
69
|
+
My::Runner.expects(:add)
|
70
|
+
My::Runner.execute "add"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
describe "and the method does not exist" do
|
74
|
+
describe "and the command is a registered script name" do
|
75
|
+
it "runs the registered script" do
|
76
|
+
File.open("sample_script.rb","w"){|f|f.write("blah")}
|
77
|
+
My::Runner.add(["google","sample_script.rb"])
|
78
|
+
fake_script = My::Script.new ''
|
79
|
+
My::Script.expects(:new).with('blah').returns fake_script
|
80
|
+
My::Runner.execute "google"
|
81
|
+
FileUtils.rm_rf "sample_script.rb"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
describe "and the command is not a registered script name" do
|
85
|
+
describe "and the command is a valid script location" do
|
86
|
+
it "creates a new script" do
|
87
|
+
File.open("temp_script.rb","w"){|f|f.write("blah")}
|
88
|
+
fake_script = My::Script.new ''
|
89
|
+
My::Script.expects(:new).returns(fake_script)
|
90
|
+
My::Runner.execute "temp_script.rb"
|
91
|
+
FileUtils.rm_rf "temp_script.rb"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
describe "and the command is not a valid script location" do
|
95
|
+
it "calls the help method" do
|
96
|
+
My::Runner.expects(:help)
|
97
|
+
My::Runner.execute "feajhfaejf"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
describe "when no command is passed" do
|
104
|
+
it "calls the help method" do
|
105
|
+
My::Runner.expects(:help)
|
106
|
+
My::Runner.execute
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
data/spec/script_spec.rb
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe My::Script do
|
4
|
+
|
5
|
+
describe "initializer" do
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "#instance" do
|
10
|
+
|
11
|
+
before do
|
12
|
+
FileUtils.mkdir_p("tmp")
|
13
|
+
File.open("tmp/sample.template","w"){|f|f.write("This is a sample file")}
|
14
|
+
end
|
15
|
+
|
16
|
+
after do
|
17
|
+
FileUtils.rm_rf("tmp")
|
18
|
+
end
|
19
|
+
|
20
|
+
before :each do
|
21
|
+
@script = My::Script.new("")
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#file" do
|
25
|
+
it "adds to the list of files" do
|
26
|
+
count = @script.instance_eval("@files").size
|
27
|
+
@script.file("test.txt" => "tmp/sample.template")
|
28
|
+
@script.instance_eval("@files").size.should == count+1
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#folder" do
|
33
|
+
it "adds to the list of folders" do
|
34
|
+
count = @script.instance_eval("@folders").size
|
35
|
+
@script.folder("temp")
|
36
|
+
@script.instance_eval("@folders").size.should == count+1
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#ask" do
|
41
|
+
it "adds to the list of questions" do
|
42
|
+
count = @script.instance_eval("@questions").size
|
43
|
+
@script.ask("Do you want fries with that?")
|
44
|
+
@script.instance_eval("@questions").size.should == count+1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#yes" do
|
49
|
+
describe "when a question has been added" do
|
50
|
+
before :each do
|
51
|
+
@script.ask("Do you want fries with that?")
|
52
|
+
end
|
53
|
+
it "attaches to the most recent question" do
|
54
|
+
@script.yes do
|
55
|
+
puts "hey"
|
56
|
+
end
|
57
|
+
@script.instance_eval("@questions").last[:yes].should_not be_nil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
describe "when no question has been added" do
|
61
|
+
it "does not add to the questions" do
|
62
|
+
@script.yes do
|
63
|
+
puts "hey"
|
64
|
+
end
|
65
|
+
@script.instance_eval("@questions").should be_empty
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#no" do
|
71
|
+
describe "when a question has been added" do
|
72
|
+
before :each do
|
73
|
+
@script.ask("Do you want fries with that?")
|
74
|
+
end
|
75
|
+
it "attaches to the most recent question" do
|
76
|
+
@script.no do
|
77
|
+
puts "hey"
|
78
|
+
end
|
79
|
+
@script.instance_eval("@questions").last[:no].should_not be_nil
|
80
|
+
end
|
81
|
+
end
|
82
|
+
describe "when no question has been added" do
|
83
|
+
it "does not add to the questions" do
|
84
|
+
@script.no do
|
85
|
+
puts "hey"
|
86
|
+
end
|
87
|
+
@script.instance_eval("@questions").should be_empty
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#run" do
|
93
|
+
|
94
|
+
it "creates each folder in the folder list" do
|
95
|
+
@script.folder("temp_a")
|
96
|
+
@script.folder("temp_b")
|
97
|
+
@script.instance_eval("@folders").each do |folder|
|
98
|
+
FileUtils.expects(:mkdir_p).with(folder).at_least_once
|
99
|
+
end
|
100
|
+
@script.run
|
101
|
+
end
|
102
|
+
|
103
|
+
it "creates each file in the file list" do
|
104
|
+
@script.file "temp_a.txt" => "tmp/sample.template"
|
105
|
+
@script.file "temp_b.txt" => "tmp/sample.template"
|
106
|
+
@script.run
|
107
|
+
File.exist?("temp_a.txt").should be_true
|
108
|
+
File.exist?("temp_b.txt").should be_true
|
109
|
+
FileUtils.rm("temp_a.txt")
|
110
|
+
FileUtils.rm("temp_b.txt")
|
111
|
+
end
|
112
|
+
|
113
|
+
it "prompts the user for each question" do
|
114
|
+
@script.ask "Would you like fries with that?"
|
115
|
+
$stdin.expects(:gets).returns("y\n")
|
116
|
+
@script.run
|
117
|
+
@stdout.string.should =~ /Would you like fries with that\? \[y\/N\]/
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "when the user answers yes to a question" do
|
121
|
+
it "should create a script from the yes block" do
|
122
|
+
@script.ask "Would you like fries with that?"
|
123
|
+
@script.yes do
|
124
|
+
puts "hey"
|
125
|
+
end
|
126
|
+
dummy_script = My::Script.new ''
|
127
|
+
My::Script.expects(:new).with(@script.instance_eval('@questions').first[:yes]).returns(dummy_script)
|
128
|
+
$stdin.expects(:gets).returns("y\n")
|
129
|
+
@script.run
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "when the user answers no to a question" do
|
134
|
+
it "should create a script from the no block" do
|
135
|
+
@script.ask "Would you like fries with that?"
|
136
|
+
@script.no do
|
137
|
+
puts "hey"
|
138
|
+
end
|
139
|
+
dummy_script = My::Script.new ''
|
140
|
+
My::Script.expects(:new).with(@script.instance_eval('@questions').first[:no]).returns(dummy_script)
|
141
|
+
$stdin.expects(:gets).returns("n\n")
|
142
|
+
@script.run
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color --format nested
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__))
|
2
|
+
$:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
require 'spec'
|
5
|
+
require 'spec/autorun'
|
6
|
+
|
7
|
+
require 'my'
|
8
|
+
|
9
|
+
Spec::Runner.configure do |config|
|
10
|
+
config.mock_with :mocha
|
11
|
+
My::Config.environment = "test"
|
12
|
+
config.before :each do
|
13
|
+
File.open("test.yml","w"){|f|f.write({}.to_yaml)}
|
14
|
+
@orig_stdout = $stdout
|
15
|
+
@orig_stdin = $stdin
|
16
|
+
@stdin = StringIO.new
|
17
|
+
@stdout = StringIO.new
|
18
|
+
$stdin = @stdin
|
19
|
+
$stdout = @stdout
|
20
|
+
end
|
21
|
+
config.after :each do
|
22
|
+
FileUtils.rm_rf "test.yml"
|
23
|
+
$stdout = @orig_stdout
|
24
|
+
$stdin = @orig_stdin
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
metadata
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: my
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 3
|
8
|
+
- 0
|
9
|
+
version: 0.3.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Kevin W. Gisi
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-06-07 00:00:00 -05:00
|
18
|
+
default_executable: my
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: cucumber
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 7
|
30
|
+
- 2
|
31
|
+
version: 0.7.2
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: aruba
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
- 1
|
44
|
+
- 9
|
45
|
+
version: 0.1.9
|
46
|
+
type: :development
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rspec
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 1
|
57
|
+
- 3
|
58
|
+
- 0
|
59
|
+
version: 1.3.0
|
60
|
+
type: :development
|
61
|
+
version_requirements: *id003
|
62
|
+
description: Ruby template and configuration manager
|
63
|
+
email: kevin@kevingisi.com
|
64
|
+
executables:
|
65
|
+
- my
|
66
|
+
extensions: []
|
67
|
+
|
68
|
+
extra_rdoc_files:
|
69
|
+
- LICENSE
|
70
|
+
- README.rdoc
|
71
|
+
- bin/my
|
72
|
+
- lib/my.rb
|
73
|
+
- lib/my/config.rb
|
74
|
+
- lib/my/runner.rb
|
75
|
+
- lib/my/script.rb
|
76
|
+
files:
|
77
|
+
- LICENSE
|
78
|
+
- README.rdoc
|
79
|
+
- Rakefile
|
80
|
+
- VERSION
|
81
|
+
- bin/my
|
82
|
+
- features/advanced.feature
|
83
|
+
- features/aliases.feature
|
84
|
+
- features/files.feature
|
85
|
+
- features/folder.feature
|
86
|
+
- features/questions.feature
|
87
|
+
- features/sinatra.feature
|
88
|
+
- features/support/env.rb
|
89
|
+
- features/support/hooks.rb
|
90
|
+
- features/support/interactive_steps.rb
|
91
|
+
- features/support/steps.rb
|
92
|
+
- features/usage.feature
|
93
|
+
- lib/my.rb
|
94
|
+
- lib/my/config.rb
|
95
|
+
- lib/my/runner.rb
|
96
|
+
- lib/my/script.rb
|
97
|
+
- spec/config_spec.rb
|
98
|
+
- spec/runner_spec.rb
|
99
|
+
- spec/script_spec.rb
|
100
|
+
- spec/spec.opts
|
101
|
+
- spec/spec_helper.rb
|
102
|
+
- Manifest
|
103
|
+
- my.gemspec
|
104
|
+
has_rdoc: true
|
105
|
+
homepage: http://gisikw.github.com/my
|
106
|
+
licenses: []
|
107
|
+
|
108
|
+
post_install_message:
|
109
|
+
rdoc_options:
|
110
|
+
- --line-numbers
|
111
|
+
- --inline-source
|
112
|
+
- --title
|
113
|
+
- My
|
114
|
+
- --main
|
115
|
+
- README.rdoc
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
segments:
|
123
|
+
- 0
|
124
|
+
version: "0"
|
125
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
segments:
|
130
|
+
- 1
|
131
|
+
- 2
|
132
|
+
version: "1.2"
|
133
|
+
requirements: []
|
134
|
+
|
135
|
+
rubyforge_project: my
|
136
|
+
rubygems_version: 1.3.6
|
137
|
+
signing_key:
|
138
|
+
specification_version: 3
|
139
|
+
summary: Ruby template and configuration manager
|
140
|
+
test_files: []
|
141
|
+
|