hoxworth-gitjour 6.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/History.txt +4 -0
- data/License.txt +20 -0
- data/README.txt +8 -0
- data/bin/gitjour +9 -0
- data/lib/gitjour/application.rb +232 -0
- data/lib/gitjour/version.rb +9 -0
- data/lib/gitjour.rb +1 -0
- metadata +72 -0
data/History.txt
ADDED
data/License.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Chad Fowler, Evan Phoenix, Rich Kilmer
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.txt
ADDED
data/bin/gitjour
ADDED
@@ -0,0 +1,232 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'dnssd'
|
3
|
+
require 'set'
|
4
|
+
require 'gitjour/version'
|
5
|
+
|
6
|
+
Thread.abort_on_exception = true
|
7
|
+
|
8
|
+
module Gitjour
|
9
|
+
GitService = Struct.new(:name, :host, :port, :description, :branches)
|
10
|
+
ServiceRecord = Struct.new(:name, :text_record, :service)
|
11
|
+
|
12
|
+
class Application
|
13
|
+
|
14
|
+
@@announcements = {}
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def run(*args)
|
18
|
+
case args.shift
|
19
|
+
when "list"
|
20
|
+
list
|
21
|
+
when "clone"
|
22
|
+
clone(*args)
|
23
|
+
when "serve"
|
24
|
+
serve(*args)
|
25
|
+
when "remote"
|
26
|
+
remote(*args)
|
27
|
+
when "fetch"
|
28
|
+
fetch(*args)
|
29
|
+
else
|
30
|
+
help
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def list
|
36
|
+
service_list.each do |service|
|
37
|
+
puts "=== #{service.name} on #{service.host}:#{service.port} ==="
|
38
|
+
puts " gitjour clone #{service.name}"
|
39
|
+
if service.description != '' && service.description !~ /^Unnamed repository/
|
40
|
+
puts " Description: #{service.description}"
|
41
|
+
end
|
42
|
+
puts
|
43
|
+
puts " Branches: (gitjour fetch #{service.name} <branch>)"
|
44
|
+
service.branches.each do |branch|
|
45
|
+
puts " #{branch}"
|
46
|
+
end
|
47
|
+
puts
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def clone(repository_name, *rest)
|
52
|
+
dir = rest.shift || repository_name
|
53
|
+
if File.exists?(dir)
|
54
|
+
exit_with! "ERROR: Clone directory '#{dir}' already exists."
|
55
|
+
end
|
56
|
+
|
57
|
+
puts "Cloning '#{repository_name}' into directory '#{dir}'..."
|
58
|
+
|
59
|
+
unless service = locate_repo(repository_name)
|
60
|
+
exit_with! "ERROR: Unable to find project named '#{repository_name}'"
|
61
|
+
end
|
62
|
+
|
63
|
+
puts "Connecting to #{service.host}:#{service.port}"
|
64
|
+
|
65
|
+
system "git clone git://#{service.host}:#{service.port}/ #{dir}/"
|
66
|
+
end
|
67
|
+
|
68
|
+
def fetch(repository_name, branch_name, *rest)
|
69
|
+
local_name = rest.shift || branch_name
|
70
|
+
|
71
|
+
puts "Fetching '#{repository_name}:#{branch_name}' into working version..."
|
72
|
+
|
73
|
+
unless service = locate_repo(repository_name)
|
74
|
+
exit_with! "ERROR: Unable to find project named '#{repository_name}'"
|
75
|
+
end
|
76
|
+
|
77
|
+
exit_with! "ERROR: Unable to find branch named '#{branch_name}' in project '#{repository_name}'" if !service.branches.include?(branch_name)
|
78
|
+
|
79
|
+
branches = `git branch`.split("\n").collect {|x| x[/\w.*/]}
|
80
|
+
exit_with! "ERROR: Local branch '#{local_name}' already exists!" if branches.include?(local_name)
|
81
|
+
|
82
|
+
puts "Connecting to #{service.host}:#{service.port}"
|
83
|
+
|
84
|
+
system "git fetch git://#{service.host}:#{service.port}/ #{branch_name}:#{local_name}"
|
85
|
+
end
|
86
|
+
|
87
|
+
def remote(repository_name, *rest)
|
88
|
+
dir = rest.shift || repository_name
|
89
|
+
service = locate_repo repository_name
|
90
|
+
system "git remote add #{dir} git://#{service.host}:#{service.port}/"
|
91
|
+
end
|
92
|
+
|
93
|
+
def serve(path=Dir.pwd, *rest)
|
94
|
+
path = File.expand_path(path)
|
95
|
+
name = rest.shift || File.basename(path)
|
96
|
+
port = rest.shift || 9418
|
97
|
+
interval = rest.shift || 30
|
98
|
+
branches = []
|
99
|
+
|
100
|
+
Thread.new do
|
101
|
+
loop do
|
102
|
+
# If the name starts with ^, then don't apply the prefix
|
103
|
+
if name[0] == ?^
|
104
|
+
service_name = name[1..-1]
|
105
|
+
else
|
106
|
+
prefix = `git config --get gitjour.prefix`.chomp
|
107
|
+
prefix = ENV["USER"] if prefix.empty?
|
108
|
+
service_name = [prefix, name].compact.join("-")
|
109
|
+
end
|
110
|
+
|
111
|
+
if File.exists?("#{path}/.git")
|
112
|
+
announce_repo(path, service_name, port.to_i)
|
113
|
+
else
|
114
|
+
Dir["#{path}/*"].each do |dir|
|
115
|
+
if File.directory?(dir)
|
116
|
+
service_name = File.basename(dir)
|
117
|
+
announce_repo(dir, service_name, 9418)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
sleep(interval)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
`git-daemon --verbose --export-all --port=#{port} --base-path=#{path} --base-path-relaxed`
|
126
|
+
end
|
127
|
+
|
128
|
+
def help
|
129
|
+
puts "Gitjour #{Gitjour::VERSION::STRING}"
|
130
|
+
puts "Serve up and use git repositories via Bonjour/DNSSD."
|
131
|
+
puts "\nUsage: gitjour <command> [args]"
|
132
|
+
puts
|
133
|
+
puts " list"
|
134
|
+
puts " Lists available repositories."
|
135
|
+
puts
|
136
|
+
puts " clone <project> [<directory>]"
|
137
|
+
puts " Clone a gitjour served repository."
|
138
|
+
puts
|
139
|
+
puts " serve <path_to_project> [<name_of_project>] [<port>] [<poll interval>] or"
|
140
|
+
puts " <path_to_projects>"
|
141
|
+
puts " Serve up the current directory or projects via gitjour."
|
142
|
+
puts
|
143
|
+
puts " The name of your project is automatically prefixed with"
|
144
|
+
puts " `git config --get gitjour.prefix` or your username (preference"
|
145
|
+
puts " in that order). If you don't want a prefix, put a ^ on the front"
|
146
|
+
puts " of the name_of_project (the ^ is removed before announcing)."
|
147
|
+
puts
|
148
|
+
puts " remote <project> [<name>]"
|
149
|
+
puts " Add a Bonjour remote into your current repository."
|
150
|
+
puts " Optionally pass name to not use pwd."
|
151
|
+
puts
|
152
|
+
puts " fetch <project> <branch> [<local branch>]"
|
153
|
+
puts " Fetch a specific branch from a gitjour repository."
|
154
|
+
puts
|
155
|
+
end
|
156
|
+
|
157
|
+
def exit_with!(message)
|
158
|
+
STDERR.puts message
|
159
|
+
exit!
|
160
|
+
end
|
161
|
+
|
162
|
+
class Done < RuntimeError; end
|
163
|
+
|
164
|
+
def discover(timeout=5)
|
165
|
+
waiting_thread = Thread.current
|
166
|
+
|
167
|
+
dns = DNSSD.browse "_git._tcp" do |reply|
|
168
|
+
DNSSD.resolve reply.name, reply.type, reply.domain do |resolve_reply|
|
169
|
+
service = GitService.new(reply.name,
|
170
|
+
resolve_reply.target,
|
171
|
+
resolve_reply.port,
|
172
|
+
resolve_reply.text_record['description'].to_s,
|
173
|
+
resolve_reply.text_record['branches'].to_s.split('|'))
|
174
|
+
begin
|
175
|
+
yield service
|
176
|
+
rescue Done
|
177
|
+
waiting_thread.run
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
puts "Gathering for up to #{timeout} seconds..."
|
183
|
+
sleep timeout
|
184
|
+
dns.stop
|
185
|
+
end
|
186
|
+
|
187
|
+
def locate_repo(name)
|
188
|
+
found = nil
|
189
|
+
|
190
|
+
discover do |obj|
|
191
|
+
if obj.name == name
|
192
|
+
found = obj
|
193
|
+
raise Done
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
return found
|
198
|
+
end
|
199
|
+
|
200
|
+
def service_list
|
201
|
+
list = Set.new
|
202
|
+
discover { |obj| list << obj }
|
203
|
+
|
204
|
+
return list
|
205
|
+
end
|
206
|
+
|
207
|
+
def announce_repo(path, name, port)
|
208
|
+
return unless File.exists?("#{path}/.git")
|
209
|
+
branches = `git branch`.split("\n").collect {|x| x[/\w.*/]}
|
210
|
+
|
211
|
+
if @@announcements[name]
|
212
|
+
return if @@announcements[name].text_record['branches'] == branches.join('|')
|
213
|
+
puts "Branches changed for #{name}. Reloading..."
|
214
|
+
@@announcements[name].service.stop
|
215
|
+
end
|
216
|
+
|
217
|
+
tr = DNSSD::TextRecord.new
|
218
|
+
tr['description'] = File.read("#{path}/.git/description") rescue "a git project"
|
219
|
+
tr['branches'] = branches.join('|')
|
220
|
+
|
221
|
+
service = DNSSD.register(name, "_git._tcp", 'local', port, tr.encode) do |rr|
|
222
|
+
puts "Registered #{name} on port #{port}. Starting service."
|
223
|
+
end
|
224
|
+
@@announcements[name] = ServiceRecord.new(name,tr,service)
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
|
232
|
+
|
data/lib/gitjour.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'gitjour/application'
|
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hoxworth-gitjour
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 6.3.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Chad Fowler
|
8
|
+
- Rich Kilmer
|
9
|
+
- Evan Phoenix
|
10
|
+
- Kenny Hoxworth
|
11
|
+
autorequire:
|
12
|
+
bindir: bin
|
13
|
+
cert_chain: []
|
14
|
+
|
15
|
+
date: 2008-06-25 00:00:00 -07:00
|
16
|
+
default_executable:
|
17
|
+
dependencies:
|
18
|
+
- !ruby/object:Gem::Dependency
|
19
|
+
name: dnssd
|
20
|
+
version_requirement:
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: "0"
|
26
|
+
version:
|
27
|
+
description: Chad Fowler's gitjour, now with fetch bits.
|
28
|
+
email:
|
29
|
+
executables:
|
30
|
+
- gitjour
|
31
|
+
extensions: []
|
32
|
+
|
33
|
+
extra_rdoc_files:
|
34
|
+
- README.txt
|
35
|
+
- License.txt
|
36
|
+
- History.txt
|
37
|
+
files:
|
38
|
+
- README.txt
|
39
|
+
- History.txt
|
40
|
+
- License.txt
|
41
|
+
- bin/gitjour
|
42
|
+
- lib/gitjour.rb
|
43
|
+
- lib/gitjour/application.rb
|
44
|
+
- lib/gitjour/version.rb
|
45
|
+
has_rdoc: "false"
|
46
|
+
homepage: http://github.com/hoxworth/gitjour/tree/master
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options: []
|
49
|
+
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 1.8.4
|
57
|
+
version:
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 0.6.0
|
63
|
+
version:
|
64
|
+
requirements: []
|
65
|
+
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.2.0
|
68
|
+
signing_key:
|
69
|
+
specification_version: 2
|
70
|
+
summary: Chad Fowler's gitjour, now with fetch bits.
|
71
|
+
test_files: []
|
72
|
+
|