hubeye 0.3.3 → 0.3.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.
- data/README.md +59 -40
- data/VERSION.rb +2 -2
- data/bin/hubeye +7 -12
- data/lib/hubeye/client/client.rb +3 -5
- data/lib/hubeye/config/environment.rb +0 -1
- data/lib/hubeye/hooks/{executer.rb → command.rb} +8 -4
- data/lib/hubeye/hooks/git.rb +19 -0
- data/lib/hubeye/log/logger.rb +1 -0
- data/lib/hubeye/server/commit.rb +17 -39
- data/lib/hubeye/server/server.rb +79 -531
- data/lib/hubeye/server/session.rb +5 -32
- data/lib/hubeye/server/strategies/add_hook.rb +32 -0
- data/lib/hubeye/server/strategies/add_repo.rb +91 -0
- data/lib/hubeye/server/strategies/decision.rb +121 -0
- data/lib/hubeye/server/strategies/exit.rb +23 -0
- data/lib/hubeye/server/strategies/list_hooks.rb +38 -0
- data/lib/hubeye/server/strategies/list_tracking.rb +27 -0
- data/lib/hubeye/server/strategies/load_hook.rb +34 -0
- data/lib/hubeye/server/strategies/load_repo.rb +35 -0
- data/lib/hubeye/server/strategies/next.rb +13 -0
- data/lib/hubeye/server/strategies/rm_repo.rb +34 -0
- data/lib/hubeye/server/strategies/save_hook.rb +31 -0
- data/lib/hubeye/server/strategies/save_repo.rb +31 -0
- data/lib/hubeye/server/strategies/shutdown.rb +23 -0
- data/lib/hubeye/server/tracker.rb +89 -0
- data/tasks/install.rb +8 -9
- data/test/helpers/server.rb +39 -0
- metadata +19 -4
- data/lib/hubeye/hooks/git_hooks.rb +0 -19
data/lib/hubeye/server/server.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
require "hubeye/shared/hubeye_protocol"
|
2
2
|
require "hubeye/log/logger"
|
3
3
|
require "hubeye/helpers/time"
|
4
|
+
require "hubeye/config/parser"
|
5
|
+
require "hubeye/notification/finder"
|
6
|
+
require "hubeye/hooks/command"
|
7
|
+
require "hubeye/hooks/git"
|
8
|
+
|
9
|
+
require File.expand_path("../strategies/decision", __FILE__)
|
10
|
+
require File.expand_path("../tracker", __FILE__)
|
11
|
+
require File.expand_path("../session", __FILE__)
|
4
12
|
|
5
13
|
include Hubeye::Helpers::Time
|
6
14
|
include Hubeye::Log
|
@@ -8,20 +16,7 @@ include Hubeye::Log
|
|
8
16
|
module Hubeye
|
9
17
|
module Server
|
10
18
|
attr_accessor :remote_connection
|
11
|
-
attr_reader :socket, :sockets, :session, :daemonized
|
12
|
-
|
13
|
-
require 'yaml'
|
14
|
-
require 'json'
|
15
|
-
require 'open-uri'
|
16
|
-
require 'forwardable'
|
17
|
-
|
18
|
-
require_relative "commit"
|
19
|
-
require_relative "session"
|
20
|
-
|
21
|
-
require "hubeye/config/parser"
|
22
|
-
require "hubeye/notification/finder"
|
23
|
-
require "hubeye/hooks/git_hooks"
|
24
|
-
require "hubeye/hooks/executer"
|
19
|
+
attr_reader :socket, :sockets, :tracker, :session, :daemonized
|
25
20
|
|
26
21
|
CONFIG_FILE = File.join(ENV['HOME'], ".hubeye", "hubeyerc")
|
27
22
|
CONFIG = {}
|
@@ -61,495 +56,57 @@ module Hubeye
|
|
61
56
|
end
|
62
57
|
|
63
58
|
if CONFIG[:notification_wanted]
|
64
|
-
CONFIG[:desktop_notification] =
|
65
|
-
Notification::Finder.find_notify
|
66
|
-
end
|
67
|
-
|
68
|
-
class Exit
|
69
|
-
def call
|
70
|
-
socket = server.socket
|
71
|
-
session = server.session
|
72
|
-
socket.deliver "Bye!"
|
73
|
-
# mark the session as continuous to not wipe the log file
|
74
|
-
session.continuous = true
|
75
|
-
Logger.log "Closing connection to #{socket.peeraddr[2]}"
|
76
|
-
server.remote_connection = false
|
77
|
-
unless session.tracker.empty?
|
78
|
-
Logger.log "Tracking: #{session.tracker.keys.join ', '}"
|
79
|
-
end
|
80
|
-
Logger.log ""
|
81
|
-
server.sockets.delete(socket)
|
82
|
-
socket.close
|
83
|
-
end
|
59
|
+
CONFIG[:desktop_notification] = Notification::Finder.find_notify
|
84
60
|
end
|
85
61
|
|
86
|
-
|
87
|
-
def call
|
88
|
-
socket = server.socket
|
89
|
-
Logger.log "Closing connection to #{socket.peeraddr[2]}"
|
90
|
-
Logger.log "Shutting down... (#{NOW})"
|
91
|
-
Logger.log ""
|
92
|
-
Logger.log ""
|
93
|
-
socket.deliver "Shutting down server"
|
94
|
-
server.sockets.delete(socket)
|
95
|
-
socket.close
|
96
|
-
unless server.daemonized
|
97
|
-
STDOUT.puts "Shutting down gracefully."
|
98
|
-
end
|
99
|
-
exit 0
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
class SaveHook
|
104
|
-
def call
|
105
|
-
socket = server.socket
|
106
|
-
hooks = server.session.hooks
|
107
|
-
if !hooks.empty?
|
108
|
-
file = "#{ENV['HOME']}/.hubeye/hooks/#{@matches[2]}.yml"
|
109
|
-
if File.exists? file
|
110
|
-
override?
|
111
|
-
end
|
112
|
-
File.open(file, "w") do |f_out|
|
113
|
-
::YAML.dump(hooks, f_out)
|
114
|
-
end
|
115
|
-
socket.deliver "Saved hook#{@matches[1]} as #{@matches[2]}"
|
116
|
-
else
|
117
|
-
socket.deliver "No hook#{@matches[1]} to save"
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
private
|
122
|
-
def override?
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
class SaveRepo
|
127
|
-
def call
|
128
|
-
socket = server.socket
|
129
|
-
if !server.session.tracker.empty?
|
130
|
-
file = "#{ENV['HOME']}/.hubeye/repos/#{@matches[2]}.yml"
|
131
|
-
if File.exists? file
|
132
|
-
override?
|
133
|
-
end
|
134
|
-
# dump only the repository names, not the shas
|
135
|
-
File.open(file, "w") do |f_out|
|
136
|
-
::YAML.dump(server.session.tracker.keys, f_out)
|
137
|
-
end
|
138
|
-
socket.deliver "Saved repo#{@matches[1]} as #{@matches[2]}"
|
139
|
-
else
|
140
|
-
socket.deliver "No remote repos are being tracked"
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
private
|
145
|
-
def override?
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
class LoadHook
|
150
|
-
def call
|
151
|
-
socket = server.socket
|
152
|
-
if _t = @options[:internal]
|
153
|
-
@silent = _t
|
154
|
-
end
|
155
|
-
hookfile = "#{ENV['HOME']}/.hubeye/hooks/#{@matches[2]}.yml"
|
156
|
-
new_hooks = nil
|
157
|
-
if File.exists?(hookfile)
|
158
|
-
File.open(hookfile) do |f|
|
159
|
-
new_hooks = ::YAML.load(f)
|
160
|
-
end
|
161
|
-
# need to fix this to check if there are already commands for that
|
162
|
-
# repo
|
163
|
-
server.session.hooks.merge!(new_hooks)
|
164
|
-
unless @silent
|
165
|
-
socket.deliver "Loaded #{@matches[1]} #{@matches[2]}"
|
166
|
-
end
|
167
|
-
else
|
168
|
-
unless @silent
|
169
|
-
socket.deliver "No #{@matches[1]} file to load from"
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
class LoadRepo
|
176
|
-
def call
|
177
|
-
socket = server.socket
|
178
|
-
if _t = @options[:internal]
|
179
|
-
@silent = _t
|
180
|
-
end
|
181
|
-
if File.exists?(repo_file = "#{ENV['HOME']}/.hubeye/repos/#{@matches[2]}.yml")
|
182
|
-
new_repos = nil
|
183
|
-
File.open(repo_file) do |f|
|
184
|
-
new_repos = ::YAML.load(f)
|
185
|
-
end
|
186
|
-
if !new_repos
|
187
|
-
socket.deliver "Unable to load #{@matches[2]}: empty file" unless @silent
|
188
|
-
return
|
189
|
-
end
|
190
|
-
new_repos.each do |r|
|
191
|
-
# add the repo name to the hubeye tracker
|
192
|
-
commit = server.track(r)
|
193
|
-
server.session.tracker.add_or_replace!(commit.repo, commit.sha)
|
194
|
-
end
|
195
|
-
unless @silent
|
196
|
-
socket.deliver "Loaded #{@matches[2]}.\nTracking:\n#{server.session.tracker.keys.join ', '}"
|
197
|
-
end
|
198
|
-
else
|
199
|
-
socket.deliver "No file to load from" unless @silent
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
class AddHook
|
205
|
-
def call
|
206
|
-
socket = server.socket
|
207
|
-
cwd = File.expand_path('.')
|
208
|
-
repo = @matches[1]
|
209
|
-
_dir = @matches[3]
|
210
|
-
cmd = @matches[4]
|
211
|
-
hooks = server.session.hooks
|
212
|
-
if repo.nil? and cmd.nil?
|
213
|
-
socket.deliver "Format: 'hook add user/repo [dir: /my/dir/repo ] cmd: some_cmd'"
|
214
|
-
return
|
215
|
-
end
|
216
|
-
if hooks[repo]
|
217
|
-
_dir ? dir = _dir : dir = cwd
|
218
|
-
if hooks[repo][dir]
|
219
|
-
hooks[repo][dir] << cmd
|
220
|
-
else
|
221
|
-
hooks[repo][dir] = [cmd]
|
222
|
-
end
|
223
|
-
else
|
224
|
-
dir = _dir || cwd
|
225
|
-
hooks[repo] = {dir => [cmd]}
|
226
|
-
end
|
227
|
-
socket.deliver "Hook added"
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
class ListHooks
|
232
|
-
def call
|
233
|
-
socket = server.socket
|
234
|
-
hooks = server.session.hooks
|
235
|
-
if hooks.empty?
|
236
|
-
socket.deliver "No hooks"
|
237
|
-
return
|
238
|
-
end
|
239
|
-
pwd = File.expand_path('.')
|
240
|
-
format_string = ""
|
241
|
-
hooks.each do |repo, hash|
|
242
|
-
local_dir = nil
|
243
|
-
command = nil
|
244
|
-
hash.each do |dir,cmd|
|
245
|
-
if dir.nil?
|
246
|
-
local_dir = pwd
|
247
|
-
command = cmd.join("\n" + (' ' * 8))
|
248
|
-
else
|
249
|
-
command = cmd
|
250
|
-
local_dir = dir
|
251
|
-
end
|
252
|
-
end
|
253
|
-
format_string << <<EOS
|
254
|
-
remote: #{repo}
|
255
|
-
dir: #{local_dir}
|
256
|
-
cmds: #{command}\n
|
257
|
-
EOS
|
258
|
-
end
|
259
|
-
socket.deliver format_string
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
class ListTracking
|
264
|
-
def call
|
265
|
-
socket = server.socket
|
266
|
-
tracker = server.session.tracker
|
267
|
-
output = ''
|
268
|
-
if @options[:details]
|
269
|
-
commit_list = []
|
270
|
-
tracker.keys.each do |repo|
|
271
|
-
commit = server.track(repo, :list => true)
|
272
|
-
commit_list << commit
|
273
|
-
end
|
274
|
-
commit_list.each do |c|
|
275
|
-
output << c.repo + "\n"
|
276
|
-
underline = '=' * c.repo.length
|
277
|
-
output << underline + "\n\n"
|
278
|
-
output << c.commit_message + "\n=> " +
|
279
|
-
c.committer_name + "\n"
|
280
|
-
output << "\n" unless c.repo == commit_list.last.repo
|
281
|
-
end
|
282
|
-
else
|
283
|
-
output << tracker.keys.join(', ')
|
284
|
-
end
|
285
|
-
output = "none" if output.empty?
|
286
|
-
socket.deliver output
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
class Next
|
291
|
-
def call
|
292
|
-
server.socket.deliver ""
|
293
|
-
end
|
294
|
-
end
|
295
|
-
|
296
|
-
class RmRepo
|
297
|
-
def call
|
298
|
-
socket = server.socket
|
299
|
-
session = server.session
|
300
|
-
username = session.username
|
301
|
-
repo_name = session.repo_name
|
302
|
-
m1 = @matches[1]
|
303
|
-
if m1.include?('/')
|
304
|
-
username, repo_name = m1.split('/')
|
305
|
-
else
|
306
|
-
repo_name = m1
|
307
|
-
end
|
308
|
-
full_repo_name = "#{username}/#{repo_name}"
|
309
|
-
rm = session.tracker.delete(full_repo_name)
|
310
|
-
if rm
|
311
|
-
socket.deliver "Stopped watching repository #{full_repo_name}"
|
312
|
-
else
|
313
|
-
socket.deliver "Repository #{full_repo_name} not currently being watched"
|
314
|
-
end
|
315
|
-
end
|
316
|
-
end
|
317
|
-
|
318
|
-
class AddRepo
|
319
|
-
def call
|
320
|
-
session = server.session
|
321
|
-
if @options and @options[:fullpath]
|
322
|
-
session.username, session.repo_name = input.split('/')
|
323
|
-
else
|
324
|
-
session.repo_name = input
|
325
|
-
end
|
326
|
-
add_repo
|
327
|
-
end
|
328
|
-
|
329
|
-
private
|
330
|
-
def add_repo
|
331
|
-
socket = server.socket
|
332
|
-
session = server.session
|
333
|
-
full_repo_name = "#{session.username}/#{session.repo_name}"
|
334
|
-
commit = server.track(full_repo_name, :latest => true)
|
335
|
-
new_sha = commit.sha
|
336
|
-
commit_msg = commit.commit_message
|
337
|
-
committer = commit.committer_name
|
338
|
-
msg = "#{commit_msg}\n=> #{committer}"
|
339
|
-
change = session.tracker.add_or_replace!(full_repo_name, new_sha)
|
340
|
-
# new repo to track
|
341
|
-
if !change
|
342
|
-
socket.deliver "Repository #{full_repo_name} has not changed"
|
343
|
-
return
|
344
|
-
elsif change[:add]
|
345
|
-
# log the fact that the user added a repo to be tracked
|
346
|
-
Logger.log("Added to tracker: #{full_repo_name} (#{NOW})")
|
347
|
-
# show the user, via the client, the info and commit msg for the commit
|
348
|
-
socket.deliver msg
|
349
|
-
elsif change[:replace]
|
350
|
-
change_msg = "New commit on #{full_repo_name}\n"
|
351
|
-
change_msg << msg
|
352
|
-
socket.deliver change_msg
|
353
|
-
if server.daemonized
|
354
|
-
Logger.log_change(full_repo_name, commit_msg, committer)
|
355
|
-
else
|
356
|
-
Logger.log_change(full_repo_name, commit_msg, committer,
|
357
|
-
:include_terminal => true)
|
358
|
-
end
|
359
|
-
end
|
360
|
-
end
|
361
|
-
end
|
362
|
-
|
363
|
-
class Strategy
|
364
|
-
attr_reader :server, :input
|
365
|
-
|
366
|
-
UnknownStrategy = Class.new(StandardError)
|
367
|
-
extend Forwardable
|
368
|
-
def_delegator :@server, :socket
|
369
|
-
|
370
|
-
def initialize(server, options={})
|
371
|
-
@server = server
|
372
|
-
opts = {:internal_input => nil}.merge options
|
373
|
-
invalid_input = lambda {
|
374
|
-
@server.remote_connection = false
|
375
|
-
throw(:invalid_input)
|
376
|
-
}
|
377
|
-
|
378
|
-
if !opts[:internal_input]
|
379
|
-
begin
|
380
|
-
@input = socket.read_all
|
381
|
-
rescue => e
|
382
|
-
STDOUT.puts e
|
383
|
-
invalid_input.call
|
384
|
-
end
|
385
|
-
# check if the client pressed ^C or ^D
|
386
|
-
if @input.nil?
|
387
|
-
invalid_input.call
|
388
|
-
end
|
389
|
-
else
|
390
|
-
@input = opts[:internal_input]
|
391
|
-
end
|
392
|
-
@input = @input.strip.downcase
|
393
|
-
@input.gsub! /diiv/, '/'
|
394
|
-
end
|
395
|
-
|
396
|
-
STRATEGY_CLASSES = [ "Shutdown", "Exit", "SaveHook", "SaveRepo",
|
397
|
-
"LoadHook", "LoadRepo", "AddHook", "ListHooks", "ListTracking",
|
398
|
-
"Next", "RmRepo", "AddRepo" ]
|
399
|
-
|
400
|
-
STRATEGY_CLASSES.each do |klass_str|
|
401
|
-
klass = eval "::Hubeye::Server::#{klass_str}"
|
402
|
-
klass.class_eval do
|
403
|
-
extend Forwardable
|
404
|
-
def_delegators :@strategy, :input, :server
|
405
|
-
def initialize matches, strategy, options={}
|
406
|
-
@matches = matches
|
407
|
-
@strategy = strategy
|
408
|
-
@options = options
|
409
|
-
call
|
410
|
-
end
|
411
|
-
end
|
412
|
-
end
|
413
|
-
|
414
|
-
# strategy classes
|
415
|
-
|
416
|
-
# STRATEGIES hash
|
417
|
-
# ===============
|
418
|
-
# keys: input matches
|
419
|
-
# OR
|
420
|
-
# lambda {|input| input.something?} => value
|
421
|
-
#
|
422
|
-
# values: lambda {|matchdata, basestrategy| SomeStrategy.new(matchdata, basestrategy)}
|
423
|
-
STRATEGIES = {
|
424
|
-
%r{\Ashutdown\Z} => lambda {|m, s| Shutdown.new(m, s)},
|
425
|
-
%r{\Aquit|exit\Z} => lambda {|m, s| Exit.new(m, s)},
|
426
|
-
%r{\Atracking\s*\Z} => lambda {|m, s| ListTracking.new(m, s)},
|
427
|
-
%r{\Atracking\s*-d\Z} => lambda {|m, s| ListTracking.new(m, s, :details => true)},
|
428
|
-
%r{\A\s*save hook(s?) as (.+)\Z} => lambda {|m, s| SaveHook.new(m, s)},
|
429
|
-
%r{\A\s*save repo(s?) as (.+)\Z} => lambda {|m, s| SaveRepo.new(m, s)},
|
430
|
-
%r{\A\s*load hook(s?) (.+)\Z} => lambda {|m, s| LoadHook.new(m, s)},
|
431
|
-
%r{\A\s*load repo(s?) (.+)\Z} => lambda {|m, s| LoadRepo.new(m, s)},
|
432
|
-
%r{\A\s*internal load hook(s?) (.+)\Z} => lambda {|m, s| LoadHook.new(m, s, :internal => true)},
|
433
|
-
%r{\A\s*internal load repo(s?) (.+)\Z} => lambda {|m, s| LoadRepo.new(m, s, :internal => true)},
|
434
|
-
%r{\Ahook add ([-\w]+/[-\w]+) (dir:\s?(.*))?\s*cmd:\s?(.*)\Z} => lambda {|m, s| AddHook.new(m, s)},
|
435
|
-
%r{\Ahook list\Z} => lambda {|m, s| ListHooks.new(m, s)},
|
436
|
-
%r{^\s*$} => lambda {|m, s| Next.new(m, s)},
|
437
|
-
%r{\Arm ([-\w]+/?[-\w]*)\Z} => lambda {|m, s| RmRepo.new(m, s)},
|
438
|
-
lambda {|inp| inp.include? '/'} => lambda {|m, s| AddRepo.new(m, s, :fullpath => true)},
|
439
|
-
lambda {|inp| not inp.nil?} => lambda {|m, s| AddRepo.new(m, s)}
|
440
|
-
}
|
441
|
-
|
442
|
-
def call
|
443
|
-
STRATEGIES.each do |inp,strat|
|
444
|
-
if inp.respond_to? :match
|
445
|
-
if m = @input.match(inp)
|
446
|
-
return strat.call(m, self)
|
447
|
-
end
|
448
|
-
elsif inp.respond_to? :call
|
449
|
-
if m = inp.call(@input)
|
450
|
-
return strat.call(m, self)
|
451
|
-
end
|
452
|
-
end
|
453
|
-
end
|
454
|
-
raise UnknownStrategy
|
455
|
-
end
|
456
|
-
end # end of Strategy
|
457
|
-
|
458
|
-
|
62
|
+
# main server loop
|
459
63
|
def start(port, options={})
|
460
64
|
listen(port)
|
461
65
|
setup_env(options)
|
462
66
|
loop do
|
463
|
-
|
464
|
-
look_for_changes
|
67
|
+
unless @remote_connection
|
68
|
+
look_for_changes
|
69
|
+
client_connect(@sockets)
|
465
70
|
end
|
466
|
-
client_connect(@sockets) if waiting
|
467
71
|
catch(:invalid_input) do
|
468
|
-
|
469
|
-
|
72
|
+
decision = Strategies::Decision.new(self)
|
73
|
+
decision.call_strategy
|
470
74
|
end
|
471
|
-
@session.cleanup
|
75
|
+
@session.cleanup!
|
472
76
|
end
|
473
77
|
end
|
474
78
|
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
# Options: :sha, :latest, :full, :list (all boolean).
|
479
|
-
# The :list => true option gives back the commit object from the list.
|
480
|
-
list = []
|
481
|
-
|
482
|
-
define_method :track do |repo, options={}|
|
483
|
-
if repo.include? '/'
|
484
|
-
username, repo_name = repo.split '/'
|
485
|
-
full_repo_name = repo
|
486
|
-
else
|
487
|
-
username, repo_name = @session.username, repo
|
488
|
-
full_repo_name = "#{username}/#{repo_name}"
|
489
|
-
end
|
490
|
-
unless options[:list]
|
491
|
-
hist = nil
|
492
|
-
begin
|
493
|
-
open "https://api.github.com/repos/#{username}/" \
|
494
|
-
"#{repo_name}/commits" do |f|
|
495
|
-
hist = JSON.parse f.read
|
496
|
-
end
|
497
|
-
rescue
|
498
|
-
@socket.deliver "Not a Github repository name"
|
499
|
-
throw(:invalid_input)
|
500
|
-
end
|
501
|
-
new_info =
|
502
|
-
{full_repo_name =>
|
503
|
-
{'sha' => hist.first['sha'],
|
504
|
-
'commit' =>
|
505
|
-
{'message' => hist.first['commit']['message'],
|
506
|
-
'committer' => {'name' => hist.first['commit']['committer']['name']}
|
507
|
-
}
|
508
|
-
}
|
509
|
-
}
|
510
|
-
commit = Commit.new(new_info)
|
511
|
-
# update the list
|
512
|
-
list.reject! {|cmt| cmt.repo == full_repo_name}
|
513
|
-
list << commit
|
514
|
-
end
|
515
|
-
if options[:full]
|
516
|
-
# unsupported so far
|
517
|
-
raise ArgumentError.new
|
518
|
-
elsif options[:latest]
|
519
|
-
commit.dup
|
520
|
-
elsif options[:list]
|
521
|
-
list.each {|c| return c if c.repo == full_repo_name}
|
522
|
-
nil
|
523
|
-
else
|
524
|
-
Commit.new full_repo_name => {'sha' => hist.first['sha']}
|
525
|
-
end
|
79
|
+
def full_repo_name(repo)
|
80
|
+
return repo if repo.include? '/'
|
81
|
+
[@session.username, repo].join '/'
|
526
82
|
end
|
527
83
|
|
528
84
|
private
|
529
85
|
def listen(port)
|
530
|
-
@
|
86
|
+
@tcp_server = TCPServer.open(port)
|
531
87
|
end
|
532
88
|
|
533
89
|
def setup_env(options={})
|
534
90
|
@remote_connection = false
|
535
91
|
@daemonized = options[:daemon]
|
536
|
-
@sockets = [@
|
92
|
+
@sockets = [@tcp_server]
|
537
93
|
trap_signals 'INT', 'KILL'
|
538
94
|
@session = Session.new
|
539
95
|
@session.username = CONFIG[:username]
|
96
|
+
@tracker = Tracker.new
|
540
97
|
unless CONFIG[:default_track].empty?
|
541
|
-
repos = CONFIG[:default_track]
|
98
|
+
repos = CONFIG[:default_track]
|
542
99
|
repos.each do |repo|
|
543
|
-
|
544
|
-
@
|
100
|
+
repo_name = full_repo_name(repo)
|
101
|
+
@tracker << repo_name
|
545
102
|
end
|
546
103
|
end
|
547
104
|
unless CONFIG[:load_hooks].empty?
|
548
|
-
hooks = CONFIG[:load_hooks]
|
105
|
+
hooks = CONFIG[:load_hooks]
|
549
106
|
session_load :hooks => hooks
|
550
107
|
end
|
551
108
|
unless CONFIG[:load_repos].empty?
|
552
|
-
repos = CONFIG[:load_repos]
|
109
|
+
repos = CONFIG[:load_repos]
|
553
110
|
session_load :repos => repos
|
554
111
|
end
|
555
112
|
end
|
@@ -558,7 +115,7 @@ EOS
|
|
558
115
|
sigs.each do |sig|
|
559
116
|
trap(sig) do
|
560
117
|
@sockets.each {|s| s.close}
|
561
|
-
STDOUT.
|
118
|
+
STDOUT.print "\n"
|
562
119
|
exit 1
|
563
120
|
end
|
564
121
|
end
|
@@ -568,94 +125,88 @@ EOS
|
|
568
125
|
opts = {:hooks => nil, :repos => nil}.merge options
|
569
126
|
if hooks = opts[:hooks]
|
570
127
|
hooks.each do |h|
|
571
|
-
|
572
|
-
|
128
|
+
decision = Strategies::Decision.new(self, :internal_input => "internal load hook #{h}")
|
129
|
+
decision.call_strategy
|
573
130
|
end
|
574
131
|
elsif repos = opts[:repos]
|
575
132
|
repos.each do |r|
|
576
|
-
|
577
|
-
|
133
|
+
decision = Strategies::Decision.new(self, :internal_input => "internal load repo #{r}")
|
134
|
+
decision.call_strategy
|
578
135
|
end
|
579
136
|
else
|
580
137
|
raise ArgumentError.new "Must load either hooks or repos"
|
581
138
|
end
|
582
139
|
end
|
583
140
|
|
584
|
-
#TODO: refactor this ugly, long method into a new class
|
585
141
|
def look_for_changes
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
already_logged = true
|
617
|
-
end
|
142
|
+
if @tracker.length.zero?
|
143
|
+
@remote_connection = client_ready(@sockets, :block => true)
|
144
|
+
end
|
145
|
+
while not @remote_connection
|
146
|
+
sleep_amt = CONFIG[:oncearound] / @tracker.length
|
147
|
+
@tracker.repo_names.each do |repo_name|
|
148
|
+
change_state = @tracker << repo_name
|
149
|
+
if change_state == :unchanged
|
150
|
+
(sleep_amt).times do
|
151
|
+
@remote_connection = client_ready(@sockets)
|
152
|
+
return if @remote_connection
|
153
|
+
end
|
154
|
+
else
|
155
|
+
# There was a change to a tracked repository.
|
156
|
+
commit = @tracker.last
|
157
|
+
full_repo_name = commit.repo
|
158
|
+
commit_msg = commit.message
|
159
|
+
committer = commit.committer_name
|
160
|
+
new_sha = commit.sha
|
161
|
+
change_msg = "Repo #{full_repo_name} has changed\nNew commit: " \
|
162
|
+
"#{commit_msg}\n=> #{committer}"
|
163
|
+
case CONFIG[:desktop_notification]
|
164
|
+
when "libnotify"
|
165
|
+
Notification::GnomeNotify.notify("Hubeye", change_msg)
|
166
|
+
when "growl"
|
167
|
+
Autotest::Growl.growl("Hubeye", change_msg)
|
168
|
+
when nil
|
169
|
+
unless @daemonized
|
170
|
+
Logger.log_change(full_repo_name, commit_msg, committer, :include_terminal => true)
|
171
|
+
already_logged = true
|
618
172
|
end
|
619
|
-
|
173
|
+
end
|
174
|
+
Logger.log_change(full_repo_name, commit_msg, committer) unless
|
620
175
|
already_logged
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
end
|
176
|
+
# execute any hooks for that repository
|
177
|
+
unless @session.hooks.empty?
|
178
|
+
if hooks = @session.hooks[full_repo_name]
|
179
|
+
hooks.each do |dir,cmds|
|
180
|
+
Hooks::Command.execute(cmds, :directory => dir, :repo => full_repo_name)
|
627
181
|
end
|
628
182
|
end
|
629
|
-
@session.tracker.add_or_replace!(full_repo_name, new_sha)
|
630
183
|
end
|
631
184
|
end
|
632
|
-
end
|
633
|
-
else
|
634
|
-
@remote_connection = client_ready(@sockets, :block => true) ? true : false
|
635
|
-
throw(:connect, true) if @remote_connection
|
185
|
+
end
|
636
186
|
end
|
637
187
|
end
|
638
188
|
|
639
189
|
def client_ready(sockets, options={})
|
640
190
|
if options[:block]
|
641
|
-
select(sockets, nil, nil)
|
191
|
+
r = select(sockets, nil, nil)
|
642
192
|
else
|
643
|
-
select(sockets, nil, nil, 1)
|
193
|
+
r = select(sockets, nil, nil, 1)
|
644
194
|
end
|
195
|
+
not r.nil?
|
645
196
|
end
|
646
197
|
|
647
198
|
def client_connect(sockets)
|
648
199
|
ready = select(sockets)
|
649
200
|
readable = ready[0]
|
650
201
|
readable.each do |socket|
|
651
|
-
if socket == @
|
652
|
-
@socket = @
|
653
|
-
@socket.sync =
|
202
|
+
if socket == @tcp_server
|
203
|
+
@socket = @tcp_server.accept
|
204
|
+
@socket.sync = true
|
654
205
|
sockets << @socket
|
655
206
|
# Inform the client of connection
|
656
207
|
basic_inform = "Hubeye running on #{Socket.gethostname} as #{@session.username}"
|
657
|
-
if !@
|
658
|
-
@socket.deliver "#{basic_inform}\nTracking: #{@
|
208
|
+
if !@tracker.empty?
|
209
|
+
@socket.deliver "#{basic_inform}\nTracking: #{@tracker.repo_names.join ', '}"
|
659
210
|
else
|
660
211
|
@socket.deliver basic_inform
|
661
212
|
end
|
@@ -679,8 +230,5 @@ EOS
|
|
679
230
|
@debug = debug
|
680
231
|
end
|
681
232
|
end
|
682
|
-
|
683
233
|
end # of Server module
|
684
|
-
|
685
234
|
end # end of Hubeye module
|
686
|
-
|