hubeye 0.3.0 → 0.3.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.
- data/VERSION.rb +2 -2
- data/bin/hubeye +69 -67
- data/lib/hubeye/client/client.rb +83 -0
- data/lib/hubeye/client/connection.rb +44 -0
- data/lib/hubeye/config/environment.rb +13 -0
- data/lib/{config → hubeye/config}/parser.rb +1 -1
- data/lib/hubeye/helpers/time.rb +8 -0
- data/lib/{hooks → hubeye/hooks}/executer.rb +6 -5
- data/lib/{hooks → hubeye/hooks}/git_hooks.rb +2 -3
- data/lib/hubeye/log/logger.rb +39 -0
- data/lib/hubeye/notification/finder.rb +64 -0
- data/lib/hubeye/notification/gnomenotify.rb +15 -0
- data/lib/{notification → hubeye/notification}/growl.rb +0 -0
- data/lib/hubeye/server/commit.rb +51 -0
- data/lib/hubeye/server/server.rb +686 -0
- data/lib/hubeye/server/session.rb +59 -0
- data/lib/hubeye/shared/hubeye_protocol.rb +36 -0
- data/test/config_parser.rb +2 -2
- data/test/environment.rb +1 -1
- data/test/integration.rb +24 -0
- data/test/notification.rb +3 -2
- data/test/runner.rb +3 -3
- metadata +18 -13
- data/lib/client/hubeye_client.rb +0 -103
- data/lib/environment.rb +0 -10
- data/lib/helpers/time.rb +0 -5
- data/lib/log/logger.rb +0 -38
- data/lib/notification/finder.rb +0 -62
- data/lib/notification/gnomenotify.rb +0 -13
- data/lib/server/hubeye_server.rb +0 -767
data/VERSION.rb
CHANGED
data/bin/hubeye
CHANGED
@@ -1,79 +1,82 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
require File.join(File.expand_path(File.dirname(__FILE__) + "/../"), "lib/environment")
|
5
|
-
include Environment
|
6
|
-
require File.join(ROOTDIR, 'VERSION')
|
3
|
+
module Hubeye
|
7
4
|
|
8
|
-
#
|
9
|
-
require
|
10
|
-
|
5
|
+
# require environment and VERSION files
|
6
|
+
require File.join(File.expand_path(File.dirname(__FILE__) + "/../"), "lib/hubeye/config/environment")
|
7
|
+
include Environment
|
8
|
+
require File.join(ROOTDIR, 'VERSION')
|
11
9
|
|
12
|
-
|
13
|
-
require '
|
10
|
+
# standard lib
|
11
|
+
require 'optparse'
|
12
|
+
require 'ostruct'
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
unless File.exists?(File.join(ENV['HOME'],'.hubeye'))
|
15
|
+
require 'rake'
|
16
|
+
require File.join(ROOTDIR, 'tasks', 'install')
|
17
|
+
Rake.application['install'].invoke
|
18
|
+
end
|
18
19
|
|
19
|
-
class Options
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
20
|
+
class Options
|
21
|
+
DEFAULT_PORT = 4545
|
22
|
+
|
23
|
+
def self.parse(args)
|
24
|
+
|
25
|
+
# defaults
|
26
|
+
options = OpenStruct.new
|
27
|
+
options.server_wanted = true
|
28
|
+
options.client_wanted = false
|
29
|
+
options.server_daemonized = true
|
30
|
+
options.port = DEFAULT_PORT
|
31
|
+
options.host = 'localhost'
|
32
|
+
|
33
|
+
opts_saved = OptionParser.new do |opts|
|
34
|
+
opts.banner = "Usage: hubeye [options]"
|
35
|
+
opts.separator ""
|
36
|
+
opts.separator "Note: The default port (for server and client) is #{DEFAULT_PORT}"
|
37
|
+
opts.separator " The default host (for server and client) is localhost"
|
38
|
+
opts.separator ""
|
39
|
+
opts.separator "Specific options:"
|
40
|
+
|
41
|
+
opts.on("-s", "--server", "Start the server (default: daemonized)") do
|
42
|
+
options.client_wanted = false
|
43
|
+
options.server_wanted = true
|
44
|
+
end
|
40
45
|
|
41
|
-
|
42
|
-
|
43
|
-
|
46
|
+
opts.on("-t", "--top", "Run server process in terminal") do
|
47
|
+
options.server_daemonized = false
|
48
|
+
end
|
44
49
|
|
45
|
-
|
46
|
-
|
47
|
-
|
50
|
+
opts.on("-o", "--host HOST", "Host that the server runs on / client connects to") do |h|
|
51
|
+
options.host = h
|
52
|
+
end
|
48
53
|
|
49
|
-
|
50
|
-
|
51
|
-
|
54
|
+
opts.on("-p", "--port PORT", "Port that the server runs on / client connects to") do |p|
|
55
|
+
options.port = p.to_i
|
56
|
+
end
|
52
57
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
58
|
+
opts.on("-c", "--client", "Start hubeye client to interact with server") do
|
59
|
+
options.server_wanted = false
|
60
|
+
options.client_wanted = true
|
61
|
+
end
|
57
62
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
63
|
+
opts.on_tail("-v", "--version", "Show hubeye version") do
|
64
|
+
puts VERSION.join('.')
|
65
|
+
exit
|
66
|
+
end
|
62
67
|
|
63
|
-
|
64
|
-
|
65
|
-
|
68
|
+
opts.on_tail("-h", "--help", "Show this message") do
|
69
|
+
puts opts
|
70
|
+
exit
|
71
|
+
end
|
66
72
|
end
|
67
|
-
end
|
68
|
-
|
69
|
-
opts_saved.parse!(args)
|
70
|
-
options
|
71
|
-
end # end of Options::parse
|
72
73
|
|
73
|
-
|
74
|
+
opts_saved.parse!(args)
|
75
|
+
options
|
76
|
+
end # end of Options::parse
|
74
77
|
|
78
|
+
end # end of class
|
75
79
|
|
76
|
-
class Hubeye
|
77
80
|
class << self
|
78
81
|
|
79
82
|
def start
|
@@ -86,7 +89,7 @@ class Hubeye
|
|
86
89
|
puts "A service is already running on this port"
|
87
90
|
exit 1
|
88
91
|
end
|
89
|
-
require File.join(
|
92
|
+
require File.join('hubeye', 'server', 'server')
|
90
93
|
options.server_daemonized ?
|
91
94
|
start_server(port, :daemon => true) :
|
92
95
|
start_server(port, :daemon => false)
|
@@ -94,7 +97,7 @@ class Hubeye
|
|
94
97
|
['INT', 'KILL'].each do |sig|
|
95
98
|
trap(sig) { STDOUT.puts; exit 1 }
|
96
99
|
end
|
97
|
-
require File.join(
|
100
|
+
require File.join('hubeye', 'client', 'client')
|
98
101
|
start_client(host, port)
|
99
102
|
end
|
100
103
|
end
|
@@ -109,17 +112,16 @@ class Hubeye
|
|
109
112
|
true
|
110
113
|
end
|
111
114
|
|
112
|
-
def start_server(port, options={})
|
113
|
-
server =
|
115
|
+
def start_server(port, options={}, *)
|
116
|
+
server = Server::Server.new(true) # debug
|
114
117
|
if options[:daemon]
|
115
118
|
Process.daemon(true) # don't change dir to '/'
|
116
119
|
end
|
117
120
|
server.start(port, options)
|
118
121
|
end
|
119
122
|
|
120
|
-
|
121
|
-
|
122
|
-
client = HubeyeClient.new
|
123
|
+
def start_client(host, port, *)
|
124
|
+
client = Client::Client.new(false) # debug
|
123
125
|
client.start(host, port)
|
124
126
|
end
|
125
127
|
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'readline'
|
3
|
+
require_relative 'connection'
|
4
|
+
|
5
|
+
module Hubeye
|
6
|
+
module Client
|
7
|
+
class Client
|
8
|
+
@@stty_save = `stty -g`
|
9
|
+
|
10
|
+
begin
|
11
|
+
Readline.emacs_editing_mode
|
12
|
+
rescue NotImplementedError
|
13
|
+
@@libedit = true
|
14
|
+
ensure
|
15
|
+
LIST = %w{quit shutdown exit tracking hook add dir}
|
16
|
+
comp_proc = Proc.new {|s| LIST.grep /^#{Regexp.escape(s)}/}
|
17
|
+
Readline.completion_proc = comp_proc rescue nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(debug=false)
|
21
|
+
@debug = debug
|
22
|
+
end
|
23
|
+
|
24
|
+
def start(host, port)
|
25
|
+
conn = Connection.new(host, port)
|
26
|
+
conn.receive_welcome
|
27
|
+
@s = conn.s
|
28
|
+
interact
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
# Now begin a loop of client/server interaction.
|
34
|
+
def interact
|
35
|
+
loop do
|
36
|
+
get_input_from_readline
|
37
|
+
begin
|
38
|
+
if @input.match(/^\.$/) # '.' = pwd (of client process)
|
39
|
+
@input.gsub!(/\A\.\Z/, File.split(File.expand_path('.')).last)
|
40
|
+
else
|
41
|
+
@input.gsub!(/\//, 'diiv')
|
42
|
+
end
|
43
|
+
@s.deliver @input
|
44
|
+
rescue => e
|
45
|
+
# Errno::EPIPE for broken pipes in Unix (server got an ^C or
|
46
|
+
# something like that)
|
47
|
+
puts e.message
|
48
|
+
puts e.backtrace
|
49
|
+
exit 1
|
50
|
+
end
|
51
|
+
if @input =~ /load repo/
|
52
|
+
puts "Loading..."
|
53
|
+
end
|
54
|
+
begin
|
55
|
+
mesg = @s.read_all
|
56
|
+
rescue EOFError
|
57
|
+
mesg = "Bye!\n"
|
58
|
+
end
|
59
|
+
if mesg.chop.strip == "Bye!"
|
60
|
+
mesg[-1] == "\n" ? print(mesg) : puts(mesg)
|
61
|
+
@s.close
|
62
|
+
exit 0
|
63
|
+
elsif mesg.chop.strip.match(/shutting/i)
|
64
|
+
@s.close
|
65
|
+
exit 0
|
66
|
+
else
|
67
|
+
mesg[-1] == "\n" ? print(mesg) : puts(mesg)
|
68
|
+
next
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def get_input_from_readline
|
74
|
+
begin
|
75
|
+
@input = Readline.readline('> ', true)
|
76
|
+
rescue Interrupt => e
|
77
|
+
system('stty', @@stty_save)
|
78
|
+
exit
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "hubeye/shared/hubeye_protocol"
|
2
|
+
|
3
|
+
module Hubeye
|
4
|
+
module Client
|
5
|
+
class Connection
|
6
|
+
attr_reader :s, :local, :peer, :peeraddr
|
7
|
+
|
8
|
+
def initialize(host, port)
|
9
|
+
_begin do
|
10
|
+
print "Connecting..."
|
11
|
+
@s = TCPSocket.open(host, port)
|
12
|
+
@s.sync = false
|
13
|
+
@local, @peer = @s.addr, @s.peeraddr
|
14
|
+
puts "Done" if @s
|
15
|
+
puts "Connected to #{peer[2]}:#{peer[1]} using port #{local[1]}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def receive_welcome
|
20
|
+
begin
|
21
|
+
mesg = @s.read_all
|
22
|
+
puts mesg
|
23
|
+
rescue SystemCallError, NoMethodError
|
24
|
+
puts "The server's not running!"
|
25
|
+
rescue EOFError
|
26
|
+
@retried ||= -1
|
27
|
+
@retried += 1
|
28
|
+
retry unless @retried >= 1
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def _begin
|
35
|
+
begin
|
36
|
+
yield
|
37
|
+
rescue
|
38
|
+
@debug ? puts($!) : nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -1,7 +1,8 @@
|
|
1
|
-
module
|
2
|
-
|
1
|
+
module Hubeye
|
2
|
+
module Hooks
|
3
|
+
class Command
|
3
4
|
|
4
|
-
|
5
|
+
class NoHookError < ArgumentError; end
|
5
6
|
|
6
7
|
#options include the directory to execute the command
|
7
8
|
#(that's it for now, will add more functionality later)
|
@@ -20,10 +21,10 @@ module Hooks
|
|
20
21
|
end
|
21
22
|
end
|
22
23
|
rescue ArgumentError
|
23
|
-
raise NoHookError
|
24
|
+
raise NoHookError "There aren't any hook commands for the repository #{repo}"
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
28
|
+
end
|
27
29
|
end
|
28
30
|
end
|
29
|
-
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Hubeye
|
2
|
+
module Log
|
3
|
+
class Logger
|
4
|
+
|
5
|
+
LOG_DIR = File.join(ENV['HOME'], '.hubeye', 'log')
|
6
|
+
|
7
|
+
def self.log(msg)
|
8
|
+
File.open(LOG_DIR, "a") do |f|
|
9
|
+
f.puts(msg)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.relog(msg)
|
14
|
+
#wipe the file and start anew
|
15
|
+
File.open(LOG_DIR, "w") do |f|
|
16
|
+
f.puts(msg)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# If :include_terminal => true, log to the terminal too (make sure that the
|
21
|
+
# process is not daemonized). Always log to the logfile.
|
22
|
+
def self.log_change(repo_name, commit_msg, committer, options={})
|
23
|
+
opts = {:include_terminal => false}.merge options
|
24
|
+
change_msg = <<MSG
|
25
|
+
===============================
|
26
|
+
Repository: #{repo_name.downcase.strip} has changed (#{Time.now.strftime("%m/%d/%Y at %I:%M%p")})
|
27
|
+
Commit msg: #{commit_msg}
|
28
|
+
Committer : #{committer}
|
29
|
+
===============================
|
30
|
+
MSG
|
31
|
+
if opts[:include_terminal]
|
32
|
+
STDOUT.puts change_msg
|
33
|
+
end
|
34
|
+
log(change_msg)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Hubeye
|
2
|
+
module Notification
|
3
|
+
include Environment
|
4
|
+
|
5
|
+
CHANGE_ICON = "change_icon.jpg"
|
6
|
+
CHANGE_ICON_PATH = (File.join(ROOTDIR, "images", CHANGE_ICON))
|
7
|
+
|
8
|
+
class Finder
|
9
|
+
def self.find_notify
|
10
|
+
if RUBY_PLATFORM =~ /mswin/
|
11
|
+
return
|
12
|
+
elsif RUBY_PLATFORM =~ /linux/
|
13
|
+
libnotify = system('locate libnotify-bin > /dev/null')
|
14
|
+
if libnotify
|
15
|
+
require_relative "gnomenotify"
|
16
|
+
return "libnotify"
|
17
|
+
elsif LibCheck.autotest_notification
|
18
|
+
require_relative "growl"
|
19
|
+
return "growl"
|
20
|
+
end
|
21
|
+
elsif RUBY_PLATFORM =~ /darwin/i and LibCheck.autotest_notification
|
22
|
+
require_relative "growl"
|
23
|
+
return "growl"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class LibCheck
|
29
|
+
class << self
|
30
|
+
def autotest
|
31
|
+
begin
|
32
|
+
require 'autotest'
|
33
|
+
rescue LoadError
|
34
|
+
if require 'rubygems'
|
35
|
+
retry
|
36
|
+
else
|
37
|
+
return
|
38
|
+
end
|
39
|
+
end
|
40
|
+
if defined? Autotest
|
41
|
+
true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def autotest_notification
|
46
|
+
begin
|
47
|
+
require 'autotest_notification'
|
48
|
+
rescue LoadError
|
49
|
+
if require 'rubygems'
|
50
|
+
retry
|
51
|
+
else
|
52
|
+
return
|
53
|
+
end
|
54
|
+
end
|
55
|
+
if defined? Autotest
|
56
|
+
true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end # end Notification
|
63
|
+
end # end Hubeye
|
64
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Hubeye
|
2
|
+
module Notification
|
3
|
+
module GnomeNotify
|
4
|
+
|
5
|
+
EXPIRATION_IN_SECONDS = 2
|
6
|
+
|
7
|
+
def self.notify(title, msg, img=CHANGE_ICON_PATH)
|
8
|
+
options = "-t #{EXPIRATION_IN_SECONDS * 1000} -i #{img}"
|
9
|
+
system "notify-send #{options} '#{title}' '#{msg}'"
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
File without changes
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Hubeye
|
2
|
+
module Server
|
3
|
+
|
4
|
+
# simple interface to Github's api v3 for commits
|
5
|
+
class Commit
|
6
|
+
attr_reader :raw_input, :repo, :only_sha, :latest
|
7
|
+
|
8
|
+
def initialize(input)
|
9
|
+
@raw_input = input
|
10
|
+
@repo = input.keys.first
|
11
|
+
if Hash === input
|
12
|
+
if input[@repo].keys == ["sha"]
|
13
|
+
@only_sha = true
|
14
|
+
else
|
15
|
+
@latest = true
|
16
|
+
end
|
17
|
+
else
|
18
|
+
raise ArgumentError.new "input must be a kind of hash"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def sha
|
23
|
+
@sha ||= @raw_input[@repo]['sha']
|
24
|
+
end
|
25
|
+
|
26
|
+
def commit_message
|
27
|
+
if @only_sha
|
28
|
+
return
|
29
|
+
elsif @latest
|
30
|
+
@commit_message ||=
|
31
|
+
@raw_input[@repo]['commit']['message']
|
32
|
+
else
|
33
|
+
raise
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def committer_name
|
38
|
+
if @only_sha
|
39
|
+
return
|
40
|
+
elsif @latest
|
41
|
+
@committer_name ||=
|
42
|
+
@raw_input[@repo]['commit']['committer']['name']
|
43
|
+
else
|
44
|
+
raise
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|