rake-subproject 0.0.1 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.gitignore +1 -0
- data/Rakefile +30 -0
- data/lib/rake/subproject.rb +9 -0
- data/lib/rake/subproject/client/port.rb +52 -0
- data/lib/rake/subproject/client/session.rb +24 -0
- data/lib/rake/subproject/client/session_manager.rb +101 -0
- data/lib/rake/subproject/server/port.rb +52 -0
- data/lib/rake/subproject/server/session.rb +24 -0
- data/lib/rake/subproject/server/session_manager.rb +101 -0
- data/lib/rake/subproject/server/task.rb +47 -0
- data/lib/rake/subproject/task_manager.rb +18 -29
- data/lib/rake/subproject/task_runner.rb +58 -0
- data/lib/rake/subproject/version.rb +1 -1
- data/rake-subproject.gemspec +9 -4
- metadata +13 -5
- data/Gemfile.lock +0 -27
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MjFiN2QzYzg4OTFkYjk1NmQxNzI3N2U3MTZhNTk1ZGJlZThlOGM3YQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MzQ2M2E3ZjBkMWQ0NzQ2OTFkM2QwN2Q3MTQzZTMxNWNhMzU1YTM3Zg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YmViZmRiMDQxOWJhYjIzZTIxNDgwYzc3NDBhYjc0ZjFhYTYzNWZmNWQyYzUw
|
10
|
+
OGU5YjY1MzJiOTliM2IwMWQ4MWFjN2Y2OWY5ZWQ3YmU1MjE2ZGQxNTBiZWNi
|
11
|
+
YzdiNzZhYzdhYThlNzdiNDIxOTQwYWQ0M2Y5YjYyZWJmYzA5ZWM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
OWQwOGRkZDZiYWExZGU4NzZiNjJkZGUyYjI1N2YzMTkyNGQxMzdjMTJmYTc0
|
14
|
+
NDlhZWM2NTM1MmNiNDVjNThkZDExNmQ4N2UxMzVlOWIxNzA0MTgyYWJkYzIx
|
15
|
+
ZDI0YTFiNDczOTJhZDI2MGQzYjgwYWU3YmUyMDkwNzNkNmE0OWU=
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Gemfile.lock
|
data/Rakefile
CHANGED
@@ -1,6 +1,36 @@
|
|
1
1
|
require "bundler/gem_tasks"
|
2
2
|
require "rspec/core/rake_task"
|
3
|
+
require 'rake/clean'
|
3
4
|
|
4
5
|
RSpec::Core::RakeTask.new(:spec)
|
5
6
|
|
6
7
|
task :default => :spec
|
8
|
+
|
9
|
+
['Client', 'Server'].each do |name|
|
10
|
+
dir = "lib/rake/subproject/#{name.downcase}"
|
11
|
+
directory dir
|
12
|
+
CLEAN.include dir
|
13
|
+
FileList["resources/network/*.rb"].each do |path|
|
14
|
+
file "#{dir}/#{File.basename(path)}" => "lib/rake/subproject/#{name.downcase}" do |t|
|
15
|
+
File.open(t.name, 'w') do |f|
|
16
|
+
f.puts "module Rake ; module Subproject ; module #{name}"
|
17
|
+
f.puts File.read(path)
|
18
|
+
f.puts "end ; end ; end"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
namespace :build do
|
22
|
+
task :library => "#{dir}/#{File.basename(path)}"
|
23
|
+
end
|
24
|
+
CLEAN.include "#{dir}/#{File.basename(path)}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
file "lib/rake/subproject/server/task.rb" => ["resources/server_task.rb", "lib/rake/subproject/server"] do |t|
|
29
|
+
cp t.prerequisites.first, t.name
|
30
|
+
end
|
31
|
+
|
32
|
+
namespace :build do
|
33
|
+
task :library => "lib/rake/subproject/server/task.rb"
|
34
|
+
end
|
35
|
+
|
36
|
+
task :build => 'build:library'
|
data/lib/rake/subproject.rb
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
require 'rake'
|
2
|
+
require 'json'
|
2
3
|
|
4
|
+
module Rake::Subproject
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rake/subproject/client/port'
|
8
|
+
require 'rake/subproject/client/session_manager'
|
9
|
+
require 'rake/subproject/client/session'
|
10
|
+
require 'rake/subproject/client/port'
|
11
|
+
require 'rake/subproject/task_runner'
|
3
12
|
require 'rake/subproject/task_manager'
|
4
13
|
require 'rake/subproject/ext/application'
|
5
14
|
require 'rake/subproject/ext/dsl'
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Rake ; module Subproject ; module Client
|
2
|
+
class Port
|
3
|
+
attr_accessor :name
|
4
|
+
|
5
|
+
def self.open(fd, option)
|
6
|
+
return unless block_given?
|
7
|
+
IO.open(fd, option) do |io|
|
8
|
+
yield port = self.new(io, "server")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
DELIMITER = "\0"
|
13
|
+
|
14
|
+
def initialize(io, name = nil)
|
15
|
+
fail ArgumentError, "Requires an IO object" unless io.kind_of?(IO)
|
16
|
+
@io = io
|
17
|
+
self.name = name
|
18
|
+
end
|
19
|
+
|
20
|
+
def inspect
|
21
|
+
"Port(#{self.name || @io.fileno})"
|
22
|
+
end
|
23
|
+
|
24
|
+
def read
|
25
|
+
log "reading #{self.inspect}..."
|
26
|
+
json_message = @io.readline(DELIMITER).chomp(DELIMITER)
|
27
|
+
log "... #{self.inspect} received: #{json_message}"
|
28
|
+
::JSON.parse(json_message)
|
29
|
+
end
|
30
|
+
|
31
|
+
def write(object)
|
32
|
+
json_message = ::JSON.generate(object)
|
33
|
+
@io.print(json_message+DELIMITER)
|
34
|
+
@io.flush
|
35
|
+
log "#{self.inspect} wrote: #{json_message}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def close
|
39
|
+
log "closing #{self.inspect}"
|
40
|
+
@io.close
|
41
|
+
end
|
42
|
+
|
43
|
+
def closed?
|
44
|
+
@io.closed?
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
def log(message)
|
49
|
+
$stderr.print "#{message}\n" if false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end ; end ; end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Rake ; module Subproject ; module Client
|
2
|
+
class Session
|
3
|
+
def initialize(manager, id = nil)
|
4
|
+
@id = id
|
5
|
+
@manager = manager
|
6
|
+
end
|
7
|
+
|
8
|
+
def id
|
9
|
+
@id || object_id
|
10
|
+
end
|
11
|
+
|
12
|
+
def write(object)
|
13
|
+
@manager.send(:write_session, self, object)
|
14
|
+
end
|
15
|
+
|
16
|
+
def read
|
17
|
+
@manager.send(:read_session, self)
|
18
|
+
end
|
19
|
+
|
20
|
+
def close
|
21
|
+
@manager.send(:close_session, self)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end ; end ; end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module Rake ; module Subproject ; module Client
|
2
|
+
class SessionManager
|
3
|
+
|
4
|
+
def initialize(port)
|
5
|
+
fail ArgumentError, "Requires a Port object" unless port.kind_of?(Port)
|
6
|
+
@port = port
|
7
|
+
@session_queues = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.with_each_session(port, &block)
|
11
|
+
return unless block_given?
|
12
|
+
session_manager = self.new(port)
|
13
|
+
threads = Set.new
|
14
|
+
mutex = Mutex.new
|
15
|
+
session_manager.start do |session|
|
16
|
+
mutex.synchronize do
|
17
|
+
threads << thread = Thread.start do
|
18
|
+
block.call(session)
|
19
|
+
mutex.synchronize { threads.delete thread }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
ensure
|
24
|
+
log "Waiting for #{threads.count} threads"
|
25
|
+
mutex.synchronize { threads.dup }.each(&:join)
|
26
|
+
session_manager.close
|
27
|
+
end
|
28
|
+
|
29
|
+
def start(&block)
|
30
|
+
log "starting read loop on #{@port.inspect}"
|
31
|
+
loop do
|
32
|
+
envelope = @port.read
|
33
|
+
fail "no 'message' tag in envelope" if (message = envelope['message']).nil?
|
34
|
+
fail "no 'session_id' tag in envelope" if (session_id = envelope['session_id']).nil? || session_id == "0"
|
35
|
+
session_id = session_id.to_i
|
36
|
+
fail "null(0) 'session_id' tag in envelope" if session_id == 0
|
37
|
+
|
38
|
+
case message
|
39
|
+
when 'create_session'
|
40
|
+
session = Session.new(self, session_id.to_i)
|
41
|
+
@session_queues[session.id] = Queue.new
|
42
|
+
block.call(session) unless block.nil?
|
43
|
+
when 'message_session'
|
44
|
+
fail "No session for #{session_id.to_i}" if (queue = @session_queues[session_id.to_i]).nil?
|
45
|
+
queue << envelope['payload']
|
46
|
+
else
|
47
|
+
fail "did not recognize message: '#{message}'" if (session_id = envelope['session_id']).nil? || session_id == 0
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
rescue EOFError => e
|
52
|
+
# log "#{e.message}\n#{e.backtrace.join("\n")}"
|
53
|
+
rescue IOError => e
|
54
|
+
# log "#{e.message}\n#{e.backtrace.join("\n")}"
|
55
|
+
# raise
|
56
|
+
end
|
57
|
+
|
58
|
+
def with_session
|
59
|
+
return unless block_given?
|
60
|
+
yield session = create_session
|
61
|
+
ensure
|
62
|
+
session.close
|
63
|
+
end
|
64
|
+
|
65
|
+
def create_session
|
66
|
+
session = Session.send(:new, self)
|
67
|
+
@port.write(message: 'create_session', session_id: session.id)
|
68
|
+
@session_queues[session.id] = Queue.new
|
69
|
+
session
|
70
|
+
end
|
71
|
+
|
72
|
+
def close
|
73
|
+
log "session manager: closing #{@port.inspect}"
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def close_session(session)
|
79
|
+
log "closing session: #{session.id} on #{@port.inspect}"
|
80
|
+
@session_queues.delete(session.id)
|
81
|
+
end
|
82
|
+
|
83
|
+
def read_session(session)
|
84
|
+
fail "No queue for #{session.inspect}" if (queue = @session_queues[session.id]).nil?
|
85
|
+
fail EOFError if queue.empty? && @port.closed?
|
86
|
+
queue.pop
|
87
|
+
end
|
88
|
+
|
89
|
+
def write_session(session, object)
|
90
|
+
@port.write(message: 'message_session', session_id: session.id, payload: object)
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
def self.log(message)
|
95
|
+
$stderr.print "#{message}\n" if false
|
96
|
+
end
|
97
|
+
def log(message)
|
98
|
+
self.class.log(message)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end ; end ; end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Rake ; module Subproject ; module Server
|
2
|
+
class Port
|
3
|
+
attr_accessor :name
|
4
|
+
|
5
|
+
def self.open(fd, option)
|
6
|
+
return unless block_given?
|
7
|
+
IO.open(fd, option) do |io|
|
8
|
+
yield port = self.new(io, "server")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
DELIMITER = "\0"
|
13
|
+
|
14
|
+
def initialize(io, name = nil)
|
15
|
+
fail ArgumentError, "Requires an IO object" unless io.kind_of?(IO)
|
16
|
+
@io = io
|
17
|
+
self.name = name
|
18
|
+
end
|
19
|
+
|
20
|
+
def inspect
|
21
|
+
"Port(#{self.name || @io.fileno})"
|
22
|
+
end
|
23
|
+
|
24
|
+
def read
|
25
|
+
log "reading #{self.inspect}..."
|
26
|
+
json_message = @io.readline(DELIMITER).chomp(DELIMITER)
|
27
|
+
log "... #{self.inspect} received: #{json_message}"
|
28
|
+
::JSON.parse(json_message)
|
29
|
+
end
|
30
|
+
|
31
|
+
def write(object)
|
32
|
+
json_message = ::JSON.generate(object)
|
33
|
+
@io.print(json_message+DELIMITER)
|
34
|
+
@io.flush
|
35
|
+
log "#{self.inspect} wrote: #{json_message}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def close
|
39
|
+
log "closing #{self.inspect}"
|
40
|
+
@io.close
|
41
|
+
end
|
42
|
+
|
43
|
+
def closed?
|
44
|
+
@io.closed?
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
def log(message)
|
49
|
+
$stderr.print "#{message}\n" if false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end ; end ; end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Rake ; module Subproject ; module Server
|
2
|
+
class Session
|
3
|
+
def initialize(manager, id = nil)
|
4
|
+
@id = id
|
5
|
+
@manager = manager
|
6
|
+
end
|
7
|
+
|
8
|
+
def id
|
9
|
+
@id || object_id
|
10
|
+
end
|
11
|
+
|
12
|
+
def write(object)
|
13
|
+
@manager.send(:write_session, self, object)
|
14
|
+
end
|
15
|
+
|
16
|
+
def read
|
17
|
+
@manager.send(:read_session, self)
|
18
|
+
end
|
19
|
+
|
20
|
+
def close
|
21
|
+
@manager.send(:close_session, self)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end ; end ; end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module Rake ; module Subproject ; module Server
|
2
|
+
class SessionManager
|
3
|
+
|
4
|
+
def initialize(port)
|
5
|
+
fail ArgumentError, "Requires a Port object" unless port.kind_of?(Port)
|
6
|
+
@port = port
|
7
|
+
@session_queues = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.with_each_session(port, &block)
|
11
|
+
return unless block_given?
|
12
|
+
session_manager = self.new(port)
|
13
|
+
threads = Set.new
|
14
|
+
mutex = Mutex.new
|
15
|
+
session_manager.start do |session|
|
16
|
+
mutex.synchronize do
|
17
|
+
threads << thread = Thread.start do
|
18
|
+
block.call(session)
|
19
|
+
mutex.synchronize { threads.delete thread }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
ensure
|
24
|
+
log "Waiting for #{threads.count} threads"
|
25
|
+
mutex.synchronize { threads.dup }.each(&:join)
|
26
|
+
session_manager.close
|
27
|
+
end
|
28
|
+
|
29
|
+
def start(&block)
|
30
|
+
log "starting read loop on #{@port.inspect}"
|
31
|
+
loop do
|
32
|
+
envelope = @port.read
|
33
|
+
fail "no 'message' tag in envelope" if (message = envelope['message']).nil?
|
34
|
+
fail "no 'session_id' tag in envelope" if (session_id = envelope['session_id']).nil? || session_id == "0"
|
35
|
+
session_id = session_id.to_i
|
36
|
+
fail "null(0) 'session_id' tag in envelope" if session_id == 0
|
37
|
+
|
38
|
+
case message
|
39
|
+
when 'create_session'
|
40
|
+
session = Session.new(self, session_id.to_i)
|
41
|
+
@session_queues[session.id] = Queue.new
|
42
|
+
block.call(session) unless block.nil?
|
43
|
+
when 'message_session'
|
44
|
+
fail "No session for #{session_id.to_i}" if (queue = @session_queues[session_id.to_i]).nil?
|
45
|
+
queue << envelope['payload']
|
46
|
+
else
|
47
|
+
fail "did not recognize message: '#{message}'" if (session_id = envelope['session_id']).nil? || session_id == 0
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
rescue EOFError => e
|
52
|
+
# log "#{e.message}\n#{e.backtrace.join("\n")}"
|
53
|
+
rescue IOError => e
|
54
|
+
# log "#{e.message}\n#{e.backtrace.join("\n")}"
|
55
|
+
# raise
|
56
|
+
end
|
57
|
+
|
58
|
+
def with_session
|
59
|
+
return unless block_given?
|
60
|
+
yield session = create_session
|
61
|
+
ensure
|
62
|
+
session.close
|
63
|
+
end
|
64
|
+
|
65
|
+
def create_session
|
66
|
+
session = Session.send(:new, self)
|
67
|
+
@port.write(message: 'create_session', session_id: session.id)
|
68
|
+
@session_queues[session.id] = Queue.new
|
69
|
+
session
|
70
|
+
end
|
71
|
+
|
72
|
+
def close
|
73
|
+
log "session manager: closing #{@port.inspect}"
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def close_session(session)
|
79
|
+
log "closing session: #{session.id} on #{@port.inspect}"
|
80
|
+
@session_queues.delete(session.id)
|
81
|
+
end
|
82
|
+
|
83
|
+
def read_session(session)
|
84
|
+
fail "No queue for #{session.inspect}" if (queue = @session_queues[session.id]).nil?
|
85
|
+
fail EOFError if queue.empty? && @port.closed?
|
86
|
+
queue.pop
|
87
|
+
end
|
88
|
+
|
89
|
+
def write_session(session, object)
|
90
|
+
@port.write(message: 'message_session', session_id: session.id, payload: object)
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
def self.log(message)
|
95
|
+
$stderr.print "#{message}\n" if false
|
96
|
+
end
|
97
|
+
def log(message)
|
98
|
+
self.class.log(message)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end ; end ; end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
require_relative 'port'
|
5
|
+
require_relative 'session'
|
6
|
+
require_relative 'session_manager'
|
7
|
+
|
8
|
+
Rake::Task.define_task(:'subproject:server:start', [:fd]) do |t, args|
|
9
|
+
include Rake::Subproject::Server
|
10
|
+
Port.open(args[:fd].to_i, 'r+') do |port|
|
11
|
+
|
12
|
+
def log(message)
|
13
|
+
$stderr.print "#{message}\n" if false
|
14
|
+
end
|
15
|
+
|
16
|
+
port.name = "server"
|
17
|
+
log "Starting server on #{port.inspect}\n"
|
18
|
+
|
19
|
+
SessionManager.with_each_session(port) do |session|
|
20
|
+
|
21
|
+
log "Received session"
|
22
|
+
request = session.read
|
23
|
+
message = request['message']
|
24
|
+
|
25
|
+
log "Got message: '#{message}'"
|
26
|
+
next unless message == 'invoke_task'
|
27
|
+
|
28
|
+
task_name = request['name']
|
29
|
+
log "Got task name: '#{task_name}'"
|
30
|
+
|
31
|
+
task_args = request['args']
|
32
|
+
|
33
|
+
log "Got task args: '#{task_args}'"
|
34
|
+
|
35
|
+
begin
|
36
|
+
log "Executing task #{task_name}"
|
37
|
+
Rake::Task[task_name].invoke(*task_args['array'])
|
38
|
+
log "#{task_name} complete!"
|
39
|
+
session.write(message: 'task_complete')
|
40
|
+
rescue RuntimeError => e
|
41
|
+
session.write(message: 'task_failed', exception:{message: e.message, backtrace: e.backtrace})
|
42
|
+
ensure
|
43
|
+
session.close
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -1,39 +1,28 @@
|
|
1
|
-
|
1
|
+
module Rake::Subproject
|
2
|
+
module TaskManager
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def run(*args)
|
8
|
-
ruby '-S', 'rake', *args
|
4
|
+
def define_subproject(path)
|
5
|
+
return if runners[path]
|
6
|
+
runners[path] = Rake::Subproject::TaskRunner.new(path)
|
9
7
|
end
|
10
|
-
end
|
11
8
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
def [](task_name, scopes=nil)
|
22
|
-
self.lookup(task_name, scopes) or
|
23
|
-
subprojects.each do |subproject|
|
24
|
-
task_name.match /^#{subproject}[\/\:](.*)/ do |md|
|
25
|
-
return Rake::Task.define_task task_name do |t|
|
26
|
-
subproject_semaphores[subproject].synchronize do
|
27
|
-
RakeRunner.new.run md[1], {chdir: subproject}, {verbose: false}
|
9
|
+
def [](task_name, scopes=nil)
|
10
|
+
self.lookup(task_name, scopes) or
|
11
|
+
runners.each do |dir, subproject|
|
12
|
+
task_name.match /^#{dir}[\/\:](.*)/ do |md|
|
13
|
+
# Here, we need a remote task class that can receive the
|
14
|
+
return Rake::Task.define_task task_name do |t, args|
|
15
|
+
subproject.invoke_task(md[1], args)
|
28
16
|
end
|
29
17
|
end
|
30
18
|
end
|
19
|
+
super
|
31
20
|
end
|
32
|
-
super
|
33
|
-
end
|
34
|
-
private
|
35
21
|
|
36
|
-
|
37
|
-
|
22
|
+
private
|
23
|
+
|
24
|
+
def runners
|
25
|
+
@runners ||= {}
|
26
|
+
end
|
38
27
|
end
|
39
28
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'json'
|
2
|
+
module Rake::Subproject
|
3
|
+
class TaskRunner
|
4
|
+
attr_reader :directory
|
5
|
+
|
6
|
+
include FileUtils
|
7
|
+
include Rake::Subproject::Client
|
8
|
+
|
9
|
+
def initialize(directory)
|
10
|
+
@directory = directory
|
11
|
+
@@rake_env ||= ARGV.each_with_object({}) do |arg, hash|
|
12
|
+
hash[$1] = $2 if arg =~ /^(\w+)=(.*)$/m
|
13
|
+
end
|
14
|
+
|
15
|
+
child_socket, parent_socket = Socket.pair(:UNIX, :STREAM, 0)
|
16
|
+
port = Port.new(parent_socket, "client")
|
17
|
+
@session_manager = SessionManager.new(port)
|
18
|
+
thread = Thread.new { @session_manager.start }
|
19
|
+
at_exit do
|
20
|
+
@session_manager.close
|
21
|
+
port.close
|
22
|
+
thread.join
|
23
|
+
end
|
24
|
+
|
25
|
+
Bundler.with_clean_env do
|
26
|
+
@server_pid = Process.spawn(
|
27
|
+
"bundle", "exec", "--keep-file-descriptors",
|
28
|
+
"rake",
|
29
|
+
# Do not search parent directories for the Rakefile.
|
30
|
+
"--no-search",
|
31
|
+
# Include LIBDIR in the search path for required modules.
|
32
|
+
"--libdir", File.dirname(__FILE__)+ "/server",
|
33
|
+
# Require MODULE before executing rakefile.
|
34
|
+
"-r", "task", "subproject:server:start[#{child_socket.fileno}]",
|
35
|
+
{child_socket.fileno => child_socket, :chdir => @directory})
|
36
|
+
end
|
37
|
+
child_socket.close
|
38
|
+
end
|
39
|
+
|
40
|
+
def invoke_task(name, args)
|
41
|
+
log "TaskRunner#invoke_task: #{name} with #{args}"
|
42
|
+
session = @session_manager.with_session do |session|
|
43
|
+
session.write(message: 'invoke_task', name: name, args: {hash: args.to_hash, array: args.to_a})
|
44
|
+
response = session.read
|
45
|
+
if (response['message'] == 'task_failed')
|
46
|
+
e = ::RuntimeError.new(response['exception']['message'])
|
47
|
+
e.set_backtrace(response['exception']['backtrace'] + Thread.current.backtrace)
|
48
|
+
raise e
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def log(message)
|
55
|
+
$stderr.print "#{message}\n" if false
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/rake-subproject.gemspec
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
|
3
|
+
# $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
require "#{lib}/rake/subproject/version"
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
8
|
spec.name = "rake-subproject"
|
@@ -13,11 +14,15 @@ Gem::Specification.new do |spec|
|
|
13
14
|
spec.homepage = ""
|
14
15
|
spec.license = "MIT"
|
15
16
|
|
16
|
-
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.start_with?('resources/')
|
19
|
+
end + Dir["lib/rake/subproject/{client,server}/*.rb"]
|
17
20
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
21
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
22
|
spec.require_paths = ["lib"]
|
20
|
-
|
23
|
+
|
24
|
+
spec.required_ruby_version = '~> 2.0'
|
25
|
+
|
21
26
|
spec.add_runtime_dependency "rake"
|
22
27
|
|
23
28
|
spec.add_development_dependency "bundler", "~> 1.5"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rake-subproject
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Bishop
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -59,15 +59,23 @@ executables: []
|
|
59
59
|
extensions: []
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
|
+
- .gitignore
|
62
63
|
- Gemfile
|
63
|
-
- Gemfile.lock
|
64
64
|
- LICENSE.txt
|
65
65
|
- README.md
|
66
66
|
- Rakefile
|
67
67
|
- lib/rake/subproject.rb
|
68
|
+
- lib/rake/subproject/client/port.rb
|
69
|
+
- lib/rake/subproject/client/session.rb
|
70
|
+
- lib/rake/subproject/client/session_manager.rb
|
68
71
|
- lib/rake/subproject/ext/application.rb
|
69
72
|
- lib/rake/subproject/ext/dsl.rb
|
73
|
+
- lib/rake/subproject/server/port.rb
|
74
|
+
- lib/rake/subproject/server/session.rb
|
75
|
+
- lib/rake/subproject/server/session_manager.rb
|
76
|
+
- lib/rake/subproject/server/task.rb
|
70
77
|
- lib/rake/subproject/task_manager.rb
|
78
|
+
- lib/rake/subproject/task_runner.rb
|
71
79
|
- lib/rake/subproject/version.rb
|
72
80
|
- rake-subproject.gemspec
|
73
81
|
- spec/rake/subproject_spec.rb
|
@@ -82,9 +90,9 @@ require_paths:
|
|
82
90
|
- lib
|
83
91
|
required_ruby_version: !ruby/object:Gem::Requirement
|
84
92
|
requirements:
|
85
|
-
- -
|
93
|
+
- - ~>
|
86
94
|
- !ruby/object:Gem::Version
|
87
|
-
version: '0'
|
95
|
+
version: '2.0'
|
88
96
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
97
|
requirements:
|
90
98
|
- - ! '>='
|
data/Gemfile.lock
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
rake-subproject (0.0.1)
|
5
|
-
rake
|
6
|
-
|
7
|
-
GEM
|
8
|
-
remote: https://rubygems.org/
|
9
|
-
specs:
|
10
|
-
diff-lcs (1.2.5)
|
11
|
-
rake (10.2.0)
|
12
|
-
rspec (2.14.1)
|
13
|
-
rspec-core (~> 2.14.0)
|
14
|
-
rspec-expectations (~> 2.14.0)
|
15
|
-
rspec-mocks (~> 2.14.0)
|
16
|
-
rspec-core (2.14.8)
|
17
|
-
rspec-expectations (2.14.5)
|
18
|
-
diff-lcs (>= 1.1.3, < 2.0)
|
19
|
-
rspec-mocks (2.14.6)
|
20
|
-
|
21
|
-
PLATFORMS
|
22
|
-
ruby
|
23
|
-
|
24
|
-
DEPENDENCIES
|
25
|
-
bundler (~> 1.5)
|
26
|
-
rake-subproject!
|
27
|
-
rspec
|