Skip to content

Loading…

Prepare to 0.1.2. #13

Merged
merged 8 commits into from

1 participant

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 25, 2011
Commits on Jun 16, 2011
  1. Fixing strange behaviours on method #change

    committed
    Now #change checks if current_dir is an extension when no
    extension_name is supplied.
    
    Refs #9
  2. adding ctags task

    committed
  3. adding tags to .gitignore

    committed
Commits on Jun 17, 2011
  1. adjusting json missing dependencie

    committed
    PGXN Utils failed on ruby 1.8 because json is missing. This fix
    that problem.
    
    Refs #11
Commits on Jun 23, 2011
  1. Closing some issues

    committed
Commits on Jun 24, 2011
This page is out of date. Refresh to see the latest.
Showing with 170 additions and 39 deletions.
  1. +1 −0 .gitignore
  2. +15 −3 README.md
  3. +7 −4 Rakefile
  4. +3 −0 lib/pgxn_utils.rb
  5. +116 −16 lib/pgxn_utils/cli.rb
  6. +5 −0 lib/pgxn_utils/constants.rb
  7. +1 −1 lib/pgxn_utils/version.rb
  8. +22 −15 pgxn_utils.gemspec
View
1 .gitignore
@@ -3,3 +3,4 @@
Gemfile.lock
pkg/*
*.sw?
+tags
View
18 README.md
@@ -105,18 +105,30 @@ 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).
-Just type:
+Bundle it:
$ pgxn_utils bundle my_cool_extension
Extension generated at: /home/guedes/extensions/my_cool_extension-0.0.1.zip
+and release it:
+
+ $ pgxn_utils release my_cool_extension-0.0.1.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
---------------------
View
11 Rakefile
@@ -1,15 +1,18 @@
require 'bundler'
+#include Rake::DSL
Bundler::GemHelper.install_tasks
-
require 'rspec/core/rake_task'
desc "Run RSpec"
RSpec::Core::RakeTask.new do |t|
t.verbose = false
- #t.rspec_opts = %w(-fs --color)
t.rspec_opts = %w(--color)
- #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/")
+ system("ctags -R --exclude=.git --exclude=log *")
end
task :default => :spec
View
3 lib/pgxn_utils.rb
@@ -2,7 +2,10 @@
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
View
132 lib/pgxn_utils/cli.rb
@@ -3,8 +3,10 @@ class CLI < Thor
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."
@@ -12,7 +14,6 @@ class CLI < Thor
# META required fields
method_option :maintainer, :aliases => "-m", :type => :string, :desc => "Maintainer's name <maintainer@email>"
- #method_option :maintainer_mail, :aliases => "-e", :type => :string, :desc => "Maintainer's mail"
method_option :abstract, :aliases => "-a", :type => :string, :desc => "Defines a short description to abstract"
method_option :license, :aliases => "-l", :type => :string, :desc => "The extension license."
method_option :version, :aliases => "-v", :type => :string, :desc => "Initial version"
@@ -25,16 +26,26 @@ class CLI < Thor
def skeleton(extension_name,target=nil)
self.target = options[:target] || target || "."
- self.set_accessors extension_name
- directory "root", extension_name
+ if is_extension?("#{self.target}/#{extension_name}")
+ say "'#{extension_name}' already exists. Please, use 'change' instead 'skeleton'.", :red
+ elsif is_extension?(".")
+ say "You are inside a extension directory, already. Consider use 'change' instead.", :red
+ elsif is_dir?("#{self.target}/#{extension_name}")
+ say "Can't create an extension overwriting an existing directory.", :red
+ else
+ self.set_accessors extension_name
+
+ directory "root", extension_name
+ end
end
desc "change [extension_name]", "Change META's attributes in current extension."
+ method_option :target, :aliases => "-p", :type => :string, :default => ".", :desc => "Define the target directory"
+
# META required fields
method_option :maintainer, :aliases => "-m", :type => :string, :desc => "Maintainer's name <maintainer@email>"
- #method_option :maintainer_mail, :aliases => "-e", :type => :string, :desc => "Maintainer's mail"
method_option :abstract, :aliases => "-a", :type => :string, :desc => "Defines a short description to abstract"
method_option :license, :aliases => "-l", :type => :string, :desc => "The extension license."
method_option :version, :aliases => "-v", :type => :string, :desc => "Initial version"
@@ -46,19 +57,26 @@ def skeleton(extension_name,target=nil)
method_option :release_status, :aliases => "-r", :type => :string, :desc => "Initial extension's release status"
def change(extension_name=".")
- path = File.expand_path(extension_name)
+ extension_path, extension_name = resolve_extension_path_and_name(extension_name)
+
+ self.target = extension_path
+ self.extension_name = extension_name
- target = File.expand_path('..', path)
- extension_name = File.basename(path)
+ set_accessors(extension_name)
- skeleton(extension_name, target)
+ if is_extension?(extension_path)
+ template "root/META.json.tt", "#{extension_path}/META.json"
+ template "root/%extension_name%.control.tt", "#{extension_path}/%extension_name%.control"
+ else
+ say "'#{extension_name}' doesn't appears to be an extension. Please, supply the extension's name", :red
+ end
end
desc "bundle [extension_name]", "Bundles an extension."
def bundle(extension_name=".")
unless is_extension?(extension_name)
- say "'#{extension_name}' isn't a valid extension"
+ say "'#{extension_name}' doesn't appears to be an extension. Please, supply the extension's name", :red
else
path = File.expand_path(extension_name)
extension_name = File.basename(path)
@@ -69,22 +87,104 @@ def bundle(extension_name=".")
archive = "#{archive_name}.#{ext}"
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)
+ begin
+ Net::HTTP.start(UPLOAD_URL.host, UPLOAD_URL.port) do |http|
+ say "Trying to release #{File.basename(filename)} ... "
+ http.request(request)
+ end
+ rescue SocketError
+ say "Please, check your connection.", :red
+ exit(1)
+ 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 = "."
+
+ if target != "." && extension_name == "."
+ raise ArgumentError, "Please, supply a extension name"
+ elsif target == "."
+ extension_path = File.expand_path(extension_name)
+ extension_name = File.basename(extension_path)
+ else
+ extension_path = "#{target}/#{extension_name}"
+ end
+ [ extension_path, extension_name ]
+ end
+
def can_zip?(archive)
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
@@ -98,11 +198,12 @@ def is_extension?(dir=".")
File.directory?(dir) && File.exists?("#{dir}/META.json")
end
+ def is_dir?(dir)
+ File.directory?(dir)
+ end
+
def config_options
- file = ""
- file = File.join(file, self.target) if self.target != "."
- file = File.join(file, self.extension_name) if self.extension_name
- file = File.join(file, "META.json")
+ file = File.join(target, "META.json")
if File.exist?(file)
@@config_options ||= JSON.load(File.read(file))
@@ -115,7 +216,6 @@ def set_accessors(extension_name="your_extension_name")
self.extension_name = extension_name
self.maintainer = options[:maintainer] || config_options["maintainer"] || "The maintainer's name"
- #self.maintainer_mail = options[:maintainer_mail] || config_options["maintainer_mail"] || "maintainer@email.here"
self.abstract = options[:abstract] || config_options["abstract"] || "A short description"
self.license = options[:license] || config_options["license"] || "postgresql"
self.version = options[:version] || config_options["version"] || "0.0.1"
View
5 lib/pgxn_utils/constants.rb
@@ -0,0 +1,5 @@
+module PgxnUtils
+ module Constants
+ UPLOAD_URL = URI.parse('https://manager.pgxn.org/auth/upload')
+ end
+end
View
2 lib/pgxn_utils/version.rb
@@ -1,3 +1,3 @@
module PgxnUtils
- VERSION = "0.1.1"
+ VERSION = "0.1.2"
end
View
37 pgxn_utils.gemspec
@@ -13,33 +13,40 @@ Gem::Specification.new do |s|
s.summary = %q{A PGXN set of tools to PostgreSQL extension's developers}
s.description = %q{A PGXN set of tools to help developers create and publish your PostgreSQL extensions without pain}
- s.rubyforge_project = "pgxn_utils"
+ s.required_ruby_version = '>= 1.8.7'
+ s.required_rubygems_version = '>= 1.3.7'
s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]
- # dev
- s.add_development_dependency "rspec"
- s.add_development_dependency "simplecov", ">= 0.4.0"
-
- # prod
if s.respond_to? :specification_version then
s.specification_version = 3
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
- s.add_runtime_dependency(%q<thor>, ["~> 0.14"])
- s.add_runtime_dependency(%q<rubyzip>, ["~> 0.9.4"])
- s.add_runtime_dependency(%q<zippy>, ["~> 0.1.0"])
+ s.add_runtime_dependency "json", "~> 1.5.2"
+ 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
- s.add_dependency(%q<thor>, ["~> 0.14"])
- s.add_runtime_dependency(%q<rubyzip>, ["~> 0.9.4"])
- s.add_runtime_dependency(%q<zippy>, ["~> 0.1.0"])
+ 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
else
- s.add_dependency(%q<thor>, ["~> 0.14"])
- s.add_runtime_dependency(%q<rubyzip>, ["~> 0.9.4"])
- s.add_runtime_dependency(%q<zippy>, ["~> 0.1.0"])
+ 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
Something went wrong with that request. Please try again.