pgxn_utils 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/META.json +12 -0
- data/Makefile +3 -0
- data/README.md +26 -23
- data/Rakefile +102 -0
- data/bin/{pgxn_utils → pgxn-utils} +2 -1
- data/lib/pgxn_utils/cli.rb +6 -130
- data/lib/pgxn_utils/constants.rb +1 -1
- data/lib/pgxn_utils/no_tasks.rb +129 -0
- data/lib/pgxn_utils/version.rb +1 -1
- data/lib/pgxn_utils.rb +3 -0
- data/pgxn_utils.gemspec +26 -0
- data/spec/no_tasks_spec.rb +59 -0
- data/spec/spec_helper.rb +1 -1
- metadata +82 -83
data/META.json
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
{
|
2
|
+
"name": "pgxn_utils",
|
3
|
+
"abstract": "pgxn_utils is a development tool to create PostgreSQL extensions",
|
4
|
+
"version": "0.1.3",
|
5
|
+
"maintainer": "Dickson S. Guedes <guedes@guedesoft.net>",
|
6
|
+
"license": "postgres",
|
7
|
+
"release_status": "stable",
|
8
|
+
"repository": {
|
9
|
+
"url": "git://github.com/guedes/pgxn-utils.git",
|
10
|
+
"type": "git"
|
11
|
+
}
|
12
|
+
}
|
data/Makefile
ADDED
data/README.md
CHANGED
@@ -4,13 +4,17 @@ pgxn utils
|
|
4
4
|
What is it?
|
5
5
|
--------
|
6
6
|
|
7
|
-
It aims to be a set of task
|
8
|
-
|
9
|
-
It's a WIP but very functional. Please use it and help me improve it.
|
7
|
+
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.
|
10
8
|
|
11
9
|
How to install it?
|
12
10
|
------------------
|
13
11
|
|
12
|
+
If you have pgxn client installed you can do:
|
13
|
+
|
14
|
+
pgxn install pgxn_utils
|
15
|
+
|
16
|
+
Or you can install it by rubygems:
|
17
|
+
|
14
18
|
gem install pgxn_utils
|
15
19
|
|
16
20
|
How it works?
|
@@ -20,11 +24,11 @@ It is all about tasks. Let's see what tasks we have:
|
|
20
24
|
|
21
25
|
$ pgxn_utils help
|
22
26
|
Tasks:
|
23
|
-
pgxn_utils bundle [extension_name] # Bundles an extension
|
24
|
-
pgxn_utils change [extension_name] # Change META's attributes in current extension
|
27
|
+
pgxn_utils bundle [extension_name] # Bundles an extension.
|
28
|
+
pgxn_utils change [extension_name] # Change META's attributes in current extension.
|
25
29
|
pgxn_utils help [TASK] # Describe available tasks or one specific task
|
26
|
-
pgxn_utils
|
27
|
-
|
30
|
+
pgxn_utils release filename # Release a extension
|
31
|
+
pgxn_utils skeleton extension_name # Creates an extension skeleton in current directory.
|
28
32
|
|
29
33
|
# Creating a new extension
|
30
34
|
|
@@ -47,11 +51,9 @@ Thats it! Just start coding! ":)
|
|
47
51
|
Well suppose you want to change the default maintainer's name and the license, well just do:
|
48
52
|
|
49
53
|
$ pgxn_utils change my_cool_extension --maintainer "Dickson Guedes" --license bsd
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
Overwrite /home/guedes/extensions/my_cool_extension/META.json? (enter "h" for help) [Ynaqdh] d
|
54
|
-
{
|
54
|
+
conflict META.json
|
55
|
+
Overwrite /tmp/my_cool_extension/META.json? (enter "h" for help) [Ynaqdh] d
|
56
|
+
{
|
55
57
|
"name": "my_cool_extension",
|
56
58
|
"abstract": "A short description",
|
57
59
|
"description": "A long description",
|
@@ -79,12 +81,9 @@ Well suppose you want to change the default maintainer's name and the license, w
|
|
79
81
|
}
|
80
82
|
}
|
81
83
|
Retrying...
|
82
|
-
Overwrite /
|
83
|
-
force
|
84
|
-
identical my_cool_extension
|
85
|
-
...
|
86
|
-
...
|
87
|
-
...
|
84
|
+
Overwrite /tmp/my_cool_extension/META.json? (enter "h" for help) [Ynaqdh] Y
|
85
|
+
force META.json
|
86
|
+
identical my_cool_extension.control
|
88
87
|
|
89
88
|
It will wait you decide what to do.
|
90
89
|
|
@@ -93,8 +92,10 @@ For all switches that you can use with *change*, type:
|
|
93
92
|
$ pgxn_utils help change
|
94
93
|
Usage:
|
95
94
|
pgxn_utils change [extension_name]
|
96
|
-
|
95
|
+
|
97
96
|
Options:
|
97
|
+
-p, [--target=TARGET] # Define the target directory
|
98
|
+
# Default: .
|
98
99
|
-m, [--maintainer=MAINTAINER] # Maintainer's name <maintainer@email>
|
99
100
|
-a, [--abstract=ABSTRACT] # Defines a short description to abstract
|
100
101
|
-l, [--license=LICENSE] # The extension license.
|
@@ -103,7 +104,8 @@ For all switches that you can use with *change*, type:
|
|
103
104
|
-b, [--generated-by=GENERATED_BY] # Name of extension's generator
|
104
105
|
-t, [--tags=one two three] # Defines extension's tags
|
105
106
|
-r, [--release-status=RELEASE_STATUS] # Initial extension's release status
|
106
|
-
|
107
|
+
|
108
|
+
Change META's attributes in current extension.
|
107
109
|
|
108
110
|
# Bundling and Releasing!
|
109
111
|
|
@@ -120,15 +122,16 @@ and release it:
|
|
120
122
|
Enter your PGXN username: guedes
|
121
123
|
Enter your PGXN password: ******
|
122
124
|
Trying to release my_cool_extension-0.0.1.zip ... released successfully!
|
123
|
-
Visit:
|
125
|
+
Visit: https://manager.pgxn.org/distributions/my_cool_extension/0.0.1
|
124
126
|
|
125
127
|
You can export `PGXN_USER` and `PGXN_PASSWORD` environment variables to avoid
|
126
128
|
type username and password everytime.
|
127
129
|
|
128
130
|
# Working in progress
|
129
131
|
|
130
|
-
*
|
131
|
-
* support
|
132
|
+
* [git](http://git-scm.org) support
|
133
|
+
* proxy support
|
134
|
+
* custom templates
|
132
135
|
|
133
136
|
Copyright and License
|
134
137
|
---------------------
|
data/Rakefile
CHANGED
@@ -3,6 +3,10 @@ require 'bundler'
|
|
3
3
|
Bundler::GemHelper.install_tasks
|
4
4
|
require 'rspec/core/rake_task'
|
5
5
|
|
6
|
+
def format_cmd_output(cmd)
|
7
|
+
`./bin/pgxn_utils #{cmd} | sed 's/^/ /' | sed 's/\[[0-9]*m//g'`
|
8
|
+
end
|
9
|
+
|
6
10
|
desc "Run RSpec"
|
7
11
|
RSpec::Core::RakeTask.new do |t|
|
8
12
|
t.verbose = false
|
@@ -15,4 +19,102 @@ task :ctag do
|
|
15
19
|
system("ctags -R --exclude=.git --exclude=log *")
|
16
20
|
end
|
17
21
|
|
22
|
+
desc "Generate README.md"
|
23
|
+
task :generate_readme do
|
24
|
+
rm_r "/tmp/my_cool_extension" if File.exist?("/tmp/my_cool_extension")
|
25
|
+
readme = File.new("README.md.new", 'w')
|
26
|
+
readme.puts <<-README
|
27
|
+
pgxn utils
|
28
|
+
==========
|
29
|
+
|
30
|
+
What is it?
|
31
|
+
--------
|
32
|
+
|
33
|
+
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.
|
34
|
+
|
35
|
+
How to install it?
|
36
|
+
------------------
|
37
|
+
|
38
|
+
gem install pgxn_utils
|
39
|
+
|
40
|
+
How it works?
|
41
|
+
-------------
|
42
|
+
|
43
|
+
It is all about tasks. Let's see what tasks we have:
|
44
|
+
|
45
|
+
$ pgxn_utils help
|
46
|
+
#{format_cmd_output("help")}
|
47
|
+
|
48
|
+
# Creating a new extension
|
49
|
+
|
50
|
+
$ pgxn_utils skeleton my_cool_extension
|
51
|
+
#{format_cmd_output("skeleton my_cool_extension -p /tmp")}
|
52
|
+
|
53
|
+
Thats it! Just start coding! ":)
|
54
|
+
|
55
|
+
# Changing something
|
56
|
+
|
57
|
+
Well suppose you want to change the default maintainer's name and the license, well just do:
|
58
|
+
|
59
|
+
$ pgxn_utils change my_cool_extension --maintainer "Dickson Guedes" --license bsd
|
60
|
+
#{format_cmd_output("change my_cool_extension -p /tmp --maintainer 'Dickson Guedes' --license bsd")}
|
61
|
+
|
62
|
+
It will wait you decide what to do.
|
63
|
+
|
64
|
+
For all switches that you can use with *change*, type:
|
65
|
+
|
66
|
+
$ pgxn_utils help change
|
67
|
+
#{format_cmd_output("help change")}
|
68
|
+
|
69
|
+
# Bundling and Releasing!
|
70
|
+
|
71
|
+
Well, since you finished your work you can bundle it to send to [PGXN](http://pgxn.org).
|
72
|
+
|
73
|
+
Bundle it:
|
74
|
+
|
75
|
+
$ pgxn_utils bundle my_cool_extension
|
76
|
+
Extension generated at: /home/guedes/extensions/my_cool_extension-0.0.1.zip
|
77
|
+
|
78
|
+
and release it:
|
79
|
+
|
80
|
+
$ pgxn_utils release my_cool_extension-0.0.1.zip
|
81
|
+
Enter your PGXN username: guedes
|
82
|
+
Enter your PGXN password: ******
|
83
|
+
Trying to release my_cool_extension-0.0.1.zip ... released successfully!
|
84
|
+
Visit: https://manager.pgxn.org/distributions/my_cool_extension/0.0.1
|
85
|
+
|
86
|
+
You can export `PGXN_USER` and `PGXN_PASSWORD` environment variables to avoid
|
87
|
+
type username and password everytime.
|
88
|
+
|
89
|
+
# Working in progress
|
90
|
+
|
91
|
+
* [git](http://git-scm.org) support
|
92
|
+
* proxy support
|
93
|
+
* custom templates
|
94
|
+
|
95
|
+
Copyright and License
|
96
|
+
---------------------
|
97
|
+
|
98
|
+
Copyright (c) 2011 Dickson S. Guedes.
|
99
|
+
|
100
|
+
This module is free software; you can redistribute it and/or modify it under
|
101
|
+
the [PostgreSQL License](http://www.opensource.org/licenses/postgresql).
|
102
|
+
|
103
|
+
Permission to use, copy, modify, and distribute this software and its
|
104
|
+
documentation for any purpose, without fee, and without a written agreement is
|
105
|
+
hereby granted, provided that the above copyright notice and this paragraph
|
106
|
+
and the following two paragraphs appear in all copies.
|
107
|
+
|
108
|
+
In no event shall Dickson S. Guedes be liable to any party for direct,
|
109
|
+
indirect, special, incidental, or consequential damages, including lost
|
110
|
+
profits, arising out of the use of this software and its documentation, even
|
111
|
+
if Dickson S. Guedes has been advised of the possibility of such damage.
|
112
|
+
|
113
|
+
Dickson S. Guedes specifically disclaims any warranties, including, but not
|
114
|
+
limited to, the implied warranties of merchantability and fitness for a
|
115
|
+
particular purpose. The software provided hereunder is on an "as is" basis,
|
116
|
+
and Dickson S. Guedes has no obligations to provide maintenance, support,
|
117
|
+
updates, enhancements, or modifications.
|
118
|
+
README
|
119
|
+
end
|
18
120
|
task :default => :spec
|
@@ -3,7 +3,8 @@ $:.unshift File.expand_path('..', __FILE__)
|
|
3
3
|
$:.unshift File.expand_path('../../lib', __FILE__)
|
4
4
|
require 'pgxn_utils'
|
5
5
|
|
6
|
-
task = __FILE__.
|
6
|
+
task = __FILE__.gsub(/pgxn-utils-/,'').gsub(/-/,'_') if File.basename(__FILE__) =~ /^pgxn-utils-/
|
7
7
|
command_args = [ task ] + ARGV if task
|
8
8
|
|
9
|
+
puts "PGXN Utils version: #{PgxnUtils::VERSION}" if ARGV.empty?
|
9
10
|
PgxnUtils::CLI.start( command_args || ARGV )
|
data/lib/pgxn_utils/cli.rb
CHANGED
@@ -6,16 +6,16 @@ module PgxnUtils
|
|
6
6
|
attr_accessor :pgxn_username, :pgxn_password
|
7
7
|
|
8
8
|
include Thor::Actions
|
9
|
-
include PgxnUtils::
|
9
|
+
include PgxnUtils::NoTasks
|
10
10
|
|
11
|
-
desc "skeleton extension_name", "Creates an extension skeleton in current directory
|
11
|
+
desc "skeleton extension_name", "Creates an extension skeleton in current directory"
|
12
12
|
|
13
13
|
method_option :target, :aliases => "-p", :default => ".", :desc => "Define the target directory"
|
14
14
|
|
15
15
|
# META required fields
|
16
16
|
method_option :maintainer, :aliases => "-m", :type => :string, :desc => "Maintainer's name <maintainer@email>"
|
17
17
|
method_option :abstract, :aliases => "-a", :type => :string, :desc => "Defines a short description to abstract"
|
18
|
-
method_option :license, :aliases => "-l", :type => :string, :desc => "The extension license
|
18
|
+
method_option :license, :aliases => "-l", :type => :string, :desc => "The extension license"
|
19
19
|
method_option :version, :aliases => "-v", :type => :string, :desc => "Initial version"
|
20
20
|
|
21
21
|
# META optional fields
|
@@ -40,7 +40,7 @@ module PgxnUtils
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
desc "change [extension_name]", "
|
43
|
+
desc "change [extension_name]", "Changes META's attributes in current extension"
|
44
44
|
|
45
45
|
method_option :target, :aliases => "-p", :type => :string, :default => ".", :desc => "Define the target directory"
|
46
46
|
|
@@ -72,7 +72,7 @@ module PgxnUtils
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
-
desc "bundle [extension_name]", "Bundles
|
75
|
+
desc "bundle [extension_name]", "Bundles the extension in a zip file"
|
76
76
|
|
77
77
|
def bundle(extension_name=".")
|
78
78
|
unless is_extension?(extension_name)
|
@@ -99,136 +99,12 @@ module PgxnUtils
|
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
|
-
desc "release filename", "Release
|
102
|
+
desc "release filename", "Release an extension to PGXN"
|
103
103
|
|
104
104
|
def release(filename)
|
105
105
|
send_file_to_pgxn(filename)
|
106
106
|
end
|
107
107
|
|
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
|
-
|
182
|
-
def can_zip?(archive)
|
183
|
-
can_zip = false
|
184
|
-
|
185
|
-
if File.exists?(archive)
|
186
|
-
say_status :conflict, archive, :red
|
187
|
-
if yes? "Overwrite #{archive}? [yN]"
|
188
|
-
can_zip = true
|
189
|
-
else
|
190
|
-
can_zip = false
|
191
|
-
end
|
192
|
-
else
|
193
|
-
can_zip = true
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
def is_extension?(dir=".")
|
198
|
-
File.directory?(dir) && File.exists?("#{dir}/META.json")
|
199
|
-
end
|
200
|
-
|
201
|
-
def is_dir?(dir)
|
202
|
-
File.directory?(dir)
|
203
|
-
end
|
204
|
-
|
205
|
-
def config_options
|
206
|
-
file = File.join(target, "META.json")
|
207
|
-
|
208
|
-
if File.exist?(file)
|
209
|
-
@@config_options ||= JSON.load(File.read(file))
|
210
|
-
else
|
211
|
-
{}
|
212
|
-
end
|
213
|
-
end
|
214
|
-
|
215
|
-
def set_accessors(extension_name="your_extension_name")
|
216
|
-
self.extension_name = extension_name
|
217
|
-
|
218
|
-
self.maintainer = options[:maintainer] || config_options["maintainer"] || "The maintainer's name"
|
219
|
-
self.abstract = options[:abstract] || config_options["abstract"] || "A short description"
|
220
|
-
self.license = options[:license] || config_options["license"] || "postgresql"
|
221
|
-
self.version = options[:version] || config_options["version"] || "0.0.1"
|
222
|
-
|
223
|
-
self.description = options[:description] || config_options["description"] || "A long description"
|
224
|
-
self.generated_by = options[:generated_by] || config_options["generated_by"] || maintainer
|
225
|
-
self.tags = options[:tags] || config_options["tags"]
|
226
|
-
self.release_status = options[:release_status] || config_options["release_status"] || "unstable"
|
227
|
-
|
228
|
-
self.destination_root = target
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
108
|
def self.source_root
|
233
109
|
@_source_root ||= File.expand_path('../templates', __FILE__)
|
234
110
|
end
|
data/lib/pgxn_utils/constants.rb
CHANGED
@@ -0,0 +1,129 @@
|
|
1
|
+
module PgxnUtils
|
2
|
+
module NoTasks
|
3
|
+
|
4
|
+
include PgxnUtils::Constants
|
5
|
+
|
6
|
+
def make_dist_clean(path)
|
7
|
+
inside path do
|
8
|
+
run 'make distclean', :capture => true
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def ask_for_pgxn_credential
|
13
|
+
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])?$/ }
|
14
|
+
self.pgxn_password = ENV["PGXN_PASS"] || HighLine.ask("Enter your PGXN password: ") { |q| q.echo = '*' }
|
15
|
+
end
|
16
|
+
|
17
|
+
def check_response(response)
|
18
|
+
case response
|
19
|
+
when Net::HTTPUnauthorized then
|
20
|
+
say "oops!", :red
|
21
|
+
say "It seems that you entered a wrong username or password.", :red
|
22
|
+
when Net::HTTPConflict then
|
23
|
+
say "conflict!", :yellow
|
24
|
+
say "Distribution already exists! Please, check your META.json.", :yellow
|
25
|
+
when Net::HTTPSeeOther then
|
26
|
+
say "released successfully!", :green
|
27
|
+
say "Visit: #{URI.parse(response['Location'])}", :green
|
28
|
+
else
|
29
|
+
say "Unknown error. (#{response})"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def prepare_multipart_post_for(filename)
|
34
|
+
file_basename = File.basename(filename)
|
35
|
+
zip_file = File.open(filename)
|
36
|
+
Net::HTTP::Post::Multipart.new(
|
37
|
+
UPLOAD_URL.path,
|
38
|
+
"archive" => UploadIO.new(zip_file, "application/zip", file_basename),
|
39
|
+
"Expect" => ""
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def try_send_file(request, filename)
|
44
|
+
begin
|
45
|
+
http = Net::HTTP.new(UPLOAD_URL.host, UPLOAD_URL.port)
|
46
|
+
http.use_ssl = true
|
47
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
48
|
+
say "Trying to release #{File.basename(filename)} ... "
|
49
|
+
http.request(request)
|
50
|
+
rescue SocketError
|
51
|
+
say "Please, check your connection.", :red
|
52
|
+
exit(1)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def send_file_to_pgxn(filename)
|
57
|
+
request = prepare_multipart_post_for(filename)
|
58
|
+
ask_for_pgxn_credential
|
59
|
+
|
60
|
+
request.basic_auth pgxn_username, pgxn_password
|
61
|
+
response = try_send_file(request, filename)
|
62
|
+
check_response(response)
|
63
|
+
end
|
64
|
+
|
65
|
+
def resolve_extension_path_and_name(extension_name)
|
66
|
+
target = options[:target]
|
67
|
+
extension_path = "."
|
68
|
+
|
69
|
+
if target != "." && extension_name == "."
|
70
|
+
raise ArgumentError, "Please, supply a extension name"
|
71
|
+
elsif target == "."
|
72
|
+
extension_path = File.expand_path(extension_name)
|
73
|
+
extension_name = File.basename(extension_path)
|
74
|
+
else
|
75
|
+
extension_path = "#{target}/#{extension_name}"
|
76
|
+
end
|
77
|
+
[ extension_path, extension_name ]
|
78
|
+
end
|
79
|
+
|
80
|
+
def can_zip?(archive)
|
81
|
+
can_zip = false
|
82
|
+
|
83
|
+
if File.exists?(archive)
|
84
|
+
say_status :conflict, archive, :red
|
85
|
+
if yes? "Overwrite #{archive}? [yN]"
|
86
|
+
can_zip = true
|
87
|
+
else
|
88
|
+
can_zip = false
|
89
|
+
end
|
90
|
+
else
|
91
|
+
can_zip = true
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def is_extension?(dir=".")
|
96
|
+
is_dir?(dir) && File.exists?("#{dir}/META.json")
|
97
|
+
end
|
98
|
+
|
99
|
+
def is_dir?(dir)
|
100
|
+
File.directory?(dir)
|
101
|
+
end
|
102
|
+
|
103
|
+
def config_options
|
104
|
+
file = File.join(target, "META.json")
|
105
|
+
|
106
|
+
if File.exist?(file)
|
107
|
+
@@config_options ||= JSON.load(File.read(file))
|
108
|
+
else
|
109
|
+
{}
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def set_accessors(extension_name="your_extension_name")
|
114
|
+
self.extension_name = extension_name
|
115
|
+
|
116
|
+
self.maintainer = options[:maintainer] || config_options["maintainer"] || "The maintainer's name"
|
117
|
+
self.abstract = options[:abstract] || config_options["abstract"] || "A short description"
|
118
|
+
self.license = options[:license] || config_options["license"] || "postgresql"
|
119
|
+
self.version = options[:version] || config_options["version"] || "0.0.1"
|
120
|
+
|
121
|
+
self.description = options[:description] || config_options["description"] || "A long description"
|
122
|
+
self.generated_by = options[:generated_by] || config_options["generated_by"] || maintainer
|
123
|
+
self.tags = options[:tags] || config_options["tags"]
|
124
|
+
self.release_status = options[:release_status] || config_options["release_status"] || "unstable"
|
125
|
+
|
126
|
+
self.destination_root = target
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
data/lib/pgxn_utils/version.rb
CHANGED
data/lib/pgxn_utils.rb
CHANGED
@@ -3,9 +3,12 @@ require 'json'
|
|
3
3
|
require 'zip/zip'
|
4
4
|
require 'zippy'
|
5
5
|
require 'net/http/post/multipart'
|
6
|
+
require 'net/https'
|
6
7
|
require 'highline/import'
|
7
8
|
|
8
9
|
module PgxnUtils
|
9
10
|
autoload :CLI, 'pgxn_utils/cli'
|
11
|
+
autoload :VERSION, 'pgxn_utils/version'
|
10
12
|
autoload :Constants, 'pgxn_utils/constants'
|
13
|
+
autoload :NoTasks, 'pgxn_utils/no_tasks'
|
11
14
|
end
|
data/pgxn_utils.gemspec
CHANGED
@@ -20,6 +20,32 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
21
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
22
22
|
s.require_paths = ["lib"]
|
23
|
+
s.post_install_message= <<-EOF
|
24
|
+
|
25
|
+
PGXN Utils version #{PgxnUtils::VERSION} was installed!
|
26
|
+
|
27
|
+
Issues? Please visit: https://github.com/guedes/pgxn-utils/issues
|
28
|
+
|
29
|
+
#{
|
30
|
+
unless `which pgxn`.nil?
|
31
|
+
"PGXN Client found. Cool!"
|
32
|
+
else
|
33
|
+
"PGXN Client is recommended but not found. You could install it if you want, just follow instructions: http://pgxnclient.projects.postgresql.org/"
|
34
|
+
end
|
35
|
+
}
|
36
|
+
#{
|
37
|
+
unless `which validate_pgxn_meta`.nil?
|
38
|
+
"PGXN Meta Validator found. Cool!"
|
39
|
+
else
|
40
|
+
"PGXN Meta Validator is recommended but not found! You could install it if you want, just type: cpan PGXN::Meta::Validator"
|
41
|
+
end
|
42
|
+
}
|
43
|
+
|
44
|
+
Thank you for use this tool!
|
45
|
+
|
46
|
+
Regards, Dickson S. Guedes
|
47
|
+
|
48
|
+
EOF
|
23
49
|
|
24
50
|
if s.respond_to? :specification_version then
|
25
51
|
s.specification_version = 3
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.expand_path('spec/spec_helper')
|
2
|
+
|
3
|
+
describe PgxnUtils::NoTasks do
|
4
|
+
include PgxnUtils::NoTasks
|
5
|
+
include FileUtils
|
6
|
+
|
7
|
+
after(:all) do
|
8
|
+
rm_r("/tmp/teste")
|
9
|
+
rm_r("/tmp/teste2")
|
10
|
+
end
|
11
|
+
|
12
|
+
context "#resolve_extension_path_and_name" do
|
13
|
+
it "should raise error when no extension name was supplied" do
|
14
|
+
PgxnUtils::NoTasks.send(:define_method, :options) do
|
15
|
+
{ :target => "/something" }
|
16
|
+
end
|
17
|
+
extension_name = "."
|
18
|
+
lambda {resolve_extension_path_and_name(extension_name)}.should raise_error(ArgumentError)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return correctly if target is '.'" do
|
22
|
+
PgxnUtils::NoTasks.send(:define_method, :options) do
|
23
|
+
{ :target => "." }
|
24
|
+
end
|
25
|
+
|
26
|
+
original_dir = File.expand_path(".")
|
27
|
+
destination_dir = "/tmp/teste"
|
28
|
+
mkdir destination_dir
|
29
|
+
cd destination_dir
|
30
|
+
|
31
|
+
extension_name = "teste"
|
32
|
+
resolved_path, resolved_name = resolve_extension_path_and_name(extension_name)
|
33
|
+
|
34
|
+
cd original_dir
|
35
|
+
|
36
|
+
resolved_path.should == "#{destination_dir}/#{extension_name}"
|
37
|
+
resolved_name.should == extension_name
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return correctly when target are not '.' and a extension name was specified" do
|
41
|
+
PgxnUtils::NoTasks.send(:define_method, :options) do
|
42
|
+
{ :target => "/tmp" }
|
43
|
+
end
|
44
|
+
|
45
|
+
original_dir = File.expand_path(".")
|
46
|
+
destination_dir = "/tmp/teste2"
|
47
|
+
mkdir destination_dir
|
48
|
+
cd destination_dir
|
49
|
+
|
50
|
+
extension_name = "teste2"
|
51
|
+
resolved_path, resolved_name = resolve_extension_path_and_name(extension_name)
|
52
|
+
|
53
|
+
cd original_dir
|
54
|
+
|
55
|
+
resolved_path.should == destination_dir
|
56
|
+
resolved_name.should == extension_name
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -9,7 +9,7 @@ require 'pgxn_utils'
|
|
9
9
|
$counter = 0
|
10
10
|
|
11
11
|
LIB_PATH = File.expand_path('../../lib', __FILE__)
|
12
|
-
BIN_PATH = File.expand_path('../../bin/
|
12
|
+
BIN_PATH = File.expand_path('../../bin/pgxn-utils', __FILE__)
|
13
13
|
|
14
14
|
DESTINATION_ROOT = File.expand_path('../pgxn_utils', __FILE__)
|
15
15
|
FileUtils.rm_rf(DESTINATION_ROOT)
|
metadata
CHANGED
@@ -1,124 +1,124 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: pgxn_utils
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.3
|
4
5
|
prerelease:
|
5
|
-
version: 0.1.2
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Dickson S. Guedes
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
dependencies:
|
16
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-05-06 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
17
15
|
name: json
|
18
|
-
|
19
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &74341240 !ruby/object:Gem::Requirement
|
20
17
|
none: false
|
21
|
-
requirements:
|
18
|
+
requirements:
|
22
19
|
- - ~>
|
23
|
-
- !ruby/object:Gem::Version
|
20
|
+
- !ruby/object:Gem::Version
|
24
21
|
version: 1.5.2
|
25
22
|
type: :runtime
|
26
|
-
version_requirements: *id001
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: thor
|
29
23
|
prerelease: false
|
30
|
-
|
24
|
+
version_requirements: *74341240
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: thor
|
27
|
+
requirement: &74341010 !ruby/object:Gem::Requirement
|
31
28
|
none: false
|
32
|
-
requirements:
|
29
|
+
requirements:
|
33
30
|
- - ~>
|
34
|
-
- !ruby/object:Gem::Version
|
35
|
-
version:
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0.14'
|
36
33
|
type: :runtime
|
37
|
-
version_requirements: *id002
|
38
|
-
- !ruby/object:Gem::Dependency
|
39
|
-
name: rubyzip
|
40
34
|
prerelease: false
|
41
|
-
|
35
|
+
version_requirements: *74341010
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rubyzip
|
38
|
+
requirement: &74340780 !ruby/object:Gem::Requirement
|
42
39
|
none: false
|
43
|
-
requirements:
|
40
|
+
requirements:
|
44
41
|
- - ~>
|
45
|
-
- !ruby/object:Gem::Version
|
42
|
+
- !ruby/object:Gem::Version
|
46
43
|
version: 0.9.4
|
47
44
|
type: :runtime
|
48
|
-
version_requirements: *id003
|
49
|
-
- !ruby/object:Gem::Dependency
|
50
|
-
name: zippy
|
51
45
|
prerelease: false
|
52
|
-
|
46
|
+
version_requirements: *74340780
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: zippy
|
49
|
+
requirement: &74340550 !ruby/object:Gem::Requirement
|
53
50
|
none: false
|
54
|
-
requirements:
|
51
|
+
requirements:
|
55
52
|
- - ~>
|
56
|
-
- !ruby/object:Gem::Version
|
53
|
+
- !ruby/object:Gem::Version
|
57
54
|
version: 0.1.0
|
58
55
|
type: :runtime
|
59
|
-
version_requirements: *id004
|
60
|
-
- !ruby/object:Gem::Dependency
|
61
|
-
name: multipart-post
|
62
56
|
prerelease: false
|
63
|
-
|
57
|
+
version_requirements: *74340550
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: multipart-post
|
60
|
+
requirement: &74340320 !ruby/object:Gem::Requirement
|
64
61
|
none: false
|
65
|
-
requirements:
|
62
|
+
requirements:
|
66
63
|
- - ~>
|
67
|
-
- !ruby/object:Gem::Version
|
64
|
+
- !ruby/object:Gem::Version
|
68
65
|
version: 1.1.2
|
69
66
|
type: :runtime
|
70
|
-
version_requirements: *id005
|
71
|
-
- !ruby/object:Gem::Dependency
|
72
|
-
name: highline
|
73
67
|
prerelease: false
|
74
|
-
|
68
|
+
version_requirements: *74340320
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: highline
|
71
|
+
requirement: &74340090 !ruby/object:Gem::Requirement
|
75
72
|
none: false
|
76
|
-
requirements:
|
73
|
+
requirements:
|
77
74
|
- - ~>
|
78
|
-
- !ruby/object:Gem::Version
|
75
|
+
- !ruby/object:Gem::Version
|
79
76
|
version: 1.6.2
|
80
77
|
type: :runtime
|
81
|
-
version_requirements: *id006
|
82
|
-
- !ruby/object:Gem::Dependency
|
83
|
-
name: rspec
|
84
78
|
prerelease: false
|
85
|
-
|
79
|
+
version_requirements: *74340090
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: rspec
|
82
|
+
requirement: &74339900 !ruby/object:Gem::Requirement
|
86
83
|
none: false
|
87
|
-
requirements:
|
88
|
-
- -
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
version:
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
91
88
|
type: :development
|
92
|
-
version_requirements: *id007
|
93
|
-
- !ruby/object:Gem::Dependency
|
94
|
-
name: simplecov
|
95
89
|
prerelease: false
|
96
|
-
|
90
|
+
version_requirements: *74339900
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: simplecov
|
93
|
+
requirement: &74339630 !ruby/object:Gem::Requirement
|
97
94
|
none: false
|
98
|
-
requirements:
|
95
|
+
requirements:
|
99
96
|
- - ~>
|
100
|
-
- !ruby/object:Gem::Version
|
97
|
+
- !ruby/object:Gem::Version
|
101
98
|
version: 0.4.0
|
102
99
|
type: :development
|
103
|
-
|
104
|
-
|
105
|
-
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *74339630
|
102
|
+
description: A PGXN set of tools to help developers create and publish your PostgreSQL
|
103
|
+
extensions without pain
|
104
|
+
email:
|
106
105
|
- guedes@guedesoft.net
|
107
|
-
executables:
|
108
|
-
-
|
106
|
+
executables:
|
107
|
+
- pgxn-utils
|
109
108
|
extensions: []
|
110
|
-
|
111
109
|
extra_rdoc_files: []
|
112
|
-
|
113
|
-
files:
|
110
|
+
files:
|
114
111
|
- .gitignore
|
115
112
|
- Gemfile
|
113
|
+
- META.json
|
114
|
+
- Makefile
|
116
115
|
- README.md
|
117
116
|
- Rakefile
|
118
|
-
- bin/
|
117
|
+
- bin/pgxn-utils
|
119
118
|
- lib/pgxn_utils.rb
|
120
119
|
- lib/pgxn_utils/cli.rb
|
121
120
|
- lib/pgxn_utils/constants.rb
|
121
|
+
- lib/pgxn_utils/no_tasks.rb
|
122
122
|
- lib/pgxn_utils/templates/root/%extension_name%.control.tt
|
123
123
|
- lib/pgxn_utils/templates/root/META.json.tt
|
124
124
|
- lib/pgxn_utils/templates/root/Makefile.tt
|
@@ -131,34 +131,33 @@ files:
|
|
131
131
|
- lib/pgxn_utils/version.rb
|
132
132
|
- pgxn_utils.gemspec
|
133
133
|
- spec/cli_spec.rb
|
134
|
+
- spec/no_tasks_spec.rb
|
134
135
|
- spec/spec_helper.rb
|
135
|
-
has_rdoc: true
|
136
136
|
homepage: http://github.com/guedes/pgxn-utils
|
137
137
|
licenses: []
|
138
|
-
|
139
|
-
|
138
|
+
post_install_message: ! "\n PGXN Utils version 0.1.3 was installed!\n\n Issues?
|
139
|
+
Please visit: https://github.com/guedes/pgxn-utils/issues\n\n PGXN Client found.
|
140
|
+
Cool!\n PGXN Meta Validator found. Cool!\n\n Thank you for use this tool!\n\n
|
141
|
+
\ Regards, Dickson S. Guedes\n\n"
|
140
142
|
rdoc_options: []
|
141
|
-
|
142
|
-
require_paths:
|
143
|
+
require_paths:
|
143
144
|
- lib
|
144
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
145
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
145
146
|
none: false
|
146
|
-
requirements:
|
147
|
-
- -
|
148
|
-
- !ruby/object:Gem::Version
|
147
|
+
requirements:
|
148
|
+
- - ! '>='
|
149
|
+
- !ruby/object:Gem::Version
|
149
150
|
version: 1.8.7
|
150
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
151
152
|
none: false
|
152
|
-
requirements:
|
153
|
-
- -
|
154
|
-
- !ruby/object:Gem::Version
|
153
|
+
requirements:
|
154
|
+
- - ! '>='
|
155
|
+
- !ruby/object:Gem::Version
|
155
156
|
version: 1.3.7
|
156
157
|
requirements: []
|
157
|
-
|
158
158
|
rubyforge_project:
|
159
|
-
rubygems_version: 1.6
|
159
|
+
rubygems_version: 1.8.6
|
160
160
|
signing_key:
|
161
161
|
specification_version: 3
|
162
162
|
summary: A PGXN set of tools to PostgreSQL extension's developers
|
163
163
|
test_files: []
|
164
|
-
|