warrenseen-gemjour 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,48 @@
1
+ = Gemjour
2
+
3
+ Server and install gems over Bonjour.
4
+
5
+ == Installation
6
+
7
+ sudo gem install dnssd
8
+ sudo gem install evanphx-gemjour --source=http://gems.github.com
9
+
10
+ == Usage
11
+
12
+ alice$ gemjour serve # publishes gems via bonjour
13
+ bob$ gemjour list # finds alice
14
+ bob$ gemjour list alice # shows alice's gems
15
+ bob$ gemjour diff alice # shows differences between bob and alice gems
16
+ bob$ gemjour install_diff alice # installs any gem bob doesn't have installed from alice
17
+
18
+ alice$ gem install blah.gem; gitjour serve
19
+ bob$ gemjour install alice blah
20
+
21
+ Prefix the cmds with "sudo" as necessary.
22
+
23
+ == Awesome!
24
+
25
+ You know it.
26
+
27
+ == License
28
+
29
+ Copyright (c) 2008 Evan Phoenix
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining
32
+ a copy of this software and associated documentation files (the
33
+ "Software"), to deal in the Software without restriction, including
34
+ without limitation the rights to use, copy, modify, merge, publish,
35
+ distribute, sublicense, and/or sell copies of the Software, and to
36
+ permit persons to whom the Software is furnished to do so, subject to
37
+ the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be
40
+ included in all copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
43
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
45
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
46
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
47
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
48
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,47 @@
1
+ require "date"
2
+ require "fileutils"
3
+ require "rubygems"
4
+ require "rake/gempackagetask"
5
+
6
+ require "./lib/gemjour/version.rb"
7
+
8
+ gemjour_gemspec = Gem::Specification.new do |s|
9
+ s.name = "gemjour"
10
+ s.version = Gemjour::VERSION
11
+ s.platform = Gem::Platform::RUBY
12
+ s.has_rdoc = true
13
+ s.extra_rdoc_files = ["README.rdoc"]
14
+ s.summary = "Advertise, list, and install gems over Bonjour."
15
+ s.description = s.summary
16
+ s.authors = ["Evan Phoenix"]
17
+ s.email = "evan@fallingsnow.net"
18
+ s.homepage = "http://github.com/evanphx/gemjour"
19
+ s.require_path = "lib"
20
+ s.autorequire = "gemjour"
21
+ s.files = %w(README.rdoc Rakefile) + Dir.glob("{bin,lib}/**/*")
22
+ s.executables = %w(gemjour)
23
+
24
+ s.add_dependency "dnssd", ">= 0.6.0"
25
+ end
26
+
27
+ Rake::GemPackageTask.new(gemjour_gemspec) do |pkg|
28
+ pkg.gem_spec = gemjour_gemspec
29
+ end
30
+
31
+ namespace :gem do
32
+ namespace :spec do
33
+ desc "Update gemjour.gemspec"
34
+ task :generate do
35
+ File.open("gemjour.gemspec", "w") do |f|
36
+ f.puts(gemjour_gemspec.to_ruby)
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ task :install => :package do
43
+ sh %{sudo gem install pkg/gemjour-#{Gemjour::VERSION}}
44
+ end
45
+
46
+ desc "Remove all generated artifacts"
47
+ task :clean => :clobber_package
data/bin/gemjour ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rubygems"
4
+ require File.dirname(__FILE__) + '/../lib/gemjour'
5
+
6
+ begin
7
+
8
+ cmd = ARGV.shift
9
+
10
+ case cmd
11
+ when "serve"
12
+ Gemjour.serve(*ARGV)
13
+ when "list"
14
+ Gemjour.list(*ARGV)
15
+ when "diff"
16
+ Gemjour.diff(*ARGV)
17
+ when "install_diff"
18
+ Gemjour.install_diff(*ARGV)
19
+ when "install"
20
+ Gemjour.install(*ARGV)
21
+ else
22
+ Gemjour.usage
23
+ end
24
+
25
+ rescue => e
26
+ puts "ERROR: running '#{cmd}': #{e.message} (#{e.class})"
27
+ puts
28
+ Gemjour.usage
29
+ end
data/lib/gemjour.rb ADDED
@@ -0,0 +1,144 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'net/dns/mdns-sd'
5
+ require "set"
6
+ require "gemjour/version"
7
+
8
+ DNSSD = Net::DNS::MDNSSD
9
+
10
+ Thread.abort_on_exception = true
11
+
12
+ module Gemjour
13
+ Server = Struct.new(:name, :host, :port)
14
+ PORT = 8808
15
+ SERVICE = "_rubygems._tcp"
16
+
17
+ def self.usage
18
+ puts <<-HELP
19
+ Usage:
20
+
21
+ serve [<name>] [<port>]
22
+ Start up a gem server as <name> on <port>. <name> is your username
23
+ by default, and <port> is 8088. If you want to use the default <name>,
24
+ pass it as "".
25
+
26
+ install <server> <gem>
27
+ Installs <gem> from <server>. <server> is the name the server announces
28
+ itself as.
29
+
30
+ list
31
+ List all available gem servers.
32
+
33
+ show <server>
34
+ List all gems available from <server>
35
+
36
+ HELP
37
+ end
38
+
39
+ def self.find(name)
40
+ host = nil
41
+
42
+ waiting = Thread.current
43
+
44
+ service = DNSSD.browse(SERVICE) do |reply|
45
+ if name === reply.name
46
+ DNSSD.resolve(reply.name, reply.type, reply.domain) do |rr|
47
+ host = Server.new(reply.name, rr.target, rr.port)
48
+ waiting.run
49
+ end
50
+ end
51
+ end
52
+
53
+ sleep 5
54
+ service.stop
55
+
56
+ host
57
+ end
58
+
59
+ def self.list(name = nil)
60
+ return show(name) if name
61
+ hosts = []
62
+
63
+ waiting = Thread.current
64
+
65
+ service = DNSSD.browse(SERVICE) do |reply|
66
+ DNSSD.resolve(reply.name, reply.type, reply.domain) do |rr|
67
+ host = Server.new(reply.name, rr.target, rr.port)
68
+ unless hosts.include? host
69
+ puts "#{host.name} (#{host.host}:#{host.port})"
70
+ hosts << host
71
+ end
72
+ end
73
+ end
74
+
75
+ sleep 5
76
+ service.stop
77
+ end
78
+
79
+ def self.show(name)
80
+ host = find(name)
81
+
82
+ unless host
83
+ puts "ERROR: Unable to find server '#{name}'"
84
+ return
85
+ end
86
+
87
+ system "gem list -r --source=http://#{host.host}:#{host.port}"
88
+ end
89
+
90
+ def self._diff(name)
91
+ host = find(name)
92
+
93
+ unless host
94
+ puts "ERROR: Unable to find server named '#{name}'"
95
+ return
96
+ end
97
+
98
+ require "tempfile"
99
+ local_gems, remote_gems = Tempfile.new("local_gems"), Tempfile.new("remote_gems")
100
+ local_gems.print(`gem list --no-versions --no-verbose`)
101
+ local_gems.close
102
+ remote_gems.print(`gem list --no-versions --no-verbose -r --source=http://#{host.host}:#{host.port}`)
103
+ remote_gems.close
104
+ `diff -u #{local_gems.path} #{remote_gems.path}`
105
+ end
106
+
107
+ def self.diff(name)
108
+ return unless diff = _diff(name)
109
+ puts diff
110
+ end
111
+
112
+ def self.install_diff(name)
113
+ return unless gem_diff = _diff(name)
114
+ gem_diff.scan(/^\+([\w_\-]+)/) do |match|
115
+ install(name, match)
116
+ end
117
+ end
118
+
119
+ def self.install(name, gem)
120
+ host = find(name)
121
+
122
+ unless host
123
+ puts "ERROR: Unable to find server named '#{name}'"
124
+ return
125
+ end
126
+
127
+ puts "Installing gem '#{gem}' from #{host.host}:#{host.port}"
128
+ system "gem install #{gem} -s http://#{host.host}:#{host.port}"
129
+ end
130
+
131
+ def self.serve(name="", port=PORT)
132
+ name = ENV['USER'] if name.empty?
133
+
134
+ tr = DNSSD::TextRecord.new
135
+ tr['description'] = "#{name}'s gem server"
136
+
137
+ DNSSD.register(name, SERVICE, "local", port, tr.encode) do |reply|
138
+ puts "Serving gems under name '#{name}'..."
139
+ end
140
+
141
+ system "gem server --port=#{port} -q > /dev/null 2>&1"
142
+ end
143
+
144
+ end
@@ -0,0 +1,3 @@
1
+ module Gemjour
2
+ VERSION = "1.0.0".freeze
3
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: warrenseen-gemjour
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Evan Phoenix
8
+ autorequire: gemjour
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-06-03 00:00:00 -07:00
13
+ default_executable: gemjour
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: net-mdns
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.4.0
24
+ version:
25
+ description: Advertise, list, and install gems over Bonjour.
26
+ email: evan@fallingsnow.net
27
+ executables:
28
+ - gemjour
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.rdoc
33
+ files:
34
+ - README.rdoc
35
+ - Rakefile
36
+ - bin/gemjour
37
+ - lib/gemjour
38
+ - lib/gemjour/version.rb
39
+ - lib/gemjour.rb
40
+ has_rdoc: true
41
+ homepage: http://github.com/evanphx/gemjour
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: "0"
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project:
62
+ rubygems_version: 1.2.0
63
+ signing_key:
64
+ specification_version: 2
65
+ summary: Advertise, list, and install gems over Bonjour.
66
+ test_files: []
67
+