hubeye 0.0.4 → 0.1.0

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/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ $:.unshift 'lib'
2
+
3
+ require 'rake/testtask'
4
+ require 'rake/clean'
5
+
6
+ task :default => [:test]
7
+
8
+ desc 'Run tests (default)'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.test_files = FileList['test/runner.rb']
11
+ end
12
+
13
+ desc 'Display current version'
14
+ task :version do
15
+ require_relative 'VERSION'
16
+ puts Hubeye::VERSION * '.'
17
+ end
data/VERSION.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  class Hubeye
2
- # 0.0.4 since sept.5 2011
3
- VERSION = [0,0,4]
2
+ # 0.1.0 since oct.4, 2011
3
+ VERSION = [0,1,0]
4
4
  end
5
5
 
data/bin/hubeye CHANGED
@@ -17,7 +17,7 @@ unless RUBY_VERSION >= '1.9'
17
17
  retry
18
18
  else
19
19
  raise "The daemons gem is needed to run hubeye as a daemon " +
20
- "on Ruby < 1.9"
20
+ "on Ruby < 1.9"
21
21
  end
22
22
  end
23
23
 
@@ -36,12 +36,11 @@ class HubeyeClient
36
36
  def read_welcome
37
37
  # Wait just a bit, to see if the server sends any initial message.
38
38
  begin
39
- sleep(0.5) # Wait half a second
39
+ sleep(1) # Wait a second
40
40
  msg = @s.readpartial(4096) # Read whatever is ready
41
41
  STDOUT.puts msg.chop # And display it
42
42
  # If nothing was ready to read, just ignore the exception.
43
- rescue SystemCallError
44
- rescue NoMethodError
43
+ rescue SystemCallError, NoMethodError
45
44
  STDOUT.puts "The server's not running!"
46
45
  end
47
46
  end
@@ -64,7 +63,13 @@ class HubeyeClient
64
63
  # The server may send more than one line, so use readpartial
65
64
  # to read whatever it sends (as long as it all arrives in one chunk).
66
65
 
67
- sleep 0.5
66
+ if local =~ /load repo/
67
+ puts "Loading..."
68
+ sleep 1
69
+ else
70
+ sleep 0.5
71
+ end
72
+
68
73
  begin
69
74
  response = @s.readpartial(4096)
70
75
  rescue EOFError
data/lib/log/logger.rb CHANGED
@@ -14,12 +14,11 @@ class Logger
14
14
  end
15
15
  end
16
16
 
17
- ##If {include_socket: true} is passed, then log to the client as well. If
18
- #{include_terminal: true}, log to the terminal too (make sure that the
19
- #process is not daemonized). Always log to the logfile.
17
+ # If {include_terminal: true}, log to the terminal too (make sure that the
18
+ # process is not daemonized). Always log to the logfile.
20
19
 
21
20
  def self.log_change(repo_name, commit_msg, committer, options={})
22
- opts = {:include_socket => false, :include_terminal => false}.merge options
21
+ opts = {:include_terminal => false}.merge options
23
22
  change_msg = <<-MSG
24
23
  ===============================
25
24
  Repository: #{repo_name.downcase.strip} has changed (#{Time.now.strftime("%m/%d/%Y at %I:%M%p")})
@@ -27,10 +26,6 @@ class Logger
27
26
  Committer : #{committer}
28
27
  ===============================
29
28
  MSG
30
- if opts[:include_socket]
31
- socket.puts(change_msg)
32
- end
33
-
34
29
  if opts[:include_terminal]
35
30
  puts change_msg
36
31
  end
@@ -8,10 +8,10 @@ module Notification
8
8
  elsif RUBY_PLATFORM =~ /linux/
9
9
  libnotify = system('locate libnotify-bin > /dev/null')
10
10
 
11
- if libnotify && LibChecker.autotest
11
+ if libnotify && LibCheck.autotest
12
12
  require_relative "gnomenotify"
13
13
  return "libnotify"
14
- elsif LibChecker.autotest_notification
14
+ elsif LibCheck.autotest_notification
15
15
  require_relative "growl"
16
16
  return "growl"
17
17
  else
@@ -20,9 +20,9 @@ module Notification
20
20
 
21
21
  elsif RUBY_PLATFORM =~ /darwin/i
22
22
 
23
- if LibChecker.autotest_notification
24
- require_relative "growl"
25
- return "growl"
23
+ if LibCheck.autotest_notification
24
+ require_relative "growl"
25
+ return "growl"
26
26
  else
27
27
  return
28
28
  end
@@ -32,7 +32,7 @@ module Notification
32
32
 
33
33
  end
34
34
 
35
- class LibChecker
35
+ class LibCheck
36
36
 
37
37
  class << self
38
38
  def autotest
@@ -1,19 +1,19 @@
1
1
  module Server
2
2
  # standard lib.
3
3
  require 'socket'
4
- require 'open-uri'
5
4
  require 'yaml'
6
5
 
7
6
  # vendor
8
7
  begin
9
- require 'nokogiri'
8
+ require 'octopi'
10
9
  rescue LoadError
11
10
  if require 'rubygems'
12
11
  retry
13
12
  else
14
- abort 'Nokogiri is needed to run hubeye. Gem install nokogiri'
13
+ abort 'Octopi is needed to run hubeye. Gem install octopi'
15
14
  end
16
15
  end
16
+ include Octopi
17
17
 
18
18
  # hubeye
19
19
  require "config/parser"
@@ -32,28 +32,27 @@ module Server
32
32
  #
33
33
  # Option overview:
34
34
  #
35
- # CONFIG[:oncearound]: 30 (seconds) is the default amount of time for looking
35
+ # CONFIG[:oncearound]: 60 (seconds) is the default amount of time for looking
36
36
  # for changes in every single repository. If tracking lots of repos,
37
37
  # it might be a good idea to increase the value, or hubeye will cry
38
38
  # due to overwork, fatigue and general anhedonia.
39
39
  #
40
- # hubeyerc format: oncearound: 1000
40
+ # hubeyerc format => oncearound: 1000
41
41
  #
42
- # CONFIG[:username] is the username used when not specified:
42
+ # CONFIG[:username] is the username used when not specified.
43
+ # hubeyerc format => username: 'hansolo'
43
44
  # when set to 'hansolo'
44
45
  # >rails
45
46
  # would track https://www.github.com/hansolo/rails
46
47
  # but a full URI path won't use CONFIG[:username]
47
48
  # >rails/rails
48
49
  # would track https://www.github.com/rails/rails
49
- #
50
- # hubeyerc format: username: hansolo
51
50
  ::Hubeye::Config::Parser.new(CONFIG_FILE) do |c|
52
- CONFIG[:username] = c.username || ''
51
+ CONFIG[:username] = c.username || 'john_doe'
53
52
  CONFIG[:oncearound] = c.oncearound || 60
54
53
  CONFIG[:load_repos] = c.load_repos || []
55
54
  CONFIG[:load_hooks] = c.load_hooks || []
56
- CONFIG[:default_track] = c.default_track || []
55
+ CONFIG[:default_track] = c.default_track || nil
57
56
  # returns true or false if defined in hubeyerc
58
57
  CONFIG[:notification_wanted] = case c.notification_wanted
59
58
  when false
@@ -66,7 +65,8 @@ module Server
66
65
  end
67
66
  end
68
67
 
69
- CONFIG[:desktop_notification] = (CONFIG[:notification_wanted] ? Notification::Finder.find_notify : nil)
68
+ CONFIG[:desktop_notification] = (CONFIG[:notification_wanted] ?
69
+ Notification::Finder.find_notify : nil)
70
70
 
71
71
  class InputError < StandardError; end
72
72
 
@@ -79,7 +79,6 @@ module Server
79
79
  get_input(@socket)
80
80
  puts @input if @debug
81
81
  parse_input()
82
- get_github_doc("/#{@username}/#{@repo_name}")
83
82
  parse_doc()
84
83
  @username = CONFIG[:username]
85
84
  end
@@ -95,14 +94,18 @@ module Server
95
94
  def setup_env(options={})
96
95
  @daemonized = options[:daemon]
97
96
  @sockets = [@server] # An array of sockets we'll monitor
98
- if CONFIG[:default_track].empty?
99
- @ary_commits_repos = []
97
+ if CONFIG[:default_track].nil?
98
+ # will be array of 2-element arrays that contain the
99
+ # tracked repo name [0] and hash of latest sha and latest commit object
100
+ # for that repo [1]
101
+ # Example:
102
+ # [ ['luke-gru/hubeye', {:sha1 => 90j93r0rf389, :commit => <#Commit Object>}], [..., ...] ]
100
103
  @hubeye_tracker = []
101
104
  else
102
105
  # default tracking arrays (hubeyerc configurations)
103
106
  @hubeye_tracker = CONFIG[:default_track]
104
- @ary_commits_repos = insert_default_tracking_messages
105
107
  end
108
+ setup_hubeye_singleton_methods
106
109
 
107
110
  if CONFIG[:load_hooks].empty?
108
111
  # do nothing (the hooks hash is only assigned when needed)
@@ -125,89 +128,148 @@ module Server
125
128
  @remote_connection = false
126
129
  end
127
130
 
128
- def insert_default_tracking_messages
129
- track_default = CONFIG[:default_track].dup
130
- track_default.each do |repo|
131
- commit_msg = get_commit_msg(repo)
132
- # next unless commit_msg is non-false
133
- commit_msg ? nil : next
134
- ary_index = track_default.index(repo)
135
- track_default.insert(ary_index + 1, commit_msg)
131
+ class ::Array
132
+ include Octopi
133
+ class NotTrackerElementError < TypeError ; end
134
+
135
+ def extract_old_and_new
136
+ if length != 2
137
+ raise NotTrackerElementError.new "#{self} is not a @hubeye_tracker element"
138
+ else
139
+ tracked_repo, tracked_sha = self[0], self[1][:sha1]
140
+ username, repo_name = tracked_repo.split '/'
141
+ begin
142
+ gh_user = User.find(username)
143
+ rescue Octopi::NotFound
144
+ # fall back to using default username if not found
145
+ gh_user = @username
146
+ end
147
+ begin
148
+ repo = gh_user.repository repo_name
149
+ rescue Octopi::NotFound
150
+ raise
151
+ end
152
+ end
153
+ [tracked_sha, repo]
136
154
  end
137
- track_default
138
155
  end
139
- private :insert_default_tracking_messages
140
156
 
157
+ def setup_hubeye_singleton_methods
158
+ def_try_append_or_replace!
159
+ def_eyeing
160
+ def_rm_repo
161
+ end
141
162
 
142
- def not_connected
143
- # if no client is connected, but the commits array contains repos
144
- if @sockets.size == 1 and @ary_commits_repos.empty? == false
145
-
146
- while @remote_connection == false
147
- @hubeye_tracker.each do |repo|
148
- doc = Nokogiri::HTML(open("https://github.com/#{repo}/"))
149
-
150
- # make variable not block-local
151
- commit_msg = nil
152
-
153
- doc.xpath('//div[@class = "message"]/pre').each do |node|
154
- commit_msg = node.text
155
- if @ary_commits_repos.include?(commit_msg)
156
- CONFIG[:oncearound].times do
157
- sleep 1
158
- @remote_connection = client_ready(@sockets) ? true : false
159
- break if @remote_connection
160
- end
163
+ def def_try_append_or_replace!
164
+ @hubeye_tracker.singleton_class.class_eval do
165
+ define_method :try_append_or_replace! do |repo_name, new_commit_obj|
166
+ status = {:replace => nil, :add => nil, :same => true}
167
+ match = nil
168
+ map! do |e|
169
+ if e[0] == repo_name
170
+ match = true
171
+ if e[1][:sha1] == new_commit_obj.id
172
+ e
161
173
  else
162
- # There was a change to a tracked repository.
174
+ e[1][:sha1] = new_commit_obj.id
175
+ e[1][:commit] = new_commit_obj
176
+ status = status.merge :replace => true, :same => false
177
+ end
178
+ else
179
+ e
180
+ end
181
+ end # end of map!
182
+ if match
183
+ return status
184
+ else
185
+ self << [repo_name, {:sha1 => new_commit_obj.id,
186
+ :commit => new_commit_obj}]
187
+ return status.merge :add => true, :same => false
188
+ end
189
+ end
190
+ end
191
+ end
163
192
 
164
- # make variable not block-local
165
- committer = nil
193
+ def def_eyeing
194
+ @hubeye_tracker.singleton_class.class_eval do
195
+ define_method :eyeing do
196
+ (ary = []).tap do
197
+ each do |e|
198
+ ary << e[0]
199
+ end
200
+ end
201
+ end
202
+ end
203
+ end
204
+
205
+ def def_rm_repo
206
+ @hubeye_tracker.singleton_class.class_eval do
207
+ define_method :rm_repo do |repo_name|
208
+ match = nil
209
+ reject! do |e|
210
+ e[0] == repo_name ? match = true : nil
211
+ end
212
+ match
213
+ end
214
+ end
215
+ end
166
216
 
167
- doc.xpath('//div[@class = "actor"]/div[@class = "name"]').each do |node|
168
- committer = node.text
169
- end
170
217
 
171
- # notify of change to repository
172
- # if they have a Desktop notification
173
- # library installed
174
- change_msg = "Repo #{repo} has changed\nNew commit: #{commit_msg} => #{committer}"
175
- case CONFIG[:desktop_notification]
176
- when "libnotify"
177
- Autotest::GnomeNotify.notify("Hubeye", change_msg)
178
- Logger.log_change(repo, commit_msg, committer)
179
- when "growl"
180
- Autotest::Growl.growl("Hubeye", change_msg)
181
- Logger.log_change(repo, commit_msg, committer)
182
- when nil
183
-
184
- if @daemonized
185
- Logger.log_change(repo, commit_msg, committer)
186
- else
187
- Logger.log_change(repo, commit_msg, committer, :include_terminal => true)
188
- end
218
+ def not_connected
219
+ # if no client is connected, but the commits array contains repos
220
+ if @sockets.size == 1 and !@hubeye_tracker.empty?
189
221
 
222
+ while @remote_connection == false
223
+ sleep_amt = CONFIG[:oncearound] / @hubeye_tracker.length
224
+ @hubeye_tracker.each do |ary|
225
+ # this method does api calls, takes a couple of seconds to
226
+ # complete right now (TODO: see what's taking so long)
227
+ start_time = Time.now
228
+ old_sha, new_repo = ary.extract_old_and_new
229
+ api_time = (Time.now - start_time).to_i
230
+ new_commit = new_repo.commits.first
231
+ if new_commit.id == old_sha
232
+ (sleep_amt - api_time).times do
233
+ sleep 1
234
+ @remote_connection = client_ready(@sockets) ? true : false
235
+ break if @remote_connection
236
+ end
237
+ else
238
+ # There was a change to a tracked repository.
239
+ full_repo_name = ary[0]
240
+ commit_msg = new_commit.message
241
+ committer = new_commit.author['name']
242
+ # notify of change to repository
243
+ # if they have a Desktop notification
244
+ # library installed
245
+ change_msg = "Repo #{full_repo_name} has changed\nNew commit: " +
246
+ "#{commit_msg}\n=> #{committer}"
247
+ case CONFIG[:desktop_notification]
248
+ when "libnotify"
249
+ Autotest::GnomeNotify.notify("Hubeye", change_msg)
250
+ Logger.log_change(full_repo_name, commit_msg, committer)
251
+ when "growl"
252
+ Autotest::Growl.growl("Hubeye", change_msg)
253
+ Logger.log_change(full_repo_name, commit_msg, committer)
254
+ when nil
255
+ if @daemonized
256
+ Logger.log_change(full_repo_name, commit_msg, committer)
257
+ else
258
+ Logger.log_change(full_repo_name, commit_msg, committer, :include_terminal => true)
190
259
  end
191
- # execute any hooks for that repository
192
- unless @hook_cmds.nil? || @hook_cmds.empty?
193
- if @hook_cmds[repo]
194
- hook_cmds = @hook_cmds[repo].dup
195
- dir = (hook_cmds.include?('/') ? hook_cmds.shift : nil)
196
-
197
- # execute() takes [commands], {options} where
198
- # options = :directory and :repo
199
- Hooks::Command.execute(hook_cmds, :directory => dir, :repo => repo)
200
- end
260
+ end
261
+ # execute any hooks for that repository
262
+ unless @hook_cmds.nil? || @hook_cmds.empty?
263
+ if @hook_cmds[full_repo_name]
264
+ hook_cmds = @hook_cmds[full_repo_name].dup
265
+ dir = (hook_cmds.include?('/') ? hook_cmds.shift : nil)
266
+
267
+ # execute() takes [commands], {options} where
268
+ # options = :directory and :repo
269
+ Hooks::Command.execute(hook_cmds, :directory => dir, :repo => repo)
201
270
  end
202
-
203
- @ary_commits_repos << repo
204
- @ary_commits_repos << commit_msg
205
- # delete the repo and old commit that appear first in the array
206
- index_old_HEAD = @ary_commits_repos.index(repo)
207
- @ary_commits_repos.delete_at(index_old_HEAD)
208
- # and again to get rid of the commit message
209
- @ary_commits_repos.delete_at(index_old_HEAD)
210
271
  end
272
+ @hubeye_tracker.try_append_or_replace!(full_repo_name, new_commit)
211
273
  end
212
274
  end
213
275
  redo unless @remote_connection
@@ -232,10 +294,11 @@ module Server
232
294
  @socket = client # From here on in referred to as @socket
233
295
  sockets << @socket # Add it to the set of sockets
234
296
  # Inform the client of connection
297
+ basic_inform = "Hubeye running on #{Socket.gethostname} as #{@username}"
235
298
  if !@hubeye_tracker.empty?
236
- @socket.puts "Hubeye running on #{Socket.gethostname}\nTracking:#{@hubeye_tracker.join(' ')}"
299
+ @socket.puts "#{basic_inform}\nTracking:#{@hubeye_tracker.eyeing.join ', '}"
237
300
  else
238
- @socket.puts "Hubeye running on #{Socket.gethostname}"
301
+ @socket.puts basic_inform
239
302
  end
240
303
 
241
304
  if !@daemonized
@@ -298,11 +361,8 @@ module Server
298
361
  @socket.puts("Bye!") # Say goodbye
299
362
  Logger.log "Closing connection to #{@socket.peeraddr[2]}"
300
363
  @remote_connection = false
301
- if !@ary_commits_repos.empty?
302
- Logger.log "Tracking: "
303
- @ary_commits_repos.each do |repo|
304
- Logger.log repo if @ary_commits_repos.index(repo).even?
305
- end
364
+ if !@hubeye_tracker.empty?
365
+ Logger.log "Tracking: #{@hubeye_tracker.eyeing.join ', '}"
306
366
  end
307
367
  Logger.log "" # to look pretty when multiple connections per loop
308
368
  @sockets.delete(@socket) # Stop monitoring the socket
@@ -328,7 +388,7 @@ module Server
328
388
  else
329
389
  return
330
390
  end
331
- shutdown()
391
+ shutdown
332
392
  end
333
393
 
334
394
 
@@ -341,14 +401,13 @@ module Server
341
401
 
342
402
  def parse_hook
343
403
  if %r{hook add} =~ @input
344
- hook_add()
404
+ hook_add
345
405
  else
346
406
  return
347
407
  end
348
408
  end
349
409
 
350
410
 
351
- ##
352
411
  # @hook_cmds:
353
412
  # repo is the key, value is array of directory and commands. First element
354
413
  # of array is the local directory for that remote repo, rest are commands
@@ -390,7 +449,7 @@ module Server
390
449
  elsif @input =~ %r{\A\s*save repo(s?) as (.+)\Z}
391
450
  if !@hubeye_tracker.empty?
392
451
  File.open("#{ENV['HOME']}/.hubeye/repos/#{$2}.yml", "w") do |f_out|
393
- ::YAML.dump(@hubeye_tracker, f_out)
452
+ ::YAML.dump(@hubeye_tracker.eyeing, f_out)
394
453
  end
395
454
  @socket.puts("Saved repo#{$1} as #{$2}")
396
455
  else
@@ -452,20 +511,15 @@ module Server
452
511
  end
453
512
  # newrepos is an array of repos to be tracked
454
513
  newrepos.each do |e|
455
- # append the repo and the newest commit message to the repos and
456
- # commit messages array, then inform the client of the newest
457
- # commit message
458
- commit_msg = get_commit_msg(e)
459
- # if the commit_msg is non-false, don't do anything, otherwise 'next'
460
- commit_msg ? nil : next
461
- @ary_commits_repos << e << commit_msg
462
- # and append the repo to the hubeye_tracker array
463
- @hubeye_tracker << e
514
+ # append the repo name and the commit hash to the hubeye tracker
515
+ # array, then inform the client of the newest commit message
516
+ username, repo = e.split '/'
517
+ gh_user = User.find(username)
518
+ gh_repo = gh_user.repository repo
519
+ new_commit = gh_repo.commits.first
520
+ @hubeye_tracker.try_append_or_replace!(e, new_commit)
464
521
  end
465
- @ary_commits_repos.uniq!
466
- @hubeye_tracker.uniq!
467
-
468
- @socket.puts "Loaded #{$2}.\nTracking:\n#{show_repos_pretty()}"
522
+ @socket.puts "Loaded #{$2}.\nTracking:\n#{@hubeye_tracker.eyeing.join ', '}"
469
523
  else
470
524
  # no repo file with that name
471
525
  @socket.puts("No file to load from")
@@ -522,46 +576,18 @@ module Server
522
576
  end # end of input#each
523
577
  # flatten the newrepos array because it contains arrays
524
578
  newrepos.flatten!
525
- newrepos.each do |repo|
526
- commit_msg = get_commit_msg(repo)
527
- commit_msg ? nil : next
528
- @ary_commits_repos << repo << commit_msg
529
- @hubeye_tracker << repo
579
+ newrepos.each do |e|
580
+ username, repo = e.split '/'
581
+ gh_user = User.find(username)
582
+ gh_repo = gh_user.repository repo
583
+ new_commit = gh_repo.commits.first
584
+ @hubeye_tracker.try_append_or_replace!(e, new_commit)
530
585
  end
531
- @ary_commits_repos.uniq!
532
- @hubeye_tracker.uniq!
533
586
  else
534
587
  raise ArgumentError.new "#{input} must be array-like"
535
588
  end
536
589
  end
537
590
 
538
-
539
- # helper method to get commit message for a
540
- # single repo
541
- def get_commit_msg(remote_repo)
542
- begin
543
- @doc = Nokogiri::HTML(open("https://github.com#{'/' + remote_repo}"))
544
- rescue
545
- return nil
546
- end
547
- # returns the commit message
548
- commit_msg = parse_msg(@doc)
549
- end
550
-
551
-
552
- def show_repos_pretty
553
- pretty_repos = ""
554
- @ary_commits_repos.each do |e|
555
- if @ary_commits_repos.index(e).even?
556
- pretty_repos += e + "\n"
557
- else
558
- pretty_repos += " " + e + "\n"
559
- end
560
- end
561
- pretty_repos
562
- end
563
-
564
-
565
591
  def hook_list
566
592
  if @input =~ %r{hook list}
567
593
  unless @hook_cmds.nil? || @hook_cmds.empty?
@@ -597,7 +623,7 @@ remote: #{remote}
597
623
  # they're tracking
598
624
  def tracking_list
599
625
  if @input =~ /\Atracking\s*\Z/
600
- list = show_repos_pretty
626
+ list = @hubeye_tracker.eyeing.join ', '
601
627
  @socket.puts(list)
602
628
  throw(:next)
603
629
  else
@@ -648,24 +674,13 @@ remote: #{remote}
648
674
  else
649
675
  @username, @repo_name = "#{@username}/#{$1}".split('/')
650
676
  end
651
-
652
- begin
653
- index_found = @ary_commits_repos.index("#{@username}/#{@repo_name}")
654
- if index_found
655
- # consecutive indices in the array
656
- for i in 1..2
657
- @ary_commits_repos.delete_at(index_found)
658
- end
659
- @hubeye_tracker.delete("#{@username}/#{@repo_name}")
660
- @socket.puts("Stopped watching repository #{@username}/#{@repo_name}")
661
- sleep 0.5
662
- throw(:next)
663
- else
664
- @socket.puts("Repository #{@username}/#{@repo_name} not currently being watched")
665
- throw(:next)
666
- end
667
- rescue
668
- @socket.puts($!)
677
+ rm = @hubeye_tracker.rm_repo("#{@username}/#{@repo_name}")
678
+ if rm
679
+ @socket.puts("Stopped watching repository #{@username}/#{@repo_name}")
680
+ sleep 0.5
681
+ throw(:next)
682
+ else
683
+ @socket.puts("Repository #{@username}/#{@repo_name} not currently being watched")
669
684
  throw(:next)
670
685
  end
671
686
  else
@@ -690,84 +705,49 @@ remote: #{remote}
690
705
  @repo_name = @input
691
706
  end
692
707
 
693
-
694
- def get_github_doc(full_repo_path)
695
- begin
696
- # if adding a repo with another username
697
- @doc = Nokogiri::HTML(open("https://github.com#{full_repo_path}"))
698
- rescue OpenURI::HTTPError
699
- @socket.puts("Not a Github repository!")
700
- throw(:next)
701
- rescue URI::InvalidURIError
702
- @socket.puts("Not a valid URI")
703
- throw(:next)
704
- end
705
- end
706
-
707
-
708
708
  def parse_doc
709
- # get commit msg
710
- @commit_msg = parse_msg(@doc)
711
- # get committer
712
- @committer = parse_committer()
713
-
709
+ @full_repo_name = "#{@username}/#{@repo_name}"
710
+ begin
711
+ gh_user = User.find(@username)
712
+ gh_repo = gh_user.repository @repo_name
713
+ rescue ArgumentError, Octopi::NotFound
714
+ #Octopi library's User.find ArgumentError
715
+ @socket.puts "Not a Github repository name"
716
+ throw :next
717
+ end
718
+ new_commit = gh_repo.commits.first
719
+ change_status = @hubeye_tracker.try_append_or_replace!(@full_repo_name, new_commit)
720
+ # get commit info
721
+ commit_msg = new_commit.message
722
+ committer = new_commit.author['name']
723
+ url = "https://www.github.com#{new_commit.url[0..-30]}"
724
+ msg = "#{commit_msg}\n=> #{committer}"
714
725
  # new repo to track
715
- full_repo_name = "#{@username}/#{@repo_name}"
716
- if !@ary_commits_repos.include?(full_repo_name)
717
- @ary_commits_repos << full_repo_name
718
- @hubeye_tracker << full_repo_name
719
- @ary_commits_repos << @commit_msg
720
- # get commit info
721
- @info = parse_info()
722
- @msg = "#{@commit_msg} => #{@committer}".gsub(/\(author\)/, '')
726
+ if change_status[:add]
723
727
  # log the fact that the user added a repo to be tracked
724
- Logger.log("Added to tracker: #{@ary_commits_repos[-2]} (#{NOW})")
728
+ Logger.log("Added to tracker: #{@full_repo_name} (#{NOW})")
725
729
  # show the user, via the client, the info and commit msg for the commit
726
- @socket.puts("#{@info}\n#{@msg}")
730
+ @socket.puts("#{msg}\n#{url}")
727
731
 
728
732
  # new commit to tracked repo
729
- elsif !@ary_commits_repos.include?(@commit_msg)
733
+ elsif change_status[:replace]
734
+ change_msg = "New commit on #{@full_repo_name}\n"
735
+ change_msg << "#{msg}\n#{url}"
736
+ @socket.puts(change_msg)
730
737
  begin
731
- index_of_msg = @ary_commits_repos.index(@username + "/" + @repo_name) + 1
732
- @ary_commits_repos.delete_at(index_of_msg)
733
- @ary_commits_repos.insert(index_of_msg - 1, @commit_msg)
734
-
735
738
  # log to the logfile and tell the client
736
739
  if @daemonized
737
- Logger.log_change(@repo_name, @commit_msg, @committer,
738
- :include_socket => true)
740
+ Logger.log_change(@full_repo_name, commit_msg, committer)
739
741
  else
740
- Logger.log_change(@repo_name, @commit_msg, @committer,
741
- :include_socket => true, :include_terminal => true)
742
+ Logger.log_change(@full_repo_name, commit_msg, committer,
743
+ :include_terminal => true)
742
744
  end
743
745
  rescue
744
- @socket.puts($!)
746
+ throw :next
745
747
  end
746
748
  else
747
749
  # no change to the tracked repo
748
- @socket.puts("Repository #{@repo_name} has not changed")
749
- end
750
- end
751
-
752
-
753
- def parse_msg(html_doc)
754
- # get commit msg
755
- html_doc.xpath('//div[@class = "message"]/pre').each do |node|
756
- return commit_msg = node.text
757
- end
758
- end
759
-
760
-
761
- def parse_committer
762
- @doc.xpath('//div[@class = "actor"]/div[@class = "name"]').each do |node|
763
- return committer = node.text
764
- end
765
- end
766
-
767
-
768
- def parse_info
769
- @doc.xpath('//div[@class = "machine"]').each do |node|
770
- return info = node.text.gsub(/\n/, '').gsub(/tree/, "\ntree").gsub(/parent.*?(\w)/, "\nparent \\1").strip!
750
+ @socket.puts("Repository #{@full_repo_name} has not changed")
771
751
  end
772
752
  end
773
753
 
@@ -776,7 +756,7 @@ end # of Server module
776
756
  class HubeyeServer
777
757
  include Server
778
758
 
779
- def initialize(debug=false)
759
+ def initialize(debug=true)
780
760
  @debug = debug
781
761
  end
782
762
 
data/test/runner.rb CHANGED
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  # environment file
4
- require File.join(File.dirname(__FILE__), "/../lib/environment")
4
+ require File.join(File.expand_path(File.dirname(__FILE__) + '/..'), "lib/environment")
5
5
 
6
6
  # test/unit
7
7
  require 'test/unit'
8
8
 
9
9
  # test files
10
10
  require_relative 'environment'
11
- require File.join(File.dirname(__FILE__), "/../lib/notification/notification")
11
+ require File.join(File.expand_path(File.dirname(__FILE__) + '/..'), "lib/notification/notification")
12
12
  require_relative "notification"
13
13
  require Environment::LIBDIR + '/config/parser'
14
14
  require_relative "config_parser"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hubeye
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-05 00:00:00.000000000Z
12
+ date: 2011-10-04 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: nokogiri
16
- requirement: &71785010 !ruby/object:Gem::Requirement
15
+ name: octopi
16
+ requirement: &86576300 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *71785010
24
+ version_requirements: *86576300
25
25
  description: Github repository commit watcher -- keep your eye on new commits from
26
26
  multiple repos through an interactive CLI
27
27
  email: luke.gru@gmail.com
@@ -42,7 +42,7 @@ files:
42
42
  - lib/environment.rb
43
43
  - lib/helpers/time.rb
44
44
  - bin/hubeye
45
- - README.md.html
45
+ - Rakefile
46
46
  - README.md
47
47
  - VERSION.rb
48
48
  - LICENSE
data/README.md.html DELETED
@@ -1,212 +0,0 @@
1
- <h1>Hubeye</h1>
2
-
3
- <p><br />
4
- Keep track of repositories on Github, get notified when they change and<br />
5
- (optionally) run local system commands when new commits come in to Github.<br />
6
- <br /></p>
7
-
8
- <p>Hubeye is composed of a client and server. Once the server is run,<br />
9
- you can connect to it via the client. Once connected, you'll be<br />
10
- prompted by a '>'. Type the name of a Github repository.</p>
11
-
12
- <p>Example: (what the user enters is preceded by the prompt)</p>
13
-
14
- <pre><code>&gt;hubeye
15
- commit 77b82b54044c16751228
16
- tree 8ce18af1461b5c741003
17
- parent ea63fe317fe58dff1c95
18
- log tracking info for repos on client quit =&gt; luke-gru
19
- </code></pre>
20
-
21
- <p>What you see is the latest commit reference, tree reference and parent<br />
22
- commit reference on Github for that repository. Note that the user did<br />
23
- not type a username. This is because the user defined a username in his<br />
24
- ~/.hubeye/hubeyerc file.</p>
25
-
26
- <h2>Starting Hubeye</h2>
27
-
28
- <p>To start the server:</p>
29
-
30
- <pre><code>&gt;hubeye -s
31
- </code></pre>
32
-
33
- <p>or just</p>
34
-
35
- <pre><code>&gt;hubeye
36
- </code></pre>
37
-
38
- <p>This starts the server as a daemonized process. To run the server in<br />
39
- your terminal (on <b>t</b>op):</p>
40
-
41
- <pre><code>&gt;hubeye -st
42
- </code></pre>
43
-
44
- <p>Hubeye runs on port 2000 be default. Change the port like this:</p>
45
-
46
- <pre><code>&gt;hubeye -sp 9001
47
- </code></pre>
48
-
49
- <p>To connect with the client:</p>
50
-
51
- <pre><code>&gt;hubeye -c
52
- </code></pre>
53
-
54
- <p>For more options:</p>
55
-
56
- <pre><code>&gt;hubeye -h
57
- </code></pre>
58
-
59
- <h3>~/.hubeye/hubeyerc</h3>
60
-
61
- <pre><code>username: luke-gru
62
- </code></pre>
63
-
64
- <p>This allows the user to type a repository name only, and to receive<br />
65
- information regarding that <i>username</i>'s repository. The username<br />
66
- should be a valid Github username.</p>
67
-
68
- <h3>Keeping track of repositories</h3>
69
-
70
- <p>Hubeye doesn't actually track any repositories unless you disconnect<br />
71
- from the server and leave the server running. This can be done by:</p>
72
-
73
- <pre><code>&gt;quit
74
- Bye!
75
- </code></pre>
76
-
77
- <p>If Hubeye has any repos to watch (track), it will watch Github for changes.<br />
78
- It can keep track of as many repos as you want; just keep typing<br />
79
- them in. If Hubeye finds a change to a repo, it will notify you of the<br />
80
- changes using your Desktop notification system (libnotify, growl). It will<br />
81
- also log the changes to your $HOME/.hubeye/log file. If the server is run<br />
82
- in a terminal (-t option), the changes will also be logged to the terminal.<br
83
- /></p>
84
-
85
- <p>To track your own repository, start the client in the root directory<br />
86
- of your local git repo:</p>
87
-
88
- <pre><code>&gt;.
89
- </code></pre>
90
-
91
- <p>This only works if a <i>username</i> is added to the hubeyerc, and if the<br />
92
- Github repository name is the same as the local root directory name.<br />
93
- ie: '.' put in '/home/luke/code/hubeye' would track https://www.github.com/
94
- luke-gru/hubeye<br />
95
- if <i>username</i> was set to luke-gru.<br /></p>
96
-
97
- <p>You can add another user's repo like this:</p>
98
-
99
- <pre><code>&gt;rails/rails
100
- </code></pre>
101
-
102
- <p>This adds https://github.com/rails/rails to the watch list.<br />
103
- Hubeye does not remove a repo from the watch list unless explicitly<br />
104
- told to do so:</p>
105
-
106
- <pre><code>&gt;rm luke-gru/hubeye
107
- </code></pre>
108
-
109
- <p>To see a list of all repos (with recent commit messages) in the watch (track) list:</p>
110
-
111
- <pre><code>&gt;tracking
112
- </code></pre>
113
-
114
- <h3>Desktop Notification</h3>
115
-
116
- <p><i>On Linux: install libnotify-bin. On Mac: install growl (if not already installed).<br />
117
- The autotest gem is needed for Desktop notification to work in both
118
- cases.</i><br /></p>
119
-
120
- <h3>Shutting down and persistence between sessions</h3>
121
-
122
- <pre><code>&gt;shutdown
123
- </code></pre>
124
-
125
- <p>Next time you start up the server, the watch list will be empty<br />
126
- (and so will the log file). In order to have a default watch list:</p>
127
-
128
- <p><i>~/.hubeye/hubeyerc</i></p>
129
-
130
- <pre><code>track: rails/rails, dchelimsky/rspec
131
- </code></pre>
132
-
133
- <p>These will be watched automatically when starting up the server.<br /></p>
134
-
135
- <p>A way to interactively save all currently tracked repositories:</p>
136
-
137
- <pre><code>&gt;save repos as my_work_repos
138
- </code></pre>
139
-
140
- <p>And then load any time (even after a shutdown; next session, next week, etc...)</p>
141
-
142
- <pre><code>&gt;load repos my_work_repos
143
- </code></pre>
144
-
145
- <h3>Working with hooks</h3>
146
-
147
- <pre><code>&gt;hook add rails/rails dir: /path/to/local/rails cmd: git pull origin master
148
- </code></pre>
149
-
150
- <p>When <b>https://www.github.com/rails/rails</b> changes, a process will start,
151
- <br />
152
- change to the selected directory and execute the command. The <i>(dir: /my/dir)
153
- <br />
154
- </i> part is optional, and when ignored won't change directories. In this
155
- case,
156
- <br />
157
- the directory will be where the hubeye server was originally
158
- started from.<br /></p>
159
-
160
- <p>To see all currently loaded hooks:</p>
161
-
162
- <pre><code>&gt;hook list
163
- </code></pre>
164
-
165
- <p>To save all hooks for next sessions (after a server shutdown)</p>
166
-
167
- <pre><code>&gt;save hooks as weekend_projects_hooks
168
- </code></pre>
169
-
170
- <p>Then, next weekend:</p>
171
-
172
- <pre><code>&gt;load hooks weekend_projects_hooks
173
- </code></pre>
174
-
175
- <p>These hooks, of course, will only really do anything if the repositories they
176
- <br />
177
- are hooked to are currently being watched. This is not done automatically.</p>
178
-
179
- <h3>All ~/.hubeyerc configurations</h3>
180
-
181
- <p>When the server is started, the options are set here.</p>
182
-
183
- <pre><code>username: luke-gru
184
- track: username/reponame, username2/reponame2, myreponame
185
- oncearound = 90
186
- load hooks: myhook1, myworkhooks
187
- load repos: workprojects, funprojects
188
- desktop notification: on/off
189
- </code></pre>
190
-
191
- <p><i>username</i>: username used for Github URLS when the full path is not
192
- given<br />
193
- inside of the client.<br /></p>
194
-
195
- <p><i>track</i>: default repositories to watch for changes upon server start<br /></p>
196
-
197
- <p><i>oncearound</i>: number of seconds before completing a check of every repo in<br />
198
- the watch list for changes<br /></p>
199
-
200
- <p><i>load hooks</i>: load hooks on server start. To see how to save hooks in the
201
- <br />
202
- client, see the <i>Working with hooks</i> section<br /></p>
203
-
204
- <p><i>load repos</i>: load repos on server start. To see how to save repos in the
205
- <br />
206
- client, see the <i>Shutting down and persistence between sessions</i> section.
207
- <br /></p>
208
-
209
- <p><i>desktop notification</i>: whether to notify of repo changes using libnotify
210
- <br />
211
- or growl. This is set to <i>on</i> by default. However, if no notification<br />
212
- system is found, it is ignored.</p>