model_validator 1.0.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64f760c55b0d9771afce630e56523e689a3bf1ebd65f21acc003009518f1c340
4
- data.tar.gz: 5854b1987c516583bd2e50a8b97ff576594a6bd9cb3fc1157262ce2995cd4cd4
3
+ metadata.gz: 8aa2a1ac69ee4d57ea5cb34f7c6ebe0a22a7958ab92bef61a4a643705734a780
4
+ data.tar.gz: e2a2120fc1916a24d98534a98bc6a5d5f6761eabc03c0a70e0e49d45334f33e1
5
5
  SHA512:
6
- metadata.gz: 6550ec508bfa1a5670f6ad3548e3efddc744dd08df7302d7dbbdbe5afd331e59aa44ca4dbe8681172ed6ed0299a500370d98220153d5a7df63fed0025cc86900
7
- data.tar.gz: e66fb4032041a9b6323a70afd95939f8083736b089d3a27e2f09843c266e43d1d414085ae05d5919dadeac8daf6e8416d03378a2a534bf8e3e1b729a810f733c
6
+ metadata.gz: 65384c2f8d4c0b76b73505cca1a674f85ed586eb07b685563144c70c263ea4836c546f9fc293f576b6024d5dec6030d372527be884008380ec578393436bfb86
7
+ data.tar.gz: '029e28fa3733eadfd67453b52ab6966b93753c3dce5e70b1ca2880b94a0b20a2575e3153f0f27d981c16a4119288dca1c4192f0598d409af00de45dd461982f3'
data/.travis.yml CHANGED
@@ -4,3 +4,4 @@ cache: bundler
4
4
  rvm:
5
5
  - 2.7.2
6
6
  before_install: gem install bundler -v 2.2.7
7
+ script: make test
data/Gemfile CHANGED
@@ -3,13 +3,3 @@
3
3
  source "https://rubygems.org"
4
4
 
5
5
  gemspec
6
-
7
- gem "rake", "~> 13.0"
8
- gem "rspec", "~> 3.0"
9
- gem "rubocop", "~> 1.7"
10
-
11
- gem "sqlite3", "~> 1.4"
12
-
13
- gem "rubocop-rspec", "~> 2.2"
14
-
15
- gem "rubocop-rake", "~> 0.5.1"
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- model_validator (1.0.0)
5
- rails (~> 6.1)
4
+ model_validator (1.3.0)
5
+ rails (>= 5.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
@@ -69,14 +69,24 @@ GEM
69
69
  ast (2.4.2)
70
70
  builder (3.2.4)
71
71
  concurrent-ruby (1.1.7)
72
+ coveralls (0.8.23)
73
+ json (>= 1.8, < 3)
74
+ simplecov (~> 0.16.1)
75
+ term-ansicolor (~> 1.3)
76
+ thor (>= 0.19.4, < 2.0)
77
+ tins (~> 1.6)
72
78
  crass (1.0.6)
73
79
  diff-lcs (1.4.4)
80
+ docile (1.3.5)
74
81
  erubi (1.10.0)
82
+ factory_bot (6.1.0)
83
+ activesupport (>= 5.0.0)
75
84
  globalid (0.4.2)
76
85
  activesupport (>= 4.2.0)
77
86
  i18n (1.8.5)
78
87
  concurrent-ruby (~> 1.0)
79
- loofah (2.8.0)
88
+ json (2.5.1)
89
+ loofah (2.9.0)
80
90
  crass (~> 1.0.2)
81
91
  nokogiri (>= 1.5.9)
82
92
  mail (2.7.1)
@@ -88,7 +98,7 @@ GEM
88
98
  mini_mime (1.0.2)
89
99
  mini_portile2 (2.4.0)
90
100
  minitest (5.14.2)
91
- nio4r (2.5.4)
101
+ nio4r (2.5.5)
92
102
  nokogiri (1.10.10)
93
103
  mini_portile2 (~> 2.4.0)
94
104
  parallel (1.20.1)
@@ -157,6 +167,11 @@ GEM
157
167
  rubocop (~> 1.0)
158
168
  rubocop-ast (>= 1.1.0)
159
169
  ruby-progressbar (1.11.0)
170
+ simplecov (0.16.1)
171
+ docile (~> 1.1)
172
+ json (>= 1.8, < 3)
173
+ simplecov-html (~> 0.10.0)
174
+ simplecov-html (0.10.2)
160
175
  sprockets (4.0.2)
161
176
  concurrent-ruby (~> 1.0)
162
177
  rack (> 1, < 3)
@@ -165,7 +180,12 @@ GEM
165
180
  activesupport (>= 4.0)
166
181
  sprockets (>= 3.0.0)
167
182
  sqlite3 (1.4.2)
183
+ sync (0.5.0)
184
+ term-ansicolor (1.7.1)
185
+ tins (~> 1.0)
168
186
  thor (1.0.1)
187
+ tins (1.28.0)
188
+ sync
169
189
  tzinfo (2.0.3)
170
190
  concurrent-ruby (~> 1.0)
171
191
  unicode-display_width (2.0.0)
@@ -179,6 +199,8 @@ PLATFORMS
179
199
  x86_64-linux
180
200
 
181
201
  DEPENDENCIES
202
+ coveralls
203
+ factory_bot
182
204
  model_validator!
183
205
  rake (~> 13.0)
184
206
  rspec (~> 3.0)
data/Makefile CHANGED
@@ -5,6 +5,7 @@ install: ## Install dependencies
5
5
  bundle install
6
6
 
7
7
  test: ## Test application
8
+ rm -f db/test.sqlite3
8
9
  bundle exec rspec
9
10
 
10
11
  lint: ## Check file format, smell code, conventions…
@@ -12,3 +13,6 @@ lint: ## Check file format, smell code, conventions…
12
13
 
13
14
  lint-fix: ## Fix violations when possible
14
15
  bundle exec rubocop -a
16
+
17
+ install-locally: ## Install this gem locally
18
+ bundle exec rake install
data/README.md CHANGED
@@ -1,4 +1,6 @@
1
- [![Build Status](https://www.travis-ci.com/jibidus/model_validation.svg?branch=main)](https://www.travis-ci.com/jibidus/model_validation)
1
+ [![Build Status](https://www.travis-ci.com/jibidus/model_validator.svg?branch=main)](https://www.travis-ci.com/jibidus/model_validator)
2
+ [![Coverage Status](https://coveralls.io/repos/github/jibidus/model_validation/badge.svg?branch=main)](https://coveralls.io/github/jibidus/model_validation?branch=main)
3
+ [![Gem Version](https://badge.fury.io/rb/model_validator.svg)](https://badge.fury.io/rb/model_validator)
2
4
 
3
5
  # model_validator
4
6
 
@@ -14,23 +16,23 @@ This is useful since error may occur when manipulating such data.
14
16
 
15
17
  It is recommended to use this gem during deployment step:
16
18
 
17
- - restore production database in a staging/preprod/non-production environment
18
- - validate the database
19
- - add missing migrations in case of violations
20
- - repeat validation and fix until there is no more violation
21
- - then, you are ready to deploy your application in production
19
+ 1. restore production database in a staging/preprod/non-production environment
20
+ 2. validate the database
21
+ 3. add missing migrations in case of violations
22
+ 4. repeat validation and fix until there is no more violation
23
+ 5. then, you are ready to deploy your application in production
22
24
 
23
25
  ## Limitations
24
26
 
25
27
  This gem fetch **all** record in database, and, for each record run the Active Record validation.
26
- So, because of performances reason, this is only acceptable for tiny databases (thousand of records).
28
+ So, because of performances reason, this may be only acceptable for tiny databases (thousand of records).
27
29
 
28
30
  ## Installation
29
31
 
30
- Add this line to your application's Gemfile:
32
+ Add this line to your application"s Gemfile:
31
33
 
32
34
  ```ruby
33
- gem 'model_validator'
35
+ gem "model_validator"
34
36
  ```
35
37
 
36
38
  And then execute:
@@ -70,16 +72,20 @@ ModelValidator.validate_all skipped_models: [Model1,Model2]
70
72
 
71
73
  After checking out the repo, run `make install` to install dependencies.
72
74
 
73
- Then, run `make test` to run the tests.
75
+ Then, run `make test` to run the tests (test coverage is available in `coverage/index.html`).
74
76
 
75
77
  Then, run `make lint` to run linters ([rubocop](https://github.com/rubocop-hq/rubocop)).
76
78
 
77
- To install this gem onto your local machine, run `bundle exec rake install`.
79
+ To install this gem onto your local machine, run `make install-locally`.
78
80
 
79
81
  ### How to release new version?
80
82
 
81
- - Update the version number in `version.rb`
82
- - run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
83
+ Make sure your are in `main` branch. Then, run:
84
+ ```bash
85
+ rake release:make[major|minor|patch|x.y.z]
86
+ ```
87
+
88
+ Example for building a new minor release: `rake release:make[minor]`
83
89
 
84
90
  ## Why not contributing to existing gem?
85
91
 
@@ -87,8 +93,8 @@ Many already existing gems may do the same, but none are satisfying:
87
93
 
88
94
  - [validb](https://github.com/jgeiger/validb): depends on [sidekiq](https://github.com/mperham/sidekiq)
89
95
  - [validates_blacklist](https://www.rubydoc.info/gems/validates_blacklist/0.0.1): requires to add configuration in each model 😨
90
- - [valid_items](https://rubygems.org/gems/valid_items): requires rails eager load 🤔
91
- - [schema-validations](https://github.com/robworley/schema-validations): I don't understand what it really does 🤪
96
+ - [valid_items](https://rubygems.org/gems/valid_items): not compliant with rails 6 + cannot find sources to contribute
97
+ - [schema-validations](https://github.com/robworley/schema-validations): I didn't understand what it really does 🤪
92
98
 
93
99
  ## Contributing
94
100
 
@@ -100,4 +106,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
100
106
 
101
107
  ## Code of Conduct
102
108
 
103
- Everyone interacting in the ModelValidator project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/model_validator/blob/master/CODE_OF_CONDUCT.md).
109
+ Everyone interacting in the ModelValidator project"s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/model_validator/blob/master/CODE_OF_CONDUCT.md).
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rails"
4
+ require_relative "model_validator/stats_handler"
5
+ require_relative "model_validator/log_handler"
6
+ require_relative "model_validator/validator"
4
7
 
5
8
  # Validate models in database according Active Record model validation rules
6
9
  module ModelValidator
@@ -12,49 +15,9 @@ module ModelValidator
12
15
  else
13
16
  Rails.logger.info "Skipped model(s): #{skipped_models.map(&:to_s).join(", ")}"
14
17
  end
15
- handler = LogHandler.new
16
- Validator.new(handler, skip_models: skipped_models).run
17
- handler.violations_count
18
- end
19
-
20
- # Validation engine, which fetch, and validate each database records
21
- class Validator
22
- def initialize(handler, skip_models: [])
23
- @handler = handler
24
- @skip_models = skip_models
25
- end
26
-
27
- def models_to_validate
28
- ActiveRecord::Base.subclasses
29
- .reject { |type| type.to_s.include? "::" } # subclassed classes are not our own models
30
- .reject { |type| @skip_models.include? type }
31
- end
32
-
33
- def run
34
- models_to_validate.each do |type|
35
- @handler.start_model type
36
- type.unscoped.find_each do |record|
37
- @handler.on_violation(type, record) unless record.valid?
38
- end
39
- end
40
- end
41
- end
42
-
43
- # Validation handler, which logs each violation
44
- class LogHandler
45
- attr_reader :violations_count
46
-
47
- def initialize
48
- @violations_count = 0
49
- end
50
-
51
- def start_model(type)
52
- Rails.logger.info "Checking #{type}..."
53
- end
54
-
55
- def on_violation(type, record)
56
- Rails.logger.error "#<#{type} id: #{record.id}, errors: #{record.errors.full_messages}>" unless record.valid?
57
- @violations_count += 1
58
- end
18
+ stats_handler = StatsHandler.new
19
+ handlers = [LogHandler.new, stats_handler]
20
+ Validator.new(handlers: handlers, skip_models: skipped_models).run
21
+ stats_handler.result
59
22
  end
60
23
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails"
4
+
5
+ module ModelValidator
6
+ # This handler logs validation progression
7
+ class LogHandler
8
+ def on_new_class(model_class)
9
+ Rails.logger.info "Checking #{model_class.count} #{model_class}…"
10
+ end
11
+
12
+ def on_violation(model)
13
+ Rails.logger.error "#<#{model.class} id: #{model.id}, errors: #{model.errors.full_messages}>" unless model.valid?
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ModelValidator
4
+ # Validations summary, with:
5
+ # - violations: number of violations (i.e. number of model which validation failed)
6
+ # - total: total number of validated models
7
+ Result = Struct.new(:violations, :total)
8
+
9
+ # This handler computes validation statistics
10
+ class StatsHandler
11
+ attr_reader :result
12
+
13
+ def initialize
14
+ @result = Result.new(0, 0)
15
+ end
16
+
17
+ def on_violation(_)
18
+ @result.violations += 1
19
+ end
20
+
21
+ def after_validation(_)
22
+ @result.total += 1
23
+ end
24
+ end
25
+ end
@@ -7,7 +7,7 @@ namespace :db do
7
7
  task validate: :environment do
8
8
  Rails.logger.info "Validate database (this will take some time)…"
9
9
  skipped_models = (ENV["MODEL_VALIDATOR_SKIPPED_MODELS"] || "").split(",")
10
- count = ModelValidator.validate_all(skipped_models: skipped_models)
11
- Rails.logger.info "Validation finished with #{count} violation(s)"
10
+ result = ModelValidator.validate_all(skipped_models: skipped_models)
11
+ Rails.logger.info "Validation finished with #{result.violations}/#{result.total} violation(s)"
12
12
  end
13
13
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails"
4
+
5
+ module ModelValidator
6
+ # ApplicationRecord is the base class used to loop up for all models to validate.
7
+ # So this class is mandatory for ModelValidator to work well.
8
+ class ApplicationRecordNotFound < StandardError
9
+ def message
10
+ <<~MSG
11
+ ApplicationRecord not found.
12
+ model_validator requires that all models extends a super class ApplicationRecord.
13
+ This is expected in a rails application since rails 5.0.
14
+ MSG
15
+ end
16
+ end
17
+
18
+ # Validation engine, which fetch, and validate each database records
19
+ class Validator
20
+ def initialize(handlers: [], skip_models: [])
21
+ @handlers = handlers
22
+ @skip_models = skip_models
23
+ end
24
+
25
+ def classes_to_validate
26
+ raise ApplicationRecordNotFound unless defined?(ApplicationRecord)
27
+
28
+ Rails.application.try(:eager_load!) if Rails.env.development?
29
+ ApplicationRecord.descendants
30
+ .reject(&:abstract_class)
31
+ .select { |type| type.subclasses.empty? }
32
+ .reject { |type| @skip_models.include? type }
33
+ end
34
+
35
+ def run
36
+ classes_to_validate.each do |model_class|
37
+ @handlers.each { |h| h.try(:on_new_class, model_class) }
38
+ model_class.unscoped.find_each do |model|
39
+ @handlers.each { |h| h.try(:on_violation, model) } unless model.valid?
40
+ @handlers.each { |h| h.try(:after_validation, model) }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ModelValidator
4
- VERSION = "1.0.0"
4
+ VERSION = "1.3.0"
5
5
  end
@@ -2,25 +2,24 @@
2
2
 
3
3
  require_relative "lib/model_validator/version"
4
4
 
5
- Gem::Specification.new do |spec|
5
+ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
6
6
  spec.name = "model_validator"
7
7
  spec.version = ModelValidator::VERSION
8
8
  spec.authors = ["Jibidus"]
9
9
  spec.email = ["jibidus@gmail.com"]
10
10
 
11
- spec.summary = "Validate database against Active Record model validations."
12
- spec.description = <<~FOO
13
- Many reason may make database violate Active Record validation rules
14
- (database modification without Active Record, migration…).
15
- This raises unexpected error when these records are manipulated by rails.
16
- FOO
17
- spec.homepage = "https://github.com/jibidus/model_validation"
11
+ spec.summary = "Validate database against Active Record model validations"
12
+ spec.description = <<~DESC
13
+ Find models in database which violate Active Record validation rules.
14
+ Invalid models may raise unexpected error when updated.
15
+ DESC
16
+ spec.homepage = "https://github.com/jibidus/model_validator"
18
17
  spec.license = "MIT"
19
18
  spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
20
19
 
21
20
  spec.metadata["homepage_uri"] = spec.homepage
22
- spec.metadata["source_code_uri"] = "https://github.com/jibidus/model_validation"
23
- spec.metadata["changelog_uri"] = "https://github.com/jibidus/model_validation"
21
+ spec.metadata["source_code_uri"] = "https://github.com/jibidus/model_validator"
22
+ spec.metadata["changelog_uri"] = "https://github.com/jibidus/model_validator"
24
23
 
25
24
  # Specify which files should be added to the gem when it is released.
26
25
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -31,7 +30,16 @@ Gem::Specification.new do |spec|
31
30
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
32
31
  spec.require_paths = ["lib"]
33
32
 
34
- spec.add_dependency "rails", "~> 6.1"
33
+ spec.add_runtime_dependency "rails", ">= 5.0"
34
+
35
+ spec.add_development_dependency "coveralls"
36
+ spec.add_development_dependency "factory_bot"
37
+ spec.add_development_dependency "rake", "~> 13.0"
38
+ spec.add_development_dependency "rspec", "~> 3.0"
39
+ spec.add_development_dependency "rubocop", "~> 1.7"
40
+ spec.add_development_dependency "rubocop-rake", "~> 0.5.1"
41
+ spec.add_development_dependency "rubocop-rspec", "~> 2.2"
42
+ spec.add_development_dependency "sqlite3", "~> 1.4"
35
43
 
36
44
  # For more information and examples about making a new gem, checkout our
37
45
  # guide at: https://bundler.io/guides/creating_gem.html
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "./rakelib/release/release"
4
+
5
+ namespace :release do
6
+ desc <<~DESC
7
+ Build new release.
8
+ - bump_type (mandatory): [major|minor|patch|x.y.z]
9
+ - dry_run (optional): skip commit, tag and publishing
10
+ DESC
11
+ task :make, [:bump_type, :dry_run] do |_, args|
12
+ release = Release.new args[:bump_type]
13
+ puts "Bump version from #{release.current_version} to #{release.new_version}"
14
+ release.apply!
15
+
16
+ puts
17
+ puts "#{release.new_version} changelog"
18
+ puts "---------------------------------------------------------------------"
19
+ puts release.changelog
20
+ puts "---------------------------------------------------------------------"
21
+ next if args[:dry_run]
22
+
23
+ release.git_commit!
24
+ puts release.publishing_instructions
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Represents a commit in a git repository
4
+ class Commit
5
+ attr_reader :type, :message
6
+
7
+ def initialize(type, message)
8
+ @type = type
9
+ @message = message
10
+ end
11
+
12
+ def type?(types)
13
+ types.include? @type
14
+ end
15
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "./rakelib/release/repository"
4
+ require "./rakelib/release/version"
5
+ require "./lib/model_validator/version"
6
+
7
+ AUTHORIZED_BRANCH = "main"
8
+
9
+ # All commit message prefix to include in changelog
10
+ COMMIT_TYPES = {
11
+ "tada" => "Feature",
12
+ "bug" => "Bug fix"
13
+ }.freeze
14
+
15
+ # This class can create and publish a new version of the current gem
16
+ class Release
17
+ GEM_NAME = "model_validator"
18
+ VERSION_FILE = "lib/model_validator/version.rb"
19
+ GEMFILE_LOCK = "Gemfile.lock"
20
+
21
+ def initialize(type)
22
+ @type = type
23
+ end
24
+
25
+ def current_version
26
+ Version.new(*ModelValidator::VERSION.split(".").map(&:to_i))
27
+ end
28
+
29
+ def new_version
30
+ @new_version ||= current_version.bump(@type)
31
+ end
32
+
33
+ def apply!
34
+ if Repository.current_branch != AUTHORIZED_BRANCH
35
+ raise <<~MSG
36
+ You can only release new version from '#{AUTHORIZED_BRANCH}' branch.
37
+ Current branch: '#{Repository.current_branch}'
38
+ MSG
39
+ end
40
+
41
+ sub_file_content VERSION_FILE, current_version.to_s, new_version.to_s
42
+ sub_file_content GEMFILE_LOCK, "#{GEM_NAME} (#{current_version})", "#{GEM_NAME} (#{new_version})"
43
+ end
44
+
45
+ def changelog
46
+ commits_by_type.map do |type, commits|
47
+ messages_list = commits.map { |commit| "- #{commit.message}\n" }.join
48
+ "# #{COMMIT_TYPES[type]}\n#{messages_list}"
49
+ end.join("\n")
50
+ end
51
+
52
+ def git_commit!
53
+ `git add #{VERSION_FILE} #{GEMFILE_LOCK}`
54
+ `git commit -m ":label: release version #{new_version}"`
55
+ end
56
+
57
+ def publishing_instructions
58
+ <<~MSG
59
+ New commit created with the release.
60
+
61
+ Run following commands to publish version #{new_version}:
62
+ $> git push
63
+ $> bundle exec rake release
64
+
65
+ Then edit tag with changelog:
66
+ $> git tag v#{new_version} -f -a
67
+ $> git push -f --tags
68
+ MSG
69
+ end
70
+
71
+ private
72
+
73
+ def sub_file_content(file_path, from, to)
74
+ current_content = File.read(file_path)
75
+ modified_content = current_content.sub(from, to)
76
+ raise "Cannot find regexp '#{from}' in file #{file_path}" if modified_content == current_content
77
+
78
+ File.open(file_path, "w") { |file| file << modified_content }
79
+ end
80
+
81
+ def commits_by_type
82
+ Repository.commits_from(current_version)
83
+ .select { |commit| commit.type?(COMMIT_TYPES.keys) }
84
+ .group_by(&:type)
85
+ end
86
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "./rakelib/release/commit"
4
+
5
+ # This module contains many methods to manipulate current git repository
6
+ module Repository
7
+ def self.current_branch
8
+ `git rev-parse --abbrev-ref HEAD`.strip
9
+ end
10
+
11
+ def self.commits_from(tag)
12
+ logs_from("v#{tag}").sort
13
+ .uniq
14
+ .map do |commit_message|
15
+ _, type, message = commit_message.split(":", 3).map(&:strip)
16
+ if message.nil?
17
+ message = type
18
+ type = "unknown"
19
+ end
20
+ Commit.new(type, message)
21
+ end
22
+ end
23
+
24
+ def self.logs_from(revision)
25
+ `git log #{revision}..HEAD --pretty=format:"%s"`.split("\n")
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Represent a gem version, which can be bumped for new release.
4
+ class Version
5
+ def initialize(major, minor, patch)
6
+ @major = major
7
+ @minor = minor
8
+ @patch = patch
9
+ end
10
+
11
+ def bump(release_type)
12
+ case release_type
13
+ when "major"
14
+ Version.new(@major + 1, 0, 0)
15
+ when "minor"
16
+ Version.new(@major, @minor + 1, 0)
17
+ when "patch"
18
+ Version.new(@major, @minor, @patch + 1)
19
+ else
20
+ raise "Unknonwn bump type '#{release_type}'"
21
+ end
22
+ end
23
+
24
+ def to_s
25
+ [@major, @minor, @patch].join(".")
26
+ end
27
+ end
metadata CHANGED
@@ -1,33 +1,144 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: model_validator
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jibidus
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-02-14 00:00:00.000000000 Z
11
+ date: 2021-02-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '6.1'
19
+ version: '5.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '5.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: coveralls
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: factory_bot
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '13.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '13.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.7'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.7'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.5.1
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.5.1
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop-rspec
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '2.2'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '2.2'
125
+ - !ruby/object:Gem::Dependency
126
+ name: sqlite3
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.4'
132
+ type: :development
133
+ prerelease: false
22
134
  version_requirements: !ruby/object:Gem::Requirement
23
135
  requirements:
24
136
  - - "~>"
25
137
  - !ruby/object:Gem::Version
26
- version: '6.1'
138
+ version: '1.4'
27
139
  description: |
28
- Many reason may make database violate Active Record validation rules
29
- (database modification without Active Record, migration…).
30
- This raises unexpected error when these records are manipulated by rails.
140
+ Find models in database which violate Active Record validation rules.
141
+ Invalid models may raise unexpected error when updated.
31
142
  email:
32
143
  - jibidus@gmail.com
33
144
  executables: []
@@ -45,21 +156,27 @@ files:
45
156
  - Makefile
46
157
  - README.md
47
158
  - Rakefile
48
- - bin/console
49
- - bin/setup
50
159
  - lib/model_validator.rb
51
160
  - lib/model_validator/Rakefile
161
+ - lib/model_validator/log_handler.rb
52
162
  - lib/model_validator/railtie.rb
163
+ - lib/model_validator/stats_handler.rb
53
164
  - lib/model_validator/tasks/db/validate.rake
165
+ - lib/model_validator/validator.rb
54
166
  - lib/model_validator/version.rb
55
167
  - model_validator.gemspec
56
- homepage: https://github.com/jibidus/model_validation
168
+ - rakelib/release.rake
169
+ - rakelib/release/commit.rb
170
+ - rakelib/release/release.rb
171
+ - rakelib/release/repository.rb
172
+ - rakelib/release/version.rb
173
+ homepage: https://github.com/jibidus/model_validator
57
174
  licenses:
58
175
  - MIT
59
176
  metadata:
60
- homepage_uri: https://github.com/jibidus/model_validation
61
- source_code_uri: https://github.com/jibidus/model_validation
62
- changelog_uri: https://github.com/jibidus/model_validation
177
+ homepage_uri: https://github.com/jibidus/model_validator
178
+ source_code_uri: https://github.com/jibidus/model_validator
179
+ changelog_uri: https://github.com/jibidus/model_validator
63
180
  post_install_message:
64
181
  rdoc_options: []
65
182
  require_paths:
@@ -78,5 +195,5 @@ requirements: []
78
195
  rubygems_version: 3.1.4
79
196
  signing_key:
80
197
  specification_version: 4
81
- summary: Validate database against Active Record model validations.
198
+ summary: Validate database against Active Record model validations
82
199
  test_files: []
data/bin/console DELETED
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require "bundler/setup"
5
- require "model_validator"
6
-
7
- # You can add fixtures and/or initialization code here to make experimenting
8
- # with your gem easier. You can also use a different console, if you like.
9
-
10
- # (If you use this, don't forget to add pry to your Gemfile!)
11
- # require "pry"
12
- # Pry.start
13
-
14
- require "irb"
15
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here