declare_schema 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +37 -0
  3. data/CHANGELOG.md +28 -4
  4. data/Gemfile +0 -2
  5. data/Gemfile.lock +1 -4
  6. data/README.md +59 -2
  7. data/Rakefile +13 -20
  8. data/gemfiles/rails_4.gemfile +4 -7
  9. data/gemfiles/rails_5.gemfile +4 -7
  10. data/gemfiles/rails_6.gemfile +4 -7
  11. data/lib/declare_schema/model.rb +0 -1
  12. data/lib/declare_schema/model/field_spec.rb +4 -14
  13. data/lib/declare_schema/version.rb +1 -1
  14. data/lib/generators/declare_schema/migration/migration_generator.rb +20 -13
  15. data/lib/generators/declare_schema/migration/migrator.rb +58 -38
  16. data/lib/generators/declare_schema/migration/templates/migration.rb.erb +1 -1
  17. data/lib/generators/declare_schema/support/eval_template.rb +12 -3
  18. data/lib/generators/declare_schema/support/model.rb +77 -2
  19. data/spec/lib/declare_schema/api_spec.rb +125 -0
  20. data/spec/lib/declare_schema/field_declaration_dsl_spec.rb +8 -4
  21. data/spec/lib/declare_schema/generator_spec.rb +57 -0
  22. data/spec/lib/declare_schema/interactive_primary_key_spec.rb +51 -0
  23. data/spec/lib/declare_schema/migration_generator_spec.rb +686 -0
  24. data/spec/lib/declare_schema/prepare_testapp.rb +29 -0
  25. data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +42 -0
  26. data/spec/spec_helper.rb +26 -0
  27. metadata +9 -12
  28. data/.jenkins/Jenkinsfile +0 -72
  29. data/.jenkins/ruby_build_pod.yml +0 -19
  30. data/lib/generators/declare_schema/model/templates/model_injection.rb.erb +0 -25
  31. data/test/api.rdoctest +0 -136
  32. data/test/doc-only.rdoctest +0 -76
  33. data/test/generators.rdoctest +0 -60
  34. data/test/interactive_primary_key.rdoctest +0 -56
  35. data/test/migration_generator.rdoctest +0 -846
  36. data/test/migration_generator_comments.rdoctestDISABLED +0 -74
  37. data/test/prepare_testapp.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5cf5ebc856041d2f6a90e4a6f30a56e5a538545f79b227cd2ca691eb99dcf9a8
4
- data.tar.gz: 3d2b3efe4d0647f8c94052e2e8a22433a021503f458203e9f0f73d131d7c6225
3
+ metadata.gz: 3f3116a6fbb5a47de5809f3f813c88783284bad601452679fa59784f3598834b
4
+ data.tar.gz: 8f4b6fee7b4d17e5b644f32a4b624a3f77526f91826a8c0b82d61b6e25130332
5
5
  SHA512:
6
- metadata.gz: 4771090d9ef1dbe0267eddfa4ac7d2fc25dd37a9c75a8e76bdb27ea9a072aac894671dc8115387eb9489855f6849ff7cf4c1f2f4e82eb36039824fd83328f2f3
7
- data.tar.gz: 7fc9feb7d02f2b71f11ec4c21f3624c3dc503df64c443f304b1d19f75d6a81102a86d0b27be3c32749a191f966440a88c54c86db260123cd2e6457bdacd474cf
6
+ metadata.gz: b833000d28d64e7856de05c9ae822c88dcceeb7861f777f13177ea8017e56bf937aba42b9da14ae1ce4810fd275c5462cb08c18c32839255ab46f1de116eee1d
7
+ data.tar.gz: c41c8cbdafd96eeb92fcf5c646ff9d18f4ce2374f06ecc6977015fa8406bc4639ab3722354212d1a75274c5af982f10b6c2f4c838de94f4b9436da20f836d5d3
@@ -0,0 +1,37 @@
1
+ ---
2
+ dist: trusty
3
+ os: linux
4
+ language: ruby
5
+ cache: bundler
6
+ rvm:
7
+ - 2.4.5
8
+ - 2.5.8
9
+ - 2.6.5
10
+ - 2.7.1
11
+ - ruby-head
12
+ gemfile:
13
+ - gemfiles/rails_4.gemfile
14
+ - gemfiles/rails_5.gemfile
15
+ - gemfiles/rails_6.gemfile
16
+ jobs:
17
+ fast_finish: false
18
+ exclude:
19
+ - gemfile: gemfiles/rails_4.gemfile
20
+ rvm: 2.7.1
21
+ - gemfile: gemfiles/rails_5.gemfile
22
+ rvm: 2.4.5
23
+ - gemfile: gemfiles/rails_6.gemfile
24
+ rvm: 2.4.5
25
+ allow_failures:
26
+ - rvm: ruby-head
27
+ before_install:
28
+ - rm -f /home/travis/.rvm/rubies/ruby-2.*/lib/ruby/gems/2.*/specifications/default/bundler-2.*.gemspec
29
+ - echo y | rvm @global do gem install bundler -v 1.17.3 --force --default
30
+ - gem install bundler -v 1.17.3 --force --default
31
+ - gem install bundler -v 1.17.3
32
+ install:
33
+ - bundle --version
34
+ - bundle install --jobs=3 --retry=3 --path=${BUNDLE_PATH:-vendor/bundle}
35
+ script:
36
+ - bundle exec rake test:prepare_testapp[force]
37
+ - bundle exec rake test:all < test_responses.txt
@@ -1,11 +1,35 @@
1
- # CHANGELOG for `declarative_schema`
1
+ # CHANGELOG for `declare_schema`
2
2
 
3
3
  Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
4
4
 
5
5
  Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
- ## [0.1.0] - Unreleased
7
+ ## [0.2.0] - 2020-10-26
8
8
  ### Added
9
- - Initial version from https://github.com/Invoca/declare_schema v4.0.0.
9
+ - Automatically eager_load! all Rails::Engines before generating migrations.
10
10
 
11
- [0.1.0]: https://github.com/Invoca/declarative_schema/tree/v0.1.0
11
+ ### Changed
12
+ - Changed tests from rdoctest to rspec.
13
+
14
+ ### Fixed
15
+ - Fixed a bug where `:text limit: 0xffff_ffff` (max size) was omitted from migrations.
16
+ - Fixed a bug where `:bigint` foreign keys were omitted from the migration.
17
+
18
+ ## [0.1.3] - 2020-10-08
19
+ ### Changed
20
+ - Updated the `always_ignore_tables` list in `Migrator` to access Rails metadata table names
21
+ using the appropriate Rails configuration attributes.
22
+
23
+ ## [0.1.2] - 2020-09-29
24
+ ### Changed
25
+ - Added travis support and created 2 specs as a starting point.
26
+
27
+
28
+ ## [0.1.1] - 2020-09-24
29
+ ### Added
30
+ - Initial version from https://github.com/Invoca/hobo_fields v4.1.0.
31
+
32
+ [0.2.0]: https://github.com/Invoca/declare_schema/compare/v0.1.3...v0.2.0
33
+ [0.1.3]: https://github.com/Invoca/declare_schema/compare/v0.1.2...v0.1.3
34
+ [0.1.2]: https://github.com/Invoca/declare_schema/compare/v0.1.1...v0.1.2
35
+ [0.1.1]: https://github.com/Invoca/declare_schema/tree/v0.1.1
data/Gemfile CHANGED
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  source 'https://rubygems.org'
4
- source 'https://gem.fury.io/invoca'
5
4
 
6
5
  gemspec
7
6
 
@@ -19,6 +18,5 @@ gem 'rails', '~> 5.2', '>= 5.2.4.3'
19
18
  gem 'responders'
20
19
  gem 'rspec'
21
20
  gem 'rubocop'
22
- gem 'rubydoctest'
23
21
  gem 'sqlite3'
24
22
  gem 'yard'
@@ -1,12 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- declare_schema (0.1.0)
4
+ declare_schema (0.2.0)
5
5
  rails (>= 4.2)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
- remote: https://gem.fury.io/invoca/
10
9
  specs:
11
10
  actioncable (5.2.4.4)
12
11
  actionpack (= 5.2.4.4)
@@ -160,7 +159,6 @@ GEM
160
159
  rubocop-ast (0.4.2)
161
160
  parser (>= 2.7.1.4)
162
161
  ruby-progressbar (1.10.1)
163
- rubydoctest (1.1.5)
164
162
  sprockets (4.0.2)
165
163
  concurrent-ruby (~> 1.0)
166
164
  rack (> 1, < 3)
@@ -195,7 +193,6 @@ DEPENDENCIES
195
193
  responders
196
194
  rspec
197
195
  rubocop
198
- rubydoctest
199
196
  sqlite3
200
197
  yard
201
198
 
data/README.md CHANGED
@@ -1,11 +1,68 @@
1
1
  # DeclareSchema
2
2
 
3
- Declare your active_record model schemas and have database migrations generated for you!
3
+ Declare your Rails/active_record model schemas and have database migrations generated for you!
4
4
 
5
+ ## Example
6
+
7
+ Make a model and declare your schema within a `fields do ... end` block:
8
+ ```ruby
9
+ class Company < ActiveRecord::Base
10
+ fields do
11
+ company_name :string, limit: 100
12
+ ticker_symbol :string, limit: 4, null: true, index: true, unique: true
13
+ employee_count :integer
14
+ comments :text
15
+
16
+ timestamps
17
+ end
18
+
19
+ belongs_to :industry
20
+ end
21
+ ```
22
+ Then generate the migration:
23
+ ```sh
24
+ $ rails generate declare_schema:migration
25
+
26
+ ---------- Up Migration ----------
27
+ create_table :companies, id: :bigint do |t|
28
+ t.string :company_name, null: false, limit: 100
29
+ t.string :ticker_symbol, limit: 4
30
+ t.integer :employee_count, null: false
31
+ t.text :comments, null: false
32
+ t.datetime :created_at
33
+ t.datetime :updated_at
34
+ t.integer :industry_id, null: false
35
+ end
36
+ add_index :companies, [:ticker_symbol], unique: true, name: 'on_ticker_symbol'
37
+ add_index :companies, [:industry_id], name: 'on_industry_id'
38
+ execute "ALTER TABLE companies ADD CONSTRAINT index_companies_on_industry_id FOREIGN KEY index_companies_on_industry_id(industry_id) REFERENCES industries(id) "
39
+ ----------------------------------
40
+
41
+ ---------- Down Migration --------
42
+ drop_table :companies
43
+ ----------------------------------
44
+
45
+
46
+ What now: [g]enerate migration, generate and [m]igrate now or [c]ancel? g
47
+ => "g"
48
+
49
+ Migration filename: [<enter>=declare_schema_migration_1|<custom_name>]: add_company_model
50
+ ```
51
+ Note that the migration generator is interactive -- it can't tell the difference between renaming something vs. adding one thing and removing another, so sometimes it will ask you to clarify.
52
+
53
+ ## Installing
54
+
55
+ Install the `DeclareSchema` gem directly:
56
+ ```
57
+ $ gem install declare_schema
58
+ ```
59
+ or add it to your `bundler` Gemfile:
60
+ ```
61
+ gem 'declare_schema'
62
+ ```
5
63
  ## Testing
6
64
  To run tests:
7
65
  ```
8
66
  rake test:prepare_testapp[force]
9
67
  rake test:all < test_responses.txt
10
68
  ```
11
- (Note: there currently are no unit tests. The above will run the `rdoctests`.)
data/Rakefile CHANGED
@@ -14,7 +14,6 @@ $LOAD_PATH.unshift File.expand_path('lib', __dir__)
14
14
  require 'declare_schema'
15
15
 
16
16
  RUBY = 'ruby'
17
- RUBYDOCTEST = ENV['RUBYDOCTEST'] || "#{RUBY} -S rubydoctest"
18
17
  GEM_ROOT = __dir__
19
18
  TESTAPP_PATH = ENV['TESTAPP_PATH'] || File.join(Dir.tmpdir, 'declare_schema_testapp')
20
19
  BIN = File.expand_path('bin/declare_schema', __dir__)
@@ -24,13 +23,7 @@ task default: 'test:all'
24
23
  include Rake::DSL
25
24
 
26
25
  namespace "test" do
27
- task all: [:doctest, :spec]
28
-
29
- desc "Run the doctests"
30
- task :doctest do |_t|
31
- files = Dir['test/*.rdoctest'].sort.map { |f| File.expand_path(f) }.join(' ')
32
- system("#{RUBYDOCTEST} #{files}") or exit(1)
33
- end
26
+ task all: :spec
34
27
 
35
28
  desc "Prepare a rails application for testing"
36
29
  task :prepare_testapp, :force do |_t, args|
@@ -38,19 +31,19 @@ namespace "test" do
38
31
  FileUtils.remove_entry_secure(TESTAPP_PATH, true)
39
32
  sh %(#{BIN} new #{TESTAPP_PATH} --skip-wizard --skip-bundle)
40
33
  FileUtils.chdir TESTAPP_PATH
41
- sh %(bundle install)
42
- sh %(echo "" >> Gemfile)
43
- sh %(echo "gem 'irt', :group => :development" >> Gemfile) # to make the bundler happy
44
- sh %(echo "gem 'therubyracer'" >> Gemfile)
45
- sh %(echo "gem 'kramdown'" >> Gemfile)
46
- sh %(echo "" > app/models/.gitignore) # because git reset --hard would rm the dir
47
- rm %(.gitignore) # we need to reset everything in a testapp
48
- sh %(git init && git add . && git commit -m "initial commit")
49
- puts %(The testapp has been created in '#{TESTAPP_PATH}')
34
+ sh "bundle install"
35
+ sh "(echo '';
36
+ echo \"gem 'irt', :group => :development\";
37
+ echo \"gem 'therubyracer'\";
38
+ echo \"gem 'kramdown'\") > Gemfile"
39
+ sh "echo '' > app/models/.gitignore" # because git reset --hard would rm the dir
40
+ rm ".gitignore" # we need to reset everything in a testapp
41
+ sh "git init && git add . && git commit -m \"initial commit\""
42
+ puts "The testapp has been created in '#{TESTAPP_PATH}'"
50
43
  else
51
- FileUtils.chdir TESTAPP_PATH
52
- sh %(git add .)
53
- sh %(git reset --hard -q HEAD)
44
+ FileUtils.chdir(TESTAPP_PATH)
45
+ sh "git add ."
46
+ sh "git reset --hard -q HEAD"
54
47
  end
55
48
  end
56
49
  end
@@ -1,25 +1,22 @@
1
- # frozen_string_literal: true
2
-
3
1
  # This file was generated by Appraisal
4
2
 
5
3
  source "https://rubygems.org"
6
- source "https://gem.fury.io/invoca"
7
4
 
8
5
  gem "appraisal"
6
+ gem "bundler", "< 2"
7
+ gem "climate_control", "~> 0.2"
9
8
  gem "pry"
10
9
  gem "pry-byebug"
11
10
  gem "rails", "~> 4.2"
12
11
  gem "responders"
13
- gem "rubydoctest"
12
+ gem "rspec"
13
+ gem "rubocop"
14
14
  gem "sqlite3", "~> 1.3.0"
15
- gem "test_overrides"
16
15
  gem "yard"
17
16
 
18
17
  group :testapp do
19
18
  gem "bootsnap", ">= 1.1.0", require: false
20
- gem "kramdown"
21
19
  gem "listen"
22
- gem "RedCloth"
23
20
  end
24
21
 
25
22
  gemspec path: "../"
@@ -1,25 +1,22 @@
1
- # frozen_string_literal: true
2
-
3
1
  # This file was generated by Appraisal
4
2
 
5
3
  source "https://rubygems.org"
6
- source "https://gem.fury.io/invoca"
7
4
 
8
5
  gem "appraisal"
6
+ gem "bundler", "< 2"
7
+ gem "climate_control", "~> 0.2"
9
8
  gem "pry"
10
9
  gem "pry-byebug"
11
10
  gem "rails", "~> 5.2"
12
11
  gem "responders"
13
- gem "rubydoctest"
12
+ gem "rspec"
13
+ gem "rubocop"
14
14
  gem "sqlite3"
15
- gem "test_overrides"
16
15
  gem "yard"
17
16
 
18
17
  group :testapp do
19
18
  gem "bootsnap", ">= 1.1.0", require: false
20
- gem "kramdown"
21
19
  gem "listen"
22
- gem "RedCloth"
23
20
  end
24
21
 
25
22
  gemspec path: "../"
@@ -1,25 +1,22 @@
1
- # frozen_string_literal: true
2
-
3
1
  # This file was generated by Appraisal
4
2
 
5
3
  source "https://rubygems.org"
6
- source "https://gem.fury.io/invoca"
7
4
 
8
5
  gem "appraisal"
6
+ gem "bundler", "< 2"
7
+ gem "climate_control", "~> 0.2"
9
8
  gem "pry"
10
9
  gem "pry-byebug"
11
10
  gem "rails", "~> 6.0"
12
11
  gem "responders"
13
- gem "rubydoctest"
12
+ gem "rspec"
13
+ gem "rubocop"
14
14
  gem "sqlite3"
15
- gem "test_overrides"
16
15
  gem "yard"
17
16
 
18
17
  group :testapp do
19
18
  gem "bootsnap", ">= 1.1.0", require: false
20
- gem "kramdown"
21
19
  gem "listen"
22
- gem "RedCloth"
23
20
  end
24
21
 
25
22
  gemspec path: "../"
@@ -117,7 +117,6 @@ module DeclareSchema
117
117
  end
118
118
  column_options = {}
119
119
  column_options[:null] = options.delete(:null) || false
120
- column_options[:comment] = options.delete(:comment) if options.has_key?(:comment)
121
120
  column_options[:default] = options.delete(:default) if options.has_key?(:default)
122
121
  column_options[:limit] = options.delete(:limit) if options.has_key?(:limit)
123
122
 
@@ -41,7 +41,8 @@ module DeclareSchema
41
41
 
42
42
  @model = model
43
43
  @name = name.to_sym
44
- @type = type.is_a?(String) ? type.to_sym : type
44
+ type.is_a?(Symbol) or raise ArgumentError, "type must be a Symbol; got #{type.inspect}"
45
+ @type = type
45
46
  position_option = options.delete(:position)
46
47
  @options = options
47
48
 
@@ -52,7 +53,7 @@ module DeclareSchema
52
53
  @options[:limit] = self.class.round_up_mysql_text_limit(@options[:limit] || MYSQL_LONGTEXT_LIMIT)
53
54
  end
54
55
  when :string
55
- @options[:limit] or raise "limit must be given for :string field #{model}##{@name}: #{@options.inspect}; do you want 255?"
56
+ @options[:limit] or raise "limit must be given for :string field #{model}##{@name}: #{@options.inspect}; do you want `limit: 255`?"
56
57
  end
57
58
  @position = position_option || model.field_specs.length
58
59
  end
@@ -72,7 +73,7 @@ module DeclareSchema
72
73
  type
73
74
  else
74
75
  field_class = DeclareSchema.to_class(type)
75
- field_class && field_class::COLUMN_TYPE or raise UnknownSqlTypeError, "#{type.inspect} for #{model}.#{@name}"
76
+ field_class && field_class::COLUMN_TYPE or raise UnknownSqlTypeError, "#{type.inspect} for #{model}##{@name}"
76
77
  end
77
78
  end
78
79
  end
@@ -101,10 +102,6 @@ module DeclareSchema
101
102
  @options[:default]
102
103
  end
103
104
 
104
- def comment
105
- @options[:comment]
106
- end
107
-
108
105
  def same_type?(col_spec)
109
106
  type = sql_type
110
107
  normalized_type = TYPE_SYNONYMS[type] || type
@@ -114,13 +111,6 @@ module DeclareSchema
114
111
 
115
112
  def different_to?(col_spec)
116
113
  !same_type?(col_spec) ||
117
- # we should be able to use col_spec.comment, but col_spec has
118
- # a nil table_name for some strange reason.
119
- (model.table_exists? &&
120
- ActiveRecord::Base.respond_to?(:column_comment) &&
121
- !(col_comment = ActiveRecord::Base.column_comment(col_spec.name, model.table_name)).nil? &&
122
- col_comment != comment
123
- ) ||
124
114
  begin
125
115
  native_type = native_types[type]
126
116
  check_attributes = [:null, :default]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DeclareSchema
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
@@ -3,6 +3,7 @@
3
3
  require 'rails/generators/migration'
4
4
  require 'rails/generators/active_record'
5
5
  require 'generators/declare_schema/support/thor_shell'
6
+ require 'declare_schema/model/field_spec'
6
7
 
7
8
  module DeclareSchema
8
9
  class MigrationGenerator < Rails::Generators::Base
@@ -85,7 +86,7 @@ module DeclareSchema
85
86
  @down = down
86
87
  @migration_class_name = final_migration_name.camelize
87
88
 
88
- migration_template 'migration.rb.erb', "db/migrate/#{final_migration_name.underscore}.rb"
89
+ migration_template('migration.rb.erb', "db/migrate/#{final_migration_name.underscore}.rb")
89
90
  if action == 'm'
90
91
  case Rails::VERSION::MAJOR
91
92
  when 4
@@ -117,14 +118,13 @@ module DeclareSchema
117
118
  ActiveRecord::Migrator.new(:up, migrations, ActiveRecord::SchemaMigration).pending_migrations
118
119
  end
119
120
 
120
- if pending_migrations.any?
121
- say "You have #{pending_migrations.size} pending migration#{'s' if pending_migrations.size > 1}:"
122
- pending_migrations.each do |pending_migration|
123
- say format(' %4d %s', pending_migration.version, pending_migration.name)
121
+ pending_migrations.any?.tap do |any|
122
+ if any
123
+ say "You have #{pending_migrations.size} pending migration#{'s' if pending_migrations.size > 1}:"
124
+ pending_migrations.each do |pending_migration|
125
+ say format(' %4d %s', pending_migration.version, pending_migration.name)
126
+ end
124
127
  end
125
- true
126
- else
127
- false
128
128
  end
129
129
  end
130
130
 
@@ -138,10 +138,10 @@ module DeclareSchema
138
138
  loop do
139
139
  if rename_to_choices.empty?
140
140
  say "\nCONFIRM DROP! #{kind_str} #{name_prefix}#{t}"
141
- resp = ask("Enter 'drop #{t}' to confirm or press enter to keep:")
142
- if resp.strip == "drop #{t}"
141
+ resp = ask("Enter 'drop #{t}' to confirm or press enter to keep:").strip
142
+ if resp == "drop #{t}"
143
143
  break
144
- elsif resp.strip.empty?
144
+ elsif resp.empty?
145
145
  to_drop.delete(t)
146
146
  break
147
147
  else
@@ -150,8 +150,7 @@ module DeclareSchema
150
150
  else
151
151
  say "\nDROP, RENAME or KEEP?: #{kind_str} #{name_prefix}#{t}"
152
152
  say "Rename choices: #{to_create * ', '}"
153
- resp = ask "Enter either 'drop #{t}' or one of the rename choices or press enter to keep:"
154
- resp = resp.strip
153
+ resp = ask("Enter either 'drop #{t}' or one of the rename choices or press enter to keep:").strip
155
154
 
156
155
  if resp == "drop #{t}"
157
156
  # Leave things as they are
@@ -182,3 +181,11 @@ module DeclareSchema
182
181
  end
183
182
  end
184
183
  end
184
+
185
+ module Generators
186
+ module DeclareSchema
187
+ module Migration
188
+ MigrationGenerator = ::DeclareSchema::MigrationGenerator
189
+ end
190
+ end
191
+ end