rake-subproject 0.0.1 → 0.0.5
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.
- 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
|