hubeye 0.3.3 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- class Shutdown
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
- waiting = catch(:connect) do
464
- look_for_changes unless @remote_connection
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
- strategy = Strategy.new(self)
469
- strategy.call
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
- #TODO: refactor this into its own class. Getting unwieldy.
476
- # The track method closes over a list variable to store recent info on
477
- # tracked repositories.
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
- @server = TCPServer.open(port)
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 = [@server] # An array of sockets we'll monitor
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].dup
98
+ repos = CONFIG[:default_track]
542
99
  repos.each do |repo|
543
- commit = track(repo)
544
- @session.tracker.add_or_replace! commit.repo => commit.sha
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].dup
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].dup
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.puts
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
- strat = Strategy.new(self, :internal_input => "internal load hook #{h}")
572
- strat.call
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
- strat = Strategy.new(self, :internal_input => "internal load repo #{r}")
577
- strat.call
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
- # if no client is connected, and the tracker hash is non-empty
587
- if @sockets.size == 1 and !@session.tracker.empty?
588
- loop do
589
- sleep_amt = CONFIG[:oncearound] / @session.tracker.length
590
- @session.tracker.each do |repo,sha|
591
- start_time = Time.now
592
- commit = track(repo, :latest => true)
593
- api_time = (Time.now - start_time).to_i
594
- if commit.sha == sha
595
- (sleep_amt - api_time).times do
596
- sleep 1
597
- @remote_connection = client_ready(@sockets) ? true : false
598
- throw(:connect, true) if @remote_connection
599
- end
600
- else
601
- # There was a change to a tracked repository.
602
- full_repo_name = commit.repo
603
- commit_msg = commit.commit_message
604
- committer = commit.committer_name
605
- new_sha = commit.sha
606
- change_msg = "Repo #{full_repo_name} has changed\nNew commit: " \
607
- "#{commit_msg}\n=> #{committer}"
608
- case CONFIG[:desktop_notification]
609
- when "libnotify"
610
- Notification::GnomeNotify.notify("Hubeye", change_msg)
611
- when "growl"
612
- Autotest::Growl.growl("Hubeye", change_msg)
613
- when nil
614
- unless @daemonized
615
- Logger.log_change(full_repo_name, commit_msg, committer, :include_terminal => true)
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
- Logger.log_change(full_repo_name, commit_msg, committer) unless
173
+ end
174
+ Logger.log_change(full_repo_name, commit_msg, committer) unless
620
175
  already_logged
621
- # execute any hooks for that repository
622
- unless @session.hooks.empty?
623
- if hooks = @session.hooks[full_repo_name]
624
- hooks.each do |dir,cmds|
625
- Hooks::Command.execute(cmds, :directory => dir, :repo => full_repo_name)
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 # end of loop
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 == @server
652
- @socket = @server.accept
653
- @socket.sync = false
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 !@session.tracker.empty?
658
- @socket.deliver "#{basic_inform}\nTracking: #{@session.tracker.keys.join ', '}"
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
-