diff options
| author | Dickson S. Guedes | 2011-05-12 23:05:33 +0000 |
|---|---|---|
| committer | Dickson S. Guedes | 2011-05-12 23:05:33 +0000 |
| commit | 9413def79582928e09a0a703a8f4d75b9086ad2f (patch) | |
| tree | ef6ad223616329490aa4a9c8a6f2fa9632103cb8 | |
| parent | 5db36c5e5fe9d93c293f63d982d08175783afa70 (diff) | |
| parent | 00bd623e2bcf80738d411b6e1759809b889e26bc (diff) | |
Merge branches 'master' and 'pgxn_utils'
| -rw-r--r-- | Gemfile | 4 | ||||
| -rw-r--r-- | Rakefile | 15 | ||||
| -rwxr-xr-x | bin/pgxn_utils | 5 | ||||
| -rw-r--r-- | lib/pgxn_utils.rb | 5 | ||||
| -rw-r--r-- | lib/pgxn_utils/cli.rb | 56 | ||||
| -rw-r--r-- | lib/pgxn_utils/templates/root/%extension_name%.control.tt | 5 | ||||
| -rw-r--r-- | lib/pgxn_utils/templates/root/META.json.tt | 27 | ||||
| -rw-r--r-- | lib/pgxn_utils/templates/root/Makefile.tt | 24 | ||||
| -rw-r--r-- | lib/pgxn_utils/templates/root/README.md.tt | 80 | ||||
| -rw-r--r-- | lib/pgxn_utils/templates/root/doc/%extension_name%.md.tt | 33 | ||||
| -rw-r--r-- | lib/pgxn_utils/templates/root/sql/%extension_name%.sql.tt | 6 | ||||
| -rw-r--r-- | lib/pgxn_utils/templates/root/sql/uninstall_%extension_name%.sql | 0 | ||||
| -rw-r--r-- | lib/pgxn_utils/templates/root/test/expected/base.out | 2 | ||||
| -rw-r--r-- | lib/pgxn_utils/templates/root/test/sql/base.sql.tt | 8 | ||||
| -rw-r--r-- | lib/pgxn_utils/version.rb | 3 | ||||
| -rwxr-xr-x | pgxn_create_extension | 114 | ||||
| -rw-r--r-- | pgxn_utils.gemspec | 38 | ||||
| -rw-r--r-- | spec/cli_spec.rb | 92 | ||||
| -rw-r--r-- | spec/spec_helper.rb | 26 |
19 files changed, 429 insertions, 114 deletions
@@ -0,0 +1,4 @@ +source "http://rubygems.org" + +# Specify your gem's dependencies in pgxn_utils.gemspec +gemspec diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..32dc7c9 --- /dev/null +++ b/Rakefile @@ -0,0 +1,15 @@ +require 'bundler' +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 + +task :default => :spec diff --git a/bin/pgxn_utils b/bin/pgxn_utils new file mode 100755 index 0000000..671c4bf --- /dev/null +++ b/bin/pgxn_utils @@ -0,0 +1,5 @@ +#!/usr/bin/env ruby +$:.unshift File.expand_path('..', __FILE__) +$:.unshift File.expand_path('../../lib', __FILE__) +require 'pgxn_utils' +PgxnUtils::CLI.start diff --git a/lib/pgxn_utils.rb b/lib/pgxn_utils.rb new file mode 100644 index 0000000..e16c13a --- /dev/null +++ b/lib/pgxn_utils.rb @@ -0,0 +1,5 @@ +require 'thor' + +module PgxnUtils + autoload :CLI, 'pgxn_utils/cli' +end diff --git a/lib/pgxn_utils/cli.rb b/lib/pgxn_utils/cli.rb new file mode 100644 index 0000000..44c07e1 --- /dev/null +++ b/lib/pgxn_utils/cli.rb @@ -0,0 +1,56 @@ +module PgxnUtils + class CLI < Thor + attr_accessor :extension_name, :target, :maintainer, :maintainer_mail + attr_accessor :abstract, :description, :version, :tags + attr_accessor :license, :release_status, :generated_by + + include Thor::Actions + + 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, :default => "The maintainer's name", :desc => "Maintainer's name" + method_option :maintainer_mail, :aliases => "-e", :type => :string, :default => "maintainer@email.here", :desc => "Maintainer's mail" + method_option :abstract, :aliases => "-a", :type => :string, :default => "A short description", :desc => "Defines a short description to abstract" + method_option :license, :aliases => "-l", :type => :string, :default => "postgresql", :desc => "The extension license." + method_option :version, :aliases => "-v", :type => :string, :default => "0.0.1", :desc => "Initial version" + + # META optional fields + method_option :description, :aliases => "-d", :type => :string, :default => "A long description", :desc => "A long text that contains more information about extension" + method_option :generated_by, :aliases => "-b", :type => :string, :desc => "Name of extension's generator" + method_option :tags, :aliases => "-t", :type => :array, :desc => "Defines extension's tags" + method_option :release_status, :aliases => "-r", :type => :string, :default => "unstable", :desc => "Initial extension's release status" + + def skeleton(extension_name) + self.set_accessors extension_name + + directory "root", extension_name + end + + no_tasks do + def set_accessors(extension_name="your_extension_name") + self.extension_name = extension_name + + self.target = options[:target] + self.maintainer = options[:maintainer] + self.maintainer_mail = options[:maintainer_mail] + self.abstract = options[:abstract] + self.license = options[:license] + self.version = options[:version] + + self.description = options[:description] + self.generated_by = options[:generated_by] + self.tags = options[:tags] + self.release_status = options[:release_status] + + self.destination_root = target + end + end + + def self.source_root + @_source_root ||= File.expand_path('../templates', __FILE__) + end + end +end diff --git a/lib/pgxn_utils/templates/root/%extension_name%.control.tt b/lib/pgxn_utils/templates/root/%extension_name%.control.tt new file mode 100644 index 0000000..395dc27 --- /dev/null +++ b/lib/pgxn_utils/templates/root/%extension_name%.control.tt @@ -0,0 +1,5 @@ +# <%= extension_name %> extension +comment = '<%= abstract %>' +default_version = '1.0.0' +module_pathname = '/<%= extension_name %>' +relocatable = true diff --git a/lib/pgxn_utils/templates/root/META.json.tt b/lib/pgxn_utils/templates/root/META.json.tt new file mode 100644 index 0000000..3e1d4e9 --- /dev/null +++ b/lib/pgxn_utils/templates/root/META.json.tt @@ -0,0 +1,27 @@ +{ + "name": "<%= extension_name %>", + "abstract": "<%= abstract %>", + "description": "<%= description %>", + "version": "<%= version %>", + "maintainer": "<%= maintainer %> <<%= maintainer_mail %>>", + "license": "<%= license %>", + "provides": { + "<%= extension_name %>": { + "abstract": "<%= abstract %>", + "file": "sql/<%= extension_name %>.sql", + "docfile": "doc/<%= extension_name %>.md", + "version": "<%= version %>" + } + }, + "release_status": "<%= release_status %>", +<% if generated_by %> + "generated_by": "<%= generated_by %>", +<% end %> +<% if tags %> + "tags": [ <%= tags.collect { |t| %Q|"#{t}"| }.join(",") %> ], +<% end %> + "meta-spec": { + "version": "1.0.0", + "url": "http://pgxn.org/meta/spec.txt" + } +} diff --git a/lib/pgxn_utils/templates/root/Makefile.tt b/lib/pgxn_utils/templates/root/Makefile.tt new file mode 100644 index 0000000..ff0022e --- /dev/null +++ b/lib/pgxn_utils/templates/root/Makefile.tt @@ -0,0 +1,24 @@ +EXTENSION = <%= extension_name %> +EXTVERSION = $(shell grep default_version $(EXTENSION).control | sed -e "s/default_version[[:space:]]*=[[:space:]]*'\([^']*\)'/\1/") + +DATA = $(filter-out $(wildcard sql/*--*.sql),$(wildcard sql/*.sql)) +DOCS = $(wildcard doc/*.txt) +TESTS = $(wildcard test/sql/*.sql) +REGRESS = $(patsubst test/sql/%.sql,%,$(TESTS)) +REGRESS_OPTS = --inputdir=test --load-language=plpgsql +MODULES = $(patsubst %.c,%,$(wildcard src/*.c)) +PG_CONFIG = pg_config +PG91 = $(shell $(PG_CONFIG) --version | grep -qE " 8\.| 9\.0" && echo no || echo yes) + +ifeq ($(PG91),yes) +all: sql/$(EXTENSION)--$(EXTVERSION).sql + +sql/$(EXTENSION)--$(EXTVERSION).sql: sql/$(EXTENSION).sql + cp $< $@ + +DATA = $(wildcard sql/*--*.sql) sql/$(EXTENSION)--$(EXTVERSION).sql +EXTRA_CLEAN = sql/$(EXTENSION)--$(EXTVERSION).sql +endif + +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) diff --git a/lib/pgxn_utils/templates/root/README.md.tt b/lib/pgxn_utils/templates/root/README.md.tt new file mode 100644 index 0000000..dea5186 --- /dev/null +++ b/lib/pgxn_utils/templates/root/README.md.tt @@ -0,0 +1,80 @@ +<%= extension_name %> +<%= extension_name.gsub(/./,"=") %> + +<%= description %> + +To build it, just do this: + + make + make installcheck + make install + +If you encounter an error such as: + + "Makefile", line 8: Need an operator + +You need to use GNU make, which may well be installed on your system as +`gmake`: + + gmake + gmake install + gmake installcheck + +If you encounter an error such as: + + make: pg_config: Command not found + +Be sure that you have `pg_config` installed and in your path. If you used a +package management system such as RPM to install PostgreSQL, be sure that the +`-devel` package is also installed. If necessary tell the build process where +to find it: + + env PG_CONFIG=/path/to/pg_config make && make installcheck && make install + +And finally, if all that fails (and if you're on PostgreSQL 8.1 or lower, it +likely will), copy the entire distribution directory to the `contrib/` +subdirectory of the PostgreSQL source tree and try it there without +`pg_config`: + + env NO_PGXS=1 make && make installcheck && make install + +If you encounter an error such as: + + ERROR: must be owner of database regression + +You need to run the test suite using a super user, such as the default +"postgres" super user: + + make installcheck PGUSER=postgres + +Once <%= extension_name %> is installed, you can add it to a database. If you're running +PostgreSQL 9.1.0 or greater, it's a simple as connecting to a database as a +super user and running: + + CREATE EXTENSION <%= extension_name %>; + +If you've upgraded your cluster to PostgreSQL 9.1 and already had <%= extension_name %> +installed, you can upgrade it to a properly packaged extension with: + + CREATE EXTENSION <%= extension_name %> FROM unpackaged; + +For versions of PostgreSQL less than 9.1.0, you'll need to run the +installation script: + + psql -d mydb -f /path/to/pgsql/share/contrib/<%= extension_name %>.sql + +If you want to install <%= extension_name %> and all of its supporting objects into a specific +schema, use the `PGOPTIONS` environment variable to specify the schema, like +so: + + PGOPTIONS=--search_path=extensions psql -d mydb -f <%= extension_name %>.sql + +Dependencies +------------ +The `<%= extension_name %>` data type has no dependencies other than PostgreSQL. + +Copyright and License +--------------------- + +Copyright (c) <%= Time.now.strftime("%Y") %> <%= maintainer %>. + diff --git a/lib/pgxn_utils/templates/root/doc/%extension_name%.md.tt b/lib/pgxn_utils/templates/root/doc/%extension_name%.md.tt new file mode 100644 index 0000000..4df92fe --- /dev/null +++ b/lib/pgxn_utils/templates/root/doc/%extension_name%.md.tt @@ -0,0 +1,33 @@ +<%= extension_name %> +<%= extension_name.gsub(/./,"=") %> + +Synopsis +-------- + + Show a brief synopsis of the extension. + +Description +----------- + +<%= description %> + +Usage +----- + + Show usage. + +Support +------- + + There is issues tracker? Github? Put this information here. + +Author +------ + +[<%= maintainer %>] + +Copyright and License +--------------------- + +Copyright (c) <%= Time.now.strftime("%Y") %> <%= maintainer %>. + diff --git a/lib/pgxn_utils/templates/root/sql/%extension_name%.sql.tt b/lib/pgxn_utils/templates/root/sql/%extension_name%.sql.tt new file mode 100644 index 0000000..b2ebdaf --- /dev/null +++ b/lib/pgxn_utils/templates/root/sql/%extension_name%.sql.tt @@ -0,0 +1,6 @@ +/* + * Author: <%= maintainer %> <<%= maintainer_mail %>> + * Created at: <%= Time.now %> + * + */ + diff --git a/lib/pgxn_utils/templates/root/sql/uninstall_%extension_name%.sql b/lib/pgxn_utils/templates/root/sql/uninstall_%extension_name%.sql new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/lib/pgxn_utils/templates/root/sql/uninstall_%extension_name%.sql diff --git a/lib/pgxn_utils/templates/root/test/expected/base.out b/lib/pgxn_utils/templates/root/test/expected/base.out new file mode 100644 index 0000000..6cc5058 --- /dev/null +++ b/lib/pgxn_utils/templates/root/test/expected/base.out @@ -0,0 +1,2 @@ +\set ECHO 0 +ROLLBACK; diff --git a/lib/pgxn_utils/templates/root/test/sql/base.sql.tt b/lib/pgxn_utils/templates/root/test/sql/base.sql.tt new file mode 100644 index 0000000..3c163b8 --- /dev/null +++ b/lib/pgxn_utils/templates/root/test/sql/base.sql.tt @@ -0,0 +1,8 @@ +\set ECHO 0 +BEGIN; +\i sql/<%= extension_name %>.sql +\set ECHO all + +-- Tests goes here. + +ROLLBACK; diff --git a/lib/pgxn_utils/version.rb b/lib/pgxn_utils/version.rb new file mode 100644 index 0000000..a061e78 --- /dev/null +++ b/lib/pgxn_utils/version.rb @@ -0,0 +1,3 @@ +module PgxnUtils + VERSION = "0.0.2" +end diff --git a/pgxn_create_extension b/pgxn_create_extension deleted file mode 100755 index 1b0fea6..0000000 --- a/pgxn_create_extension +++ /dev/null @@ -1,114 +0,0 @@ -#!/bin/bash -## -# Copyright (c) 2010-2011 Dickson S. Guedes. -# -# This module is free software; you can redistribute it and/or modify it under -# the [PostgreSQL License](http://www.opensource.org/licenses/postgresql). -# -# Permission to use, copy, modify, and distribute this software and its -# documentation for any purpose, without fee, and without a written agreement is -# hereby granted, provided that the above copyright notice and this paragraph -# and the following two paragraphs appear in all copies. -# -# In no event shall Dickson S. Guedes be liable to any party for direct, -# indirect, special, incidental, or consequential damages, including lost -# profits, arising out of the use of this software and its documentation, even -# if Dickson S. Guedes has been advised of the possibility of such damage. -# -# Dickson S. Guedes specifically disclaims any warranties, including, but not -# limited to, the implied warranties of merchantability and fitness for a -# particular purpose. The software provided hereunder is on an "as is" basis, -# and Dickson S. Guedes has no obligations to provide maintenance, support, -# updates, enhancements, or modifications. -## -[ $# -lt 2 ] && echo "Usage: $0 name short_description" && exit - -extension=$1 -shift -description=$* - -userlogin=$USER -username=`grep $userlogin /etc/passwd | cut -d":" -f5 | cut -d "," -f1` - -[ -d $extension ] && echo "$extension already exists" && exit - -echo -n creating dirs -mkdir -p $extension/{sql,doc,test/{sql,expected}} -touch $extension/{sql/{$extension,uninstall_$extension}.sql,doc/$extension.md,test/{sql/base.sql,expected/base.out}} -echo "results/" > $extension/.gitignore -echo ... ok - -echo -n creating META.json -cat > $extension/META.json <<EOF -{ - "name": "$extension", - "abstract": "$description", - "description": "A long description for $extension", - "version": "1.0.0", - "maintainer": [ - "$username \<your@email.here\>" - ], - "license": "postgresql", - "provides": { - "$extension": { - "abstract": "", - "file": "sql/$extension.sql", - "docfile": "doc/$extension.md", - "version": "1.0.0" - } - }, - "generated_by": "$username", - "meta-spec": { - "version": "1.0.0", - "url": "http://pgxn.org/meta/spec.txt" - }, - "tags": [ - "$extension", - "some", - "tags" - ] -} -EOF -echo ... ok - -echo -n creating Makefile -cat > $extension/Makefile <<EOF -EXTENSION = $extension -EXTVERSION = \$(shell grep default_version \$(EXTENSION).control | \ - sed -e "s/default_version[[:space:]]*=[[:space:]]*'\([^']*\)'/\1/") - -DATA = \$(filter-out \$(wildcard sql/*--*.sql),\$(wildcard sql/*.sql)) -DOCS = \$(wildcard doc/*.txt) -TESTS = \$(wildcard test/sql/*.sql) -REGRESS = \$(patsubst test/sql/%.sql,%,\$(TESTS)) -REGRESS_OPTS = --inputdir=test --load-language=plpgsql -MODULES = \$(patsubst %.c,%,\$(wildcard src/*.c)) -PG_CONFIG = pg_config -PG91 = \$(shell \$(PG_CONFIG) --version | grep -qE " 8\.| 9\.0" && echo no || echo yes) - -ifeq (\$(PG91),yes) -all: sql/\$(EXTENSION)--\$(EXTVERSION).sql - -sql/\$(EXTENSION)--\$(EXTVERSION).sql: sql/\$(EXTENSION).sql - cp $< \$@ - -DATA = \$(wildcard sql/*--*.sql) sql/\$(EXTENSION)--\$(EXTVERSION).sql -EXTRA_CLEAN = sql/\$(EXTENSION)--\$(EXTVERSION).sql -endif - -PGXS := \$(shell \$(PG_CONFIG) --pgxs) -include \$(PGXS) -EOF -echo ... ok - -echo -n creating $extension.control -cat > $extension/$extension.control <<EOF -# $extension extension -comment = '$description' -default_version = '1.0.0' -module_pathname = '$libdir/$extension' -relocatable = true -EOF -echo ... ok - -echo all done diff --git a/pgxn_utils.gemspec b/pgxn_utils.gemspec new file mode 100644 index 0000000..68007d2 --- /dev/null +++ b/pgxn_utils.gemspec @@ -0,0 +1,38 @@ +# -*- encoding: utf-8 -*- +$:.push File.expand_path("../lib", __FILE__) +require "pgxn_utils/version" + +Gem::Specification.new do |s| + s.name = "pgxn_utils" + s.version = PgxnUtils::VERSION + s.platform = Gem::Platform::RUBY + s.date = %q{2011-05-06} + s.authors = ["Dickson S. Guedes"] + s.email = ["guedes@guedesoft.net"] + s.homepage = "http://github.com/guedes/pgxn-utils" + s.summary = %q{A PGXN set of tools to 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.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" + + # 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"]) + else + s.add_dependency(%q<thor>, ["~> 0.14"]) + end + else + s.add_dependency(%q<thor>, ["~> 0.14"]) + end +end diff --git a/spec/cli_spec.rb b/spec/cli_spec.rb new file mode 100644 index 0000000..2005756 --- /dev/null +++ b/spec/cli_spec.rb @@ -0,0 +1,92 @@ +require File.expand_path('spec/spec_helper') + +describe PgxnUtils::CLI do + + after(:all) do + system "rm -rf /tmp/extension.*" + system "rm -rf extension.*" + end + + context "create skeleton" do + before(:each) do + @cli = PgxnUtils::CLI.new + end + + it "should accepts or not a target" do + expected_extension = next_extension + + File.should_not exist(expected_extension) + skeleton "#{expected_extension}", "-p /tmp" + File.should exist("/tmp/#{expected_extension}") + + File.should_not exist(expected_extension) + skeleton "#{expected_extension}" + File.should exist(expected_extension) + end + + it "should store author's name, email, short_description, long_desctiption, tags" do + expected_extension = next_extension + expected_name = "Guedes" + expected_mail = "guedes@none.here" + expected_abstract = "Short description" + expected_description = "Very Long description for my cool extension" + expected_tags = "one two tree" + expected_version = "1.0.0" + + skeleton expected_extension, "-p /tmp -m #{expected_name} -e #{expected_mail} -t #{expected_tags} -a '#{expected_abstract}' -d '#{expected_description}' -v #{expected_version}" + + meta = File.read("/tmp/#{expected_extension}/META.json") + meta.should match(/"name": "#{expected_extension}"/) + meta.should match(/"abstract": "#{expected_abstract}"/) + meta.should match(/"description": "#{expected_description}"/) + meta.should match(/"version": "#{expected_version}"/) + meta.should match(/"license": "postgresql"/) + meta.should match(/"release_status": "unstable"/) + meta.should match(/"#{expected_name} <#{expected_mail}>"/) + meta.should match(/"file": "sql\/#{expected_extension}.sql"/) + meta.should match(/"docfile": "doc\/#{expected_extension}.md"/) + meta.should_not match(/"generated_by":/) + meta.should match(/"tags": \[ "one","two","tree" \],/) + + makefile = File.read("/tmp/#{expected_extension}/Makefile") + makefile.should match(/EXTENSION = #{expected_extension}/) + + control = File.read("/tmp/#{expected_extension}/#{expected_extension}.control") + control.should match(/module_pathname = '\/#{expected_extension}'/) + end + + it "should generates a skeleton" do + extension = next_extension + skeleton extension + + Dir["#{extension}/**/*"].sort.should == [ + "#{extension}/META.json", + "#{extension}/Makefile", + "#{extension}/README.md", + "#{extension}/doc", + "#{extension}/doc/#{extension}.md", + "#{extension}/sql", + "#{extension}/sql/#{extension}.sql", + "#{extension}/sql/uninstall_#{extension}.sql", + "#{extension}/test", + "#{extension}/test/expected", + "#{extension}/test/expected/base.out", + "#{extension}/test/sql", + "#{extension}/test/sql/base.sql", + "#{extension}/#{extension}.control" + ].sort + end + + it "should generates a git repo" + end + + context "bundle" do + it "should bundle to zip by default" + it "should create the name in semver spec" + end + + context "release" do + it "should send the bundle to PGXN" + end + +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..f078b0b --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,26 @@ +$:.unshift File.expand_path('..', __FILE__) +$:.unshift File.expand_path('../../lib', __FILE__) + +require 'rspec' +require 'pgxn_utils' + +$counter = 0 + +LIB_PATH = File.expand_path('../../lib', __FILE__) +BIN_PATH = File.expand_path('../../bin/pgxn_utils', __FILE__) + +DESTINATION_ROOT = File.expand_path('../pgxn_utils', __FILE__) +FileUtils.rm_rf(DESTINATION_ROOT) + +def next_extension + $counter += 1 + "extension.#{$counter}" +end + +def skeleton(extension_name, args=nil) + run_pgxn_utils(:skeleton, "#{extension_name} #{args}") +end + +def run_pgxn_utils(task, args) + system "#{BIN_PATH} #{task.to_s} #{args} >/dev/null" +end |
