Closing some issues
authorDickson S. Guedes <[email protected]>
Thu, 23 Jun 2011 20:24:27 +0000 (17:24 -0300)
committerDickson S. Guedes <[email protected]>
Thu, 23 Jun 2011 20:24:27 +0000 (17:24 -0300)
README.md
Rakefile
lib/pgxn_utils.rb
lib/pgxn_utils/cli.rb
lib/pgxn_utils/constants.rb [new file with mode: 0644]
lib/pgxn_utils/version.rb
pgxn_utils.gemspec

index f72922283f72d26fb925f686aa896fba5d97f2fc..3f0c4014e6b22f0827a0acb33b51d005227a8db9 100644 (file)
--- a/README.md
+++ b/README.md
@@ -105,7 +105,7 @@ For all switches that you can use with *change*, type:
       -r, [--release-status=RELEASE_STATUS]  # Initial extension's release status
 
 
-# Bundle it!
+# Bundling and Releasing!
 
 Well, since you finished your work you can bundle it to send to [PGXN](http://pgxn.org).
 
@@ -114,9 +114,19 @@ Just type:
     $ pgxn_utils bundle my_cool_extension
     Extension generated at: /home/guedes/extensions/my_cool_extension-0.0.1.zip
 
+    $ ../pgxn-utils/bin/pgxn_utils release overpaid-0.0.6b3.zip 
+    Enter your PGXN username: guedes
+    Enter your PGXN password: **************
+    Trying to release my_cool_extension-0.0.1.zip ... released successfully!
+    Visit: http://manager.pgxn.org/distributions/my_cool_extension/0.0.1
+
+You can export `PGXN_USER` and `PGXN_PASSWORD` environment variables to avoid
+type username and password everytime.
+
 # Working in progress
 
-I'm working in an option to release the bundled extension, sending it to [PGXN](http://pgxn.org).
+* support to [git](http://git-scm.org)
+* support to proxy
 
 Copyright and License
 ---------------------
index ec28752d8cb1f1697a0d51dcbec8bee0c913cfc2..39881c0b96b635fa485199fa11ba514eb8d2ab3c 100644 (file)
--- a/Rakefile
+++ b/Rakefile
@@ -1,6 +1,6 @@
 require 'bundler'
+include Rake::DSL
 Bundler::GemHelper.install_tasks
-
 require 'rspec/core/rake_task'
 
 desc "Run RSpec"
@@ -11,7 +11,6 @@ RSpec::Core::RakeTask.new do |t|
   #dont show warnings here yet
   #t.ruby_opts  = %w(-w)
 end
-
 desc "CTag Files"
 task :ctag do
   #system("ctags -R --exclude=.git --exclude=log * ~/.rvm/gems/")
index c3750bba7094030d7b0ff9fb4d925d59833da566..04c0c23f1275589978d2fa66afcb26e0ba5e4306 100644 (file)
@@ -2,7 +2,10 @@ require 'thor'
 require 'json'
 require 'zip/zip'
 require 'zippy'
+require 'net/http/post/multipart'
+require 'highline/import'
 
 module PgxnUtils
  autoload :CLI, 'pgxn_utils/cli'
+ autoload :Constants, 'pgxn_utils/constants'
 end
index c8ab5d4a14fa0005a948a69b5b86509ee7020904..18ca7966eadb61c73b09b6082f83d20a9eea1d05 100644 (file)
@@ -3,8 +3,10 @@ module PgxnUtils
     attr_accessor :extension_name, :target, :maintainer #, :maintainer_mail
     attr_accessor :abstract, :description, :version, :tags
     attr_accessor :license, :release_status, :generated_by
+    attr_accessor :pgxn_username, :pgxn_password
 
     include Thor::Actions
+    include PgxnUtils::Constants
 
     desc "skeleton extension_name", "Creates an extension skeleton in current directory."
 
@@ -84,18 +86,79 @@ module PgxnUtils
         ext = "zip"
         archive = "#{archive_name}.#{ext}"
 
+        puts path
         if can_zip?(archive)
+          make_dist_clean(path)
+
           Zippy.create(archive) do |zip|
             Dir["#{path}/**/**"].each do |file|
               zip["#{extension_name}-#{config_options['version']}/#{file.sub(path+'/','')}"] = File.open(file) unless File.directory?(file)
             end
           end
-          say "Extension generated at: #{archive}"
+          say_status :create, archive, :green
         end
       end
     end
 
+    desc "release filename", "Release a extension"
+    def release(filename)
+      send_file_to_pgxn(filename)
+    end
+
     no_tasks do
+      def make_dist_clean(path)
+        inside path do
+          run 'make distclean', :capture => true
+        end
+      end
+
+      def ask_for_pgxn_credential
+        self.pgxn_username = ENV["PGXN_USER"] || HighLine.ask("Enter your PGXN username: ") { |q| q.validate = /^[a-z]([-a-z0-9]{0,61}[a-z0-9])?$/ }
+        self.pgxn_password = ENV["PGXN_PASS"] || HighLine.ask("Enter your PGXN password: ") { |q| q.echo =  '*' }
+      end
+
+      def check_response(response)
+        case response
+        when Net::HTTPUnauthorized then 
+          say "oops!", :red
+          say "It seems that you entered a wrong username or password.", :red
+        when Net::HTTPConflict then
+          say "conflict!", :yellow
+          say "Distribution already exists! Please, check your META.json.", :yellow
+        when Net::HTTPSeeOther then
+          say "released successfully!", :green
+          say "Visit: #{URI.parse(response['Location'])}", :green
+        else
+          say "Unknown error. (#{response})"
+        end
+      end
+
+      def prepare_multipart_post_for(filename)
+        file_basename = File.basename(filename)
+        zip_file = File.open(filename)
+        Net::HTTP::Post::Multipart.new(
+          UPLOAD_URL.path,
+          "archive" => UploadIO.new(zip_file, "application/zip", file_basename),
+          "Expect" => ""
+        )
+      end
+
+      def try_send_file(request, filename)
+        Net::HTTP.start(UPLOAD_URL.host, UPLOAD_URL.port) do |http|
+          say "Trying to release #{File.basename(filename)} ... "
+          http.request(request)
+        end
+      end
+
+      def send_file_to_pgxn(filename)
+        request = prepare_multipart_post_for(filename)
+        ask_for_pgxn_credential
+
+        request.basic_auth pgxn_username, pgxn_password
+        response = try_send_file(request, filename)
+        check_response(response)
+      end
+
       def resolve_extension_path_and_name(extension_name)
         target = options[:target]
         extension_path = "."
@@ -115,7 +178,8 @@ module PgxnUtils
         can_zip = false
 
         if File.exists?(archive)
-          if yes? "#{archive} found! Overwrite? [yN]"
+          say_status :conflict, archive, :red
+          if yes? "Overwrite #{archive}? [yN]"
             can_zip = true
           else
             can_zip = false
diff --git a/lib/pgxn_utils/constants.rb b/lib/pgxn_utils/constants.rb
new file mode 100644 (file)
index 0000000..2abf759
--- /dev/null
@@ -0,0 +1,5 @@
+module PgxnUtils
+  module Constants
+    UPLOAD_URL = URI.parse('https://manager.pgxn.org/auth/upload')
+  end
+end
index c85b262f8b4d06f904a981dccc9bd31477776716..7233fc5e5d864982b1d69784f8bd71b4ff05cf80 100644 (file)
@@ -1,3 +1,3 @@
 module PgxnUtils
-  VERSION = "0.1.1"
+  VERSION = "0.1.2"
 end
index 5126280efd3e8f4695d4548724a1828178aa171f..ba7c79c3370bd5e9a42511c364c61719f3bac37d 100644 (file)
@@ -29,6 +29,8 @@ Gem::Specification.new do |s|
       s.add_runtime_dependency "thor", "~> 0.14"
       s.add_runtime_dependency "rubyzip", "~> 0.9.4"
       s.add_runtime_dependency "zippy", "~> 0.1.0"
+      s.add_runtime_dependency "multipart-post", "~> 1.1.2"
+      s.add_runtime_dependency "highline", "~> 1.6.2"
       s.add_development_dependency "rspec"
       s.add_development_dependency "simplecov", "~> 0.4.0"
     else
@@ -36,11 +38,15 @@ Gem::Specification.new do |s|
       s.add_dependency "thor", "~> 0.14"
       s.add_dependency "rubyzip", "~> 0.9.4"
       s.add_dependency "zippy", "~> 0.1.0"
+      s.add_dependency "multipart-post", "~> 1.1.2"
+      s.add_dependency "highline", "~> 1.6.2"
     end
   else
     s.add_dependency "json", "~> 1.5.2"
     s.add_dependency "thor", "~> 0.14"
     s.add_dependency "rubyzip", "~> 0.9.4"
     s.add_dependency "zippy", "~> 0.1.0"
+    s.add_dependency "multipart-post", "~> 1.1.2"
+    s.add_dependency "highline", "~> 1.6.2"
   end
 end