the_schema_is 0.0.4 → 0.0.6
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/Changelog.md +11 -0
- data/README.md +3 -2
- data/config/defaults.yml +1 -0
- data/lib/the_schema_is/cops/node_util.rb +2 -2
- data/lib/the_schema_is/cops/parser.rb +28 -4
- data/lib/the_schema_is/cops.rb +12 -6
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e9f1550133bd9ad6932e9940f55a7921b956a228dda93b14029e98d7d83d10b
|
4
|
+
data.tar.gz: 35903ce14ac034af1649d2a92be07f063fb1c224dcd48c92a8b4c696827b8968
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 24b95d5aac99fbc31fc87b7fdf7254450a6cee7f862d155d1a7a0d7539e89b2b1b105016f6f245e6a40cd913edb3e20430d9f7fab46ba47964be289c1e436596
|
7
|
+
data.tar.gz: 652544c051f292ddaaf7cde3bd7ce4a68702590f6efe79eb7fd9196dec78b726cb1cb19ca206cf0e354bc11ccbfb189b3580e7ac91c353bdafc0150c2a6ebefc
|
data/Changelog.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# the-schema-is changes
|
2
2
|
|
3
|
+
## 2024-12-22 - 0.0.6
|
4
|
+
|
5
|
+
* Drop support for Ruby < 2.7;
|
6
|
+
* Ensure support for all Ruby versions from 2.7 to 3.4-dev (replace memoist with memery);
|
7
|
+
* Slightly update code with the new Rubocop.
|
8
|
+
|
9
|
+
## 2021-11-04 - 0.0.5
|
10
|
+
|
11
|
+
* Support `enum` column type;
|
12
|
+
* Add `RemoveDefinitions` config key for leaner `the_schema_is` definitions (avoiding huge index descriptions in models).
|
13
|
+
|
3
14
|
## 2021-09-15 - 0.0.4
|
4
15
|
|
5
16
|
* Get rid of [Fast](https://jonatas.github.io/fast/) dependency. It is cool, but we switched to use Rubocop's own `NodePattern` to lessen the dependency burden (Fast was depending on [astrolabe](https://github.com/yujinakayama/astrolabe) which wasn't updated in 6 years, locking parser dependency to old version and making Fast incompatible with newer Rubocop);
|
data/README.md
CHANGED
@@ -134,8 +134,9 @@ TheSchemaIs:
|
|
134
134
|
Currently available settings are:
|
135
135
|
|
136
136
|
* `TablePrefix` to help `the_schema_is` deduce table name from class name;
|
137
|
-
* `Schema` to set path to schema (by default `db/schema.rb`)
|
138
|
-
* `BaseClass` to help `the_schema_is` guess what is a model class (by default `ApplicationRecord` and `ActiveRecord::Base`)
|
137
|
+
* `Schema` to set path to schema (by default `db/schema.rb`);
|
138
|
+
* `BaseClass` to help `the_schema_is` guess what is a model class (by default `ApplicationRecord` and `ActiveRecord::Base`);
|
139
|
+
* `RemoveDefinitions`: list of definition keys to remove (for example, `[index, foreign_key, limit]`) when copying definitions into models; this might be desirable for leaner `the_schema_is` statements, displaying only field types/names.
|
139
140
|
|
140
141
|
So, if you have your custom-named base class, you should do:
|
141
142
|
|
data/config/defaults.yml
CHANGED
@@ -15,7 +15,7 @@ module TheSchemaIs
|
|
15
15
|
extend RuboCop::AST::NodePattern::Macros
|
16
16
|
|
17
17
|
class << self
|
18
|
-
|
18
|
+
include Memery
|
19
19
|
|
20
20
|
def search(pattern, node)
|
21
21
|
search_methods[pattern].then { |m| instance.send(m, node) }
|
@@ -66,7 +66,7 @@ module TheSchemaIs
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def find_parent(type)
|
69
|
-
Enumerator.produce(parent, &:parent).
|
69
|
+
Enumerator.produce(parent, &:parent).find { |n| n && n.type == type }
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
@@ -15,7 +15,7 @@ module TheSchemaIs
|
|
15
15
|
float integer json string text time timestamp virtual].freeze
|
16
16
|
POSTGRES_COLUMN_TYPES = %i[jsonb inet cidr macaddr hstore uuid].freeze
|
17
17
|
|
18
|
-
COLUMN_DEFS = (STANDARD_COLUMN_TYPES + POSTGRES_COLUMN_TYPES + %i[column]).freeze
|
18
|
+
COLUMN_DEFS = (STANDARD_COLUMN_TYPES + POSTGRES_COLUMN_TYPES + %i[enum column]).freeze
|
19
19
|
|
20
20
|
Model = Struct.new(:class_name, :table_name, :source, :schema, :table_name_node,
|
21
21
|
keyword_init: true)
|
@@ -33,9 +33,11 @@ module TheSchemaIs
|
|
33
33
|
RuboCop::AST::ProcessedSource.new(code, 2.7).ast
|
34
34
|
end
|
35
35
|
|
36
|
-
def self.schema(path)
|
36
|
+
def self.schema(path, remove_definition_attrs: [])
|
37
37
|
ast = parse(File.read(path))
|
38
38
|
|
39
|
+
ast = remove_attributes(ast, remove_definition_attrs) unless remove_definition_attrs.empty?
|
40
|
+
|
39
41
|
ast.ast_search('(block (send nil? :create_table (str $_) _) _ $_)').to_h
|
40
42
|
end
|
41
43
|
|
@@ -68,8 +70,7 @@ module TheSchemaIs
|
|
68
70
|
|
69
71
|
Model.new(
|
70
72
|
class_name: class_name,
|
71
|
-
table_name: table_name ||
|
72
|
-
table_prefix.+(ActiveSupport::Inflector.tableize(class_name)),
|
73
|
+
table_name: table_name || table_prefix + ActiveSupport::Inflector.tableize(class_name),
|
73
74
|
source: definition_node,
|
74
75
|
schema: schema_node,
|
75
76
|
table_name_node: name_node&.first
|
@@ -95,6 +96,29 @@ module TheSchemaIs
|
|
95
96
|
end
|
96
97
|
}.compact
|
97
98
|
end
|
99
|
+
|
100
|
+
# Removes unnecessary column definitions from further comparison, using schema source tree editing
|
101
|
+
def self.remove_attributes(ast, attrs_to_remove)
|
102
|
+
buf = ast.loc.expression.source_buffer
|
103
|
+
src = buf.source
|
104
|
+
rewriter = ::Parser::Source::TreeRewriter.new(buf)
|
105
|
+
|
106
|
+
# FIXME: Two nested cycles can be simplifid to just look for column definition, probably
|
107
|
+
ast.ast_search('(block (send nil? :create_table (str _) _) _ $_)').each do |table_def|
|
108
|
+
table_def.children.each do |col|
|
109
|
+
dfn = col.children[3] or next
|
110
|
+
dfn.children
|
111
|
+
.select { |c| attrs_to_remove.include?(c.children[0].children[0]) }
|
112
|
+
.each do |c|
|
113
|
+
prev_comma = c.source_range.begin_pos.step(by: -1).find { |pos| src[pos] == ',' }
|
114
|
+
range = ::Parser::Source::Range.new(buf, prev_comma, c.source_range.end_pos)
|
115
|
+
rewriter.remove(range)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
RuboCop::AST::ProcessedSource.new(rewriter.process, 2.7).ast
|
121
|
+
end
|
98
122
|
end
|
99
123
|
end
|
100
124
|
end
|
data/lib/the_schema_is/cops.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'memery'
|
4
4
|
require 'rubocop'
|
5
5
|
require 'backports/latest'
|
6
6
|
|
@@ -15,13 +15,17 @@ module TheSchemaIs
|
|
15
15
|
using Cops::NodeRefinements
|
16
16
|
|
17
17
|
module Cops
|
18
|
-
|
19
|
-
|
18
|
+
class << self
|
19
|
+
include Memery
|
20
|
+
|
21
|
+
memoize def fetch_schema(path, remove_definition_attrs: [])
|
22
|
+
Cops::Parser.schema(path, remove_definition_attrs: remove_definition_attrs)
|
23
|
+
end
|
20
24
|
end
|
21
25
|
end
|
22
26
|
|
23
27
|
module Common
|
24
|
-
|
28
|
+
include Memery
|
25
29
|
|
26
30
|
def self.included(cls)
|
27
31
|
cls.define_singleton_method(:badge) do
|
@@ -59,7 +63,9 @@ module TheSchemaIs
|
|
59
63
|
end
|
60
64
|
|
61
65
|
memoize def schema
|
62
|
-
|
66
|
+
attrs_to_remove = cop_config['RemoveDefinitions']&.map(&:to_sym) || []
|
67
|
+
# It is OK if it returns Nil, just will be handled by "schema is absent" cop
|
68
|
+
Cops.fetch_schema(schema_path, remove_definition_attrs: attrs_to_remove)[model.table_name]
|
63
69
|
end
|
64
70
|
|
65
71
|
memoize def model_columns
|
@@ -183,7 +189,7 @@ module TheSchemaIs
|
|
183
189
|
def register_offense(_node)
|
184
190
|
return if model.schema.nil? || schema.nil?
|
185
191
|
|
186
|
-
extra_columns.
|
192
|
+
extra_columns.each_value do |col|
|
187
193
|
add_offense(col.source, message: MSG % col.name) do |corrector|
|
188
194
|
src_range = col.source.loc.expression
|
189
195
|
end_pos = col.source.next_sibling.then { |n|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: the_schema_is
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Victor Shepelev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-12-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backports
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: memery
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -137,7 +137,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
137
137
|
requirements:
|
138
138
|
- - ">="
|
139
139
|
- !ruby/object:Gem::Version
|
140
|
-
version: 2.
|
140
|
+
version: 2.7.0
|
141
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
143
|
- - ">="
|