schema_dev 4.0.0 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/prs.yml +49 -0
  3. data/.simplecov +20 -0
  4. data/Gemfile +2 -0
  5. data/README.md +7 -7
  6. data/Rakefile +3 -5
  7. data/bin/schema_dev +25 -21
  8. data/lib/schema_dev/config.rb +62 -44
  9. data/lib/schema_dev/executor.rb +9 -8
  10. data/lib/schema_dev/gem.rb +45 -37
  11. data/lib/schema_dev/gemfile_selector.rb +7 -7
  12. data/lib/schema_dev/gemfiles.rb +6 -5
  13. data/lib/schema_dev/github_actions.rb +266 -0
  14. data/lib/schema_dev/matrix_executor.rb +4 -2
  15. data/lib/schema_dev/readme.rb +17 -10
  16. data/lib/schema_dev/rspec/db.rb +44 -33
  17. data/lib/schema_dev/rspec.rb +4 -9
  18. data/lib/schema_dev/ruby_selector.rb +29 -14
  19. data/lib/schema_dev/runner.rb +14 -10
  20. data/lib/schema_dev/tasks/dbms.rb +34 -26
  21. data/lib/schema_dev/tasks.rb +2 -3
  22. data/lib/schema_dev/templates.rb +5 -5
  23. data/lib/schema_dev/version.rb +3 -1
  24. data/lib/schema_dev.rb +3 -1
  25. data/schema_dev.gemspec +23 -26
  26. data/spec/schema_dev/config_spec.rb +60 -0
  27. data/spec/schema_dev/gem_spec.rb +74 -0
  28. data/spec/schema_dev/gemfile_selector_spec.rb +11 -0
  29. data/spec/schema_dev/gemfiles_spec.rb +41 -0
  30. data/spec/schema_dev/github_actions_spec.rb +818 -0
  31. data/spec/schema_dev/runner_spec.rb +103 -0
  32. data/spec/spec_helper.rb +5 -6
  33. data/templates/README/uses.schema_dev.md.erb +1 -2
  34. data/templates/gem/GEM_NAME.gemspec.erb +15 -14
  35. data/templates/gem/Gemfile.erb +2 -0
  36. data/templates/gem/Gemfile.local.erb +2 -0
  37. data/templates/gem/README.md.erb +1 -2
  38. data/templates/gem/Rakefile.erb +2 -0
  39. data/templates/gem/schema_dev.yml.erb +4 -1
  40. data/templates/gem/simplecov.erb +20 -0
  41. metadata +38 -87
  42. data/.travis.yml +0 -4
  43. data/lib/schema_dev/tasks/coveralls.rb +0 -3
  44. data/lib/schema_dev/travis.rb +0 -147
  45. data/spec/config_spec.rb +0 -61
  46. data/spec/gem_spec.rb +0 -77
  47. data/spec/gemfile_sepector_spec.rb +0 -10
  48. data/spec/gemfiles_spec.rb +0 -41
  49. data/spec/runner_spec.rb +0 -106
  50. data/spec/travis_spec.rb +0 -392
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 99c1eb52097dcc5ab07c40814a339372afa03befae4bf7f860d75430502e3113
4
- data.tar.gz: d3056885b53f23f883c353fc636e6b86738dae442c52e0173926452f209bd123
3
+ metadata.gz: ec4c4b34d4c065f5027f7b4edf76af56b328d10194ba6e4b6ec13d6b0ffdc4bf
4
+ data.tar.gz: dc39ed695a1fa9df914cbaa0aa4163d4bade79237e80ab306238bee5605755d2
5
5
  SHA512:
6
- metadata.gz: 40dd3fd4f9ee9d4158a772fc975feacc8ed33e1ac5c17e95941caf119324ad56d15904c9b73f2b319d2285f37c241359e7ce20ceec94871211e0b4b99ee89a48
7
- data.tar.gz: af74302691415367f08a95dc8ca08c24702195bb065fc0d647e03aa986bb7dd4941f1696973cafd9bb79baf0b4a7291881629bb92e11bcdcefe3f2e9c1a019f8
6
+ metadata.gz: af15e3126328563021a8662d2a0c9180f6978a6095de9471ac2627bfbb0cf64ba47773f48f3c3c4fe21f1871511b0c249c83a9f87801651b1fef7fd367647bf3
7
+ data.tar.gz: 4f2d82816b77a658f41d5afb34f8f9f4401a58a739f1b1fc05ddc1a3b5d8ef304613363f30a2d3ed14da17cf15fb991d5febf5bb5c3ae4b0ad28cc568977058c
@@ -0,0 +1,49 @@
1
+ name: CI PR Builds
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request:
8
+
9
+ concurrency:
10
+ group: ${{ github.head_ref }}
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ test:
15
+ runs-on: ubuntu-latest
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ ruby-version: ['2.5', '2.6', '2.7', '3.0']
20
+ steps:
21
+ - uses: actions/checkout@v2
22
+
23
+ - name: Set up Ruby
24
+ uses: ruby/setup-ruby@v1
25
+ with:
26
+ ruby-version: ${{ matrix.ruby-version }}
27
+ bundler-cache: true
28
+
29
+ - name: 'Run bundle update'
30
+ run: bundle update
31
+
32
+ - name: Run tests
33
+ run: bundle exec rake spec
34
+
35
+ - name: Coveralls Parallel
36
+ uses: coverallsapp/github-action@master
37
+ with:
38
+ github-token: ${{ secrets.GITHUB_TOKEN }}
39
+ flag-name: run-${{ matrix.ruby-version }}
40
+ parallel: true
41
+ finish:
42
+ needs: 'test'
43
+ runs-on: ubuntu-latest
44
+ steps:
45
+ - name: Coveralls Finished
46
+ uses: coverallsapp/github-action@master
47
+ with:
48
+ github-token: ${{ secrets.GITHUB_TOKEN }}
49
+ parallel-finished: true
data/.simplecov ADDED
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ SimpleCov.configure do
4
+ enable_coverage :branch
5
+ add_filter '/spec/'
6
+
7
+ add_group 'Binaries', '/bin/'
8
+ add_group 'Libraries', '/lib/'
9
+
10
+ if ENV['CI']
11
+ require 'simplecov-lcov'
12
+
13
+ SimpleCov::Formatter::LcovFormatter.config do |c|
14
+ c.report_with_single_file = true
15
+ c.single_report_path = 'coverage/lcov.info'
16
+ end
17
+
18
+ formatter SimpleCov::Formatter::LcovFormatter
19
+ end
20
+ end
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in schema_dev.gemspec
data/README.md CHANGED
@@ -1,13 +1,12 @@
1
1
  # SchemaDev
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/schema_dev.svg)](http://badge.fury.io/rb/schema_dev)
4
- [![Build Status](https://secure.travis-ci.org/SchemaPlus/schema_dev.svg)](http://travis-ci.org/SchemaPlus/schema_dev)
4
+ [![Build Status](https://github.com/SchemaPlus/schema_dev/actions/workflows/prs.yml/badge.svg)](https://github.com/SchemaPlus/schema_dev/actions)
5
5
  [![Coverage Status](https://img.shields.io/coveralls/SchemaPlus/schema_dev.svg)](https://coveralls.io/r/SchemaPlus/schema_dev)
6
- [![Dependency Status](https://gemnasium.com/SchemaPlus/schema_dev.svg)](https://gemnasium.com/SchemaPlus/schema_dev)
7
6
 
8
7
  Development tools for the SchemaPlus family of gems.
9
8
 
10
- Provides support for working with multiple ruby versions, ActiveRecord, 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.
9
+ Provides support for working with multiple ruby versions, ActiveRecord, 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 `.github/workflows/prs.yml` file for [github actions](https://docs.github.com/en/actions) testing.
11
10
 
12
11
  ## Creating a new gem for the SchemaPlus family
13
12
 
@@ -99,9 +98,9 @@ Note that freshening the gemfiles happens automatically whenever you run a schem
99
98
 
100
99
  If you need to include extra specifications in the Gemfile (e.g. to specify a path for a gem), you can create a file `Gemfile.local` in the project root, and its contents will be included in the Gemfile.
101
100
 
102
- ### .travis.yml
101
+ ### .github/workflows/prs.yml
103
102
 
104
- The `.travis.yml` file gets created automatically. Don't edit it by hand.
103
+ The `.github/workflows/prs.yml` file gets created automatically. Don't edit it by hand.
105
104
 
106
105
  ### README.md
107
106
 
@@ -131,12 +130,13 @@ The client gem's `Rakefile` includes:
131
130
 
132
131
  require 'schema_dev/tasks'
133
132
 
134
- Which defines the rake task `create_databases` and also a task for travis-ci
133
+ Which defines the rake task `create_databases` and also a task for github actions
135
134
 
136
- ## Relase Notes
135
+ ## Release Notes
137
136
 
138
137
  Release notes for schema_dev versions:
139
138
 
139
+ * **4.1.0** - Switch to GitHub actions instead of travis CI
140
140
  * **4.0.0** - Drop support for AR < 5.2 and add AR 6.0 and 6.1
141
141
  * **3.13.1** - Adjust travis.yml generation to work with mysql again
142
142
  * **3.13.0** - Change coveralls gem and test against newer ruby versions
data/Rakefile CHANGED
@@ -1,8 +1,6 @@
1
- require "bundler/gem_tasks"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
2
4
 
3
5
  require 'rspec/core/rake_task'
4
6
  RSpec::Core::RakeTask.new(:spec)
5
-
6
- require 'coveralls/rake/task'
7
- Coveralls::RakeTask.new
8
- task :travis => [:spec, 'coveralls:push']
data/bin/schema_dev CHANGED
@@ -1,66 +1,70 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'active_support/core_ext/hash'
4
5
  require 'thor'
6
+ require 'English'
5
7
  require_relative '../lib/schema_dev/config'
6
8
  require_relative '../lib/schema_dev/gem'
7
9
  require_relative '../lib/schema_dev/runner'
8
10
  require_relative '../lib/schema_dev/version'
9
11
 
10
12
  def runner
11
- $config ||= SchemaDev::Config.load
12
- $runner ||= SchemaDev::Runner.new($config)
13
+ config = SchemaDev::Config.load rescue nil
14
+ @runner ||= SchemaDev::Runner.new(config)
13
15
  end
14
16
 
15
- $cmd = File.basename $0
17
+ def cmd
18
+ @cmd ||= File.basename $PROGRAM_NAME
19
+ end
16
20
 
17
21
  class CLI < Thor
18
-
19
22
  def self.matrix_options
20
- method_option :dry_run, aliases: "-n", type: :boolean, desc: "Show what the commands would be without running them"
21
- method_option :quick, type: :boolean, desc: "Only execute on the 'quick' choice: #{$config ? $config.quick.inspect : "[from schema_dev.yml]"}"
22
- method_option :ruby, type: :string, desc: "Only execute for the specified version of ruby"
23
- method_option :activerecord, aliases: "--ar", type: :string, desc: "Only execute for the specified version of activerecord"
24
- method_option :db, type: :string, desc: "Only execute for the specified database"
23
+ method_option :dry_run, aliases: '-n', type: :boolean, desc: 'Show what the commands would be without running them'
24
+ method_option :quick, type: :boolean, desc: "Only execute on the 'quick' choice: #{runner.config ? runner.config.quick.inspect : '[from schema_dev.yml]'}"
25
+ method_option :ruby, type: :string, desc: 'Only execute for the specified version of ruby'
26
+ method_option :activerecord, aliases: '--ar', type: :string, desc: 'Only execute for the specified version of activerecord'
27
+ method_option :db, type: :string, desc: 'Only execute for the specified database'
25
28
  end
26
29
 
27
- desc "freshen", "update files that depend on schema_dev.yml: .travis, gemfiles/, README.md"
30
+ desc 'freshen', 'update files that depend on schema_dev.yml: .github/worksflows/prs.yml, gemfiles/, README.md'
28
31
  def freshen
29
- runner.freshen
32
+ runner.freshen
30
33
  end
31
34
 
32
- desc "matrix", "run a command over the matrix"
35
+ desc 'matrix', 'run a command over the matrix'
33
36
  matrix_options
34
37
  def matrix(*args)
35
38
  runner.run(args, **options.to_h.symbolize_keys)
36
39
  end
37
40
 
38
- desc "bundle", "shorthand for '#{$cmd} matrix bundle ...'"
41
+ desc 'bundle', "shorthand for '#{cmd} matrix bundle ...'"
39
42
  matrix_options
40
43
  def bundle(*args)
41
44
  runner.run('bundle', args, **options.to_h.symbolize_keys)
42
45
  end
43
46
 
44
- desc "rake", "shorthand for '#{$cmd} matrix bundle exec rake ...'"
47
+ desc 'rake', "shorthand for '#{cmd} matrix bundle exec rake ...'"
45
48
  matrix_options
46
49
  def rake(*args)
47
50
  runner.run('bundle', 'exec', 'rake', args, **options.to_h.symbolize_keys)
48
51
  end
49
52
 
50
- desc "rspec", "shorthand for '#{$cmd} bundle exec rspec ...'"
53
+ desc 'rspec', "shorthand for '#{cmd} bundle exec rspec ...'"
51
54
  matrix_options
52
55
  def rspec(*args)
53
56
  runner.run('bundle', 'exec', 'rspec', args, **options.to_h.symbolize_keys)
54
57
  end
55
58
 
56
- desc "gem", "create a new SchemaPlus gem"
59
+ desc 'gem', 'create a new SchemaPlus gem'
57
60
  def gem(name)
58
- SchemaDev::Gem.build(name)
61
+ SchemaDev::Gem.build(name)
59
62
  end
60
-
61
63
  end
62
64
 
63
- case
64
- when ARGV[0] == "--version" then puts "SchemaDev #{SchemaDev::VERSION}"
65
- else CLI.start(ARGV)
65
+ case ARGV[0]
66
+ when '--version'
67
+ puts "SchemaDev #{SchemaDev::VERSION}"
68
+ else
69
+ CLI.start(ARGV)
66
70
  end
@@ -1,94 +1,112 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/core_ext/hash'
2
- require 'enumerator'
3
- require 'fastandand'
4
- require 'its-it'
5
- require 'key_struct'
6
4
  require 'pathname'
7
5
  require 'yaml'
8
- require 'hash_keyword_args'
6
+ require 'rubygems/version'
9
7
 
10
8
  module SchemaDev
11
- CONFIG_FILE = "schema_dev.yml"
9
+ CONFIG_FILE = 'schema_dev.yml'
12
10
 
13
11
  class Config
12
+ attr_accessor :quick, :db, :dbversions, :ruby, :activerecord, :exclude
14
13
 
15
- attr_accessor :quick, :db, :dbversions, :ruby, :activerecord, :notify, :exclude
16
-
17
- def self._reset ; @@config = nil end # for use by rspec
14
+ # for use by rspec
15
+ def self._reset
16
+ @load = nil
17
+ end
18
18
 
19
19
  def self.read
20
- new((YAML.load Pathname.new(CONFIG_FILE).read).symbolize_keys)
20
+ new(**YAML.safe_load(Pathname.new(CONFIG_FILE).read, [Symbol]).symbolize_keys)
21
21
  end
22
22
 
23
23
  def self.load
24
- @@config ||= read
24
+ @load ||= read
25
25
  end
26
26
 
27
- def initialize(opts={}) # once we no longer support ruby 1.9.3, can switch to native keyword args
28
- opts = opts.keyword_args(ruby: :required, activerecord: :required, db: :required, dbversions: nil, exclude: nil, notify: nil, quick: nil)
29
- @ruby = Array.wrap(opts.ruby)
30
- @activerecord = Array.wrap(opts.activerecord)
31
- @db = Array.wrap(opts.db)
32
- @dbversions = (opts.dbversions || {}).symbolize_keys
33
- @exclude = Array.wrap(opts.exclude).map(&:symbolize_keys).map {|tuple| Tuple.new(tuple)}
34
- @notify = Array.wrap(opts.notify)
35
- @quick = Array.wrap(opts.quick || {ruby: @ruby.last, activerecord: @activerecord.last, db: @db.last})
27
+ def initialize(ruby:, activerecord:, db:, dbversions: nil, exclude: nil, notify: nil, quick: nil)
28
+ @ruby = Array.wrap(ruby).map(&:to_s)
29
+ @activerecord = Array.wrap(activerecord).map(&:to_s)
30
+ @db = Array.wrap(db)
31
+ @dbversions = (dbversions || {}).symbolize_keys
32
+ @exclude = Array.wrap(exclude).map(&:symbolize_keys).map { |tuple| Tuple.new(**tuple.transform_values(&:to_s)) }
33
+ if @activerecord.include?('5.2')
34
+ ruby3 = ::Gem::Version.new('3.0')
35
+
36
+ @ruby.select { |e| ::Gem::Version.new(e) >= ruby3 }.each do |v|
37
+ @exclude << Tuple.new(ruby: v, activerecord: '5.2')
38
+ end
39
+ end
40
+ unless notify.nil?
41
+ warn 'Notify is no longer supported'
42
+ end
43
+ @quick = Array.wrap(quick || { ruby: @ruby.last, activerecord: @activerecord.last, db: @db.last })
36
44
  end
37
45
 
38
46
  def dbms
39
- @dbms ||= [:postgresql, :mysql].select{|dbm| @db.grep(/^#{dbm}/).any?}
47
+ @dbms ||= %i[postgresql mysql].select { |dbm| @db.grep(/^#{dbm}/).any? }
40
48
  end
41
49
 
42
- def dbms_versions_for(db, default = [])
43
- @dbversions.fetch(db, default)
50
+ DB_VERSION_DEFAULTS = {
51
+ postgresql: ['9.6']
52
+ }.freeze
53
+
54
+ def db_versions_for(db)
55
+ @dbversions.fetch(db.to_sym, DB_VERSION_DEFAULTS.fetch(db.to_sym, [])).map(&:to_s)
44
56
  end
45
57
 
46
- def matrix(opts={}) # once we no longer support ruby 1.9.3, can switch to native keyword args
47
- opts = opts.keyword_args(quick: false, ruby: nil, activerecord: nil, db: nil, excluded: nil)
58
+ def matrix(quick: false, ruby: nil, activerecord: nil, db: nil, excluded: nil, with_dbversion: false)
48
59
  use_ruby = @ruby
49
60
  use_activerecord = @activerecord
50
61
  use_db = @db
51
- if opts.quick
52
- use_ruby = @quick.map{|q| q[:ruby]}
53
- use_activerecord = @quick.map{|q| q[:activerecord]}
54
- use_db = @quick.map{|q| q[:db]}
62
+ if quick
63
+ use_ruby = @quick.map { |q| q[:ruby] }
64
+ use_activerecord = @quick.map { |q| q[:activerecord] }
65
+ use_db = @quick.map { |q| q[:db] }
55
66
  end
56
- use_ruby = Array.wrap(opts.ruby) if opts.ruby
57
- use_activerecord = Array.wrap(opts.activerecord) if opts.activerecord
58
- use_db = Array.wrap(opts.db) if opts.db
67
+ use_ruby = Array.wrap(ruby) if ruby
68
+ use_activerecord = Array.wrap(activerecord) if activerecord
69
+ use_db = Array.wrap(db) if db
59
70
 
60
71
  use_ruby = [nil] unless use_ruby.any?
61
72
  use_activerecord = [nil] unless use_activerecord.any?
62
73
  use_db = [nil] unless use_db.any?
63
74
 
64
75
  m = use_ruby.product(use_activerecord, use_db)
65
- m = m.map { |_ruby, _activerecord, _db| Tuple.new(ruby: _ruby, activerecord: _activerecord, db: _db) }.compact
66
- m = m.reject(&it.match_any?(@exclude)) unless opts.excluded == :none
76
+ m = m.flat_map do |loop_ruby, loop_activerecord, loop_db|
77
+ if with_dbversion && !(dbversions = db_versions_for(loop_db)).empty?
78
+ dbversions.map { |v| Tuple.new(ruby: loop_ruby, activerecord: loop_activerecord, db: loop_db, dbversion: v) }
79
+ else
80
+ [Tuple.new(ruby: loop_ruby, activerecord: loop_activerecord, db: loop_db)]
81
+ end
82
+ end.compact
83
+ m = m.reject { |r| r.match_any?(@exclude) } unless excluded == :none
67
84
  m = m.map(&:to_hash)
68
85
 
69
- if opts.excluded == :only
70
- return matrix(opts.merge(excluded: :none)) - m
86
+ if excluded == :only
87
+ matrix(quick: quick, ruby: ruby, activerecord: activerecord, db: db, with_dbversion: with_dbversion, excluded: :none) - m
71
88
  else
72
- return m
89
+ m
73
90
  end
74
91
  end
75
92
 
76
- class Tuple < KeyStruct[:ruby, :activerecord, :db]
93
+ Tuple = Struct.new(:ruby, :activerecord, :db, :dbversion, keyword_init: true) do
77
94
  def match?(other)
78
- return false if self.ruby and other.ruby and self.ruby != other.ruby
79
- return false if self.activerecord and other.activerecord and self.activerecord != other.activerecord
80
- return false if self.db and other.db and self.db != other.db
95
+ return false if ruby and other.ruby and ruby != other.ruby
96
+ return false if activerecord and other.activerecord and activerecord != other.activerecord
97
+ return false if db and other.db and db != other.db
98
+ return false if dbversion and other.dbversion and dbversion != other.dbversion
99
+
81
100
  true
82
101
  end
83
102
 
84
103
  def match_any?(others)
85
- others.any?{|other| self.match? other}
104
+ others.any? { |other| match? other }
86
105
  end
87
106
 
88
107
  def to_hash
89
- super.reject{ |k, val| val.nil? }
108
+ to_h.compact.transform_values(&:to_s)
90
109
  end
91
110
  end
92
-
93
111
  end
94
112
  end
@@ -1,12 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'open3'
3
5
 
4
- require_relative "ruby_selector"
5
- require_relative "gemfile_selector"
6
+ require_relative 'ruby_selector'
7
+ require_relative 'gemfile_selector'
6
8
 
7
9
  module SchemaDev
8
10
  class Executor
9
-
10
11
  attr_reader :ruby, :activerecord, :db, :error
11
12
 
12
13
  def initialize(ruby:, activerecord:, db:)
@@ -15,20 +16,20 @@ module SchemaDev
15
16
  end
16
17
 
17
18
  def run(cmd, dry_run: false)
18
- fullcommand = ["/usr/bin/env", @gemfile_selector, @ruby_selector, cmd].compact.join(' ')
19
+ fullcommand = ['/usr/bin/env', @gemfile_selector, @ruby_selector, cmd].compact.join(' ')
19
20
  puts "* #{fullcommand}"
20
21
  return true if dry_run
21
22
 
22
23
  @error = false
23
- Open3.popen2e(fullcommand) do |i, oe, t|
24
- oe.each {|line|
24
+ Open3.popen2e(fullcommand) do |_i, oe, t|
25
+ oe.each do |line|
25
26
  puts line
26
27
  @error ||= (line =~ /(^Failed examples)|(rake aborted)|(LoadError)/)
27
- }
28
+ end
28
29
  @error ||= !t.value.success?
29
30
  end
30
31
 
31
- return !@error
32
+ !@error
32
33
  end
33
34
  end
34
35
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'faraday'
2
4
  require 'json'
3
5
  require 'fileutils'
@@ -15,7 +17,7 @@ module SchemaDev
15
17
 
16
18
  attr_accessor :gem_name, :gem_module, :gem_root, :gem_parent_name, :gem_base_name, :gem_lib_path, :fullname, :email
17
19
 
18
- class TemplateEnv
20
+ class TemplateEnv
19
21
  extend Forwardable
20
22
 
21
23
  def_delegators :@gem, :gem_name, :gem_module, :gem_root, :gem_parent_name, :gem_base_name, :gem_lib_path, :fullname, :email
@@ -33,27 +35,28 @@ module SchemaDev
33
35
  end
34
36
 
35
37
  def year
36
- Time.now.strftime("%Y")
38
+ Time.now.strftime('%Y')
37
39
  end
38
40
 
39
41
  def get_binding
40
42
  binding
41
43
  end
42
-
44
+
43
45
  def self.schema_plus_core_version
44
- @core_version ||= begin
45
- gems = JSON.parse Faraday.get('https://rubygems.org/api/v1/versions/schema_plus_core.json').body
46
- gems.reject(&it["prerelease"]).sort_by(&it["number"].split('.')).last["number"]
47
- end
46
+ @schema_plus_core_version ||=
47
+ begin
48
+ gems = JSON.parse Faraday.get('https://rubygems.org/api/v1/versions/schema_plus_core.json').body
49
+ last = gems.reject { |e| e['prerelease'] }.max_by { |e| e['number'].split('.') }
50
+ last['number']
51
+ end
48
52
  end
49
53
 
50
- def _dependency(v)
51
- major, minor, patch = v.split('.')
52
- dep = %Q{"~> #{major}.#{minor}"}
53
- dep += %Q{, ">= #{v}"} if patch != "0"
54
+ def _dependency(version)
55
+ major, minor, patch = version.split('.')
56
+ dep = %('~> #{major}.#{minor}')
57
+ dep += %(, '>= #{version}') if patch != '0'
54
58
  dep
55
59
  end
56
-
57
60
  end
58
61
 
59
62
  def initialize(name)
@@ -79,20 +82,20 @@ module SchemaDev
79
82
  ensure_not_in_git
80
83
  ensure_doesnt_exist
81
84
  copy_template
82
- self.gem_root = self.gem_root.realpath
85
+ self.gem_root = gem_root.realpath
83
86
  rename_files
84
87
  fixup_subdir if @subdir
85
88
  freshen
86
89
  git_init
87
- puts <<-END.strip_heredoc
90
+ puts <<~TEXT
88
91
 
89
- Created #{gem_name}. Your recommended next steps are:
92
+ Created #{gem_name}. Your recommended next steps are:
90
93
 
91
- $ cd #{gem_name}
92
- $ bundle install
93
- $ schema_dev bundle install
94
- $ schema_dev rspec
95
- END
94
+ $ cd #{gem_name}
95
+ $ bundle install
96
+ $ schema_dev bundle install
97
+ $ schema_dev rspec
98
+ TEXT
96
99
  end
97
100
 
98
101
  def die(msg)
@@ -100,8 +103,8 @@ module SchemaDev
100
103
  end
101
104
 
102
105
  def ensure_not_in_git
103
- if system("git rev-parse >& /dev/null")
104
- die "Cannot create new gem inside existing git worktree; please cd elsewhere"
106
+ if system('git rev-parse >& /dev/null')
107
+ die 'Cannot create new gem inside existing git worktree; please cd elsewhere'
105
108
  end
106
109
  end
107
110
 
@@ -112,42 +115,43 @@ module SchemaDev
112
115
  end
113
116
 
114
117
  def get_fullname_and_email
115
- {'fullname' => 'name', 'email' => 'email' }.each do |myattr, gitattr|
116
- if (self.send myattr+"=", `git config user.#{gitattr}`.strip).blank?
118
+ { 'fullname' => 'name', 'email' => 'email' }.each do |myattr, gitattr|
119
+ if (send myattr + '=', `git config user.#{gitattr}`.strip).blank?
117
120
  die "Who are you? Please run 'git config --global user.#{gitattr} <your-#{gitattr}>'"
118
121
  end
119
122
  end
120
123
  end
121
124
 
122
125
  def copy_template
123
- Templates.install_subtree src: "gem", dst: gem_root, bound: template_binding
126
+ Templates.install_subtree src: 'gem', dst: gem_root, bound: template_binding
124
127
  end
125
128
 
126
129
  def rename_files
127
- (gem_root + "gitignore").rename gem_root + ".gitignore"
128
- Dir.glob(gem_root + "**/*GEM_NAME*").each do |path|
130
+ (gem_root + 'gitignore').rename gem_root + '.gitignore'
131
+ (gem_root + 'simplecov').rename gem_root + '.simplecov'
132
+ Dir.glob(gem_root + '**/*GEM_NAME*').each do |path|
129
133
  FileUtils.mv path, path.gsub(/GEM_NAME/, gem_name)
130
134
  end
131
- Dir.glob(gem_root + "**/*GEM_BASE_NAME*").each do |path|
135
+ Dir.glob(gem_root + '**/*GEM_BASE_NAME*').each do |path|
132
136
  FileUtils.mv path, path.gsub(/GEM_BASE_NAME/, gem_base_name)
133
137
  end
134
138
  end
135
139
 
136
140
  def fixup_subdir
137
- libdir = gem_root + "lib"
138
- aside = libdir.to_s + "x"
141
+ libdir = gem_root + 'lib'
142
+ aside = libdir.to_s + 'x'
139
143
  subdir = libdir + gem_parent_name
140
144
 
141
145
  FileUtils.mv libdir, aside
142
146
  libdir.mkpath
143
147
  FileUtils.mv aside, subdir
144
- (gem_root + "lib" + "#{gem_name}.rb").write <<-END.lstrip
148
+ (gem_root + 'lib' + "#{gem_name}.rb").write <<~RUBY
145
149
  require_relative '#{gem_parent_name}/#{gem_base_name}'
146
- END
150
+ RUBY
147
151
  end
148
152
 
149
- def erb(s)
150
- ERB.new(s).result template_binding
153
+ def erb(string)
154
+ ERB.new(string).result template_binding
151
155
  end
152
156
 
153
157
  def template_binding
@@ -156,14 +160,18 @@ module SchemaDev
156
160
 
157
161
  def freshen
158
162
  Dir.chdir gem_root do
159
- Runner.new(Config.read).freshen(quiet:true)
163
+ Runner.new(Config.read).freshen(quiet: true)
160
164
  end
161
165
  end
162
166
 
163
167
  def git_init
164
168
  Dir.chdir gem_name do
165
- system "git init"
166
- system "git add #{gem_root.find.select(&:exist?).reject(&it.basename.to_s == 'Gemfile.local').join(' ')}"
169
+ system 'git init'
170
+ add_param = gem_root.find
171
+ .select(&:exist?)
172
+ .reject { |e| e.basename.to_s == 'Gemfile.local' }
173
+ .join(' ')
174
+ system "git add #{add_param}"
167
175
  system "git commit -m 'Initial skeleton generated by `schema_dev gem #{gem_name}`'"
168
176
  end
169
177
  end
@@ -1,19 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pathname'
2
4
 
3
5
  module SchemaDev
4
- GEMFILES_DIR = "gemfiles"
6
+ GEMFILES_DIR = 'gemfiles'
5
7
 
6
8
  module GemfileSelector
7
9
  extend self
8
10
 
9
- def gemfile(opts = {})
10
- opts = opts.keyword_args(activerecord: :required, db: :required)
11
- Pathname.new(GEMFILES_DIR).join("activerecord-#{opts.activerecord}", "Gemfile.#{opts.db}")
11
+ def gemfile(activerecord:, db:)
12
+ Pathname.new(GEMFILES_DIR).join("activerecord-#{activerecord}", "Gemfile.#{db}")
12
13
  end
13
14
 
14
- def command(opts={})
15
- opts = opts.keyword_args(activerecord: :required, db: :required)
16
- "BUNDLE_GEMFILE=#{gemfile(activerecord: opts.activerecord, db: opts.db)}"
15
+ def command(activerecord:, db:)
16
+ "BUNDLE_GEMFILE=#{gemfile(activerecord: activerecord, db: db)}"
17
17
  end
18
18
 
19
19
  def infer_db