gitjour 6.4.0 → 6.5.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/History.txt +5 -0
- data/Manifest.txt +2 -1
- data/{README.txt → README.rdoc} +30 -1
- data/Rakefile +2 -0
- data/lib/gitjour.rb +69 -15
- data/lib/gitjour/browser.rb +111 -0
- metadata +9 -9
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
data/{README.txt → README.rdoc}
RENAMED
@@ -4,18 +4,28 @@
|
|
4
4
|
|
5
5
|
== DESCRIPTION:
|
6
6
|
|
7
|
-
Automates
|
7
|
+
Automates ZeroConf-powered serving and cloning of git repositories.
|
8
8
|
|
9
9
|
== SYNOPSIS:
|
10
10
|
|
11
|
+
=== THE BASICS
|
12
|
+
|
13
|
+
To serve a project, identified via ZeroConf:
|
14
|
+
|
11
15
|
% gitjour serve [project_dir] [name_to_advertise_as]
|
12
16
|
Registered phil-gitjour on port 9418. Starting service.
|
13
17
|
|
18
|
+
To find advertised git projects:
|
19
|
+
|
14
20
|
% gitjour list
|
15
21
|
Gathering for up to 5 seconds...
|
16
22
|
=== phil-gitjour on pdp10.local.:9418 ===
|
17
23
|
gitjour (clone|pull) phil-gitjour
|
18
24
|
|
25
|
+
=== CLONING & PULLING
|
26
|
+
|
27
|
+
To clone an advertised git repo:
|
28
|
+
|
19
29
|
% gitjour clone phil-gitjour
|
20
30
|
Gathering for up to 5 seconds...
|
21
31
|
Connecting to pdp10.local.:9418
|
@@ -23,6 +33,9 @@ Automates zeroconf-powered serving and cloning of git repositories.
|
|
23
33
|
[...]
|
24
34
|
Resolving deltas: 100% (342/342), done.
|
25
35
|
|
36
|
+
|
37
|
+
To pull from an advertised git repo:
|
38
|
+
|
26
39
|
% gitjour pull phil-gitjour
|
27
40
|
Gathering for up to 5 seconds...
|
28
41
|
Connecting to pdp10.local.:9418
|
@@ -32,8 +45,24 @@ Automates zeroconf-powered serving and cloning of git repositories.
|
|
32
45
|
[...]
|
33
46
|
4 files changed, 35 insertions(+), 80 deletions(-)
|
34
47
|
|
48
|
+
=== BROWSING GIT REPOS WITH YOUR BROWSER
|
49
|
+
|
50
|
+
To serve up your repo via 'git instaweb':
|
51
|
+
|
52
|
+
% gitjour web phil-gitjour
|
53
|
+
[2009-03-17 19:27:20] INFO WEBrick 1.3.1
|
54
|
+
[2009-03-17 19:27:20] INFO ruby 1.8.6 (2008-03-03) [universal-darwin9.0]
|
55
|
+
# Starts git-instaweb in webrick, publishes ZeroConf DNS record
|
56
|
+
|
57
|
+
To see all advertised git repos in your browser:
|
58
|
+
|
59
|
+
% gitjour browse
|
60
|
+
# Starts a small web-app to find all
|
61
|
+
|
62
|
+
|
35
63
|
== REQUIREMENTS:
|
36
64
|
|
65
|
+
* git
|
37
66
|
* dnssd, which requires development headers to bonjour or avahi
|
38
67
|
See dnssd documentation for details.
|
39
68
|
|
data/Rakefile
CHANGED
@@ -10,6 +10,8 @@ Hoe.new('gitjour', Gitjour::VERSION) do |p|
|
|
10
10
|
p.developer('Evan Phoenix', 'evan@fallingsnow.net')
|
11
11
|
p.developer('Rich Kilmer', 'rich@example.com')
|
12
12
|
p.developer('Phil Hagelberg', 'technomancy@gmail.com')
|
13
|
+
|
14
|
+
p.readme_file = 'README.rdoc'
|
13
15
|
end
|
14
16
|
|
15
17
|
# vim: syntax=Ruby
|
data/lib/gitjour.rb
CHANGED
@@ -5,7 +5,7 @@ require 'set'
|
|
5
5
|
Thread.abort_on_exception = true
|
6
6
|
|
7
7
|
module Gitjour
|
8
|
-
VERSION = "6.
|
8
|
+
VERSION = "6.5.0"
|
9
9
|
GitService = Struct.new(:name, :host, :port, :description)
|
10
10
|
|
11
11
|
class Application
|
@@ -23,6 +23,10 @@ module Gitjour
|
|
23
23
|
serve(*args)
|
24
24
|
when "remote"
|
25
25
|
remote(*args)
|
26
|
+
when "web"
|
27
|
+
web(*args)
|
28
|
+
when "browse"
|
29
|
+
browse(*args)
|
26
30
|
else
|
27
31
|
help
|
28
32
|
end
|
@@ -30,6 +34,18 @@ module Gitjour
|
|
30
34
|
|
31
35
|
private
|
32
36
|
|
37
|
+
def service_name(name)
|
38
|
+
# If the name starts with ^, then don't apply the prefix
|
39
|
+
if name[0] == ?^
|
40
|
+
name = name[1..-1]
|
41
|
+
else
|
42
|
+
prefix = `git config --get gitjour.prefix`.chomp
|
43
|
+
prefix = ENV["USER"] if prefix.empty?
|
44
|
+
name = [prefix, name].compact.join("-")
|
45
|
+
end
|
46
|
+
name
|
47
|
+
end
|
48
|
+
|
33
49
|
def list
|
34
50
|
service_list.each do |service|
|
35
51
|
puts "=== #{service.name} on #{service.host}:#{service.port} ==="
|
@@ -74,25 +90,16 @@ module Gitjour
|
|
74
90
|
|
75
91
|
def serve(path=Dir.pwd, *rest)
|
76
92
|
path = File.expand_path(path)
|
77
|
-
name = rest.shift || File.basename(path)
|
93
|
+
name = service_name(rest.shift || File.basename(path))
|
78
94
|
port = rest.shift || 9418
|
79
95
|
|
80
|
-
# If the name starts with ^, then don't apply the prefix
|
81
|
-
if name[0] == ?^
|
82
|
-
name = name[1..-1]
|
83
|
-
else
|
84
|
-
prefix = `git config --get gitjour.prefix`.chomp
|
85
|
-
prefix = ENV["USER"] if prefix.empty?
|
86
|
-
name = [prefix, name].compact.join("-")
|
87
|
-
end
|
88
|
-
|
89
96
|
if File.exists?("#{path}/.git")
|
90
|
-
|
97
|
+
announce_git(path, name, port.to_i)
|
91
98
|
else
|
92
99
|
Dir["#{path}/*"].each do |dir|
|
93
100
|
if File.directory?(dir)
|
94
101
|
name = File.basename(dir)
|
95
|
-
|
102
|
+
announce_git(dir, name, 9418)
|
96
103
|
end
|
97
104
|
end
|
98
105
|
end
|
@@ -100,6 +107,26 @@ module Gitjour
|
|
100
107
|
`git daemon --verbose --export-all --port=#{port} --base-path=#{path} --base-path-relaxed`
|
101
108
|
end
|
102
109
|
|
110
|
+
def web(path=Dir.pwd, *rest)
|
111
|
+
path = File.expand_path(path)
|
112
|
+
name = service_name(rest.shift || File.basename(path))
|
113
|
+
port = rest.shift || 1234
|
114
|
+
httpd = rest.shift || "webrick"
|
115
|
+
|
116
|
+
system("git instaweb --httpd=#{httpd} --port=#{port}") or
|
117
|
+
abort "Unable to launch git instaweb."
|
118
|
+
|
119
|
+
announce_web(path, name, port.to_i)
|
120
|
+
|
121
|
+
trap("INT") do
|
122
|
+
puts "Stopping instaweb..."
|
123
|
+
system "git instaweb stop"
|
124
|
+
exit
|
125
|
+
end
|
126
|
+
|
127
|
+
Thread.stop
|
128
|
+
end
|
129
|
+
|
103
130
|
def help
|
104
131
|
puts "Gitjour #{Gitjour::VERSION}"
|
105
132
|
puts "Serve up and use git repositories via ZeroConf."
|
@@ -127,6 +154,19 @@ module Gitjour
|
|
127
154
|
puts " Add a ZeroConf remote into your current repository."
|
128
155
|
puts " Optionally pass name to not use pwd."
|
129
156
|
puts
|
157
|
+
puts " web <path_to_project> [<name_of_project>] [<port>] [<httpd_daemon>]"
|
158
|
+
puts " Serve up the current directory via git instaweb for browsers."
|
159
|
+
puts " The default port is 1234 and the httpd_daemon is defaulted to"
|
160
|
+
puts " webrick. Other options are 'lighttpd' and 'apache2' (See the"
|
161
|
+
puts " git-instaweb man page for more details)"
|
162
|
+
puts
|
163
|
+
puts " browse [<port>] [<browser>]"
|
164
|
+
puts " Browse git repositories published with the 'web' command (see"
|
165
|
+
puts " above). This command takes two optional arguments: the first"
|
166
|
+
puts " is the port for the local web server (default 9850), the second"
|
167
|
+
puts " is the path to your web browser (see man git-web--browse for"
|
168
|
+
puts " details)."
|
169
|
+
puts
|
130
170
|
end
|
131
171
|
|
132
172
|
class Done < RuntimeError; end
|
@@ -173,16 +213,30 @@ module Gitjour
|
|
173
213
|
return list
|
174
214
|
end
|
175
215
|
|
176
|
-
def
|
216
|
+
def browse(*args)
|
217
|
+
require "gitjour/browser"
|
218
|
+
Browser.new(*args).start
|
219
|
+
end
|
220
|
+
|
221
|
+
def announce_repo(path, name, port, type)
|
177
222
|
return unless File.exists?("#{path}/.git")
|
178
223
|
|
179
224
|
tr = DNSSD::TextRecord.new
|
180
225
|
tr['description'] = File.read("#{path}/.git/description") rescue "a git project"
|
226
|
+
tr['gitjour'] = 'true' # distinguish instaweb from other HTTP servers
|
181
227
|
|
182
|
-
DNSSD.register(name,
|
228
|
+
DNSSD.register(name, type, 'local', port, tr.encode) do |rr|
|
183
229
|
puts "Registered #{name} on port #{port}. Starting service."
|
184
230
|
end
|
185
231
|
end
|
232
|
+
|
233
|
+
def announce_git(path, name, port)
|
234
|
+
announce_repo(path, name, port, "_git._tcp")
|
235
|
+
end
|
236
|
+
|
237
|
+
def announce_web(path, name, port)
|
238
|
+
announce_repo(path, name, port, "_http._tcp")
|
239
|
+
end
|
186
240
|
end
|
187
241
|
end
|
188
242
|
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require "webrick"
|
2
|
+
require "erb"
|
3
|
+
require "set"
|
4
|
+
require "thread"
|
5
|
+
|
6
|
+
module Gitjour
|
7
|
+
class Browser
|
8
|
+
|
9
|
+
def initialize(*args)
|
10
|
+
@port = args.shift || 9850
|
11
|
+
@browser = args.shift
|
12
|
+
@services = Set.new
|
13
|
+
@mutex = Mutex.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def start
|
17
|
+
DNSSD.browse("_http._tcp") do |reply|
|
18
|
+
begin
|
19
|
+
DNSSD.resolve reply.name, reply.type, reply.domain do |resolve_reply|
|
20
|
+
next unless resolve_reply.text_record['gitjour']
|
21
|
+
service = GitService.new(reply.name,
|
22
|
+
resolve_reply.target,
|
23
|
+
resolve_reply.port,
|
24
|
+
resolve_reply.text_record['description'].to_s)
|
25
|
+
|
26
|
+
@mutex.synchronize do
|
27
|
+
if @services.member? service
|
28
|
+
@services.delete service
|
29
|
+
else
|
30
|
+
@services << service
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
rescue ArgumentError # usually a jacked DNS text record
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
http = WEBrick::HTTPServer.new(:Port => @port.to_i)
|
39
|
+
http.mount_proc("/") { |req, res| index(req, res) }
|
40
|
+
http.mount_proc("/style.css") { |req, res| stylesheet(req, res) }
|
41
|
+
trap("INT") { http.shutdown }
|
42
|
+
t = Thread.new { http.start }
|
43
|
+
|
44
|
+
url = "http://localhost:#{@port}"
|
45
|
+
if @browser
|
46
|
+
`git web--browse -b '#{@browser}' http://localhost:9850`
|
47
|
+
else
|
48
|
+
`git web--browse -c "instaweb.browser" http://localhost:9850`
|
49
|
+
end
|
50
|
+
t.join
|
51
|
+
end
|
52
|
+
|
53
|
+
def index(req, res)
|
54
|
+
res['Content-Type'] = 'text/html'
|
55
|
+
res.body = index_html.result(binding)
|
56
|
+
end
|
57
|
+
|
58
|
+
def index_html
|
59
|
+
@index_html ||= ERB.new(<<-HTML)
|
60
|
+
<html>
|
61
|
+
<body>
|
62
|
+
<head>
|
63
|
+
<link rel="stylesheet" href="/style.css" type="text/css" media="screen"/>
|
64
|
+
<title>Browseable Git Repositories</title>
|
65
|
+
</head>
|
66
|
+
<h1>Browseable Git Repositories</h1>
|
67
|
+
<ul>
|
68
|
+
<% @mutex.synchronize do %>
|
69
|
+
<% @services.map do |s| %>
|
70
|
+
<li>
|
71
|
+
<a href='http://<%= s.host %>:<%= s.port %>' target="_new">
|
72
|
+
<%= s.name %>
|
73
|
+
</a>
|
74
|
+
<%= s.description unless s.description =~ /^Unnamed repository/ %>
|
75
|
+
</li>
|
76
|
+
<% end %>
|
77
|
+
<% end %>
|
78
|
+
</ul>
|
79
|
+
</body>
|
80
|
+
</html>
|
81
|
+
HTML
|
82
|
+
end
|
83
|
+
|
84
|
+
def stylesheet(req, res)
|
85
|
+
res['Content-Type'] = 'text/css'
|
86
|
+
res.body = css
|
87
|
+
end
|
88
|
+
|
89
|
+
def css
|
90
|
+
@css ||= <<-CSS
|
91
|
+
body {
|
92
|
+
font-family: sans-serif;
|
93
|
+
font-size: 12px;
|
94
|
+
background-color: #fff;
|
95
|
+
}
|
96
|
+
|
97
|
+
h1 {
|
98
|
+
font-size: 20px;
|
99
|
+
font-weight: bold;
|
100
|
+
}
|
101
|
+
|
102
|
+
ul {
|
103
|
+
border: 1px dashed #999;
|
104
|
+
padding: 10 10 10 20;
|
105
|
+
background-color: #ccc;
|
106
|
+
}
|
107
|
+
CSS
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitjour
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
4
|
+
version: 6.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chad Fowler
|
@@ -12,7 +12,7 @@ autorequire:
|
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
14
|
|
15
|
-
date: 2009-03-
|
15
|
+
date: 2009-03-17 00:00:00 -07:00
|
16
16
|
default_executable:
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
@@ -35,7 +35,7 @@ dependencies:
|
|
35
35
|
- !ruby/object:Gem::Version
|
36
36
|
version: 1.9.0
|
37
37
|
version:
|
38
|
-
description: Automates
|
38
|
+
description: Automates ZeroConf-powered serving and cloning of git repositories.
|
39
39
|
email:
|
40
40
|
- chad@chadfowler.com
|
41
41
|
- evan@fallingsnow.net
|
@@ -48,14 +48,14 @@ extensions: []
|
|
48
48
|
extra_rdoc_files:
|
49
49
|
- History.txt
|
50
50
|
- Manifest.txt
|
51
|
-
- README.txt
|
52
51
|
files:
|
53
52
|
- History.txt
|
54
53
|
- Manifest.txt
|
55
|
-
- README.
|
54
|
+
- README.rdoc
|
56
55
|
- Rakefile
|
57
56
|
- bin/gitjour
|
58
57
|
- lib/gitjour.rb
|
58
|
+
- lib/gitjour/browser.rb
|
59
59
|
- test/test_gitjour.rb
|
60
60
|
- test/test_helper.rb
|
61
61
|
has_rdoc: true
|
@@ -65,7 +65,7 @@ licenses: []
|
|
65
65
|
post_install_message:
|
66
66
|
rdoc_options:
|
67
67
|
- --main
|
68
|
-
- README.
|
68
|
+
- README.rdoc
|
69
69
|
require_paths:
|
70
70
|
- lib
|
71
71
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -83,10 +83,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
83
83
|
requirements: []
|
84
84
|
|
85
85
|
rubyforge_project: gitjour
|
86
|
-
rubygems_version: 1.3.1
|
86
|
+
rubygems_version: 1.3.1
|
87
87
|
signing_key:
|
88
88
|
specification_version: 3
|
89
|
-
summary: Automates
|
89
|
+
summary: Automates ZeroConf-powered serving and cloning of git repositories.
|
90
90
|
test_files:
|
91
|
-
- test/test_helper.rb
|
92
91
|
- test/test_gitjour.rb
|
92
|
+
- test/test_helper.rb
|