ey-deploy 0.7.0 → 0.7.1
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/lib/ey-deploy.rb +4 -0
- data/lib/ey-deploy/cli.rb +27 -16
- data/lib/ey-deploy/deploy.rb +13 -13
- data/lib/ey-deploy/deploy_hook.rb +13 -6
- data/lib/ey-deploy/logged_output.rb +58 -0
- data/lib/ey-deploy/server.rb +5 -5
- data/lib/ey-deploy/strategies/git.rb +5 -5
- data/lib/ey-deploy/task.rb +6 -12
- data/lib/ey-deploy/version.rb +1 -1
- data/lib/vendor/dataflow/HISTORY +52 -0
- data/lib/vendor/dataflow/LICENSE +19 -0
- data/lib/vendor/dataflow/README.textile +290 -0
- data/lib/vendor/dataflow/Rakefile +36 -0
- data/lib/vendor/dataflow/dataflow.rb +120 -0
- data/lib/vendor/dataflow/dataflow/actor.rb +22 -0
- data/lib/vendor/dataflow/dataflow/equality.rb +28 -0
- data/lib/vendor/dataflow/dataflow/future_queue.rb +24 -0
- data/lib/vendor/dataflow/dataflow/port.rb +54 -0
- data/lib/vendor/dataflow/examples/barrier.rb +9 -0
- data/lib/vendor/dataflow/examples/data_driven.rb +17 -0
- data/lib/vendor/dataflow/examples/dataflow_http_gets.rb +13 -0
- data/lib/vendor/dataflow/examples/flow.rb +20 -0
- data/lib/vendor/dataflow/examples/future_http_gets.rb +12 -0
- data/lib/vendor/dataflow/examples/future_queue.rb +11 -0
- data/lib/vendor/dataflow/examples/instance_variables.rb +15 -0
- data/lib/vendor/dataflow/examples/laziness.rb +9 -0
- data/lib/vendor/dataflow/examples/local_variables.rb +11 -0
- data/lib/vendor/dataflow/examples/messages.rb +26 -0
- data/lib/vendor/dataflow/examples/port_http_gets.rb +13 -0
- data/lib/vendor/dataflow/examples/port_send.rb +10 -0
- data/lib/vendor/dataflow/examples/ring.rb +21 -0
- data/lib/vendor/dataflow/spec/actor_spec.rb +28 -0
- data/lib/vendor/dataflow/spec/anonymous_variables_spec.rb +21 -0
- data/lib/vendor/dataflow/spec/barrier_spec.rb +25 -0
- data/lib/vendor/dataflow/spec/by_need_spec.rb +55 -0
- data/lib/vendor/dataflow/spec/dataflow_spec.rb +151 -0
- data/lib/vendor/dataflow/spec/equality_spec.rb +40 -0
- data/lib/vendor/dataflow/spec/flow_spec.rb +25 -0
- data/lib/vendor/dataflow/spec/forker_spec.rb +28 -0
- data/lib/vendor/dataflow/spec/future_queue_spec.rb +31 -0
- data/lib/vendor/dataflow/spec/inspect_spec.rb +19 -0
- data/lib/vendor/dataflow/spec/need_later_spec.rb +12 -0
- data/lib/vendor/dataflow/spec/port_spec.rb +26 -0
- data/lib/vendor/dataflow/spec/spec.opts +1 -0
- data/lib/vendor/dataflow/spec/spec_helper.rb +10 -0
- data/lib/vendor/open4/lib/open4.rb +403 -0
- data/spec/deploy_hook_spec.rb +16 -2
- data/spec/fixtures/invalid_hook.rb +1 -0
- data/spec/fixtures/valid_hook.rb +1 -0
- metadata +43 -4
- data/lib/ey-deploy/verbose_system.rb +0 -12
@@ -0,0 +1,28 @@
|
|
1
|
+
# The purpose of this file is to make equality use method calls in as
|
2
|
+
# many Ruby implementations as possible. If method calls are used,
|
3
|
+
# then equality operations using dataflow variaables becomes seemless
|
4
|
+
# I realize overriding core classes is a pretty nasty hack, but if you
|
5
|
+
# have a better idea that also passes the equality_specs then I'm all
|
6
|
+
# ears. Please run the rubyspec before committing changes to this file.
|
7
|
+
|
8
|
+
class Object
|
9
|
+
def ==(other)
|
10
|
+
object_id == other.object_id
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Symbol
|
15
|
+
def ==(other)
|
16
|
+
object_id == other.object_id
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Regexp
|
21
|
+
def ==(other)
|
22
|
+
other.is_a?(Regexp) &&
|
23
|
+
casefold? == other.casefold? &&
|
24
|
+
kcode == other.kcode &&
|
25
|
+
options == other.options &&
|
26
|
+
source == other.source
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Dataflow
|
2
|
+
class FutureQueue
|
3
|
+
include Dataflow
|
4
|
+
declare :push_port, :pop_port
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
local do |pushed, popped|
|
8
|
+
unify push_port, Dataflow::Port.new(pushed)
|
9
|
+
unify pop_port, Dataflow::Port.new(popped)
|
10
|
+
|
11
|
+
Thread.new {
|
12
|
+
loop do
|
13
|
+
barrier pushed.head, popped.head
|
14
|
+
unify popped.head, pushed.head
|
15
|
+
pushed, popped = pushed.tail, popped.tail
|
16
|
+
end
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def push(x) push_port.send x end
|
22
|
+
def pop(x) pop_port.send x end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'thread'
|
2
|
+
|
3
|
+
module Dataflow
|
4
|
+
class Port
|
5
|
+
include Dataflow
|
6
|
+
LOCK = Mutex.new
|
7
|
+
|
8
|
+
class Stream
|
9
|
+
include Dataflow
|
10
|
+
declare :head, :tail
|
11
|
+
|
12
|
+
# Defining each allows us to use the enumerable mixin
|
13
|
+
# None of the list can be garbage collected less the head is
|
14
|
+
# garbage collected, so it will grow indefinitely even though
|
15
|
+
# the function isn't recursive.
|
16
|
+
include Enumerable
|
17
|
+
def each
|
18
|
+
s = self
|
19
|
+
loop do
|
20
|
+
yield s.head
|
21
|
+
s = s.tail
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Backported Enumerable#take for any 1.8.6 compatible Ruby
|
26
|
+
unless method_defined?(:take)
|
27
|
+
def take(num)
|
28
|
+
result = []
|
29
|
+
each_with_index do |x, i|
|
30
|
+
return result if num == i
|
31
|
+
result << x
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Create a stream object, bind it to the input variable
|
38
|
+
# Instance variables are necessary because @end is state
|
39
|
+
def initialize(x)
|
40
|
+
@end = Stream.new
|
41
|
+
unify x, @end
|
42
|
+
end
|
43
|
+
|
44
|
+
# This needs to be synchronized because it uses @end as state
|
45
|
+
def send value
|
46
|
+
LOCK.synchronize do
|
47
|
+
unify @end.head, value
|
48
|
+
unify @end.tail, Stream.new
|
49
|
+
@end = @end.tail
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../dataflow"
|
2
|
+
include Dataflow
|
3
|
+
|
4
|
+
local do |stream, doubles, triples, squares|
|
5
|
+
unify stream, Array.new(5) { Dataflow::Variable.new }
|
6
|
+
|
7
|
+
Thread.new { unify doubles, stream.map {|n| n*2 } }
|
8
|
+
Thread.new { unify triples, stream.map {|n| n*3 } }
|
9
|
+
Thread.new { unify squares, stream.map {|n| n**2 } }
|
10
|
+
|
11
|
+
Thread.new { stream.each {|x| unify x, rand(100) } }
|
12
|
+
|
13
|
+
puts "original: #{stream.inspect}"
|
14
|
+
puts "doubles: #{doubles.inspect}"
|
15
|
+
puts "triples: #{triples.inspect}"
|
16
|
+
puts "squares: #{squares.inspect}"
|
17
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../dataflow"
|
2
|
+
require 'net/http'
|
3
|
+
include Dataflow
|
4
|
+
|
5
|
+
# Be gentle running this one
|
6
|
+
Thread.abort_on_exception = true
|
7
|
+
local do |stream, branding_occurences, number_of_mentions|
|
8
|
+
unify stream, Array.new(10) { Dataflow::Variable.new }
|
9
|
+
stream.each {|s| Thread.new(s) {|v| unify v, Net::HTTP.get_response(URI.parse("http://www.cuil.com/search?q=#{rand(1000)}")).body } }
|
10
|
+
Thread.new { unify branding_occurences, stream.map {|http_body| http_body.scan /cuil/ } }
|
11
|
+
Thread.new { unify number_of_mentions, branding_occurences.map {|occurences| occurences.length } }
|
12
|
+
puts number_of_mentions.inspect
|
13
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../dataflow"
|
2
|
+
include Dataflow
|
3
|
+
|
4
|
+
# flow without parameters
|
5
|
+
local do |x|
|
6
|
+
flow do
|
7
|
+
# other stuff
|
8
|
+
unify x, 1337
|
9
|
+
end
|
10
|
+
puts x
|
11
|
+
end
|
12
|
+
|
13
|
+
# flow with an output parameter
|
14
|
+
local do |x|
|
15
|
+
flow(x) do
|
16
|
+
# other stuff
|
17
|
+
1337
|
18
|
+
end
|
19
|
+
puts x
|
20
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../dataflow"
|
2
|
+
require 'net/http'
|
3
|
+
include Dataflow
|
4
|
+
|
5
|
+
# Be gentle running this one
|
6
|
+
Thread.abort_on_exception = true
|
7
|
+
local do |stream, branding_occurences, number_of_mentions|
|
8
|
+
unify stream, Array.new(10) { need_later { Net::HTTP.get_response(URI.parse("http://www.cuil.com/search?q=#{rand(1000)}")).body } }
|
9
|
+
unify branding_occurences, need_later { stream.map {|http_body| http_body.scan /cuil/ } }
|
10
|
+
unify number_of_mentions, need_later { branding_occurences.map {|occurences| occurences.length } }
|
11
|
+
puts number_of_mentions.inspect
|
12
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../dataflow"
|
2
|
+
include Dataflow
|
3
|
+
|
4
|
+
local do |queue, first, second|
|
5
|
+
unify queue, Dataflow::FutureQueue.new
|
6
|
+
queue.pop first
|
7
|
+
queue.push 1
|
8
|
+
queue.push 2
|
9
|
+
queue.pop second
|
10
|
+
puts "first: #{first}, second: #{second}"
|
11
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../dataflow"
|
2
|
+
|
3
|
+
class AnimalHouse
|
4
|
+
include Dataflow
|
5
|
+
declare :small_cat, :big_cat
|
6
|
+
|
7
|
+
def fetch_big_cat
|
8
|
+
Thread.new { unify big_cat, small_cat.upcase }
|
9
|
+
unify small_cat, 'cat'
|
10
|
+
big_cat
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
puts AnimalHouse.new.fetch_big_cat
|
15
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../dataflow"
|
2
|
+
include Dataflow
|
3
|
+
|
4
|
+
Ping = Actor.new {
|
5
|
+
3.times {
|
6
|
+
case receive
|
7
|
+
when "Ping"
|
8
|
+
puts "Ping"
|
9
|
+
Pong.send "Pong"
|
10
|
+
end
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
Pong = Actor.new {
|
15
|
+
3.times {
|
16
|
+
case receive
|
17
|
+
when "Pong"
|
18
|
+
puts "Pong"
|
19
|
+
Ping.send "Ping"
|
20
|
+
end
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
Ping.send "Ping"
|
25
|
+
Ping.join
|
26
|
+
Pong.join
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../dataflow"
|
2
|
+
require 'net/http'
|
3
|
+
include Dataflow
|
4
|
+
|
5
|
+
# Be gentle running this one
|
6
|
+
Thread.abort_on_exception = true
|
7
|
+
local do |port, stream, branding_occurences, number_of_mentions|
|
8
|
+
unify port, Dataflow::Port.new(stream)
|
9
|
+
10.times { Thread.new(port) {|p| p.send Net::HTTP.get_response(URI.parse("http://www.cuil.com/search?q=#{rand(1000)}")).body } }
|
10
|
+
Thread.new { unify branding_occurences, stream.take(10).map {|http_body| http_body.scan /cuil/ } }
|
11
|
+
Thread.new { unify number_of_mentions, branding_occurences.map {|occurences| occurences.length } }
|
12
|
+
puts number_of_mentions.inspect
|
13
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../dataflow"
|
2
|
+
include Dataflow
|
3
|
+
|
4
|
+
local do |port, stream|
|
5
|
+
unify port, Dataflow::Port.new(stream)
|
6
|
+
Thread.new {port.send 2}
|
7
|
+
Thread.new {port.send 8}
|
8
|
+
Thread.new {port.send 1024}
|
9
|
+
puts stream.take(3).sort.inspect
|
10
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/../dataflow"
|
2
|
+
include Dataflow
|
3
|
+
|
4
|
+
# Send M messages each along a ring of N nodes
|
5
|
+
N = 4
|
6
|
+
M = 2
|
7
|
+
actors = Array.new(N) { Dataflow::Variable.new }
|
8
|
+
|
9
|
+
N.times do |n|
|
10
|
+
unify actors[n], Actor.new {
|
11
|
+
M.times do |m|
|
12
|
+
receive
|
13
|
+
puts "[#{n} #{m}]"
|
14
|
+
actors[(n+1) % N].send :msg
|
15
|
+
end
|
16
|
+
puts "[#{n}] done"
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
actors.first.send :msg
|
21
|
+
actors.each { |x| x.join }
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/spec_helper"
|
2
|
+
|
3
|
+
describe 'Syncronously sending to an Actor' do
|
4
|
+
it 'passes in each message received and preserves order' do
|
5
|
+
local do |port, stream, actor|
|
6
|
+
unify port, Dataflow::Port.new(stream)
|
7
|
+
unify actor, Dataflow::Actor.new { 3.times { port.send receive } }
|
8
|
+
actor.send 1
|
9
|
+
actor.send 2
|
10
|
+
stream.take(2).should == [1, 2]
|
11
|
+
actor.send 3
|
12
|
+
stream.take(3).should == [1, 2, 3]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'Asyncronously sending to an Actor' do
|
18
|
+
it 'passes in each message received and preserves order' do
|
19
|
+
local do |port, stream, actor|
|
20
|
+
unify port, Dataflow::Port.new(stream)
|
21
|
+
unify actor, Dataflow::Actor.new { 3.times { port.send receive } }
|
22
|
+
Thread.new {actor.send 2}
|
23
|
+
Thread.new {actor.send 8}
|
24
|
+
Thread.new {actor.send 1024}
|
25
|
+
stream.take(3).sort.should == [2, 8, 1024]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/spec_helper"
|
2
|
+
|
3
|
+
describe 'Using an anonymous variable' do
|
4
|
+
it 'works with Variable instances' do
|
5
|
+
container = [Dataflow::Variable.new]
|
6
|
+
unify container.first, 1337
|
7
|
+
container.first.should == 1337
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'works with Dataflow.local' do
|
11
|
+
container = [Dataflow.local]
|
12
|
+
unify container.first, 1337
|
13
|
+
container.first.should == 1337
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'works with #local' do
|
17
|
+
container = [local]
|
18
|
+
unify container.first, 1337
|
19
|
+
container.first.should == 1337
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/spec_helper"
|
2
|
+
|
3
|
+
describe 'A barrier' do
|
4
|
+
it 'waits for variables to be bound before continuing' do
|
5
|
+
local do |x, y, barrier_broken|
|
6
|
+
Thread.new do
|
7
|
+
barrier x, y
|
8
|
+
unify barrier_broken, true
|
9
|
+
end
|
10
|
+
Thread.new { unify x, :x }
|
11
|
+
Thread.new { unify y, :y }
|
12
|
+
barrier_broken.should be_true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'continues for variables that are already bound' do
|
17
|
+
local do |x, y, barrier_broken|
|
18
|
+
unify x, :x
|
19
|
+
unify y, :y
|
20
|
+
barrier x, y
|
21
|
+
unify barrier_broken, true
|
22
|
+
barrier_broken.should be_true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/spec_helper"
|
2
|
+
|
3
|
+
describe 'A by_need expression' do
|
4
|
+
describe 'when a method is called on it' do
|
5
|
+
it 'binds its variable' do
|
6
|
+
local do |x, y, z|
|
7
|
+
Thread.new { unify y, by_need { 4 } }
|
8
|
+
Thread.new { unify z, x + y }
|
9
|
+
Thread.new { unify x, by_need { 3 } }
|
10
|
+
z.should == 7
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe 'when a bound variable is unified to it' do
|
16
|
+
it 'passes unififcation for equal values' do
|
17
|
+
local do |x|
|
18
|
+
unify x, by_need { 1 }
|
19
|
+
unify x, 1
|
20
|
+
x.should == 1
|
21
|
+
|
22
|
+
y = by_need { 1 }
|
23
|
+
unify y, 1
|
24
|
+
y.should == 1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'fails unififcation for unequal values' do
|
29
|
+
local do |x|
|
30
|
+
unify x, by_need { 1 }
|
31
|
+
lambda { unify x, 2 }.should raise_error(Dataflow::UnificationError)
|
32
|
+
|
33
|
+
y = by_need { 1 }
|
34
|
+
lambda { unify y, 2 }.should raise_error(Dataflow::UnificationError)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'when it is unified to a bound variable' do
|
39
|
+
it 'passes unififcation for equal values' do
|
40
|
+
local do |x|
|
41
|
+
unify x, 1
|
42
|
+
unify x, by_need { 1 }
|
43
|
+
x.should == 1
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'fails unification for unequal values' do
|
48
|
+
local do |x|
|
49
|
+
unify x, 1
|
50
|
+
lambda { unify x, by_need { 2 } }.should raise_error(Dataflow::UnificationError)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|