Skip to content

Commit

Permalink
Remove rake as gem dependency (but keep it as development dependency)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikola committed Jan 30, 2017
1 parent 9ca3667 commit 75fbfa7
Show file tree
Hide file tree
Showing 28 changed files with 396 additions and 255 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ gemspec

gem 'rspec', '~> 3.0.0'
gem 'pry'
gem 'rake', '~> 10.5'
88 changes: 70 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

# Dumbo - the PostgreSQL Extension-Development Framework

Dumbo has been created to facilitate development of PostgreSQL extensions. This
tool, together with our [pgbundle project](https://github.com/adjust/pgbundle)
makes maintaining and developing a bundle of PostgreSQL extension dependencies
easier.
Dumbo has been created with the purpose to facilitate development of PostgreSQL
extensions. Together with our [pgbundle
project](https://github.com/adjust/pgbundle) tool, it brings a lean approach
to the development of a bundle of PostgreSQL extension dependencies.

Dumbo is a framework for an easy PostgreSQL extension development. Some of the
killer features are improved extension version management, automated
upgrade/downgrade migrations generations and ERB templating support.
Some of the features the Dumbo framework offers are:

* facilitated PostgreSQL extension initialization
* improved version management
* automated generation of upgrade/downgrade migrations
* ERB templating support for automating repeated code generation

## Installation

Expand All @@ -25,28 +28,77 @@ use `sudo` for this command to run.
Dumbo comes with an executable, which would be your main interface to the
functionality of the framework.

### Creating a new extension project
### Start a new PostgreSQL extension

For new PG extension projects, Dumbo can generate a directory sceleton and
For new PG extension projects, Dumbo can generate a directory skeleton and
create the typical files for you.

$ dumbo new-extension my_data_type
$ dumbo new myextname [Initial.Version.String] ['This extension is about that']

where "myextname" is the name for the new PG extension. As a stating point take
a look at the sample functions generated in `sql/myextname.sql` as well as the
generated `Makefile`.

The optional second argument sets the initial version for the new extension; the
default value is `0.0.1` but you could for example wish to start at `0.1.0`.
Note that the extension versions must follow the Semantic versioning style. An
optional third argument is a description on what the extension would be about.

So, as a concrete example, the following command line command command:

$ dumbo new pg_currency 0.1.0 'A currency data-type for PostgreSQL'

would generate a project skeleton like this:

pg_currency
├── Makefile
├── README.md
├── config
│   └── database.yml
├── pg_currency.control
├── sql
│   └── pg_currency.sql
├── src
│   ├── pg_currency.c
│   └── pg_currency.h
└── test
├── expected
│   └── pg_currency_test.out
└── sql
└── pg_currency_test.sql

This is already enough for you to go into the newly created directory and
install your extension against Postgres using standard `make install`.

where "my_data_type" is the name for the new PG extension. As a stating point
take a look at the sample function in `sql/sample.sql` as well as the generated
`Makefile`.
Once installed, login to Postgres using `psql` and issue this SQL:

You can already build and install your extension using standard `make install`.
CREATE EXTENSION pg_currency;

TODO: illustrate the default generated file/directory tree!
This skeleton includes the SQL declaration and C implementation of a sample
funcion called `add_one(int)`. Note that there's also an automatically
generated sample regression testsuite, which you can run using the standard:

### Creating a new version
$ make installcheck

from your command line.

### Start a new version

To initialize a new version on an existing extension:

$ dumbo new-version 0.1.2
$ dumbo bump [major|minor|patch]

Note that keeping to the (major.minor.patch) versioning is required. If no
argument is given, the default level for the version bump is `patch`. So given
a current version `0.1.0`:

$ dumbo bump

Note that keeping to the (major.minor.patch) versioning is required.
will update the `*.control` file of the extension to version `0.1.1`.

### Create migrations between versions

TODO: illustrate this!

$ dumbo migrations

Expand Down
2 changes: 0 additions & 2 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@ require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec)

ENV['DUMBO_ENV'] ||= 'test'

task :default => :spec
129 changes: 3 additions & 126 deletions bin/dumbo
Original file line number Diff line number Diff line change
@@ -1,129 +1,6 @@
#!/usr/bin/env ruby

require 'thor'
require 'thor/group'
require 'erubis'
require 'fileutils'
require 'pathname'
# require 'dumbo'
require File.join(File.dirname(__FILE__), '..', 'lib', 'dumbo.rb')

module Cli
class Generate < Thor
desc 'spec <name>', 'Add a new spec file named <name> as spec/<name>_spec.rb'
def spec(name)
file_name = "spec/#{name}_spec.rb"
if File.exist?(file_name)
say_status('already exists', file_name, :yellow)
return
end

File.open("spec/#{name}_spec.rb", 'w') do |f|
f.puts <<-EOF.gsub(' ', '')
require 'spec_helper'
describe '#{name}' do
before do
install_extension
end
end
EOF
end
say_status('create', file_name)
end
end

class Dumbo < Thor
desc 'new <name>', 'creates a new extension skeleton'

def new(name, initial_version = '0.0.1')
mkdir("#{name}/sql")
mkdir("#{name}/src")
mkdir("#{name}/spec")
mkdir("#{name}/config")
mkdir("#{name}/lib/tasks")

spec_helper = Dir.glob(File.expand_path('../../spec/spec_helper.rb', __FILE__))
spec_helper += Dir.glob(File.expand_path('../../spec/support', __FILE__))

cp spec_helper, "#{name}/spec"
cp File.expand_path('../../config/boot.rb', __FILE__), "#{name}/config"

template_path = File.expand_path('../../template', __FILE__)

Dir.glob(File.expand_path('../../template/**/*', __FILE__)).each do |template|
pathname = Pathname.new(template)
dest_name = pathname.relative_path_from Pathname.new(template_path)

if pathname.directory?
mkdir("#{name}/#{dest_name}", true)
next
end

if dest_name.extname == '.erb'
eruby = Erubis::Eruby.new(File.read(template))
content = eruby.result(ext_name: name)
create "#{name}/#{dest_name.sub_ext('')}", content
else
cp template, "#{name}/#{dest_name}"
end
end

create "#{name}/#{name}.control", <<-STR
# #{name} extension
comment = 'my awesome extension'
default_version = '#{initial_version}'
relocatable = true
requires = ''
STR
end

desc "g GENERATOR args", "generates files for the given generator"
subcommand "g", Generate



no_commands do
def mkdir(path, silent_skip = false)
if File.directory?(path)
say_status('skip', "#{path}", :yellow) unless silent_skip
else
FileUtils.mkdir_p(path)
say_status('create', "#{path}")
end
end

def create(path, content, silent_skip = false)
if File.exist? path
say_status('skip', path, :yellow) unless silent_skip
else
File.open(path, 'w') do |f|
f.puts content
end
say_status('create', path)
end
end

def cp(src, dest, silent_skip = false)
Array(src).each do |p|
path = Pathname.new(p)
if File.directory?(dest)
if File.exist?("#{dest}/#{path.basename}")
say_status('skip', "#{dest}/#{path.basename}", :yellow) unless silent_skip
else
FileUtils.cp_r p, dest
say_status('create', "#{dest}/#{path.basename}")
end
else
if File.exist?(dest)
say_status('skip', dest, :yellow) unless silent_skip
else
FileUtils.cp_r p, dest
say_status('create', dest)
end
end
end
end
end
end
end

Cli::Dumbo.start(ARGV)
Dumbo::Cli.start(ARGV)
14 changes: 0 additions & 14 deletions config/boot.rb

This file was deleted.

12 changes: 3 additions & 9 deletions dumbo.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,7 @@ Gem::Specification.new do |spec|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ['lib']

# TODO extract rake as development dependency and move the rake tasks
# functionality to the bin/dumbo executable
spec.add_dependency 'rake', '~> 10.5'

spec.add_dependency 'erubis', '~> 2.7'
spec.add_dependency 'pg', '~> 0.17'

spec.add_dependency 'thor', '~> 0.19'
spec.add_dependency 'bundler', '~> 1.13'
spec.add_dependency 'erubis', '~> 2.7'
spec.add_dependency 'pg', '~> 0.17'
spec.add_dependency 'thor', '~> 0.19'
end
19 changes: 18 additions & 1 deletion lib/dumbo.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require 'dumbo/version'
require 'dumbo/db'
require 'dumbo/pg_object'
require 'dumbo/cli'
require 'dumbo/type'
require 'dumbo/types/composite_type'
require 'dumbo/types/enum_type'
Expand All @@ -18,5 +19,21 @@
require 'dumbo/binding_loader'

module Dumbo
# Your code goes here...
class NoConfigurationError < StandardError
def initialize(env)
super "Config for environment #{env} not found"
end
end

class << self
def boot(env)
raise NoConfigurationError.new(env) if db_config[env].nil?

DB.connect db_config[env]
end

def db_config
@config ||= YAML.load_file(File.join('config', 'database.yml'))
end
end
end
Loading

0 comments on commit 75fbfa7

Please sign in to comment.