enumbler 0.8.0 → 0.9.2
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 +4 -4
- data/.rubocop.yml +27 -5
- data/Gemfile +1 -1
- data/Gemfile.lock +3 -3
- data/README.md +1 -3
- data/Rakefile +2 -2
- data/bin/console +3 -3
- data/bin/pre_commit_rubocop.rb +19 -9
- data/enumbler.gemspec +25 -25
- data/lefthook.yml +12 -0
- data/lib/enumbler.rb +7 -7
- data/lib/enumbler/collection.rb +1 -1
- data/lib/enumbler/enabler.rb +52 -5
- data/lib/enumbler/enumble.rb +1 -2
- data/lib/enumbler/version.rb +1 -1
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca8de5b8e3b88d4321e0df6108f41245142f95489930e57e6d0209c260335b3d
|
4
|
+
data.tar.gz: ab12a41dc3564dd62f78cb0583ec12ac6602ba5faf6bf890be80864096f4a65d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 948e3cab58f8065ad78b67680ecc9ca0f3de53be0169ca13502a69f145af27e855707b331cf760e925859789f26f68a801ee7f6c02562d393ca6a720c30497fd
|
7
|
+
data.tar.gz: c50f6dc4282fa0ace1cdc44b97dd79f64f6a1667074bd4fe93f5ed580decfa55983b412317d3c3a4f18f83efa1ef83c16fad75177f0e575ccf0ba005f6275cf1
|
data/.rubocop.yml
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
AllCops:
|
2
|
-
|
3
|
-
|
4
|
-
- 'bin/pre_commit_rubocop.rb'
|
2
|
+
NewCops: enable
|
3
|
+
TargetRubyVersion: 2.5
|
5
4
|
|
6
5
|
Layout/ArgumentAlignment:
|
7
6
|
Enabled: true
|
@@ -11,16 +10,36 @@ Layout/FirstHashElementIndentation:
|
|
11
10
|
Enabled: true
|
12
11
|
EnforcedStyle: consistent
|
13
12
|
|
13
|
+
Layout/HashAlignment:
|
14
|
+
Enabled: true
|
15
|
+
# This allows "implicit" hash arguments (without curly braces) to be aligned
|
16
|
+
# differently.
|
17
|
+
EnforcedLastArgumentHashStyle: ignore_implicit
|
18
|
+
|
14
19
|
Layout/LineLength:
|
15
20
|
AllowURI: true
|
16
21
|
Max: 119
|
17
22
|
|
23
|
+
Layout/MultilineMethodCallIndentation:
|
24
|
+
Enabled: true
|
25
|
+
EnforcedStyle: indented
|
26
|
+
|
18
27
|
Lint/RaiseException:
|
19
28
|
Enabled: true
|
20
29
|
|
21
30
|
Lint/StructNewOverride:
|
22
31
|
Enabled: true
|
23
32
|
|
33
|
+
Metrics:
|
34
|
+
Enabled: false
|
35
|
+
|
36
|
+
Naming/MethodParameterName:
|
37
|
+
Enabled: true
|
38
|
+
AllowedNames: [at, by, db, id, in, ip, of, on, to, tz]
|
39
|
+
|
40
|
+
Naming/PredicateName:
|
41
|
+
Enabled: true
|
42
|
+
|
24
43
|
Style/Documentation:
|
25
44
|
Enabled: false
|
26
45
|
|
@@ -33,6 +52,9 @@ Style/HashTransformKeys:
|
|
33
52
|
Style/HashTransformValues:
|
34
53
|
Enabled: true
|
35
54
|
|
55
|
+
Style/StringLiterals:
|
56
|
+
EnforcedStyle: double_quotes
|
57
|
+
|
36
58
|
Style/TrailingCommaInHashLiteral:
|
37
59
|
Enabled: true
|
38
60
|
EnforcedStyleForMultiline: consistent_comma
|
@@ -41,5 +63,5 @@ Style/TrailingCommaInArrayLiteral:
|
|
41
63
|
Enabled: true
|
42
64
|
EnforcedStyleForMultiline: consistent_comma
|
43
65
|
|
44
|
-
|
45
|
-
|
66
|
+
Style/TrailingCommaInArguments:
|
67
|
+
EnforcedStyleForMultiline: consistent_comma
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -170,14 +170,12 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
170
170
|
|
171
171
|
## Roadmap
|
172
172
|
|
173
|
-
*
|
174
|
-
* Ideally, we could make this work more like a traditional `enum`; for example, overriding the `.where` method by allowing something like: `House.where(color: :blue)` instead of `House.where_color(:blue)`. But right now am in a rush and not sure how to go about doing that properly.
|
173
|
+
* Ideally, we could make this work more like a traditional `enum`; for example, overriding the `.where` method by allowing something like: `House.where(color: :blue)` instead of `House.color(:blue)`. But right now am in a rush and not sure how to go about doing that properly.
|
175
174
|
|
176
175
|
## Contributing
|
177
176
|
|
178
177
|
Bug reports and pull requests are welcome on GitHub at https://github.com/linguabee/enumbler.
|
179
178
|
|
180
|
-
|
181
179
|
## License
|
182
180
|
|
183
181
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
-
require
|
5
|
-
require
|
4
|
+
require "bundler/setup"
|
5
|
+
require "enumbler"
|
6
6
|
|
7
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
8
8
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -11,5 +11,5 @@ require 'enumbler'
|
|
11
11
|
# require "pry"
|
12
12
|
# Pry.start
|
13
13
|
|
14
|
-
require
|
14
|
+
require "irb"
|
15
15
|
IRB.start(__FILE__)
|
data/bin/pre_commit_rubocop.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
# Put this file into your path and use `<file> install` to add a new hook
|
3
5
|
# or use it as a binary to check changed files
|
4
6
|
|
5
|
-
require
|
7
|
+
require "shellwords"
|
6
8
|
|
7
9
|
if ARGV == ["install"]
|
8
10
|
exec "ln", "-sf", File.expand_path(File.basename(__FILE__), __dir__), ".git/hooks/pre-commit"
|
@@ -10,15 +12,23 @@ else
|
|
10
12
|
raise unless ARGV == []
|
11
13
|
end
|
12
14
|
|
13
|
-
changed = `git status --porcelain
|
14
|
-
split("\n")
|
15
|
-
map { |l| l.split(" ", 2) }
|
16
|
-
select { |status, _| [
|
17
|
-
map { |_, file| file.delete('"') }
|
15
|
+
changed = `git status --porcelain`
|
16
|
+
.split("\n")
|
17
|
+
.map { |l| l.split(" ", 2) }
|
18
|
+
.select { |status, _| %w[A AM M].include?(status) }
|
19
|
+
.map { |_, file| file.delete('"') }
|
18
20
|
|
19
21
|
exit if changed.empty?
|
20
22
|
|
21
|
-
parallel = (
|
23
|
+
parallel = (if begin
|
24
|
+
File.read(".rubocop.yml").include?("UseCache: false")
|
25
|
+
rescue StandardError
|
26
|
+
false
|
27
|
+
end
|
28
|
+
""
|
29
|
+
else
|
30
|
+
" --parallel"
|
31
|
+
end)
|
22
32
|
result = `bundle exec rubocop #{parallel} --color --force-exclusion #{changed.shelljoin}`
|
23
|
-
puts result unless
|
24
|
-
exit
|
33
|
+
puts result unless $CHILD_STATUS.success?
|
34
|
+
exit $CHILD_STATUS.exitstatus
|
data/enumbler.gemspec
CHANGED
@@ -1,42 +1,42 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
3
|
+
require_relative "lib/enumbler/version"
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name =
|
6
|
+
spec.name = "enumbler"
|
7
7
|
spec.version = Enumbler::VERSION
|
8
|
-
spec.authors = [
|
9
|
-
spec.email = [
|
8
|
+
spec.authors = ["Damon Timm"]
|
9
|
+
spec.email = ["damon@linguabee.com"]
|
10
10
|
|
11
11
|
spec.summary = "Enums are terrific, but lack integrity. Let's add some!"
|
12
|
-
spec.description =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
15
|
-
spec.required_ruby_version = Gem::Requirement.new(
|
12
|
+
spec.description = "A more complete description is forthcoming."
|
13
|
+
spec.homepage = "https://github.com/linguabee/enumbler"
|
14
|
+
spec.license = "MIT"
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
|
16
16
|
|
17
|
-
spec.metadata[
|
17
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
18
18
|
|
19
|
-
spec.metadata[
|
20
|
-
spec.metadata[
|
21
|
-
spec.metadata[
|
19
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
20
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
21
|
+
spec.metadata["changelog_uri"] = spec.homepage
|
22
22
|
|
23
23
|
# Specify which files should be added to the gem when it is released.
|
24
24
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
25
25
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
26
26
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
27
27
|
end
|
28
|
-
spec.bindir =
|
28
|
+
spec.bindir = "exe"
|
29
29
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
|
-
spec.require_paths = [
|
31
|
-
|
32
|
-
spec.add_dependency
|
33
|
-
spec.add_dependency
|
34
|
-
|
35
|
-
spec.add_development_dependency
|
36
|
-
spec.add_development_dependency
|
37
|
-
spec.add_development_dependency
|
38
|
-
spec.add_development_dependency
|
39
|
-
spec.add_development_dependency
|
40
|
-
spec.add_development_dependency
|
41
|
-
spec.add_development_dependency
|
30
|
+
spec.require_paths = ["lib"]
|
31
|
+
|
32
|
+
spec.add_dependency "activerecord", [">= 5.2.3", "< 7"]
|
33
|
+
spec.add_dependency "activesupport", [">= 5.2.3", "< 7"]
|
34
|
+
|
35
|
+
spec.add_development_dependency "database_cleaner-active_record", "~> 1.8.0"
|
36
|
+
spec.add_development_dependency "fuubar", "~> 2.5"
|
37
|
+
spec.add_development_dependency "pry"
|
38
|
+
spec.add_development_dependency "rake", "~> 12.0"
|
39
|
+
spec.add_development_dependency "rspec", "~> 3.9.0"
|
40
|
+
spec.add_development_dependency "rubocop", "~> 0.91.0"
|
41
|
+
spec.add_development_dependency "sqlite3", "~> 1.4.0"
|
42
42
|
end
|
data/lefthook.yml
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# EXAMPLE USAGE
|
2
|
+
# Refer for explanation to following link:
|
3
|
+
# https://github.com/Arkweid/lefthook/blob/master/docs/full_guide.md
|
4
|
+
|
5
|
+
pre-commit:
|
6
|
+
parallel: true
|
7
|
+
commands:
|
8
|
+
rubocop:
|
9
|
+
tags: backend style
|
10
|
+
glob: "*.rb"
|
11
|
+
exclude: "application.rb|routes.rb"
|
12
|
+
run: bundle exec rubocop --force-exclusion {all_files}
|
data/lib/enumbler.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "enumbler/core_ext/symbol/case_equality_operator"
|
4
4
|
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
5
|
+
require "enumbler/collection"
|
6
|
+
require "enumbler/enumble"
|
7
|
+
require "enumbler/enabler"
|
8
|
+
require "enumbler/version"
|
9
9
|
|
10
|
-
require
|
11
|
-
require
|
10
|
+
require "active_support/concern"
|
11
|
+
require "active_support/inflector"
|
12
12
|
|
13
13
|
# The Enumbler add integrity to our enum implementation!
|
14
14
|
module Enumbler
|
data/lib/enumbler/collection.rb
CHANGED
data/lib/enumbler/enabler.rb
CHANGED
@@ -12,7 +12,7 @@ module Enumbler
|
|
12
12
|
def enumble
|
13
13
|
@enumble = self.class.find_enumble(id)
|
14
14
|
|
15
|
-
raise Error,
|
15
|
+
raise Error, "An enumble is not defined for this record!" if @enumble.nil?
|
16
16
|
|
17
17
|
@enumble
|
18
18
|
end
|
@@ -227,6 +227,8 @@ module Enumbler
|
|
227
227
|
enumble =
|
228
228
|
if arg.is_a?(Symbol)
|
229
229
|
@enumbled_model.enumbles.find { |e| e.enum == arg }
|
230
|
+
elsif arg.is_a?(Enumbler::Enumble)
|
231
|
+
@enumbled_model.enumbles.find { |e| e.enum == arg.enum }
|
230
232
|
elsif arg.is_a?(String)
|
231
233
|
@enumbled_model.enumbles.find do |e|
|
232
234
|
if case_sensitive
|
@@ -330,7 +332,7 @@ module Enumbler
|
|
330
332
|
# longer defined (default: false)
|
331
333
|
# @param validate [Boolean] validate on save?
|
332
334
|
def seed_the_enumbler(delete_missing_records: false, validate: true)
|
333
|
-
max_database_id = all.order(
|
335
|
+
max_database_id = all.order("id desc").take&.id || 0
|
334
336
|
max_enumble_id = @enumbles.map(&:id).max
|
335
337
|
|
336
338
|
# If we are not deleting records, we just need to update each listed
|
@@ -375,11 +377,21 @@ module Enumbler
|
|
375
377
|
method_name = "#{enumble.enum}?"
|
376
378
|
not_method_name = "not_#{enumble.enum}?"
|
377
379
|
alias_method_name = "is_#{enumble.enum}"
|
380
|
+
any_method_name = "any_#{enumble.enum}?"
|
381
|
+
|
382
|
+
[method_name, not_method_name, alias_method_name].each do |mname|
|
383
|
+
detect_enumbler_conflict(enumble.enum, mname)
|
384
|
+
end
|
385
|
+
|
386
|
+
[enumble.enum, any_method_name].each do |mname|
|
387
|
+
detect_enumbler_conflict(enumble.enum, mname, klass_method: true)
|
388
|
+
end
|
378
389
|
|
379
390
|
const_set(enumble.enum.to_s.upcase, enumble.id)
|
380
391
|
define_method(method_name) { id == enumble.id }
|
381
392
|
define_method(not_method_name) { id != enumble.id }
|
382
393
|
alias_method alias_method_name, method_name
|
394
|
+
|
383
395
|
define_singleton_method(enumble.enum) do |attr = nil|
|
384
396
|
return find(enumble.id) if attr.nil?
|
385
397
|
|
@@ -388,13 +400,42 @@ module Enumbler
|
|
388
400
|
raise Enumbler::Error, "The attribute #{attr} is not supported on this Enumble."
|
389
401
|
end
|
390
402
|
|
391
|
-
define_singleton_method(
|
392
|
-
|
403
|
+
define_singleton_method(any_method_name) do
|
404
|
+
exists?(id: enumble.id)
|
393
405
|
rescue NoMethodError
|
394
406
|
raise Enumbler::Error, "The attribute #{attr} is not supported on this Enumble."
|
395
407
|
end
|
396
408
|
end
|
397
409
|
|
410
|
+
# This idea sourced lovingly from ActiveRecord::Enum
|
411
|
+
ENUMBLER_CONFLICT_MESSAGE = <<~TEXT.squish
|
412
|
+
You tried to define the enumble :%<enum>s on the model %<klass>s, but
|
413
|
+
this will generate a %<type>s method `%<method>s`, which is already defined
|
414
|
+
by %<source>s.
|
415
|
+
TEXT
|
416
|
+
|
417
|
+
def detect_enumbler_conflict(enumble_name, method_name, klass_method: false)
|
418
|
+
if klass_method && dangerous_class_method?(method_name)
|
419
|
+
raise_conflict_error(enumble_name, method_name, type: "class")
|
420
|
+
elsif klass_method && method_defined_within?(method_name, ActiveRecord::Relation)
|
421
|
+
raise_conflict_error(enumble_name, method_name, type: "class", source: ActiveRecord::Relation.name)
|
422
|
+
elsif !klass_method && dangerous_attribute_method?(method_name)
|
423
|
+
raise_conflict_error(enumble_name, method_name)
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
def raise_conflict_error(enumble_name, method_name, type: "instance", source: "ActiveRecord")
|
428
|
+
raise Error,
|
429
|
+
format(
|
430
|
+
ENUMBLER_CONFLICT_MESSAGE,
|
431
|
+
enum: enumble_name,
|
432
|
+
klass: name,
|
433
|
+
type: type,
|
434
|
+
method: method_name,
|
435
|
+
source: source,
|
436
|
+
)
|
437
|
+
end
|
438
|
+
|
398
439
|
# I accidentally forgot to provide an id one time and it was confusing as
|
399
440
|
# the last argument became the hash of options. This should help.
|
400
441
|
def validate_id_is_numeric(enum, id)
|
@@ -411,11 +452,17 @@ module Enumbler
|
|
411
452
|
|
412
453
|
return if unsupported_attrs.blank?
|
413
454
|
|
455
|
+
ActiveRecord::Migration.check_pending!
|
456
|
+
|
414
457
|
raise Enumbler::Error,
|
415
458
|
"The model #{self} does not support the attribute(s): #{unsupported_attrs.keys.map(&:to_s).to_sentence}"
|
459
|
+
rescue ActiveRecord::PendingMigrationError
|
460
|
+
warn "[Enumbler Warning] => The model #{self} does not currently support the attribute(s): #{unsupported_attrs.keys.map(&:to_s).to_sentence}." \
|
461
|
+
" You have a pending migration which hopefully would remedy this! If not, you need to add a migration for this attibrute or" \
|
462
|
+
" remove it from the Enumbler."
|
416
463
|
rescue ActiveRecord::StatementInvalid
|
417
464
|
warn "[Enumbler Warning] => Unable to find a table for #{self}."\
|
418
|
-
|
465
|
+
"This is to be expected if there is a pending migration; however, if there is not then something is amiss."
|
419
466
|
end
|
420
467
|
end
|
421
468
|
end
|
data/lib/enumbler/enumble.rb
CHANGED
@@ -11,7 +11,7 @@ module Enumbler
|
|
11
11
|
@label_column_name = label_column_name
|
12
12
|
@label = (label_col_specified? ? attributes[label_column_name] : label) || enum.to_s.dasherize
|
13
13
|
@additional_attributes = attributes || {}
|
14
|
-
@additional_attributes.merge!({ label: label })
|
14
|
+
@additional_attributes.merge!({ label: label }) unless label.nil?
|
15
15
|
end
|
16
16
|
|
17
17
|
def ==(other)
|
@@ -21,7 +21,6 @@ module Enumbler
|
|
21
21
|
|
22
22
|
def attributes
|
23
23
|
hash = { id: id, label_column_name => label }
|
24
|
-
hash.merge!({ label: @additional_attributes[:label] }) if label_col_specified?
|
25
24
|
@additional_attributes.merge(hash)
|
26
25
|
end
|
27
26
|
|
data/lib/enumbler/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: enumbler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Damon Timm
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: 5.2.3
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '7'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +29,7 @@ dependencies:
|
|
29
29
|
version: 5.2.3
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '7'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: activesupport
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
version: 5.2.3
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '
|
42
|
+
version: '7'
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -49,7 +49,7 @@ dependencies:
|
|
49
49
|
version: 5.2.3
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version: '
|
52
|
+
version: '7'
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: database_cleaner-active_record
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -169,6 +169,7 @@ files:
|
|
169
169
|
- bin/pre_commit_rubocop.rb
|
170
170
|
- bin/setup
|
171
171
|
- enumbler.gemspec
|
172
|
+
- lefthook.yml
|
172
173
|
- lib/enumbler.rb
|
173
174
|
- lib/enumbler/collection.rb
|
174
175
|
- lib/enumbler/core_ext/symbol/case_equality_operator.rb
|
@@ -198,7 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
198
199
|
- !ruby/object:Gem::Version
|
199
200
|
version: '0'
|
200
201
|
requirements: []
|
201
|
-
rubygems_version: 3.1.
|
202
|
+
rubygems_version: 3.1.6
|
202
203
|
signing_key:
|
203
204
|
specification_version: 4
|
204
205
|
summary: Enums are terrific, but lack integrity. Let's add some!
|