diff --git a/README.markdown b/README.markdown index 08695938..a69953a4 100644 --- a/README.markdown +++ b/README.markdown @@ -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 @@ -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/ diff --git a/Rakefile b/Rakefile index ff94c566..b8a640a5 100644 --- a/Rakefile +++ b/Rakefile @@ -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" diff --git a/lib/rubygems/commands/inabox_command.rb b/lib/rubygems/commands/inabox_command.rb new file mode 100644 index 00000000..c519c944 --- /dev/null +++ b/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 diff --git a/lib/rubygems_plugin.rb b/lib/rubygems_plugin.rb new file mode 100644 index 00000000..d45a3f9c --- /dev/null +++ b/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 diff --git a/views/upload.erb b/views/upload.erb index c854f9f5..4c5e67a1 100644 --- a/views/upload.erb +++ b/views/upload.erb @@ -1,3 +1,4 @@ +<%= @error %>