hubeye 0.1.0 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -0
- data/VERSION.rb +2 -2
- data/bin/hubeye +14 -36
- data/lib/client/hubeye_client.rb +56 -51
- data/lib/config/parser.rb +17 -21
- data/lib/hooks/executer.rb +1 -1
- data/lib/hooks/git_hooks.rb +0 -4
- data/lib/log/logger.rb +3 -3
- data/lib/server/hubeye_server.rb +654 -666
- data/tasks/install.rb +16 -24
- data/test/config_parser.rb +62 -35
- metadata +15 -17
data/LICENSE
CHANGED
data/VERSION.rb
CHANGED
data/bin/hubeye
CHANGED
@@ -2,42 +2,18 @@
|
|
2
2
|
|
3
3
|
# require environment and VERSION files
|
4
4
|
require File.join(File.expand_path(File.dirname(__FILE__) + "/../"), "lib/environment")
|
5
|
-
|
5
|
+
include Environment
|
6
|
+
require File.join(ROOTDIR, 'VERSION')
|
6
7
|
|
7
8
|
# standard lib
|
8
9
|
require 'optparse'
|
9
10
|
require 'ostruct'
|
10
11
|
|
11
|
-
|
12
|
-
unless RUBY_VERSION >= '1.9'
|
13
|
-
begin
|
14
|
-
require 'daemons'
|
15
|
-
rescue
|
16
|
-
require 'rubygems'
|
17
|
-
retry
|
18
|
-
else
|
19
|
-
raise "The daemons gem is needed to run hubeye as a daemon " +
|
20
|
-
"on Ruby < 1.9"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
unless File.exists? ENV['HOME'] + '/.hubeye'
|
12
|
+
unless File.exists?(File.join(ENV['HOME'],'.hubeye'))
|
25
13
|
require 'rake'
|
26
|
-
require 'stringio'
|
27
|
-
|
28
|
-
def capture_stdout
|
29
|
-
s = StringIO.new
|
30
|
-
oldstdout = $stdout
|
31
|
-
$stdout = s
|
32
|
-
yield
|
33
|
-
s.string
|
34
|
-
ensure
|
35
|
-
$stdout = oldstdout
|
36
|
-
end
|
37
|
-
|
38
|
-
require File.join(File.expand_path(File.dirname(__FILE__) + "/.."), 'tasks/install')
|
39
|
-
results = capture_stdout { Rake.application['install'].invoke }
|
40
14
|
|
15
|
+
require File.join(ROOTDIR, 'tasks/install')
|
16
|
+
Rake.application['install'].invoke
|
41
17
|
end
|
42
18
|
|
43
19
|
class Options
|
@@ -48,14 +24,14 @@ class Options
|
|
48
24
|
options.server_wanted = true
|
49
25
|
options.client_wanted = false
|
50
26
|
options.server_daemonized = true
|
51
|
-
options.port =
|
27
|
+
options.port = 4545
|
52
28
|
options.host = 'localhost'
|
53
29
|
|
54
30
|
opts_saved = OptionParser.new do |opts|
|
55
31
|
opts.banner = "Usage: hubeye [options]"
|
56
32
|
opts.separator ""
|
57
33
|
opts.separator "Specific options:"
|
58
|
-
opts.separator "Note: The default port (for server and client) is
|
34
|
+
opts.separator "Note: The default port (for server and client) is 4545"
|
59
35
|
|
60
36
|
opts.on("-s", "--server", "Start the server (default: daemonized process)") do
|
61
37
|
options.client_wanted = false
|
@@ -110,17 +86,19 @@ class Hubeye
|
|
110
86
|
puts "Other instances are running"
|
111
87
|
exit 1
|
112
88
|
end
|
113
|
-
require File.join(
|
114
|
-
options.server_daemonized ?
|
89
|
+
require File.join(LIBDIR, 'server', 'hubeye_server')
|
90
|
+
options.server_daemonized ?
|
91
|
+
start_server(port, :daemon => true) :
|
92
|
+
start_server(port, :daemon => false)
|
115
93
|
else
|
116
|
-
require File.join(
|
94
|
+
require File.join(LIBDIR, 'client', 'hubeye_client')
|
117
95
|
start_client(host, port)
|
118
96
|
end
|
119
97
|
end
|
120
98
|
|
121
99
|
|
122
100
|
def port_open?(port)
|
123
|
-
# this is the solution until multi-threading is implemented
|
101
|
+
# this is the solution until multi-threading or forking is implemented
|
124
102
|
# on the TCP server
|
125
103
|
listening_tcps = `netstat -l --tcp --numeric`
|
126
104
|
if /#{port}/ =~ listening_tcps
|
@@ -138,7 +116,7 @@ class Hubeye
|
|
138
116
|
server.start(port, options)
|
139
117
|
end
|
140
118
|
|
141
|
-
# client connection defaults to localhost:
|
119
|
+
# client connection defaults to localhost:4545
|
142
120
|
def start_client(host, port)
|
143
121
|
client = HubeyeClient.new
|
144
122
|
client.start(host, port)
|
data/lib/client/hubeye_client.rb
CHANGED
@@ -3,73 +3,78 @@ require 'socket'
|
|
3
3
|
|
4
4
|
class HubeyeClient
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
class Connection
|
7
|
+
attr_reader :s, :local, :peer, :peeraddr
|
8
|
+
def initialize(host, port)
|
9
|
+
_begin do
|
10
|
+
# Give the user some feedback while connecting.
|
11
|
+
STDOUT.print "Connecting..."
|
12
|
+
STDOUT.flush
|
13
|
+
@s = TCPSocket.open(host, port)
|
14
|
+
STDOUT.puts "Done" if @s
|
15
|
+
|
16
|
+
# Now display information about the connection.
|
17
|
+
@local, @peer = @s.addr, @s.peeraddr
|
11
18
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
rescue
|
16
|
-
puts $! # Display the exception to the user
|
19
|
+
STDOUT.print "Connected to #{peer[2]}:#{peer[1]}"
|
20
|
+
STDOUT.puts " using local port #{local[1]}"
|
21
|
+
end
|
17
22
|
end
|
18
|
-
end
|
19
23
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
def receive_welcome
|
25
|
+
# Wait just a bit, to see if the server sends any initial message.
|
26
|
+
begin
|
27
|
+
sleep 1
|
28
|
+
msg = @s.readpartial(4096)
|
29
|
+
STDOUT.puts msg.chop
|
30
|
+
rescue SystemCallError, NoMethodError
|
31
|
+
STDOUT.puts "The server's not running!"
|
32
|
+
rescue EOFError
|
33
|
+
@retried ||= -1
|
34
|
+
@retried += 1
|
35
|
+
retry unless @retried >= 1
|
36
|
+
end
|
37
|
+
end
|
27
38
|
|
28
|
-
|
29
|
-
local, peer = @s.addr, @s.peeraddr
|
39
|
+
private
|
30
40
|
|
31
|
-
|
32
|
-
|
41
|
+
def _begin
|
42
|
+
begin
|
43
|
+
yield
|
44
|
+
rescue
|
45
|
+
puts $! if @debug
|
46
|
+
end
|
33
47
|
end
|
34
48
|
end
|
35
49
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
STDOUT.puts msg.chop # And display it
|
42
|
-
# If nothing was ready to read, just ignore the exception.
|
43
|
-
rescue SystemCallError, NoMethodError
|
44
|
-
STDOUT.puts "The server's not running!"
|
45
|
-
end
|
50
|
+
def start(host, port, debug=false)
|
51
|
+
@debug = debug
|
52
|
+
conn = Connection.new(host, port)
|
53
|
+
conn.receive_welcome
|
54
|
+
interact(conn.s)
|
46
55
|
end
|
47
56
|
|
48
|
-
|
49
|
-
def interact
|
57
|
+
# Now begin a loop of client/server interaction.
|
58
|
+
def interact(socket)
|
59
|
+
@s = socket
|
50
60
|
while @s
|
51
61
|
loop do
|
52
|
-
STDOUT.print '> '
|
53
|
-
STDOUT.flush
|
54
|
-
local = STDIN.gets
|
55
|
-
|
56
|
-
|
57
|
-
@s.puts(local.gsub(/\A\.\Z/, "pwd" + Dir.pwd.split('/').last))
|
62
|
+
STDOUT.print '> '
|
63
|
+
STDOUT.flush
|
64
|
+
local = STDIN.gets
|
65
|
+
if local.match(/^\.$/) # '.' = pwd
|
66
|
+
# Send the line to the server, daemons gem strips some special chars (/, :)
|
67
|
+
@s.puts(local.gsub(/\A\.\Z/, "pwd" + Dir.pwd.split('/').last))
|
58
68
|
else
|
59
69
|
@s.puts(local.gsub(/\//, 'diiv'))
|
60
70
|
end
|
61
|
-
@s.flush
|
62
|
-
# Read the server's response and print out.
|
63
|
-
# The server may send more than one line, so use readpartial
|
64
|
-
# to read whatever it sends (as long as it all arrives in one chunk).
|
65
|
-
|
71
|
+
@s.flush
|
66
72
|
if local =~ /load repo/
|
67
73
|
puts "Loading..."
|
68
74
|
sleep 1
|
69
75
|
else
|
70
76
|
sleep 0.5
|
71
77
|
end
|
72
|
-
|
73
78
|
begin
|
74
79
|
response = @s.readpartial(4096)
|
75
80
|
rescue EOFError
|
@@ -77,19 +82,19 @@ class HubeyeClient
|
|
77
82
|
end
|
78
83
|
|
79
84
|
if response.chop.strip == "Bye!"
|
80
|
-
puts
|
85
|
+
puts response.chop
|
81
86
|
@s.close
|
82
|
-
exit
|
87
|
+
exit 0
|
83
88
|
elsif response.chop.strip.match(/shutting/i)
|
84
89
|
@s.close
|
85
|
-
exit
|
90
|
+
exit 0
|
86
91
|
else
|
87
|
-
puts
|
92
|
+
puts response.chop
|
88
93
|
next
|
89
94
|
end
|
90
95
|
end
|
91
96
|
end
|
92
97
|
end
|
93
98
|
|
94
|
-
end
|
99
|
+
end
|
95
100
|
|
data/lib/config/parser.rb
CHANGED
@@ -9,44 +9,35 @@ class Hubeye
|
|
9
9
|
def initialize(config_file, options={})
|
10
10
|
opts = {:test => false}.merge options
|
11
11
|
if opts[:test] then klass = StringIO else klass = File end
|
12
|
-
|
13
|
-
# not a pretty line, but take options array from element 1,
|
14
|
-
# stringify it, get rid of commas separating the repos and
|
15
|
-
# split them back into an array on the spaces
|
16
|
-
get_comma_separated_values = Proc.new do
|
17
|
-
options[1..-1].join('').gsub(',', '').split(' ')
|
18
|
-
end
|
19
|
-
|
20
12
|
klass.open(config_file) do |f|
|
21
13
|
while line = f.gets
|
22
|
-
line.strip
|
14
|
+
line = line.strip
|
23
15
|
next if line.empty?
|
24
|
-
|
25
|
-
|
26
|
-
case options[0]
|
16
|
+
user_opts = line.split(':').map! {|o| o.strip}
|
17
|
+
case user_opts[0]
|
27
18
|
when "username"
|
28
|
-
@username =
|
19
|
+
@username = user_opts[1]
|
29
20
|
when "track"
|
30
|
-
@default_track = get_comma_separated_values
|
21
|
+
@default_track = get_comma_separated_values(user_opts[1])
|
31
22
|
when "load repos"
|
32
|
-
@load_repos = get_comma_separated_values
|
23
|
+
@load_repos = get_comma_separated_values(user_opts[1])
|
33
24
|
when "oncearound"
|
34
|
-
@oncearound =
|
25
|
+
@oncearound = user_opts[1].to_i
|
35
26
|
if @oncearound.zero?
|
36
|
-
raise ConfigParseError.new "oncearound in hubeyerc is "
|
37
|
-
"#{
|
27
|
+
raise ConfigParseError.new "oncearound in hubeyerc is " \
|
28
|
+
"#{user_opts[1]} but must be a number that is greater than 0"
|
38
29
|
end
|
39
30
|
when "load hooks"
|
40
|
-
@load_hooks = get_comma_separated_values
|
31
|
+
@load_hooks = get_comma_separated_values(user_opts[1])
|
41
32
|
when "desktop notification"
|
42
|
-
on_off =
|
33
|
+
on_off = user_opts[1]
|
43
34
|
@notification_wanted = case on_off
|
44
35
|
when "off"
|
45
36
|
false
|
46
37
|
when "on"
|
47
38
|
true
|
48
39
|
else
|
49
|
-
raise ConfigParseError.new "desktop notification in hubeyerc is "
|
40
|
+
raise ConfigParseError.new "desktop notification in hubeyerc is " \
|
50
41
|
"'#{on_off}' and is expected to be either on or off"
|
51
42
|
end
|
52
43
|
end
|
@@ -55,6 +46,11 @@ class Hubeye
|
|
55
46
|
yield self
|
56
47
|
end
|
57
48
|
|
49
|
+
private
|
50
|
+
def get_comma_separated_values(values)
|
51
|
+
values.split(',').map {|v| v.strip}
|
52
|
+
end
|
53
|
+
|
58
54
|
end
|
59
55
|
end
|
60
56
|
end
|
data/lib/hooks/executer.rb
CHANGED
@@ -5,7 +5,7 @@ module Hooks
|
|
5
5
|
|
6
6
|
#options include the directory to execute the command
|
7
7
|
#(that's it for now, will add more functionality later)
|
8
|
-
def self.execute(commands
|
8
|
+
def self.execute(commands, options={})
|
9
9
|
opts = {:directory => nil, :repo => nil}.merge(options)
|
10
10
|
dir = opts[:directory]
|
11
11
|
repo = opts[:repo]
|
data/lib/hooks/git_hooks.rb
CHANGED
@@ -4,16 +4,12 @@ module Hooks
|
|
4
4
|
module Default
|
5
5
|
|
6
6
|
def self.fetch(local_reponame, remotename, branchname)
|
7
|
-
#first, start a process to cd to the local repo
|
8
|
-
#then fetch the remote
|
9
7
|
Dir.chdir(File.expand_path(local_reponame)) do
|
10
8
|
::Kernel.system("git fetch #{remotename} #{branchname}")
|
11
9
|
end
|
12
10
|
end
|
13
11
|
|
14
12
|
def self.pull(local_reponame, remotename, branchname)
|
15
|
-
#first, start a process to cd to the local repo
|
16
|
-
#then pull the remote
|
17
13
|
Dir.chdir(File.expand_path(local_reponame)) do
|
18
14
|
::Kernel.system("git pull #{remotename} #{branchname}")
|
19
15
|
end
|
data/lib/log/logger.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class Logger
|
2
|
-
LOG_DIR = ENV['HOME']
|
2
|
+
LOG_DIR = File.join(ENV['HOME'], '.hubeye', 'log')
|
3
3
|
|
4
4
|
def self.log(msg)
|
5
5
|
File.open(LOG_DIR, "a") do |f|
|
@@ -27,9 +27,9 @@ class Logger
|
|
27
27
|
===============================
|
28
28
|
MSG
|
29
29
|
if opts[:include_terminal]
|
30
|
-
puts change_msg
|
30
|
+
STDOUT.puts change_msg
|
31
31
|
end
|
32
|
-
|
32
|
+
log(change_msg)
|
33
33
|
end
|
34
34
|
|
35
35
|
end
|