summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md8
-rw-r--r--lib/pgxn_utils.rb1
-rw-r--r--lib/pgxn_utils/cli.rb137
-rw-r--r--lib/pgxn_utils/no_tasks.rb129
-rw-r--r--spec/no_tasks_spec.rb59
-rw-r--r--spec/spec_helper.rb2
6 files changed, 203 insertions, 133 deletions
diff --git a/README.md b/README.md
index 843029a..7523f28 100644
--- a/README.md
+++ b/README.md
@@ -4,11 +4,17 @@ pgxn utils
What is it?
--------
-It aims to be a set of task to help PostgreSQL extension's developers to focus more on the problem that they wants to solve than in the all structure and files and control files need to PGXS to build the extension.
+It aims to be a set of task to help PostgreSQL extension's developers to focus more on the problem that they wants to solve than in all structure and files and control files need to PGXS to build the extension.
How to install it?
------------------
+If you have pgxn client installed you can do:
+
+ pgxn install pgxn_utils
+
+Or you can install it by rubygems:
+
gem install pgxn_utils
How it works?
diff --git a/lib/pgxn_utils.rb b/lib/pgxn_utils.rb
index 44bc8b6..0fea754 100644
--- a/lib/pgxn_utils.rb
+++ b/lib/pgxn_utils.rb
@@ -10,4 +10,5 @@ module PgxnUtils
autoload :CLI, 'pgxn_utils/cli'
autoload :VERSION, 'pgxn_utils/version'
autoload :Constants, 'pgxn_utils/constants'
+ autoload :NoTasks, 'pgxn_utils/no_tasks'
end
diff --git a/lib/pgxn_utils/cli.rb b/lib/pgxn_utils/cli.rb
index 53f00dd..fc22c1d 100644
--- a/lib/pgxn_utils/cli.rb
+++ b/lib/pgxn_utils/cli.rb
@@ -6,16 +6,16 @@ module PgxnUtils
attr_accessor :pgxn_username, :pgxn_password
include Thor::Actions
- include PgxnUtils::Constants
+ include PgxnUtils::NoTasks
- desc "skeleton extension_name", "Creates an extension skeleton in current directory."
+ desc "skeleton extension_name", "Creates an extension skeleton in current directory"
method_option :target, :aliases => "-p", :default => ".", :desc => "Define the target directory"
# META required fields
method_option :maintainer, :aliases => "-m", :type => :string, :desc => "Maintainer's name <maintainer@email>"
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 :license, :aliases => "-l", :type => :string, :desc => "The extension license"
method_option :version, :aliases => "-v", :type => :string, :desc => "Initial version"
# META optional fields
@@ -40,7 +40,7 @@ module PgxnUtils
end
end
- desc "change [extension_name]", "Change META's attributes in current extension."
+ desc "change [extension_name]", "Changes META's attributes in current extension"
method_option :target, :aliases => "-p", :type => :string, :default => ".", :desc => "Define the target directory"
@@ -72,7 +72,7 @@ module PgxnUtils
end
end
- desc "bundle [extension_name]", "Bundles an extension."
+ desc "bundle [extension_name]", "Bundles the extension in a zip file"
def bundle(extension_name=".")
unless is_extension?(extension_name)
@@ -99,137 +99,12 @@ module PgxnUtils
end
end
- desc "release filename", "Release a extension"
+ desc "release filename", "Release an extension to PGXN"
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
- http = Net::HTTP.new(UPLOAD_URL.host, UPLOAD_URL.port)
- http.use_ssl = true
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
- say "Trying to release #{File.basename(filename)} ... "
- http.request(request)
- 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)
- say_status :conflict, archive, :red
- if yes? "Overwrite #{archive}? [yN]"
- can_zip = true
- else
- can_zip = false
- end
- else
- can_zip = true
- end
- end
-
- 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.join(target, "META.json")
-
- if File.exist?(file)
- @@config_options ||= JSON.load(File.read(file))
- else
- {}
- end
- end
-
- 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.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"
-
- self.description = options[:description] || config_options["description"] || "A long description"
- self.generated_by = options[:generated_by] || config_options["generated_by"] || maintainer
- self.tags = options[:tags] || config_options["tags"]
- self.release_status = options[:release_status] || config_options["release_status"] || "unstable"
-
- self.destination_root = target
- end
- end
-
def self.source_root
@_source_root ||= File.expand_path('../templates', __FILE__)
end
diff --git a/lib/pgxn_utils/no_tasks.rb b/lib/pgxn_utils/no_tasks.rb
new file mode 100644
index 0000000..a066998
--- /dev/null
+++ b/lib/pgxn_utils/no_tasks.rb
@@ -0,0 +1,129 @@
+module PgxnUtils
+ module NoTasks
+
+ include PgxnUtils::Constants
+
+ 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
+ http = Net::HTTP.new(UPLOAD_URL.host, UPLOAD_URL.port)
+ http.use_ssl = true
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+ say "Trying to release #{File.basename(filename)} ... "
+ http.request(request)
+ 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)
+ say_status :conflict, archive, :red
+ if yes? "Overwrite #{archive}? [yN]"
+ can_zip = true
+ else
+ can_zip = false
+ end
+ else
+ can_zip = true
+ end
+ end
+
+ def is_extension?(dir=".")
+ is_dir?(dir) && File.exists?("#{dir}/META.json")
+ end
+
+ def is_dir?(dir)
+ File.directory?(dir)
+ end
+
+ def config_options
+ file = File.join(target, "META.json")
+
+ if File.exist?(file)
+ @@config_options ||= JSON.load(File.read(file))
+ else
+ {}
+ end
+ end
+
+ 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.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"
+
+ self.description = options[:description] || config_options["description"] || "A long description"
+ self.generated_by = options[:generated_by] || config_options["generated_by"] || maintainer
+ self.tags = options[:tags] || config_options["tags"]
+ self.release_status = options[:release_status] || config_options["release_status"] || "unstable"
+
+ self.destination_root = target
+ end
+ end
+end
diff --git a/spec/no_tasks_spec.rb b/spec/no_tasks_spec.rb
new file mode 100644
index 0000000..0117b72
--- /dev/null
+++ b/spec/no_tasks_spec.rb
@@ -0,0 +1,59 @@
+require File.expand_path('spec/spec_helper')
+
+describe PgxnUtils::NoTasks do
+ include PgxnUtils::NoTasks
+ include FileUtils
+
+ after(:all) do
+ rm_r("/tmp/teste")
+ rm_r("/tmp/teste2")
+ end
+
+ context "#resolve_extension_path_and_name" do
+ it "should raise error when no extension name was supplied" do
+ PgxnUtils::NoTasks.send(:define_method, :options) do
+ { :target => "/something" }
+ end
+ extension_name = "."
+ lambda {resolve_extension_path_and_name(extension_name)}.should raise_error(ArgumentError)
+ end
+
+ it "should return correctly if target is '.'" do
+ PgxnUtils::NoTasks.send(:define_method, :options) do
+ { :target => "." }
+ end
+
+ original_dir = File.expand_path(".")
+ destination_dir = "/tmp/teste"
+ mkdir destination_dir
+ cd destination_dir
+
+ extension_name = "teste"
+ resolved_path, resolved_name = resolve_extension_path_and_name(extension_name)
+
+ cd original_dir
+
+ resolved_path.should == "#{destination_dir}/#{extension_name}"
+ resolved_name.should == extension_name
+ end
+
+ it "should return correctly when target are not '.' and a extension name was specified" do
+ PgxnUtils::NoTasks.send(:define_method, :options) do
+ { :target => "/tmp" }
+ end
+
+ original_dir = File.expand_path(".")
+ destination_dir = "/tmp/teste2"
+ mkdir destination_dir
+ cd destination_dir
+
+ extension_name = "teste2"
+ resolved_path, resolved_name = resolve_extension_path_and_name(extension_name)
+
+ cd original_dir
+
+ resolved_path.should == destination_dir
+ resolved_name.should == extension_name
+ end
+ end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 894f648..3ad1c37 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -9,7 +9,7 @@ require 'pgxn_utils'
$counter = 0
LIB_PATH = File.expand_path('../../lib', __FILE__)
-BIN_PATH = File.expand_path('../../bin/pgxn_utils', __FILE__)
+BIN_PATH = File.expand_path('../../bin/pgxn-utils', __FILE__)
DESTINATION_ROOT = File.expand_path('../pgxn_utils', __FILE__)
FileUtils.rm_rf(DESTINATION_ROOT)