hoxworth-gitjour 6.3.2

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 0.0.1 2008-05-29
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
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
@@ -0,0 +1,8 @@
1
+ README
2
+
3
+ DEVELOPMENT
4
+
5
+ How to test from the console:
6
+
7
+ irb -r 'lib/gitjour/application'
8
+ > Gitjour::Application.run "list"
data/bin/gitjour ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'gitjour'
4
+
5
+ trap "INT" do
6
+ exit!
7
+ end
8
+
9
+ Gitjour::Application.run(*ARGV)
@@ -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
+
@@ -0,0 +1,9 @@
1
+ module Gitjour #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 6
4
+ MINOR = 3
5
+ TINY = 2
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
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
+