Skip to content

Commit

Permalink
Support the gem inabox GEM command.
Browse files Browse the repository at this point in the history
  • Loading branch information
tomlea committed Jan 27, 2010
1 parent 83e2e52 commit 83b699b
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 2 deletions.
10 changes: 9 additions & 1 deletion README.markdown
Expand Up @@ -8,7 +8,7 @@ Gem in a box is a simple [sinatra][sinatra] app to allow you to host your own ow

It has no security, or authentication so you should handle this yourself.

## Installation
## Server Setup

gem install geminabox

Expand All @@ -23,6 +23,14 @@ Create a config.ru as follows:
And finally, hook up the config.ru as you normally would ([passenger][passenger], [thin][thin], [unicorn][unicorn], whatever floats you boat).


## Client Usage

gem install geminabox

gem inabox pkg/my-awesome-gem-1.0.gem

Simples!

[sinatra]: http://www.sinatrarb.com/
[passenger]: http://www.modrails.com/
[thin]: http://code.macournoyer.com/thin/
Expand Down
2 changes: 1 addition & 1 deletion Rakefile
Expand Up @@ -6,7 +6,7 @@ task :default => :package

spec = Gem::Specification.new do |s|
s.name = "geminabox"
s.version = "0.1.0"
s.version = "0.2.0"
s.summary = "Really simple rubygem hosting"
s.author = "Tom Lea"
s.email = "contrib@tomlea.co.uk"
Expand Down
123 changes: 123 additions & 0 deletions lib/rubygems/commands/inabox_command.rb
@@ -0,0 +1,123 @@
class Gem::Commands::InaboxCommand < Gem::Command
def description
'Push a gem up to your GemInABox'
end

def arguments
"GEM built gem to push up"
end

def usage
"#{program_name} GEM"
end

def initialize
super 'inabox', description

add_option('-c', '--configure', "Configure GemInABox") do |value, options|
options[:configure] = true
end
end

def execute
return configure if options[:configure]
setup
send_gem
end

def setup
@gemfile = get_one_gem_name
configure unless geminabox_host
end

def send_gem
say "Pushing gem to #{geminabox_host}..."

File.open(@gemfile, "rb") do |file|
url = URI.parse(geminabox_host)
query, headers = Multipart::MultipartPost.new.prepare_query("file" => file)

Net::HTTP.start(url.host, url.port) {|con|
con.read_timeout = 5
response = con.post("/upload", query, headers)
puts response.body
}
end

end

def config_path
File.join(Gem.user_home, '.gem', 'geminabox')
end

def configure
say "Enter the root url for your personal geminabox instance. (E.g. http://gems/)"
host = ask("Host:")
self.geminabox_host = host
end

def geminabox_host
geminabox_host ||= Gem.configuration.load_file(config_path)[:host]
end

def geminabox_host=(host)
config = Gem.configuration.load_file(config_path).merge(:host => host)

dirname = File.dirname(config_path)
Dir.mkdir(dirname) unless File.exists?(dirname)

File.open(config_path, 'w') do |f|
f.write config.to_yaml
end
end

module Multipart
require 'rubygems'
require 'mime/types'
require 'net/http'
require 'cgi'

class Param
attr_accessor :k, :v
def initialize( k, v )
@k = k
@v = v
end

def to_multipart
return "Content-Disposition: form-data; name=\"#{k}\"\r\n\r\n#{v}\r\n"
end
end

class FileParam
attr_accessor :k, :filename, :content
def initialize( k, filename, content )
@k = k
@filename = filename
@content = content
end

def to_multipart
return "Content-Disposition: form-data; name=\"#{k}\"; filename=\"#{filename}\"\r\n" + "Content-Transfer-Encoding: binary\r\n" + "Content-Type: #{MIME::Types.type_for(@filename)}\r\n\r\n" + content + "\r\n"
end
end

class MultipartPost
BOUNDARY = 'tarsiers-rule0000'
HEADER = {"Content-type" => "multipart/form-data, boundary=" + BOUNDARY + " "}

def prepare_query(params)
fp = []
params.each {|k,v|
if v.respond_to?(:read)
fp.push(FileParam.new(k, v.path, v.read))
else
fp.push(Param.new(k,v))
end
}
query = fp.collect {|p| "--" + BOUNDARY + "\r\n" + p.to_multipart }.join("") + "--" + BOUNDARY + "--"
return query, HEADER
end
end
end
end
7 changes: 7 additions & 0 deletions lib/rubygems_plugin.rb
@@ -0,0 +1,7 @@
require 'rubygems/command_manager'

require 'rubygems/command'
require 'rubygems/dependency'
require 'rubygems/version_option'

Gem::CommandManager.instance.register_command :inabox
1 change: 1 addition & 0 deletions views/upload.erb
@@ -1,3 +1,4 @@
<%= @error %>
<form method="POST" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" value="Upload">
Expand Down

0 comments on commit 83b699b

Please sign in to comment.