warrenseen-gemjour 1.0.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/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
+