schema_dev 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +84 -6
- data/bin/schema_dev +7 -2
- data/lib/schema_dev/config.rb +37 -25
- data/lib/schema_dev/gemfile_selector.rb +5 -3
- data/lib/schema_dev/rspec/db.rb +3 -3
- data/lib/schema_dev/runner.rb +8 -1
- data/lib/schema_dev/tasks.rb +1 -3
- data/lib/schema_dev/travis.rb +48 -0
- data/lib/schema_dev/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32da67245032f4e8dda3169be236b050bcbfa230
|
4
|
+
data.tar.gz: 5c4863f4241688f83166c82d7e3357e06b80f8b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee070648972f48f9ecea215559dd141d81d1d88a5b6b0ff14c29cf27a3bad69e660af2493296c518f5cd50547e207ca072ef3a794fbb3db345f6ecaced996a77
|
7
|
+
data.tar.gz: 5b6566b814e841dc3e1321c74a05ce77c9df92634cdc5e26c92936d70a97a9232666af72f0fadc72d5d0101681ba53edba95aaad1af852ea75ee8609b67c37b9
|
data/README.md
CHANGED
@@ -1,15 +1,93 @@
|
|
1
1
|
# SchemaDev
|
2
2
|
|
3
|
-
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/schema_dev.png)](http://badge.fury.io/rb/schema_dev)
|
4
|
+
|
5
|
+
Development tools for the SchemaPlus family of gems.
|
6
|
+
|
7
|
+
Provides support for working with multiple ruby versions, rails adapaters, and db versions. In particular provides a command `schema_dev` for running rspec (or whatever) on the matrix or a slice or element of it. It also auto-generates the `.travis.yml` file for [travis-ci](https://travis-ci.org) testing.
|
4
8
|
|
5
9
|
## Installation
|
6
10
|
|
7
|
-
Include this as a development dependency in
|
11
|
+
Include this as a development dependency in the client gem's `<ame>.gemfile`:
|
12
|
+
|
13
|
+
s.add_development_dependency "schema_dev"
|
14
|
+
|
15
|
+
## Setup
|
16
|
+
|
17
|
+
#### `schema_dev.yml`
|
18
|
+
|
19
|
+
The client gem needs a file `schema_dev.yml` in it's root, which specifies the testing matrix, among other things.
|
20
|
+
|
21
|
+
* `ruby`: A single version of ruby, or a list of ruby versions.
|
22
|
+
* `rails`: A single version of rails, or a list of rails versions
|
23
|
+
* `db`: (Optional) The list of db adapters to test. Leave this out if the gem will hardwire its tests for a single adapter.
|
24
|
+
* `quick`: (Optional) Hash listing the version of ruby, rails, and db to use with `--quick` option. If not specified, the default is to use the last entry in each list.
|
25
|
+
|
26
|
+
#### Gemfiles
|
27
|
+
|
28
|
+
The client gem must organize its Gemfiles along the lines of:
|
29
|
+
|
30
|
+
gemfiles/rails-4.0/Gemfile.postgresql # if testing against multiple db adapter
|
31
|
+
|
32
|
+
gemfiles/Gemfile-rails.4.0 # if hardwired to a single db adapter
|
33
|
+
|
34
|
+
#### Rspec
|
35
|
+
|
36
|
+
The client gem should include this in its `spec/spec_helper`
|
37
|
+
|
38
|
+
require 'schema_dev/rspec'
|
39
|
+
SchemaDev::Rspec.setup_db # if testing against multiple dbs, the db will be filled in automatically
|
40
|
+
SchemaDev::Rspec.setup_db 'sqlite3' # to hardwire a single database
|
41
|
+
|
42
|
+
This will take care of connecting to the test database appropriately, and will set up logging to a file specific to the test matrix cell.
|
43
|
+
|
44
|
+
#### Rake
|
45
|
+
|
46
|
+
The client gem should include this in its `Rakefile`:
|
47
|
+
|
48
|
+
require 'schema_dev/tasks'
|
49
|
+
|
50
|
+
### Ruby selection
|
51
|
+
|
52
|
+
You must have one of [chruby](https://github.com/postmodern/chruby), [rbenv](https://github.com/sstephenson/rbenv) or [rvm](http://rvm.io) installed and working. Within it, have available whichever ruby versions you want to test.
|
53
|
+
|
54
|
+
### Database
|
55
|
+
|
56
|
+
Of course you must have installed whichever database(s) you want to test.
|
57
|
+
|
58
|
+
For PostgreSQL and MySQL the tests need a db user with permissions to create and access databases: The default username used by the specs is 'schema_plus' for both PostgreSQL and MySQL; you can change them via:
|
59
|
+
|
60
|
+
$ export POSTGRESQL_DB_USER = pgusername
|
61
|
+
$ export MYSQL_DB_USER = mysqlusername
|
62
|
+
|
63
|
+
For PostgreSQL and MySQL you must explicitly create the databases used by the tests:
|
64
|
+
|
65
|
+
$ rake create_databases # creates postgresql and/or mysql as needed
|
66
|
+
|
67
|
+
## Running The Tests
|
68
|
+
|
69
|
+
In the root directory, you can run, e.g.,
|
70
|
+
|
71
|
+
$ schema_dev bundle install
|
72
|
+
$ schema_dev rspec
|
73
|
+
|
74
|
+
Which will run those commands over the whole matrix. You can also specify slices, via any combination of `--ruby`, `--rails` and (if the gem tests multiple dbs) `--db`
|
75
|
+
|
76
|
+
$ schema_dev rspec --ruby 2.1.3 --rails 4.0
|
77
|
+
|
78
|
+
For convenience you can also use `--quick` to run just one as specified in `schema_dev.yml`
|
79
|
+
|
80
|
+
If you want to pass extra arguments to a command, make sure to use `--` to avoid them being processed by `schema_dev`. e.g.
|
81
|
+
|
82
|
+
$ schema_dev rspec --quick -- -e 'select which spec'
|
83
|
+
|
84
|
+
For more info, see
|
8
85
|
|
9
|
-
|
10
|
-
|
11
|
-
```
|
86
|
+
$ schema_dev help
|
87
|
+
$ schema_dev help rspec # etc.
|
12
88
|
|
13
|
-
##
|
89
|
+
## Generating `.travis.yml`
|
14
90
|
|
91
|
+
To keep things in sync `.travis.yml` gets automatically updated whenever you run `schema_dev matrix` or any of its shorthands. There's also a command to just explicitly update `.travis.yml`
|
15
92
|
|
93
|
+
$ schema_dev travis
|
data/bin/schema_dev
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
require 'active_support/core_ext/hash'
|
4
4
|
require 'thor'
|
5
|
-
|
6
|
-
|
5
|
+
require_relative '../lib/schema_dev/config'
|
6
|
+
require_relative '../lib/schema_dev/runner'
|
7
7
|
|
8
8
|
$config = SchemaDev::Config.load
|
9
9
|
$runner = SchemaDev::Runner.new($config)
|
@@ -18,6 +18,11 @@ class CLI < Thor
|
|
18
18
|
method_option :db, type: :string, desc: "Only execute for the specified database" if $config.db?
|
19
19
|
end
|
20
20
|
|
21
|
+
desc "update .travis.yml", "create .travis.yml based on schema_dev.yml values"
|
22
|
+
def travis
|
23
|
+
$runner.travis
|
24
|
+
end
|
25
|
+
|
21
26
|
desc "run command", "run a command over the matrix"
|
22
27
|
matrix_options
|
23
28
|
def matrix(*args)
|
data/lib/schema_dev/config.rb
CHANGED
@@ -12,7 +12,7 @@ module SchemaDev
|
|
12
12
|
|
13
13
|
class Config
|
14
14
|
|
15
|
-
attr_accessor :quick, :db
|
15
|
+
attr_accessor :quick, :db, :ruby, :rails, :notify, :exclude
|
16
16
|
|
17
17
|
def self._reset ; @@config = nil end # for use by rspec
|
18
18
|
|
@@ -20,23 +20,6 @@ module SchemaDev
|
|
20
20
|
@@config ||= new((YAML.load Pathname.new(CONFIG_FILE).read).symbolize_keys)
|
21
21
|
end
|
22
22
|
|
23
|
-
class Tuple < KeyStruct[:ruby, :rails, :db]
|
24
|
-
def match?(other)
|
25
|
-
return false if self.ruby and other.ruby and self.ruby != other.ruby
|
26
|
-
return false if self.rails and other.rails and self.rails != other.rails
|
27
|
-
return false if self.db and other.db and self.db != other.db
|
28
|
-
true
|
29
|
-
end
|
30
|
-
|
31
|
-
def match_any?(others)
|
32
|
-
others.any?{|other| self.match? other}
|
33
|
-
end
|
34
|
-
|
35
|
-
def to_hash
|
36
|
-
super.reject{ |k, val| val.nil? }
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
23
|
def initialize(opts={}) # once we no longer support ruby 1.9.3, can switch to native keyword args
|
41
24
|
opts = opts.keyword_args(ruby: :required, rails: :required, db: nil, exclude: nil, notify: nil, quick: nil)
|
42
25
|
@ruby = Array.wrap(opts.ruby)
|
@@ -51,8 +34,12 @@ module SchemaDev
|
|
51
34
|
@db.any?
|
52
35
|
end
|
53
36
|
|
37
|
+
def dbms
|
38
|
+
@dbms ||= [:postgresql, :mysql].select{|dbm| @db.grep(/^#{dbm}/).any?}
|
39
|
+
end
|
40
|
+
|
54
41
|
def matrix(opts={}) # once we no longer support ruby 1.9.3, can switch to native keyword args
|
55
|
-
opts = opts.keyword_args(quick: false, ruby: nil, rails: nil, db: nil)
|
42
|
+
opts = opts.keyword_args(quick: false, ruby: nil, rails: nil, db: nil, excluded: nil)
|
56
43
|
use_ruby = @ruby
|
57
44
|
use_rails = @rails
|
58
45
|
use_db = @db
|
@@ -65,12 +52,37 @@ module SchemaDev
|
|
65
52
|
use_rails = Array.wrap(opts.rails) if opts.rails
|
66
53
|
use_db = Array.wrap(opts.db) if opts.db
|
67
54
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
55
|
+
use_ruby = [nil] unless use_ruby.any?
|
56
|
+
use_rails = [nil] unless use_rails.any?
|
57
|
+
|
58
|
+
m = use_ruby.product(use_rails)
|
59
|
+
m = m.product(use_db).map(&:flatten) if use_db.any?
|
60
|
+
m = m.map { |_ruby, _rails, _db| Tuple.new(ruby: _ruby, rails: _rails, db: _db) }.compact
|
61
|
+
m = m.reject(&it.match_any?(@exclude)) unless opts.excluded == :none
|
62
|
+
m = m.map(&:to_hash)
|
63
|
+
|
64
|
+
if opts.excluded == :only
|
65
|
+
return matrix(opts.merge(excluded: :none)) - m
|
66
|
+
else
|
67
|
+
return m
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class Tuple < KeyStruct[:ruby, :rails, :db]
|
72
|
+
def match?(other)
|
73
|
+
return false if self.ruby and other.ruby and self.ruby != other.ruby
|
74
|
+
return false if self.rails and other.rails and self.rails != other.rails
|
75
|
+
return false if self.db and other.db and self.db != other.db
|
76
|
+
true
|
77
|
+
end
|
78
|
+
|
79
|
+
def match_any?(others)
|
80
|
+
others.any?{|other| self.match? other}
|
81
|
+
end
|
82
|
+
|
83
|
+
def to_hash
|
84
|
+
super.reject{ |k, val| val.nil? }
|
85
|
+
end
|
74
86
|
end
|
75
87
|
|
76
88
|
end
|
@@ -4,7 +4,9 @@ module SchemaDev
|
|
4
4
|
GEMFILES_DIR = "gemfiles"
|
5
5
|
|
6
6
|
module GemfileSelector
|
7
|
-
|
7
|
+
extend self
|
8
|
+
|
9
|
+
def gemfile(opts = {})
|
8
10
|
opts = opts.keyword_args(rails: :required, db: nil)
|
9
11
|
root = Pathname.new(GEMFILES_DIR)
|
10
12
|
if opts.db
|
@@ -14,12 +16,12 @@ module SchemaDev
|
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
17
|
-
def
|
19
|
+
def command(opts={})
|
18
20
|
opts = opts.keyword_args(rails: :required, db: nil)
|
19
21
|
"BUNDLE_GEMFILE=#{gemfile(rails: opts.rails, db: opts.db)}"
|
20
22
|
end
|
21
23
|
|
22
|
-
def
|
24
|
+
def infer_db
|
23
25
|
(env = ENV['BUNDLE_GEMFILE']) =~ %r{rails.*/Gemfile[.](.*)}
|
24
26
|
$1 or raise "Can't infer db: Env BUNDLE_GEMFILE=#{env.inspect}) isn't a schema_dev Gemfile path with db"
|
25
27
|
end
|
data/lib/schema_dev/rspec/db.rb
CHANGED
@@ -7,8 +7,8 @@ module SchemaDev
|
|
7
7
|
module Db
|
8
8
|
extend self
|
9
9
|
|
10
|
-
def setup(
|
11
|
-
@db =
|
10
|
+
def setup(_db = nil)
|
11
|
+
@db = _db || GemfileSelector.infer_db
|
12
12
|
set_logger
|
13
13
|
connect
|
14
14
|
RSpec.configure do |config|
|
@@ -19,7 +19,7 @@ module SchemaDev
|
|
19
19
|
config.filter_run_excluding :mysql => :skip if Helpers.mysql?
|
20
20
|
config.filter_run_excluding :sqlite3 => :only unless Helpers.sqlite3?
|
21
21
|
config.filter_run_excluding :sqlite3 => :skip if Helpers.sqlite3?
|
22
|
-
end
|
22
|
+
end unless _db
|
23
23
|
end
|
24
24
|
|
25
25
|
def tmproot
|
data/lib/schema_dev/runner.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'shellwords'
|
2
2
|
|
3
3
|
require_relative 'matrix_executor'
|
4
|
+
require_relative 'travis'
|
4
5
|
|
5
6
|
module SchemaDev
|
6
7
|
class Runner
|
@@ -8,7 +9,13 @@ module SchemaDev
|
|
8
9
|
@config = config
|
9
10
|
end
|
10
11
|
|
11
|
-
def
|
12
|
+
def travis
|
13
|
+
Travis.update(@config)
|
14
|
+
end
|
15
|
+
|
16
|
+
def run(*args, dry_run: false, quick: false, ruby: nil, rails: nil, db: nil, freshen: true)
|
17
|
+
self.travis if freshen
|
18
|
+
|
12
19
|
matrix = MatrixExecutor.new @config.matrix(quick: quick, ruby: ruby, rails: rails, db: db)
|
13
20
|
|
14
21
|
return true if matrix.run(Shellwords.join(args.flatten), dry_run: dry_run)
|
data/lib/schema_dev/tasks.rb
CHANGED
@@ -1,11 +1,9 @@
|
|
1
1
|
require_relative 'config'
|
2
2
|
|
3
|
-
|
3
|
+
dbms = SchemaDev::Config.load.dbms
|
4
4
|
|
5
5
|
DATABASES = %w[schema_plus_test]
|
6
6
|
|
7
|
-
dbms = [:postgresql, :mysql].select{|dbm| config.db.grep(/^#{dbm}/).any?}
|
8
|
-
|
9
7
|
if dbms.any?
|
10
8
|
{
|
11
9
|
postgresql: { uservar: 'POSTGRESQL_DB_USER', defaultuser: 'schema_plus', create: "createdb -U '%{user}' %{dbname}", drop: "dropdb -U '%{user}' %{dbname}" },
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module SchemaDev
|
5
|
+
TRAVIS_FILE = ".travis.yml"
|
6
|
+
|
7
|
+
module Travis
|
8
|
+
extend self
|
9
|
+
|
10
|
+
def build(config)
|
11
|
+
env = 'POSTGRESQL_DB_USER=postgres MYSQL_DB_USER="travis"'
|
12
|
+
gemfiles = config.matrix.map{|entry| GemfileSelector.gemfile(entry.slice(:rails, :db)).to_s}.uniq
|
13
|
+
exclude = config.matrix(excluded: :only).map { |entry| {}.tap {|ex|
|
14
|
+
ex["rvm"] = entry[:ruby]
|
15
|
+
ex["gemfile"] = GemfileSelector.gemfile(entry.slice(:rails, :db)).to_s
|
16
|
+
ex["env"] = env if config.dbms.any?
|
17
|
+
}}.reject{|ex| not gemfiles.include? ex["gemfile"]}
|
18
|
+
|
19
|
+
{}.tap { |travis|
|
20
|
+
travis["rvm"] = config.ruby.sort
|
21
|
+
travis["gemfile"] = gemfiles.sort
|
22
|
+
if config.dbms.any?
|
23
|
+
travis["before_script"] = 'bundle exec rake create_databases'
|
24
|
+
travis["after_script"] = 'bundle exec rake drop_databases'
|
25
|
+
travis["env"] = env
|
26
|
+
end
|
27
|
+
travis["notifications"] = { "email" => config.notify } if config.notify.any?
|
28
|
+
travis["matrix"] = { "exclude" => exclude.sort_by{|ex| [ex["rvm"], ex["gemfile"]]} } if exclude.any?
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def update(config)
|
33
|
+
filepath = Pathname.new(TRAVIS_FILE)
|
34
|
+
newtravis = build(config)
|
35
|
+
oldtravis = YAML.load(filepath.read) rescue nil
|
36
|
+
if oldtravis != newtravis
|
37
|
+
header = <<-ENDYAML
|
38
|
+
# This file was auto-generated by the schema_dev tool, based on the data in
|
39
|
+
# ./schema_dev.yml
|
40
|
+
# Please do not edit this file; any changes will be overwritten next time
|
41
|
+
# schema_dev gets run.
|
42
|
+
ENDYAML
|
43
|
+
filepath.write header + newtravis.to_yaml
|
44
|
+
puts "* Updated #{filepath}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/schema_dev/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: schema_dev
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ronen barzel
|
@@ -161,6 +161,7 @@ files:
|
|
161
161
|
- lib/schema_dev/ruby_selector.rb
|
162
162
|
- lib/schema_dev/runner.rb
|
163
163
|
- lib/schema_dev/tasks.rb
|
164
|
+
- lib/schema_dev/travis.rb
|
164
165
|
- lib/schema_dev/version.rb
|
165
166
|
- schema_dev.gemspec
|
166
167
|
- schema_dev.yml
|