pgxn_utils 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore CHANGED
@@ -3,3 +3,4 @@
3
3
  Gemfile.lock
4
4
  pkg/*
5
5
  *.sw?
6
+ tags
data/README.md CHANGED
@@ -105,18 +105,30 @@ For all switches that you can use with *change*, type:
105
105
  -r, [--release-status=RELEASE_STATUS] # Initial extension's release status
106
106
 
107
107
 
108
- # Bundle it!
108
+ # Bundling and Releasing!
109
109
 
110
110
  Well, since you finished your work you can bundle it to send to [PGXN](http://pgxn.org).
111
111
 
112
- Just type:
112
+ Bundle it:
113
113
 
114
114
  $ pgxn_utils bundle my_cool_extension
115
115
  Extension generated at: /home/guedes/extensions/my_cool_extension-0.0.1.zip
116
116
 
117
+ and release it:
118
+
119
+ $ pgxn_utils release my_cool_extension-0.0.1.zip
120
+ Enter your PGXN username: guedes
121
+ Enter your PGXN password: ******
122
+ Trying to release my_cool_extension-0.0.1.zip ... released successfully!
123
+ Visit: http://manager.pgxn.org/distributions/my_cool_extension/0.0.1
124
+
125
+ You can export `PGXN_USER` and `PGXN_PASSWORD` environment variables to avoid
126
+ type username and password everytime.
127
+
117
128
  # Working in progress
118
129
 
119
- I'm working in an option to release the bundled extension, sending it to [PGXN](http://pgxn.org).
130
+ * support to [git](http://git-scm.org)
131
+ * support to proxy
120
132
 
121
133
  Copyright and License
122
134
  ---------------------
data/Rakefile CHANGED
@@ -1,15 +1,18 @@
1
1
  require 'bundler'
2
+ #include Rake::DSL
2
3
  Bundler::GemHelper.install_tasks
3
-
4
4
  require 'rspec/core/rake_task'
5
5
 
6
6
  desc "Run RSpec"
7
7
  RSpec::Core::RakeTask.new do |t|
8
8
  t.verbose = false
9
- #t.rspec_opts = %w(-fs --color)
10
9
  t.rspec_opts = %w(--color)
11
- #dont show warnings here yet
12
- #t.ruby_opts = %w(-w)
10
+ end
11
+
12
+ desc "CTag Files"
13
+ task :ctag do
14
+ #system("ctags -R --exclude=.git --exclude=log * ~/.rvm/gems/")
15
+ system("ctags -R --exclude=.git --exclude=log *")
13
16
  end
14
17
 
15
18
  task :default => :spec
@@ -3,8 +3,10 @@ module PgxnUtils
3
3
  attr_accessor :extension_name, :target, :maintainer #, :maintainer_mail
4
4
  attr_accessor :abstract, :description, :version, :tags
5
5
  attr_accessor :license, :release_status, :generated_by
6
+ attr_accessor :pgxn_username, :pgxn_password
6
7
 
7
8
  include Thor::Actions
9
+ include PgxnUtils::Constants
8
10
 
9
11
  desc "skeleton extension_name", "Creates an extension skeleton in current directory."
10
12
 
@@ -12,7 +14,6 @@ module PgxnUtils
12
14
 
13
15
  # META required fields
14
16
  method_option :maintainer, :aliases => "-m", :type => :string, :desc => "Maintainer's name <maintainer@email>"
15
- #method_option :maintainer_mail, :aliases => "-e", :type => :string, :desc => "Maintainer's mail"
16
17
  method_option :abstract, :aliases => "-a", :type => :string, :desc => "Defines a short description to abstract"
17
18
  method_option :license, :aliases => "-l", :type => :string, :desc => "The extension license."
18
19
  method_option :version, :aliases => "-v", :type => :string, :desc => "Initial version"
@@ -25,16 +26,26 @@ module PgxnUtils
25
26
 
26
27
  def skeleton(extension_name,target=nil)
27
28
  self.target = options[:target] || target || "."
28
- self.set_accessors extension_name
29
29
 
30
- directory "root", extension_name
30
+ if is_extension?("#{self.target}/#{extension_name}")
31
+ say "'#{extension_name}' already exists. Please, use 'change' instead 'skeleton'.", :red
32
+ elsif is_extension?(".")
33
+ say "You are inside a extension directory, already. Consider use 'change' instead.", :red
34
+ elsif is_dir?("#{self.target}/#{extension_name}")
35
+ say "Can't create an extension overwriting an existing directory.", :red
36
+ else
37
+ self.set_accessors extension_name
38
+
39
+ directory "root", extension_name
40
+ end
31
41
  end
32
42
 
33
43
  desc "change [extension_name]", "Change META's attributes in current extension."
34
44
 
45
+ method_option :target, :aliases => "-p", :type => :string, :default => ".", :desc => "Define the target directory"
46
+
35
47
  # META required fields
36
48
  method_option :maintainer, :aliases => "-m", :type => :string, :desc => "Maintainer's name <maintainer@email>"
37
- #method_option :maintainer_mail, :aliases => "-e", :type => :string, :desc => "Maintainer's mail"
38
49
  method_option :abstract, :aliases => "-a", :type => :string, :desc => "Defines a short description to abstract"
39
50
  method_option :license, :aliases => "-l", :type => :string, :desc => "The extension license."
40
51
  method_option :version, :aliases => "-v", :type => :string, :desc => "Initial version"
@@ -46,19 +57,26 @@ module PgxnUtils
46
57
  method_option :release_status, :aliases => "-r", :type => :string, :desc => "Initial extension's release status"
47
58
 
48
59
  def change(extension_name=".")
49
- path = File.expand_path(extension_name)
60
+ extension_path, extension_name = resolve_extension_path_and_name(extension_name)
61
+
62
+ self.target = extension_path
63
+ self.extension_name = extension_name
50
64
 
51
- target = File.expand_path('..', path)
52
- extension_name = File.basename(path)
65
+ set_accessors(extension_name)
53
66
 
54
- skeleton(extension_name, target)
67
+ if is_extension?(extension_path)
68
+ template "root/META.json.tt", "#{extension_path}/META.json"
69
+ template "root/%extension_name%.control.tt", "#{extension_path}/%extension_name%.control"
70
+ else
71
+ say "'#{extension_name}' doesn't appears to be an extension. Please, supply the extension's name", :red
72
+ end
55
73
  end
56
74
 
57
75
  desc "bundle [extension_name]", "Bundles an extension."
58
76
 
59
77
  def bundle(extension_name=".")
60
78
  unless is_extension?(extension_name)
61
- say "'#{extension_name}' isn't a valid extension"
79
+ say "'#{extension_name}' doesn't appears to be an extension. Please, supply the extension's name", :red
62
80
  else
63
81
  path = File.expand_path(extension_name)
64
82
  extension_name = File.basename(path)
@@ -69,22 +87,104 @@ module PgxnUtils
69
87
  archive = "#{archive_name}.#{ext}"
70
88
 
71
89
  if can_zip?(archive)
90
+ make_dist_clean(path)
91
+
72
92
  Zippy.create(archive) do |zip|
73
93
  Dir["#{path}/**/**"].each do |file|
74
94
  zip["#{extension_name}-#{config_options['version']}/#{file.sub(path+'/','')}"] = File.open(file) unless File.directory?(file)
75
95
  end
76
96
  end
77
- say "Extension generated at: #{archive}"
97
+ say_status :create, archive, :green
78
98
  end
79
99
  end
80
100
  end
81
101
 
102
+ desc "release filename", "Release a extension"
103
+
104
+ def release(filename)
105
+ send_file_to_pgxn(filename)
106
+ end
107
+
82
108
  no_tasks do
109
+ def make_dist_clean(path)
110
+ inside path do
111
+ run 'make distclean', :capture => true
112
+ end
113
+ end
114
+
115
+ def ask_for_pgxn_credential
116
+ 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])?$/ }
117
+ self.pgxn_password = ENV["PGXN_PASS"] || HighLine.ask("Enter your PGXN password: ") { |q| q.echo = '*' }
118
+ end
119
+
120
+ def check_response(response)
121
+ case response
122
+ when Net::HTTPUnauthorized then
123
+ say "oops!", :red
124
+ say "It seems that you entered a wrong username or password.", :red
125
+ when Net::HTTPConflict then
126
+ say "conflict!", :yellow
127
+ say "Distribution already exists! Please, check your META.json.", :yellow
128
+ when Net::HTTPSeeOther then
129
+ say "released successfully!", :green
130
+ say "Visit: #{URI.parse(response['Location'])}", :green
131
+ else
132
+ say "Unknown error. (#{response})"
133
+ end
134
+ end
135
+
136
+ def prepare_multipart_post_for(filename)
137
+ file_basename = File.basename(filename)
138
+ zip_file = File.open(filename)
139
+ Net::HTTP::Post::Multipart.new(
140
+ UPLOAD_URL.path,
141
+ "archive" => UploadIO.new(zip_file, "application/zip", file_basename),
142
+ "Expect" => ""
143
+ )
144
+ end
145
+
146
+ def try_send_file(request, filename)
147
+ begin
148
+ Net::HTTP.start(UPLOAD_URL.host, UPLOAD_URL.port) do |http|
149
+ say "Trying to release #{File.basename(filename)} ... "
150
+ http.request(request)
151
+ end
152
+ rescue SocketError
153
+ say "Please, check your connection.", :red
154
+ exit(1)
155
+ end
156
+ end
157
+
158
+ def send_file_to_pgxn(filename)
159
+ request = prepare_multipart_post_for(filename)
160
+ ask_for_pgxn_credential
161
+
162
+ request.basic_auth pgxn_username, pgxn_password
163
+ response = try_send_file(request, filename)
164
+ check_response(response)
165
+ end
166
+
167
+ def resolve_extension_path_and_name(extension_name)
168
+ target = options[:target]
169
+ extension_path = "."
170
+
171
+ if target != "." && extension_name == "."
172
+ raise ArgumentError, "Please, supply a extension name"
173
+ elsif target == "."
174
+ extension_path = File.expand_path(extension_name)
175
+ extension_name = File.basename(extension_path)
176
+ else
177
+ extension_path = "#{target}/#{extension_name}"
178
+ end
179
+ [ extension_path, extension_name ]
180
+ end
181
+
83
182
  def can_zip?(archive)
84
183
  can_zip = false
85
184
 
86
185
  if File.exists?(archive)
87
- if yes? "#{archive} found! Overwrite? [yN]"
186
+ say_status :conflict, archive, :red
187
+ if yes? "Overwrite #{archive}? [yN]"
88
188
  can_zip = true
89
189
  else
90
190
  can_zip = false
@@ -98,11 +198,12 @@ module PgxnUtils
98
198
  File.directory?(dir) && File.exists?("#{dir}/META.json")
99
199
  end
100
200
 
201
+ def is_dir?(dir)
202
+ File.directory?(dir)
203
+ end
204
+
101
205
  def config_options
102
- file = ""
103
- file = File.join(file, self.target) if self.target != "."
104
- file = File.join(file, self.extension_name) if self.extension_name
105
- file = File.join(file, "META.json")
206
+ file = File.join(target, "META.json")
106
207
 
107
208
  if File.exist?(file)
108
209
  @@config_options ||= JSON.load(File.read(file))
@@ -115,7 +216,6 @@ module PgxnUtils
115
216
  self.extension_name = extension_name
116
217
 
117
218
  self.maintainer = options[:maintainer] || config_options["maintainer"] || "The maintainer's name"
118
- #self.maintainer_mail = options[:maintainer_mail] || config_options["maintainer_mail"] || "maintainer@email.here"
119
219
  self.abstract = options[:abstract] || config_options["abstract"] || "A short description"
120
220
  self.license = options[:license] || config_options["license"] || "postgresql"
121
221
  self.version = options[:version] || config_options["version"] || "0.0.1"
@@ -0,0 +1,5 @@
1
+ module PgxnUtils
2
+ module Constants
3
+ UPLOAD_URL = URI.parse('https://manager.pgxn.org/auth/upload')
4
+ end
5
+ end
@@ -2,7 +2,7 @@ EXTENSION = <%= extension_name %>
2
2
  EXTVERSION = $(shell grep default_version $(EXTENSION).control | sed -e "s/default_version[[:space:]]*=[[:space:]]*'\([^']*\)'/\1/")
3
3
 
4
4
  DATA = $(filter-out $(wildcard sql/*--*.sql),$(wildcard sql/*.sql))
5
- DOCS = $(wildcard doc/*.txt)
5
+ DOCS = $(wildcard doc/*.md)
6
6
  TESTS = $(wildcard test/sql/*.sql)
7
7
  REGRESS = $(patsubst test/sql/%.sql,%,$(TESTS))
8
8
  REGRESS_OPTS = --inputdir=test --load-language=plpgsql
@@ -1,3 +1,3 @@
1
1
  module PgxnUtils
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
data/lib/pgxn_utils.rb CHANGED
@@ -2,7 +2,10 @@ require 'thor'
2
2
  require 'json'
3
3
  require 'zip/zip'
4
4
  require 'zippy'
5
+ require 'net/http/post/multipart'
6
+ require 'highline/import'
5
7
 
6
8
  module PgxnUtils
7
9
  autoload :CLI, 'pgxn_utils/cli'
10
+ autoload :Constants, 'pgxn_utils/constants'
8
11
  end
data/pgxn_utils.gemspec CHANGED
@@ -13,33 +13,40 @@ Gem::Specification.new do |s|
13
13
  s.summary = %q{A PGXN set of tools to PostgreSQL extension's developers}
14
14
  s.description = %q{A PGXN set of tools to help developers create and publish your PostgreSQL extensions without pain}
15
15
 
16
- s.rubyforge_project = "pgxn_utils"
16
+ s.required_ruby_version = '>= 1.8.7'
17
+ s.required_rubygems_version = '>= 1.3.7'
17
18
 
18
19
  s.files = `git ls-files`.split("\n")
19
20
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
21
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
22
  s.require_paths = ["lib"]
22
23
 
23
- # dev
24
- s.add_development_dependency "rspec"
25
- s.add_development_dependency "simplecov", ">= 0.4.0"
26
-
27
- # prod
28
24
  if s.respond_to? :specification_version then
29
25
  s.specification_version = 3
30
26
 
31
27
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
32
- s.add_runtime_dependency(%q<thor>, ["~> 0.14"])
33
- s.add_runtime_dependency(%q<rubyzip>, ["~> 0.9.4"])
34
- s.add_runtime_dependency(%q<zippy>, ["~> 0.1.0"])
28
+ s.add_runtime_dependency "json", "~> 1.5.2"
29
+ s.add_runtime_dependency "thor", "~> 0.14"
30
+ s.add_runtime_dependency "rubyzip", "~> 0.9.4"
31
+ s.add_runtime_dependency "zippy", "~> 0.1.0"
32
+ s.add_runtime_dependency "multipart-post", "~> 1.1.2"
33
+ s.add_runtime_dependency "highline", "~> 1.6.2"
34
+ s.add_development_dependency "rspec"
35
+ s.add_development_dependency "simplecov", "~> 0.4.0"
35
36
  else
36
- s.add_dependency(%q<thor>, ["~> 0.14"])
37
- s.add_runtime_dependency(%q<rubyzip>, ["~> 0.9.4"])
38
- s.add_runtime_dependency(%q<zippy>, ["~> 0.1.0"])
37
+ s.add_dependency "json", "~> 1.5.2"
38
+ s.add_dependency "thor", "~> 0.14"
39
+ s.add_dependency "rubyzip", "~> 0.9.4"
40
+ s.add_dependency "zippy", "~> 0.1.0"
41
+ s.add_dependency "multipart-post", "~> 1.1.2"
42
+ s.add_dependency "highline", "~> 1.6.2"
39
43
  end
40
44
  else
41
- s.add_dependency(%q<thor>, ["~> 0.14"])
42
- s.add_runtime_dependency(%q<rubyzip>, ["~> 0.9.4"])
43
- s.add_runtime_dependency(%q<zippy>, ["~> 0.1.0"])
45
+ s.add_dependency "json", "~> 1.5.2"
46
+ s.add_dependency "thor", "~> 0.14"
47
+ s.add_dependency "rubyzip", "~> 0.9.4"
48
+ s.add_dependency "zippy", "~> 0.1.0"
49
+ s.add_dependency "multipart-post", "~> 1.1.2"
50
+ s.add_dependency "highline", "~> 1.6.2"
44
51
  end
45
52
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: pgxn_utils
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.1
5
+ version: 0.1.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Dickson S. Guedes
@@ -14,60 +14,93 @@ date: 2011-05-06 00:00:00 -03:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
- name: rspec
17
+ name: json
18
18
  prerelease: false
19
19
  requirement: &id001 !ruby/object:Gem::Requirement
20
20
  none: false
21
21
  requirements:
22
- - - ">="
22
+ - - ~>
23
23
  - !ruby/object:Gem::Version
24
- version: "0"
25
- type: :development
24
+ version: 1.5.2
25
+ type: :runtime
26
26
  version_requirements: *id001
27
27
  - !ruby/object:Gem::Dependency
28
- name: simplecov
28
+ name: thor
29
29
  prerelease: false
30
30
  requirement: &id002 !ruby/object:Gem::Requirement
31
31
  none: false
32
32
  requirements:
33
- - - ">="
33
+ - - ~>
34
34
  - !ruby/object:Gem::Version
35
- version: 0.4.0
36
- type: :development
35
+ version: "0.14"
36
+ type: :runtime
37
37
  version_requirements: *id002
38
38
  - !ruby/object:Gem::Dependency
39
- name: thor
39
+ name: rubyzip
40
40
  prerelease: false
41
41
  requirement: &id003 !ruby/object:Gem::Requirement
42
42
  none: false
43
43
  requirements:
44
44
  - - ~>
45
45
  - !ruby/object:Gem::Version
46
- version: "0.14"
46
+ version: 0.9.4
47
47
  type: :runtime
48
48
  version_requirements: *id003
49
49
  - !ruby/object:Gem::Dependency
50
- name: rubyzip
50
+ name: zippy
51
51
  prerelease: false
52
52
  requirement: &id004 !ruby/object:Gem::Requirement
53
53
  none: false
54
54
  requirements:
55
55
  - - ~>
56
56
  - !ruby/object:Gem::Version
57
- version: 0.9.4
57
+ version: 0.1.0
58
58
  type: :runtime
59
59
  version_requirements: *id004
60
60
  - !ruby/object:Gem::Dependency
61
- name: zippy
61
+ name: multipart-post
62
62
  prerelease: false
63
63
  requirement: &id005 !ruby/object:Gem::Requirement
64
64
  none: false
65
65
  requirements:
66
66
  - - ~>
67
67
  - !ruby/object:Gem::Version
68
- version: 0.1.0
68
+ version: 1.1.2
69
69
  type: :runtime
70
70
  version_requirements: *id005
71
+ - !ruby/object:Gem::Dependency
72
+ name: highline
73
+ prerelease: false
74
+ requirement: &id006 !ruby/object:Gem::Requirement
75
+ none: false
76
+ requirements:
77
+ - - ~>
78
+ - !ruby/object:Gem::Version
79
+ version: 1.6.2
80
+ type: :runtime
81
+ version_requirements: *id006
82
+ - !ruby/object:Gem::Dependency
83
+ name: rspec
84
+ prerelease: false
85
+ requirement: &id007 !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: "0"
91
+ type: :development
92
+ version_requirements: *id007
93
+ - !ruby/object:Gem::Dependency
94
+ name: simplecov
95
+ prerelease: false
96
+ requirement: &id008 !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 0.4.0
102
+ type: :development
103
+ version_requirements: *id008
71
104
  description: A PGXN set of tools to help developers create and publish your PostgreSQL extensions without pain
72
105
  email:
73
106
  - guedes@guedesoft.net
@@ -85,6 +118,7 @@ files:
85
118
  - bin/pgxn_utils
86
119
  - lib/pgxn_utils.rb
87
120
  - lib/pgxn_utils/cli.rb
121
+ - lib/pgxn_utils/constants.rb
88
122
  - lib/pgxn_utils/templates/root/%extension_name%.control.tt
89
123
  - lib/pgxn_utils/templates/root/META.json.tt
90
124
  - lib/pgxn_utils/templates/root/Makefile.tt
@@ -112,16 +146,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
112
146
  requirements:
113
147
  - - ">="
114
148
  - !ruby/object:Gem::Version
115
- version: "0"
149
+ version: 1.8.7
116
150
  required_rubygems_version: !ruby/object:Gem::Requirement
117
151
  none: false
118
152
  requirements:
119
153
  - - ">="
120
154
  - !ruby/object:Gem::Version
121
- version: "0"
155
+ version: 1.3.7
122
156
  requirements: []
123
157
 
124
- rubyforge_project: pgxn_utils
158
+ rubyforge_project:
125
159
  rubygems_version: 1.6.2
126
160
  signing_key:
127
161
  specification_version: 3