entangler 0.1.1 → 0.1.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 490b5a2f8672548a4e3a7d15fbd641291f9456fc
4
- data.tar.gz: 5750ebccf9775aa3971dc7dfe930527ee7803af4
3
+ metadata.gz: e910a8be4617a7df89c5a0d5f94b51617a26deb6
4
+ data.tar.gz: 1d083cf56c15e7f332c703eb36381d31e717b7f6
5
5
  SHA512:
6
- metadata.gz: 6b74a61f4a3dda5e52b8b10fe8f41e92eb9e9266dfa923bfc015b857f68e24757770c620ee6f937da0fc18e2885c2a0a723a2a329febf9871574ab9128dd223e
7
- data.tar.gz: 4df993ced868041b7f96012b425bf2b0a1d569a1d16074a852c63bf4e9d1b96f19b2ffd1ff362af09f00888bb7a8ca55ce9471848db37d19f76b63b56aa4c642
6
+ metadata.gz: 829fd8b9cc788a049e1daab942a3eff9d911351f580b71f276610c0c48b758638698868066ceb39e3bac63a6bebc7e295915d19fd95d7f93e4a66a0bfe057b65
7
+ data.tar.gz: b08f880f5e249658f83b906e3789adf84b999d9922b068dc6eec037aa069475a62434212287f3a3898f56661a1a01c43911eab4c9b70fd6c59a12f153edd92ef
@@ -28,6 +28,23 @@ module Entangler
28
28
  File.exists?(full_path)
29
29
  end
30
30
 
31
+ def export
32
+ raise "Delta file doesn't exist when creaing patched file" unless delta_exists?
33
+ tempfile = Tempfile.new('final_file')
34
+ if File.exists?(full_path)
35
+ LibRubyDiff.patch(full_path, delta_file.path, tempfile.path)
36
+ else
37
+ temp_empty_file = Tempfile.new('empty_file')
38
+ LibRubyDiff.patch(temp_empty_file.path, delta_file.path, tempfile.path)
39
+ end
40
+ tempfile.rewind
41
+ File.open(full_path, 'w'){|f| f.write(tempfile.read)}
42
+ tempfile.close
43
+ tempfile.unlink
44
+ File.utime(File.atime(full_path), @desired_modtime, full_path)
45
+ end
46
+
47
+ private
31
48
  def signature_exists?
32
49
  defined?(@signature_tempfile)
33
50
  end
@@ -79,22 +96,6 @@ module Entangler
79
96
  delta_file.read
80
97
  end
81
98
 
82
- def export
83
- raise "Delta file doesn't exist when creaing patched file" unless delta_exists?
84
- tempfile = Tempfile.new('final_file')
85
- if File.exists?(full_path)
86
- LibRubyDiff.patch(full_path, delta_file.path, tempfile.path)
87
- else
88
- temp_empty_file = Tempfile.new('empty_file')
89
- LibRubyDiff.patch(temp_empty_file.path, delta_file.path, tempfile.path)
90
- end
91
- tempfile.rewind
92
- File.open(full_path, 'w'){|f| f.write(tempfile.read)}
93
- tempfile.close
94
- tempfile.unlink
95
- File.utime(File.atime(full_path), @desired_modtime, full_path)
96
- end
97
-
98
99
  def close_and_unlink_files
99
100
  if signature_exists?
100
101
  @signature_tempfile.close
@@ -0,0 +1,108 @@
1
+ module Entangler
2
+ module Executor
3
+ module Background
4
+ module Base
5
+ protected
6
+ def wait_for_threads
7
+ @consumer_thread.join
8
+ @remote_io_thread.join
9
+ @local_io_thread.join
10
+ Process.wait @notify_daemon_pid
11
+ end
12
+
13
+ def kill_off_threads
14
+ Process.kill("TERM", @notify_daemon_pid) rescue nil
15
+ @consumer_thread.terminate
16
+ @remote_io_thread.terminate
17
+ @local_io_thread.terminate
18
+ end
19
+
20
+ def start_notify_daemon
21
+ logger.info('starting notify daemon')
22
+ r,w = IO.pipe
23
+ @notify_daemon_pid = spawn(start_notify_daemon_cmd, out: w)
24
+ w.close
25
+ @notify_reader = r
26
+ end
27
+
28
+ def start_remote_io
29
+ logger.info('starting remote IO')
30
+ @remote_io_thread = Thread.new do
31
+ begin
32
+ loop do
33
+ msg = Marshal.load(@remote_reader)
34
+ next if msg.nil?
35
+
36
+ case msg[:type]
37
+ when :new_changes
38
+ process_new_changes(msg[:content])
39
+ when :entangled_files
40
+ process_entangled_files(msg[:content])
41
+ end
42
+ end
43
+ rescue => e
44
+ $stderr.puts e.message
45
+ $stderr.puts e.backtrace.join("\n")
46
+ kill_off_threads
47
+ end
48
+ end
49
+ end
50
+
51
+ def start_local_io
52
+ logger.info('starting local IO')
53
+ @local_action_queue = Queue.new
54
+ @local_io_thread = Thread.new do
55
+ begin
56
+ msg = []
57
+ loop do
58
+ ready = IO.select([@notify_reader]).first
59
+ next unless ready && ready.any?
60
+ break if ready.first.eof?
61
+ line = ready.first.gets
62
+ next if line.nil? || line.empty?
63
+ line = line.strip
64
+ next if line == '-'
65
+ @local_action_queue.push line
66
+ end
67
+ rescue => e
68
+ $stderr.puts e.message
69
+ $stderr.puts e.backtrace.join("\n")
70
+ kill_off_threads
71
+ end
72
+ end
73
+ end
74
+
75
+ def start_local_consumer
76
+ @consumer_thread = Thread.new do
77
+ loop do
78
+ msg = [@local_action_queue.pop]
79
+ loop do
80
+ sleep 0.2
81
+ break if @local_action_queue.empty?
82
+ while !@local_action_queue.empty?
83
+ msg << @local_action_queue.pop
84
+ end
85
+ end
86
+ while Time.now.to_f <= @notify_sleep
87
+ sleep 0.5
88
+ while !@local_action_queue.empty?
89
+ msg << @local_action_queue.pop
90
+ end
91
+ end
92
+ process_lines(msg.uniq)
93
+ msg = []
94
+ sleep 0.5
95
+ end
96
+ end
97
+ end
98
+
99
+ def start_notify_daemon_cmd
100
+ uname = `uname`.strip.downcase
101
+ raise 'Unsupported OS' unless ['darwin', 'linux'].include?(uname)
102
+
103
+ "#{File.join(File.dirname(File.dirname(File.dirname(File.dirname(__FILE__)))), 'notifier', 'bin', uname, 'notify')} #{self.base_dir}"
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,24 @@
1
+ module Entangler
2
+ module Executor
3
+ module Background
4
+ module Master
5
+ protected
6
+ def start_remote_slave
7
+ require 'open3'
8
+ @remote_writer, @remote_reader, remote_err, @remote_thread = Open3.popen3("ssh -q #{@opts[:remote_user]}@#{@opts[:remote_host]} -p #{@opts[:remote_port]} -C \"source ~/.rvm/environments/default && entangler slave #{@opts[:remote_base_dir]}\"")
9
+ remote_err.close
10
+ end
11
+
12
+ def wait_for_threads
13
+ super
14
+ Process.wait @remote_thread[:pid] rescue nil
15
+ end
16
+
17
+ def kill_off_threads
18
+ Process.kill("INT", @remote_thread[:pid])
19
+ super
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,23 +1,32 @@
1
1
  require 'logger'
2
2
  require 'fileutils'
3
3
  require 'thread'
4
+ require_relative 'background/base'
5
+ require_relative 'processing/base'
4
6
 
5
7
  module Entangler
6
8
  module Executor
7
9
  class Base
10
+ include Entangler::Executor::Background::Base, Entangler::Executor::Processing::Base
11
+
8
12
  attr_reader :base_dir
9
13
 
10
14
  def initialize(base_dir, opts = {})
11
15
  @base_dir = File.realpath(File.expand_path(base_dir))
12
16
  @notify_sleep = 0
17
+ @exported_at = 0
13
18
  @opts = opts
14
19
  @opts[:ignore] = [/^\/\.git.*/, /^\/\.entangler.*/, /^\/\.idea.*/, /^\/log.*/, /^\/tmp.*/] unless @opts.has_key?(:ignore)
15
20
  validate_opts
16
21
  logger.info("Starting executor")
17
22
  end
18
23
 
19
- def validate_opts
20
- raise "Base directory doesn't exist" unless Dir.exists?(self.base_dir)
24
+ def generate_abs_path(rel_path)
25
+ File.join(self.base_dir, rel_path)
26
+ end
27
+
28
+ def strip_base_path(path, base_dir = self.base_dir)
29
+ File.expand_path(path).sub(base_dir, '')
21
30
  end
22
31
 
23
32
  def run
@@ -27,214 +36,18 @@ module Entangler
27
36
  start_local_consumer
28
37
  logger.debug("NOTIFY PID: #{@notify_daemon_pid}")
29
38
  Signal.trap("INT") { kill_off_threads }
30
- @consumer_thread.join
31
- @remote_io_thread.join
32
- @local_io_thread.join
33
- Process.wait @notify_daemon_pid
34
- end
35
-
36
- def kill_off_threads
37
- Process.kill("TERM", @notify_daemon_pid) rescue nil
38
- @consumer_thread.terminate
39
- @remote_io_thread.terminate
40
- @local_io_thread.terminate
41
- end
42
-
43
- def start_file_transfers(paths, pipe)
44
- Marshal.dump(paths.map{|path| EntangledFile.new(path) }, pipe)
39
+ wait_for_threads
45
40
  end
46
41
 
47
- def start_notify_daemon
48
- logger.info('starting notify daemon')
49
- r,w = IO.pipe
50
- @notify_daemon_pid = spawn(start_notify_daemon_cmd, out: w)
51
- w.close
52
- @notify_reader = r
53
- end
54
-
55
- def start_local_io
56
- logger.info('starting local IO')
57
- @local_action_queue = Queue.new
58
- @local_io_thread = Thread.new do
59
- begin
60
- msg = []
61
- loop do
62
- ready = IO.select([@notify_reader]).first
63
- next unless ready && ready.any?
64
- break if ready.first.eof?
65
- line = ready.first.gets
66
- next if line.nil? || line.empty?
67
- line = line.strip
68
- next if line == '-'
69
- @local_action_queue.push line
70
- end
71
- rescue => e
72
- $stderr.puts e.message
73
- $stderr.puts e.backtrace.join("\n")
74
- kill_off_threads
75
- end
76
- end
77
- end
78
-
79
- def start_local_consumer
80
- @consumer_thread = Thread.new do
81
- loop do
82
- msg = [@local_action_queue.pop]
83
- while !@local_action_queue.empty?
84
- msg << @local_action_queue.pop
85
- end
86
- while Time.now.to_i <= @notify_sleep
87
- sleep 1
88
- while !@local_action_queue.empty?
89
- msg << @local_action_queue.pop
90
- end
91
- end
92
- process_lines(msg.uniq)
93
- msg = []
94
- sleep 1
95
- end
96
- end
42
+ protected
43
+ def validate_opts
44
+ raise "Base directory doesn't exist" unless Dir.exists?(self.base_dir)
97
45
  end
98
46
 
99
47
  def send_to_remote(msg = {})
100
48
  Marshal.dump(msg, @remote_writer)
101
49
  end
102
50
 
103
- def start_remote_io
104
- logger.info('starting remote IO')
105
- @remote_io_thread = Thread.new do
106
- begin
107
- loop do
108
- msg = Marshal.load(@remote_reader)
109
- next if msg.nil?
110
-
111
- case msg[:type]
112
- when :new_changes
113
- logger.debug("Got #{msg[:content].length} new folder changes from remote")
114
-
115
- created_dirs = []
116
- dirs_to_remove = []
117
- files_to_remove = []
118
- files_to_update = []
119
-
120
- msg[:content].each do |base, changes|
121
- possible_creation_dirs = changes[:dirs].clone
122
- possible_creation_files = changes[:files].keys.clone
123
- full_base_path = generate_abs_path(base)
124
-
125
- unless File.directory?(full_base_path)
126
- FileUtils::mkdir_p(full_base_path)
127
- @notify_sleep = Time.now.to_i + 60
128
- end
129
-
130
- Dir.entries(full_base_path).each do |f|
131
- next if ['.', '..'].include? f
132
- full_path = File.join(generate_abs_path(base), f)
133
- if File.directory?(full_path)
134
- possible_creation_dirs -= [f]
135
- dirs_to_remove << full_path unless changes[:dirs].include?(f)
136
- elsif changes[:files].has_key?(f)
137
- possible_creation_files -= [f]
138
- files_to_update << File.join(base, f) unless changes[:files][f] == [File.size(full_path), File.mtime(full_path).to_i]
139
- else
140
- files_to_remove << full_path
141
- end
142
- end
143
-
144
- dirs_to_create = possible_creation_dirs.map{|d| File.join(generate_abs_path(base), d)}
145
- if dirs_to_create.any?
146
- logger.debug("Creating #{dirs_to_create.length} dirs")
147
- @notify_sleep = Time.now.to_i + 60
148
- FileUtils.mkdir_p dirs_to_create
149
- end
150
- created_dirs += dirs_to_create
151
- files_to_update += possible_creation_files.map{|f| File.join(base, f)}
152
- end
153
-
154
- @notify_sleep = Time.now.to_i + 60 if (files_to_remove + created_dirs + dirs_to_remove + files_to_update).any?
155
-
156
- if files_to_remove.any?
157
- logger.debug("Deleting #{files_to_remove.length} files")
158
- FileUtils.rm files_to_remove
159
- end
160
- if dirs_to_remove.any?
161
- logger.debug("Deleting #{dirs_to_remove.length} dirs")
162
- FileUtils.rm_r dirs_to_remove
163
- end
164
- if files_to_update.any?
165
- logger.debug("Creating #{files_to_update.length} new entangled files to sync")
166
- send_to_remote(type: :entangled_files, content: files_to_update.map{|f| Entangler::EntangledFile.new(f) })
167
- end
168
- @notify_sleep = Time.now.to_i + 1 if (files_to_remove + created_dirs + dirs_to_remove + files_to_update).any?
169
- @notify_sleep += 60 if files_to_update.any?
170
- when :entangled_files
171
- logger.debug("Got #{msg[:content].length} entangled files from remote")
172
- completed_files, updated_files = msg[:content].partition(&:done?)
173
-
174
- completed_files.each(&:export)
175
-
176
- updated_files = updated_files.find_all{|f| f.state != 1 || f.file_exists? }
177
- if updated_files.any?
178
- send_to_remote(type: :entangled_files, content: updated_files)
179
- end
180
- @notify_sleep = Time.now.to_i + 1 if completed_files.any?
181
- end
182
- end
183
- rescue => e
184
- $stderr.puts e.message
185
- $stderr.puts e.backtrace.join("\n")
186
- kill_off_threads
187
- end
188
- end
189
- end
190
-
191
- def process_lines(lines)
192
- to_process = lines.map do |line|
193
- path = line[2..-1]
194
- stripped_path = strip_base_path(path)
195
- next unless @opts[:ignore].nil? || @opts[:ignore].none?{|i| stripped_path.match(i) }
196
- next unless File.directory?(path)
197
-
198
- [stripped_path, generate_file_list(path)]
199
- end.compact.sort_by(&:first)
200
-
201
- return unless to_process.any?
202
- logger.debug("PROCESSING #{to_process.count} folder/s")
203
- send_to_remote(type: :new_changes, content: to_process)
204
- end
205
-
206
- def generate_file_list(path)
207
- dirs = []
208
- files = {}
209
-
210
- Dir.entries(path).each do |f|
211
- next if ['.', '..'].include? f
212
- f_path = File.join(path, f)
213
- if File.directory? f_path
214
- dirs << f
215
- else
216
- files[f] = [File.size(f_path), File.mtime(f_path).to_i]
217
- end
218
- end
219
-
220
- {dirs: dirs, files: files}
221
- end
222
-
223
- def generate_abs_path(rel_path)
224
- File.join(self.base_dir, rel_path)
225
- end
226
-
227
- def strip_base_path(path, base_dir = self.base_dir)
228
- File.expand_path(path).sub(base_dir, '')
229
- end
230
-
231
- def start_notify_daemon_cmd
232
- uname = `uname`.strip.downcase
233
- raise 'Unsupported OS' unless ['darwin', 'linux'].include?(uname)
234
-
235
- "#{File.join(File.dirname(File.dirname(File.dirname(__FILE__))), 'notifier', 'bin', uname, 'notify')} #{self.base_dir}"
236
- end
237
-
238
51
  def logger
239
52
  FileUtils::mkdir_p log_dir
240
53
  @logger ||= Logger.new(File.join(log_dir, 'entangler.log'))
@@ -1,30 +1,29 @@
1
+ require_relative 'background/master'
2
+
1
3
  module Entangler
2
4
  module Executor
3
5
  class Master < Base
4
- def validate_opts
5
- super
6
- raise 'Missing remote base dir' unless @opts.keys.include?(:remote_base_dir)
7
- raise 'Missing remote user' unless @opts.keys.include?(:remote_user)
8
- raise 'Missing remote host' unless @opts.keys.include?(:remote_host)
9
- @opts[:remote_port] ||= '22'
10
- res = `ssh -q #{@opts[:remote_user]}@#{@opts[:remote_host]} -p #{@opts[:remote_port]} -C "[[ -d '#{@opts[:remote_base_dir]}' ]] && echo 'ok' || echo 'missing'"`
11
- raise 'Cannot connect to remote' if res.empty?
12
- raise 'Remote base dir invalid' unless res.strip == 'ok'
13
- end
6
+ include Entangler::Executor::Background::Master
14
7
 
15
8
  def run
16
9
  perform_initial_rsync
17
10
  sleep 1
18
11
  start_remote_slave
19
12
  super
20
- Process.wait @remote_thread[:pid] rescue nil
21
13
  @remote_writer.close
22
14
  @remote_reader.close
23
15
  end
24
16
 
25
- def kill_off_threads
26
- Process.kill("INT", @remote_thread[:pid])
17
+ private
18
+ def validate_opts
27
19
  super
20
+ raise 'Missing remote base dir' unless @opts.keys.include?(:remote_base_dir)
21
+ raise 'Missing remote user' unless @opts.keys.include?(:remote_user)
22
+ raise 'Missing remote host' unless @opts.keys.include?(:remote_host)
23
+ @opts[:remote_port] ||= '22'
24
+ res = `ssh -q #{@opts[:remote_user]}@#{@opts[:remote_host]} -p #{@opts[:remote_port]} -C "[[ -d '#{@opts[:remote_base_dir]}' ]] && echo 'ok' || echo 'missing'"`
25
+ raise 'Cannot connect to remote' if res.empty?
26
+ raise 'Remote base dir invalid' unless res.strip == 'ok'
28
27
  end
29
28
 
30
29
  def perform_initial_rsync
@@ -34,12 +33,6 @@ module Entangler
34
33
  end
35
34
  logger.debug 'Initial sync complete'
36
35
  end
37
-
38
- def start_remote_slave
39
- require 'open3'
40
- @remote_writer, @remote_reader, remote_err, @remote_thread = Open3.popen3("ssh -q #{@opts[:remote_user]}@#{@opts[:remote_host]} -p #{@opts[:remote_port]} -C \"source ~/.rvm/environments/default && entangler slave #{@opts[:remote_base_dir]}\"")
41
- remote_err.close
42
- end
43
36
  end
44
37
  end
45
38
  end
@@ -0,0 +1,122 @@
1
+ module Entangler
2
+ module Executor
3
+ module Processing
4
+ module Base
5
+ protected
6
+ def generate_file_list(path)
7
+ dirs = []
8
+ files = {}
9
+
10
+ Dir.entries(path).each do |f|
11
+ next if ['.', '..'].include? f
12
+ f_path = File.join(path, f)
13
+ if File.directory? f_path
14
+ dirs << f
15
+ else
16
+ files[f] = [File.size(f_path), File.mtime(f_path).to_i]
17
+ end
18
+ end
19
+
20
+ {dirs: dirs, files: files}
21
+ end
22
+
23
+ def process_new_changes(content)
24
+ logger.debug("Got #{content.length} new folder changes from remote")
25
+
26
+ created_dirs = []
27
+ dirs_to_remove = []
28
+ files_to_remove = []
29
+ files_to_update = []
30
+
31
+ content.each do |base, changes|
32
+ possible_creation_dirs = changes[:dirs].clone
33
+ possible_creation_files = changes[:files].keys.clone
34
+ full_base_path = generate_abs_path(base)
35
+
36
+ unless File.directory?(full_base_path)
37
+ FileUtils::mkdir_p(full_base_path)
38
+ @notify_sleep = Time.now.to_i + 60
39
+ end
40
+
41
+ Dir.entries(full_base_path).each do |f|
42
+ next if ['.', '..'].include? f
43
+ full_path = File.join(generate_abs_path(base), f)
44
+ if File.directory?(full_path)
45
+ possible_creation_dirs -= [f]
46
+ dirs_to_remove << full_path unless changes[:dirs].include?(f)
47
+ elsif changes[:files].has_key?(f)
48
+ possible_creation_files -= [f]
49
+ files_to_update << File.join(base, f) unless changes[:files][f] == [File.size(full_path), File.mtime(full_path).to_i]
50
+ else
51
+ files_to_remove << full_path
52
+ end
53
+ end
54
+
55
+ dirs_to_create = possible_creation_dirs.map{|d| File.join(generate_abs_path(base), d)}
56
+ if dirs_to_create.any?
57
+ logger.debug("Creating #{dirs_to_create.length} dirs")
58
+ @notify_sleep = Time.now.to_i + 60
59
+ FileUtils.mkdir_p dirs_to_create
60
+ end
61
+ created_dirs += dirs_to_create
62
+ files_to_update += possible_creation_files.map{|f| File.join(base, f)}
63
+ end
64
+
65
+ @notify_sleep = Time.now.to_i + 60 if (files_to_remove + created_dirs + dirs_to_remove + files_to_update).any?
66
+
67
+ if files_to_remove.any?
68
+ logger.debug("Deleting #{files_to_remove.length} files")
69
+ FileUtils.rm files_to_remove
70
+ end
71
+ if dirs_to_remove.any?
72
+ logger.debug("Deleting #{dirs_to_remove.length} dirs")
73
+ FileUtils.rm_r dirs_to_remove
74
+ end
75
+ if files_to_update.any?
76
+ logger.debug("Creating #{files_to_update.length} new entangled files to sync")
77
+ send_to_remote(type: :entangled_files, content: files_to_update.map{|f| Entangler::EntangledFile.new(f) })
78
+ end
79
+ @notify_sleep = Time.now.to_f + 0.5 if (files_to_remove + created_dirs + dirs_to_remove + files_to_update).any?
80
+ @notify_sleep += 60 if files_to_update.any?
81
+ end
82
+
83
+ def process_entangled_files(content)
84
+ logger.debug("Got #{content.length} entangled files from remote")
85
+ completed_files, updated_files = content.partition(&:done?)
86
+
87
+ if completed_files.any?
88
+ @exported_at = Time.now.to_f
89
+ @exported_folders = completed_files.map{|ef| "#{File.dirname(generate_abs_path(ef.path))}/" }.uniq
90
+ completed_files.each(&:export)
91
+ end
92
+
93
+ updated_files = updated_files.find_all{|f| f.state != 1 || f.file_exists? }
94
+ if updated_files.any?
95
+ send_to_remote(type: :entangled_files, content: updated_files)
96
+ end
97
+ @notify_sleep = Time.now.to_f + 0.5 if completed_files.any?
98
+ end
99
+
100
+ def process_lines(lines)
101
+ paths = lines.map{|line| line[2..-1] }
102
+
103
+ if @exported_at < Time.now.to_f && Time.now.to_f < @exported_at + 2
104
+ paths -= @exported_folders
105
+ end
106
+
107
+ to_process = paths.map do |path|
108
+ stripped_path = strip_base_path(path)
109
+ next unless @opts[:ignore].nil? || @opts[:ignore].none?{|i| stripped_path.match(i) }
110
+ next unless File.directory?(path)
111
+
112
+ [stripped_path, generate_file_list(path)]
113
+ end.compact.sort_by(&:first)
114
+
115
+ return unless to_process.any?
116
+ logger.debug("PROCESSING #{to_process.count} folder/s")
117
+ send_to_remote(type: :new_changes, content: to_process)
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -1,3 +1,3 @@
1
1
  module Entangler
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
data/lib/entangler.rb CHANGED
@@ -1,5 +1,5 @@
1
- require 'entangler/version'
2
- require 'entangler/entangled_file'
1
+ require_relative 'entangler/version'
2
+ require_relative 'entangler/entangled_file'
3
3
 
4
4
  module Entangler
5
5
  class << self
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: entangler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dave Allie
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-10-24 00:00:00.000000000 Z
11
+ date: 2016-10-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -88,8 +88,11 @@ files:
88
88
  - exe/entangler
89
89
  - lib/entangler.rb
90
90
  - lib/entangler/entangled_file.rb
91
+ - lib/entangler/executor/background/base.rb
92
+ - lib/entangler/executor/background/master.rb
91
93
  - lib/entangler/executor/base.rb
92
94
  - lib/entangler/executor/master.rb
95
+ - lib/entangler/executor/processing/base.rb
93
96
  - lib/entangler/executor/slave.rb
94
97
  - lib/entangler/version.rb
95
98
  - lib/notifier/bin/darwin/notify