do 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -1
- data/README.md +38 -25
- data/Rakefile +7 -10
- data/bin/doit +1 -25
- data/do.gemspec +0 -2
- data/lib/do/cli.rb +14 -0
- data/lib/do/commands.rb +71 -90
- data/lib/do/common.rb +47 -16
- data/lib/do/parser.rb +38 -0
- data/lib/do/server.rb +26 -19
- data/lib/do/tasks.rb +66 -0
- data/lib/do/utils.rb +30 -7
- data/lib/do/version.rb +1 -1
- data/lib/do.rb +6 -20
- data/spec/cli_spec.rb +22 -0
- data/spec/commands_spec.rb +157 -0
- data/spec/parser_spec.rb +76 -0
- data/spec/server_spec.rb +2 -4
- data/spec/spec_helper.rb +10 -9
- data/spec/tasks_spec.rb +154 -0
- data/spec/utils_spec.rb +36 -0
- metadata +25 -51
data/lib/do/tasks.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
module DO
|
2
|
+
module Tasks
|
3
|
+
class NotFound < StandardError; end
|
4
|
+
extend self
|
5
|
+
|
6
|
+
def tasks
|
7
|
+
@_tasks ||= []
|
8
|
+
end
|
9
|
+
|
10
|
+
def desc(*args)
|
11
|
+
@_desc = args.shift
|
12
|
+
end
|
13
|
+
|
14
|
+
def namespace(text, &block)
|
15
|
+
namespace_was, @_namespace = @_namespace, text.to_s
|
16
|
+
@_namespace = '%s:%s' % [namespace_was, @_namespace] if namespace_was && namespace_was != ''
|
17
|
+
block.call
|
18
|
+
ensure
|
19
|
+
@_namespace = namespace_was
|
20
|
+
end
|
21
|
+
|
22
|
+
def task(name, options={}, &block)
|
23
|
+
name, deps = name.is_a?(Hash) ? [name.keys[0], Array(name.values[0])] : [name, []]
|
24
|
+
tasks << options.merge({
|
25
|
+
:name => name.to_s,
|
26
|
+
:desc => @_desc.to_s,
|
27
|
+
:deps => deps,
|
28
|
+
:namespace => @_namespace.to_s,
|
29
|
+
:block => block,
|
30
|
+
:in => Array(options[:in])
|
31
|
+
})
|
32
|
+
tasks[-1]
|
33
|
+
ensure
|
34
|
+
@_desc = nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def task_run(*args)
|
38
|
+
args_was = args.dup
|
39
|
+
task = task_find(args.shift)
|
40
|
+
opts = DO::Parser.new(*args)
|
41
|
+
task[:deps].each { |d| task_run(*args.unshift(d).push('--dependency')) }
|
42
|
+
if task[:in].empty?
|
43
|
+
task[:block].arity == 1 ? task[:block].call(opts) : task[:block].call if task[:block]
|
44
|
+
else
|
45
|
+
task[:in] = send(task[:in][0]) if task[:in].size == 1 && method_defined?(task[:in][0])
|
46
|
+
task[:in].each do |d|
|
47
|
+
parent = task_find(d)
|
48
|
+
case parent[:block].arity
|
49
|
+
when 1 then parent[:block].call(task[:block])
|
50
|
+
when 2 then parent[:block].call(opts, task[:block])
|
51
|
+
else parent[:block].call
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
rescue NotFound => e
|
56
|
+
method_defined?(args_was[0]) ? send(args_was.shift) : raise(e)
|
57
|
+
end
|
58
|
+
alias :run_task :task_run
|
59
|
+
|
60
|
+
def task_find(name)
|
61
|
+
spaces = name.to_s.split(":")
|
62
|
+
task = spaces.pop
|
63
|
+
tasks.find { |t| t[:name] == task && t[:namespace] == spaces.join(":") } || raise(NotFound, 'Task with "%s" not found' % name)
|
64
|
+
end
|
65
|
+
end # Tasks
|
66
|
+
end # DO
|
data/lib/do/utils.rb
CHANGED
@@ -10,12 +10,12 @@ module DO
|
|
10
10
|
# end
|
11
11
|
#
|
12
12
|
def wait
|
13
|
-
|
14
|
-
|
13
|
+
log "\e[36mPress ENTER to continue...\e[0m"
|
14
|
+
$stdin.gets
|
15
15
|
end
|
16
16
|
|
17
17
|
##
|
18
|
-
# Ask question to your
|
18
|
+
# Ask question to your $stdin.
|
19
19
|
# This command is useful in conjunction with a CLI
|
20
20
|
#
|
21
21
|
# ==== Example
|
@@ -23,13 +23,17 @@ module DO
|
|
23
23
|
# new_pwd = ask "Tell me the new password of mysql"
|
24
24
|
# run "mysqladmin -u root -p password '#{new_pwd}', :input => old_pwd
|
25
25
|
#
|
26
|
-
def ask(
|
26
|
+
def ask(*args)
|
27
|
+
question = args[0]
|
28
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
27
29
|
result = ""
|
30
|
+
`stty -echo` if options[:silent]
|
28
31
|
loop do
|
29
32
|
log("\e[36m%s: \e[0m" % question, false)
|
30
|
-
result =
|
31
|
-
break if allow_blank || result != ""
|
33
|
+
result = $stdin.gets.chomp
|
34
|
+
break if options[:allow_blank] || result != ""
|
32
35
|
end
|
36
|
+
`stty echo` && log("\n", false) if options[:silent]
|
33
37
|
result
|
34
38
|
end
|
35
39
|
|
@@ -46,10 +50,29 @@ module DO
|
|
46
50
|
question += "?" if question[-1] != ??
|
47
51
|
loop do
|
48
52
|
log("\e[36m%s (y/n): \e[0m" % question, false)
|
49
|
-
result =
|
53
|
+
result = $stdin.gets.chomp
|
50
54
|
break if result =~ /y|yes|n|no/i
|
51
55
|
end
|
52
56
|
return result =~ /y|yes/i
|
53
57
|
end
|
58
|
+
|
59
|
+
##
|
60
|
+
# Print the text into logger buffer, if you want to change
|
61
|
+
# the stream edit the constant DO_LOGGER
|
62
|
+
#
|
63
|
+
def log(text, new_line=false)
|
64
|
+
text += "\n" if new_line && text[-1] != ?\n
|
65
|
+
DO_LOGGER.print text
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Execute a local command
|
70
|
+
#
|
71
|
+
def run(*cmds)
|
72
|
+
cmd = cmds.map(&:to_s).join(' ')
|
73
|
+
log DO_LOGGER_FORMAT % [:do, :local, cmd]
|
74
|
+
system cmd
|
75
|
+
end
|
76
|
+
alias :sh :run # keep old compatibility
|
54
77
|
end # Utils
|
55
78
|
end # DO
|
data/lib/do/version.rb
CHANGED
data/lib/do.rb
CHANGED
@@ -1,27 +1,13 @@
|
|
1
1
|
DO_PATH = ENV['DO_PATH'] ||= File.expand_path("~/.do") unless defined?(DO_PATH)
|
2
|
+
DO_LOGGER = $stdout unless defined?(DO_LOGGER)
|
3
|
+
DO_LOGGER_FORMAT = "\e[36m%s\e[33m@\e[31m%s \e[33m~ \e[35m#\e[0m %s" unless defined?(DO_LOGGER_FORMAT)
|
2
4
|
|
3
5
|
module DO
|
4
|
-
|
6
|
+
autoload :CLI, 'do/cli.rb'
|
5
7
|
autoload :Server, 'do/server.rb'
|
6
8
|
autoload :Utils, 'do/utils.rb'
|
9
|
+
autoload :Commands, 'do/commands.rb'
|
10
|
+
autoload :Tasks, 'do/tasks.rb'
|
11
|
+
autoload :Parser, 'do/parser.rb'
|
7
12
|
autoload :VERSION, 'do/version.rb'
|
8
|
-
|
9
|
-
extend self
|
10
|
-
|
11
|
-
##
|
12
|
-
# DO loads rakefiles in these locations:
|
13
|
-
#
|
14
|
-
# ~/do/dorc
|
15
|
-
# ~/do/*.rake
|
16
|
-
# ./Do
|
17
|
-
# ./Dofile
|
18
|
-
#
|
19
|
-
# DO_PATH, default is ~/do.
|
20
|
-
#
|
21
|
-
def recipes
|
22
|
-
@_recipes ||= (
|
23
|
-
%w[dorc *.rake].map { |f| Dir[File.join(DO_PATH, f)] }.flatten +
|
24
|
-
%w[./Do ./Dofile].map { |f| File.expand_path(f) }
|
25
|
-
).reject { |f| !File.exist?(f) }
|
26
|
-
end
|
27
13
|
end # DO
|
data/spec/cli_spec.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DO::CLI do
|
4
|
+
|
5
|
+
def cli; DO::CLI end
|
6
|
+
|
7
|
+
it 'should show help if args are empty' do
|
8
|
+
DO::CLI.start
|
9
|
+
logger.should match(/Usage/)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should show task list if task does not exist' do
|
13
|
+
DO::CLI.start
|
14
|
+
logger.should match(/list/)
|
15
|
+
logger.should match(/version/)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should run task' do
|
19
|
+
DO::CLI.start(:version)
|
20
|
+
logger.should match(DO::VERSION)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,157 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'do/commands.rb'
|
3
|
+
|
4
|
+
class Faker
|
5
|
+
extend DO::Commands
|
6
|
+
|
7
|
+
load_recipes
|
8
|
+
|
9
|
+
task :sample do
|
10
|
+
puts "I'm a fantastic sample"
|
11
|
+
end
|
12
|
+
|
13
|
+
def demos
|
14
|
+
@a=1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe DO::Commands do
|
19
|
+
|
20
|
+
def cmd; DO::Commands; end
|
21
|
+
|
22
|
+
before(:each){ cmd.tasks.clear; cmd.load_recipes; cmd.servers.clear }
|
23
|
+
before(:all) { FileUtils.rm_rf(DO_PATH) }
|
24
|
+
after(:all) { FileUtils.rm_rf(DO_PATH) }
|
25
|
+
|
26
|
+
it 'should set DO_PATH' do
|
27
|
+
DO_PATH.should == File.expand_path('../tmp', __FILE__)
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should have not an existent DO_PATH' do
|
31
|
+
File.exist?(DO_PATH).should be_false
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should have common tasks' do
|
35
|
+
Faker.tasks.size.should == 6
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should have not servers' do
|
39
|
+
cmd.servers.should be_empty
|
40
|
+
Faker.servers.should be_empty
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should create a new task' do
|
44
|
+
tasks_was = cmd.tasks.size
|
45
|
+
cmd.task(:nope) { }
|
46
|
+
cmd.tasks.size.should == tasks_was+1
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should have one server' do
|
50
|
+
cmd.server :srv1, 'srv1.domain.local', 'root'
|
51
|
+
cmd.servers.size.should == 1
|
52
|
+
Faker.servers.should be_empty
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should setup a new environment' do
|
56
|
+
cmd.task_run(:setup)
|
57
|
+
File.exist?(File.join(DO_PATH, 'dorc')).should be_true
|
58
|
+
logger.should match("Generated template, now you can add your config to:")
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should generate a correct template' do
|
62
|
+
dorc = File.read(File.join(DO_PATH, 'dorc'))
|
63
|
+
dorc.should match(/# Server definitions/)
|
64
|
+
dorc.should match(/# Here my plugins/)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should add a plugin' do
|
68
|
+
recipe = "https://raw.github.com/gist/1143314/4e1c504e4dfbd988c76e6e28a445d985df2644d0/sample.rake"
|
69
|
+
begin
|
70
|
+
stdout_was = STDERR.dup; STDERR.reopen('/dev/null')
|
71
|
+
cmd.task_run(:download, '--url=%s' % recipe)
|
72
|
+
expect { Faker.task_run(:download, '--url=%s' % recipe) }.to raise_error(SystemExit)
|
73
|
+
ensure
|
74
|
+
STDERR.reopen(stdout_was)
|
75
|
+
end
|
76
|
+
logger.should match(/already has plugin/)
|
77
|
+
dorc = File.read(File.join(DO_PATH, 'dorc'))
|
78
|
+
dorc.should match("plugin :sample, '%s'" % recipe)
|
79
|
+
dest = File.join(DO_PATH, 'sample.rake')
|
80
|
+
File.exist?(dest).should be_true
|
81
|
+
logger.should match("## Installing plugin sample")
|
82
|
+
cmd.run_task('sample')
|
83
|
+
logger.should match("Hey")
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should print unformatted logs' do
|
87
|
+
cmd.task :sample do
|
88
|
+
cmd.log 'standard log'
|
89
|
+
end
|
90
|
+
cmd.task_run :sample
|
91
|
+
logger.should match("standard log")
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should set correclty an option to the given value' do
|
95
|
+
cmd.set :foo, :bar
|
96
|
+
cmd.foo.should == :bar
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should show version number' do
|
100
|
+
cmd.run_task(:version)
|
101
|
+
logger.should match(DO::VERSION)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should show help' do
|
105
|
+
cmd.run_task(:help)
|
106
|
+
logger.should match(/Usage/)
|
107
|
+
end
|
108
|
+
|
109
|
+
context DO::Server do
|
110
|
+
|
111
|
+
it 'should create a basic server' do
|
112
|
+
cmd.server :sho0, 'sho0.lipsiasoft.biz', 'root', :keys => Dir['/Developer/keys/*.pem']
|
113
|
+
cmd.task :test, :in => :sho0 do
|
114
|
+
cmd.run('uname').should == 'Linux'
|
115
|
+
end
|
116
|
+
cmd.task_run(:test)
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should connect to two servers' do
|
120
|
+
cmd.server :sho0, 'sho0.lipsiasoft.biz', 'root', :keys => Dir['/Developer/keys/*.pem']
|
121
|
+
cmd.server :srv1, 'srv1.lipsiasoft.biz', 'root', :keys => Dir['/Developer/keys/*.pem']
|
122
|
+
cmd.task :connection, :in => [:srv1, :sho0] do
|
123
|
+
cmd.run('uname -a').should match(cmd.current_server.name.to_s)
|
124
|
+
end
|
125
|
+
cmd.task_run(:connection)
|
126
|
+
cmd.current_server.should be_nil
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should works with complex tasks' do
|
130
|
+
cmd.server :sho0, 'sho0.lipsiasoft.biz', 'root', :keys => Dir['/Developer/keys/*.pem']
|
131
|
+
cmd.server :srv1, 'srv1.lipsiasoft.biz', 'root', :keys => Dir['/Developer/keys/*.pem']
|
132
|
+
cmd.task :connection, :in => :remote do
|
133
|
+
cmd.run('uname -a').should match(cmd.current_server.name.to_s)
|
134
|
+
end
|
135
|
+
cmd.task_run(:connection)
|
136
|
+
cmd.current_server.should be_nil
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'should skip if --no-xx' do
|
140
|
+
cmd.server :sho0, 'sho0.lipsiasoft.biz', 'root', :keys => Dir['/Developer/keys/*.pem']
|
141
|
+
cmd.server :srv1, 'srv1.lipsiasoft.biz', 'root', :keys => Dir['/Developer/keys/*.pem']
|
142
|
+
cmd.task :hostname, :in => :remote do |options|
|
143
|
+
cmd.run('hostname').should match(/srv1/)
|
144
|
+
end
|
145
|
+
cmd.task_run(:hostname, '--no-sho0')
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should match one if --xx' do
|
149
|
+
cmd.server :sho0, 'sho0.lipsiasoft.biz', 'root', :keys => Dir['/Developer/keys/*.pem']
|
150
|
+
cmd.server :srv1, 'srv1.lipsiasoft.biz', 'root', :keys => Dir['/Developer/keys/*.pem']
|
151
|
+
cmd.task :hostname, :in => :remote do |options|
|
152
|
+
cmd.run('hostname').should match(/srv1/)
|
153
|
+
end
|
154
|
+
cmd.task_run(:hostname, '--srv1')
|
155
|
+
end
|
156
|
+
end # DO::Server
|
157
|
+
end # DO::Commands
|
data/spec/parser_spec.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DO::Parser do
|
4
|
+
|
5
|
+
it 'should parse --foo=bar' do
|
6
|
+
parsed = DO::Parser.new('--foo=bar')
|
7
|
+
parsed[:foo].should == 'bar'
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should parse -foo=bar' do
|
11
|
+
parsed = DO::Parser.new('-foo=bar')
|
12
|
+
parsed[:foo].should == 'bar'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should parse --foo-bar=hey' do
|
16
|
+
parsed = DO::Parser.new('--foo-bar=hey')
|
17
|
+
parsed[:'foo-bar'].should == 'hey'
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should parse -foo-bar=hey' do
|
21
|
+
parsed = DO::Parser.new('-foo-bar=hey')
|
22
|
+
parsed[:'foo-bar'].should == 'hey'
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should parse --foo bar' do
|
26
|
+
parsed = DO::Parser.new('--foo', 'bar')
|
27
|
+
parsed[:foo].should == 'bar'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should parse -foo bar' do
|
31
|
+
parsed = DO::Parser.new('-foo', 'bar')
|
32
|
+
parsed[:foo].should == 'bar'
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should parse --foo' do
|
36
|
+
parsed = DO::Parser.new('--foo')
|
37
|
+
parsed[:foo].should == true
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should parse -foo' do
|
41
|
+
parsed = DO::Parser.new('-foo')
|
42
|
+
parsed[:foo].should == true
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should parse --no-foo' do
|
46
|
+
parsed = DO::Parser.new('--no-foo')
|
47
|
+
parsed[:foo].should == false
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should parse -no-foo' do
|
51
|
+
parsed = DO::Parser.new('-no-foo')
|
52
|
+
parsed[:foo].should == false
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should parse int' do
|
56
|
+
parsed = DO::Parser.new('--foo=1')
|
57
|
+
parsed[:foo].should == 1
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should parse boolean' do
|
61
|
+
parsed = DO::Parser.new('--foo=true')
|
62
|
+
parsed[:foo].should == true
|
63
|
+
parsed = DO::Parser.new('--foo=false')
|
64
|
+
parsed[:foo].should == false
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should parse float' do
|
68
|
+
parsed = DO::Parser.new('--foo=100.99')
|
69
|
+
parsed[:foo].should == 100.99
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should parse array' do
|
73
|
+
parsed = DO::Parser.new('--foo=1,a,b,2')
|
74
|
+
parsed[:foo].should == ['1', 'a', 'b', '2']
|
75
|
+
end
|
76
|
+
end
|
data/spec/server_spec.rb
CHANGED
@@ -2,9 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe DO::Server do
|
4
4
|
before do
|
5
|
-
|
6
|
-
@server = DO::Server.new(:sho0, 'sho0.lipsiasoft.biz', 'ec2-user', :keys => keys)
|
7
|
-
@server.logger = StringIO.new
|
5
|
+
@server = DO::Server.new(:sho0, 'sho0.lipsiasoft.biz', 'ec2-user', :keys => Dir['/Developer/keys/*.pem'])
|
8
6
|
@fixture = File.expand_path('../fixtures/sample', __FILE__)
|
9
7
|
@fixture_was = File.read(@fixture)
|
10
8
|
end
|
@@ -14,7 +12,7 @@ describe DO::Server do
|
|
14
12
|
release.should match(/Linux/)
|
15
13
|
end
|
16
14
|
|
17
|
-
it 'should upload
|
15
|
+
it 'should upload something' do
|
18
16
|
@server.upload @fixture, '/tmp/sample'
|
19
17
|
@server.exist?('/tmp/sample').should be_true
|
20
18
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,19 +1,20 @@
|
|
1
1
|
require 'rubygems' unless defined?(Gem)
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
DO_PATH = File.expand_path('../tmp', __FILE__)
|
5
|
+
DO_LOGGER = StringIO.new
|
6
|
+
|
2
7
|
require 'bundler/setup'
|
3
8
|
require 'rspec'
|
4
9
|
require 'fileutils'
|
5
10
|
require 'do'
|
6
11
|
|
7
|
-
module
|
8
|
-
def
|
9
|
-
|
10
|
-
block.call
|
11
|
-
return $stdout
|
12
|
-
ensure
|
13
|
-
$stdout = stdout_was
|
12
|
+
module Helpers
|
13
|
+
def logger
|
14
|
+
DO_LOGGER.string
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
17
|
-
RSpec.configure do |
|
18
|
-
|
18
|
+
RSpec.configure do |c|
|
19
|
+
c.include Helpers
|
19
20
|
end
|
data/spec/tasks_spec.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DO::Tasks do
|
4
|
+
|
5
|
+
def cmd; DO::Tasks; end
|
6
|
+
|
7
|
+
before(:each){ cmd.tasks.clear }
|
8
|
+
|
9
|
+
it 'should init a basic task' do
|
10
|
+
DO::Commands.load_recipes
|
11
|
+
task = cmd.task(:name){}
|
12
|
+
task[:name].should == 'name'
|
13
|
+
task[:desc].should == ''
|
14
|
+
task[:namespace].should == ''
|
15
|
+
task[:block] == nil
|
16
|
+
cmd.tasks.size.should == 1
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should clear old task' do
|
20
|
+
cmd.tasks.size.should == 0
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should have description' do
|
24
|
+
cmd.desc :desc
|
25
|
+
task = cmd.task(:name){}
|
26
|
+
task[:desc].should == 'desc'
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should not confuse desc' do
|
30
|
+
cmd.desc :desc
|
31
|
+
task = cmd.task(:name){}
|
32
|
+
task[:desc].should == 'desc'
|
33
|
+
task = cmd.task(:name_alt){}
|
34
|
+
task[:desc].should == ''
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should have namespace' do
|
38
|
+
cmd.tasks.clear
|
39
|
+
@a = 0
|
40
|
+
cmd.namespace :namespace do
|
41
|
+
cmd.task(:one){ @a+=1 }
|
42
|
+
cmd.task(:two){ @a+=1 }
|
43
|
+
end
|
44
|
+
cmd.task(:three){ @a+=1 }
|
45
|
+
cmd.tasks.should have(3).items
|
46
|
+
@a.should == 0
|
47
|
+
cmd.tasks.each { |t| t[:block].call }
|
48
|
+
@a.should == 3
|
49
|
+
cmd.tasks[0][:namespace].should == 'namespace'
|
50
|
+
cmd.tasks[1][:namespace].should == 'namespace'
|
51
|
+
cmd.tasks[2][:namespace].should == ''
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should have nested namespaces' do
|
55
|
+
cmd.namespace :foo do
|
56
|
+
cmd.task(:one)
|
57
|
+
cmd.namespace :bar do
|
58
|
+
cmd.task(:two)
|
59
|
+
cmd.namespace :bax do
|
60
|
+
cmd.task(:three)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
cmd.task(:four)
|
64
|
+
end
|
65
|
+
cmd.task(:five)
|
66
|
+
cmd.tasks[0][:namespace].should == 'foo'
|
67
|
+
cmd.tasks[1][:namespace].should == 'foo:bar'
|
68
|
+
cmd.tasks[2][:namespace].should == 'foo:bar:bax'
|
69
|
+
cmd.tasks[3][:namespace].should == 'foo'
|
70
|
+
cmd.tasks[4][:namespace].should == ''
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should raise notfound' do
|
74
|
+
expect { cmd.task_run(:foobar) }.to raise_error(DO::Tasks::NotFound)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should have a dependency flag' do
|
78
|
+
cmd.task(:foo) { |o| o[:dependency].should be_true }
|
79
|
+
cmd.task(:bar => :foo) { |o| o.should_not have_key(:dependency) }
|
80
|
+
cmd.task_run(:bar)
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'when using #task_run' do
|
84
|
+
it 'should run correctly' do
|
85
|
+
cmd.namespace :foo do
|
86
|
+
cmd.task(:one){@a=1}
|
87
|
+
cmd.namespace :bar do
|
88
|
+
cmd.task(:two){@b=2}
|
89
|
+
end
|
90
|
+
cmd.task(:three){@c=3}
|
91
|
+
end
|
92
|
+
cmd.task(:four){@d=4}
|
93
|
+
cmd.task_run('foo:one'); @a.should == 1
|
94
|
+
cmd.task_run('foo:bar:two'); @b.should == 2
|
95
|
+
cmd.task_run('foo:three'); @c.should == 3
|
96
|
+
cmd.task_run('four'); @d.should == 4
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should parse options' do
|
100
|
+
cmd.namespace :foo do
|
101
|
+
cmd.task(:one){ |o| @o=o }
|
102
|
+
cmd.namespace :bar do
|
103
|
+
cmd.task(:two){ |o| @o=o }
|
104
|
+
end
|
105
|
+
cmd.task(:three){ |o| @o=o }
|
106
|
+
end
|
107
|
+
cmd.task(:four){ |o| @o=o }
|
108
|
+
cmd.task_run('foo:one', '--name=mine'); @o[:name].should == 'mine'
|
109
|
+
cmd.task_run('foo:bar:two', '--age=2'); @o[:age].should == 2
|
110
|
+
cmd.task_run('foo:three', '--yes'); @o[:yes].should == true
|
111
|
+
cmd.task_run('four', '--no-value'); @o[:value].should == false
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should run deps' do
|
115
|
+
cmd.task(:dep1){@deps=1}
|
116
|
+
cmd.task(:last => [:dep1]){@deps}
|
117
|
+
cmd.task_run(:last) == 1
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should share with opts with deps' do
|
121
|
+
cmd.task(:dep1){ |d| @value = d[:value] }
|
122
|
+
cmd.task(:dep2){ |d| @value+=1 }
|
123
|
+
cmd.task(:dep3){ |d| @value+=1 }
|
124
|
+
cmd.task(:last => [:dep1, :dep2, :dep3]){ |d| @value+=1 }
|
125
|
+
cmd.task_run(:last, '--value=5')
|
126
|
+
@value.should == 8
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'should repeat itself with blocks' do
|
130
|
+
cmd.task(:dep1){ |b| @value=3; b.call }
|
131
|
+
cmd.task(:last, :in => :dep1){ @value+=1 }
|
132
|
+
cmd.task_run(:last)
|
133
|
+
@value.should == 4
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'should repeat itself without blocks' do
|
137
|
+
cmd.tasks.clear
|
138
|
+
cmd.task(:dep1) { @value = 5 }
|
139
|
+
cmd.task(:dep2) { @value += 1 }
|
140
|
+
cmd.task(:dep3) { @value += 1 }
|
141
|
+
cmd.task(:dep4) { @value += 1 }
|
142
|
+
cmd.task(:last, :in => [:dep1, :dep2, :dep3, :dep4])
|
143
|
+
cmd.task_run(:last)
|
144
|
+
@value.should == 8
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'should run methods if NotFound raised' do
|
148
|
+
cmd.tasks.clear
|
149
|
+
cmd.send(:define_method, :demos) {}
|
150
|
+
cmd.task(:demo => :demos)
|
151
|
+
expect { cmd.task_run(:demo) }.to_not raise_error
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
data/spec/utils_spec.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'DO::Utils' do
|
4
|
+
def shell
|
5
|
+
@_shell ||= Class.new { include DO::Utils }.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should log' do
|
9
|
+
DO_LOGGER.should_receive(:print).with('foo')
|
10
|
+
shell.log 'foo'
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should should ask' do
|
14
|
+
DO_LOGGER.should_receive(:print).with("\e[36mShould I overwrite it?: \e[0m")
|
15
|
+
$stdin.should_receive(:gets).and_return('Sure')
|
16
|
+
shell.ask("Should I overwrite it?").should == "Sure"
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should yes? and return true' do
|
20
|
+
DO_LOGGER.should_receive(:print).with("\e[36mIt is true? (y/n): \e[0m")
|
21
|
+
$stdin.should_receive(:gets).and_return('y')
|
22
|
+
shell.yes?('It is true').should be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should yes? and return false' do
|
26
|
+
DO_LOGGER.should_receive(:print).with("\e[36mIt is true? (y/n): \e[0m")
|
27
|
+
$stdin.should_receive(:gets).and_return('n')
|
28
|
+
shell.yes?('It is true').should be_false
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should wait' do
|
32
|
+
DO_LOGGER.should_receive(:print).with("\e[36mPress ENTER to continue...\e[0m")
|
33
|
+
$stdin.should_receive(:gets).and_return('fooo')
|
34
|
+
shell.wait
|
35
|
+
end
|
36
|
+
end
|