exwiw 0.9.21 → 0.9.23
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 +20 -0
- data/README.md +101 -10
- data/docs/mongodb.md +21 -1
- data/lib/exwiw/cli.rb +190 -3
- data/lib/exwiw/db_introspector/mysql_introspector.rb +160 -0
- data/lib/exwiw/db_introspector/postgresql_introspector.rb +215 -0
- data/lib/exwiw/db_introspector.rb +166 -0
- data/lib/exwiw/db_schema_generator.rb +298 -0
- data/lib/exwiw/mongodb_collection_config.rb +21 -12
- data/lib/exwiw/mongoid_schema_generator.rb +468 -69
- data/lib/exwiw/schema_check.rb +48 -6
- data/lib/exwiw/table_config.rb +1 -1
- data/lib/exwiw/version.rb +1 -1
- data/lib/exwiw.rb +4 -0
- data/lib/tasks/exwiw.rake +37 -0
- metadata +5 -1
data/lib/exwiw/schema_check.rb
CHANGED
|
@@ -9,7 +9,13 @@ module Exwiw
|
|
|
9
9
|
# Reports how the committed schema config differs from what the application
|
|
10
10
|
# would generate now, plus the columns still waiting for a masking decision.
|
|
11
11
|
# Regenerating into a copy rather than over the config directory lets it run
|
|
12
|
-
# on a working tree it must not modify (CI).
|
|
12
|
+
# on a working tree it must not modify (CI).
|
|
13
|
+
#
|
|
14
|
+
# The diff/report side is source-agnostic (it reads JSON config files); what
|
|
15
|
+
# varies per schema source is only how to regenerate, injected as
|
|
16
|
+
# `regenerator` — a callable that receives a directory pre-seeded with a copy
|
|
17
|
+
# of the committed config and rewrites it the way `generate!` + `tidy!`
|
|
18
|
+
# would. `models:` remains as the ActiveRecord shorthand for it.
|
|
13
19
|
class SchemaCheck
|
|
14
20
|
CATEGORIES = %w[
|
|
15
21
|
added_tables added_columns removed_tables removed_columns changed_tables needs_mask_decision
|
|
@@ -20,9 +26,39 @@ module Exwiw
|
|
|
20
26
|
new(models: ActiveRecord::Base.descendants, schema_dir: schema_dir)
|
|
21
27
|
end
|
|
22
28
|
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
# The Mongoid counterpart. `Mongoid.models` registers only the base class of
|
|
30
|
+
# an inheritance hierarchy, which is exactly what MongoidSchemaGenerator
|
|
31
|
+
# expects (it expands descendants itself), so the same source the generate
|
|
32
|
+
# task introspects is used here.
|
|
33
|
+
def self.from_mongoid_application(schema_dir:)
|
|
34
|
+
Rails.application.eager_load!
|
|
35
|
+
new(schema_dir: schema_dir, regenerator: mongoid_regenerator(::Mongoid.models))
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# The regeneration step `from_mongoid_application` injects, exposed so a
|
|
39
|
+
# caller (and the specs) can run the check against an explicit model list
|
|
40
|
+
# without a Rails application — and so what they exercise is the very lambda
|
|
41
|
+
# production uses.
|
|
42
|
+
#
|
|
43
|
+
# `skip_unsupported` is deliberately left off: this runs as a CI gate, and a
|
|
44
|
+
# newly added construct exwiw cannot represent has to fail the task with the
|
|
45
|
+
# generator's actionable message rather than quietly become an `ignore: true`
|
|
46
|
+
# config that reports clean while the collection stops being dumped.
|
|
47
|
+
def self.mongoid_regenerator(models)
|
|
48
|
+
lambda do |tmp_dir|
|
|
49
|
+
# Explicit: safe mode is not optional here, whatever the library default is.
|
|
50
|
+
MongoidSchemaGenerator.new(models: models, output_dir: tmp_dir, safe_new_columns: true).generate!
|
|
51
|
+
MongoidSchemaGenerator.new(models: models, output_dir: tmp_dir).tidy!
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def initialize(schema_dir:, models: nil, regenerator: nil)
|
|
56
|
+
if models.nil? && regenerator.nil?
|
|
57
|
+
raise ArgumentError, "SchemaCheck requires either models: or regenerator:"
|
|
58
|
+
end
|
|
59
|
+
|
|
25
60
|
@schema_dir = schema_dir
|
|
61
|
+
@regenerator = regenerator || active_record_regenerator(models)
|
|
26
62
|
end
|
|
27
63
|
|
|
28
64
|
# The report as a plain Hash. Every list is sorted, so a given state always
|
|
@@ -47,9 +83,15 @@ module Exwiw
|
|
|
47
83
|
|
|
48
84
|
private def regenerate_into(tmp_dir)
|
|
49
85
|
FileUtils.cp_r(File.join(@schema_dir, "."), tmp_dir) if Dir.exist?(@schema_dir)
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
86
|
+
@regenerator.call(tmp_dir)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
private def active_record_regenerator(models)
|
|
90
|
+
lambda do |tmp_dir|
|
|
91
|
+
# Explicit: safe mode is not optional here, whatever the library default is.
|
|
92
|
+
SchemaGenerator.new(models: models, output_dir: tmp_dir, safe_new_columns: true).generate!
|
|
93
|
+
SchemaGenerator.new(models: models, output_dir: tmp_dir).tidy!
|
|
94
|
+
end
|
|
53
95
|
end
|
|
54
96
|
|
|
55
97
|
# Every config file under `dir`, keyed by its path relative to `dir` so the
|
data/lib/exwiw/table_config.rb
CHANGED
|
@@ -170,9 +170,9 @@ module Exwiw
|
|
|
170
170
|
merged_table.type = passed_table.type
|
|
171
171
|
merged_table.comment = comment
|
|
172
172
|
merged_table.filter = filter
|
|
173
|
-
merged_table.bulk_insert_chunk_size = passed_table.bulk_insert_chunk_size
|
|
174
173
|
merged_table.ignore = ignore
|
|
175
174
|
# User-owned, never regenerated: carry over from the existing config.
|
|
175
|
+
merged_table.bulk_insert_chunk_size = bulk_insert_chunk_size
|
|
176
176
|
merged_table.scope_exempt = scope_exempt
|
|
177
177
|
merged_table.scope_column = scope_column
|
|
178
178
|
merged_table.reverse_scope = reverse_scope
|
data/lib/exwiw/version.rb
CHANGED
data/lib/exwiw.rb
CHANGED
|
@@ -40,6 +40,10 @@ require_relative "exwiw/after_insert_hook"
|
|
|
40
40
|
require_relative "exwiw/runner"
|
|
41
41
|
require_relative "exwiw/explain_runner"
|
|
42
42
|
require_relative "exwiw/schema_generator"
|
|
43
|
+
require_relative "exwiw/db_introspector"
|
|
44
|
+
require_relative "exwiw/db_introspector/mysql_introspector"
|
|
45
|
+
require_relative "exwiw/db_introspector/postgresql_introspector"
|
|
46
|
+
require_relative "exwiw/db_schema_generator"
|
|
43
47
|
require_relative "exwiw/schema_check"
|
|
44
48
|
require_relative "exwiw/mongoid_schema_generator"
|
|
45
49
|
|
data/lib/tasks/exwiw.rake
CHANGED
|
@@ -100,7 +100,44 @@ namespace :exwiw do
|
|
|
100
100
|
Exwiw::MongoidSchemaGenerator.from_rails_application(
|
|
101
101
|
output_dir: resolve_schema_dir.call,
|
|
102
102
|
skip_unsupported: ENV["EXWIW_SKIP_UNSUPPORTED"] == "1",
|
|
103
|
+
# Same convention as `generate`: safe unless EXWIW_NEW_COLUMNS=plain.
|
|
104
|
+
safe_new_columns: safe_new_columns.call,
|
|
103
105
|
).generate!
|
|
104
106
|
end
|
|
107
|
+
|
|
108
|
+
desc "Remove collections from the schema config that no longer exist in the Mongoid application"
|
|
109
|
+
task tidy_mongoid: :environment do
|
|
110
|
+
require "exwiw"
|
|
111
|
+
|
|
112
|
+
result = Exwiw::MongoidSchemaGenerator.from_rails_application(
|
|
113
|
+
output_dir: resolve_schema_dir.call,
|
|
114
|
+
).tidy!
|
|
115
|
+
|
|
116
|
+
if result.empty?
|
|
117
|
+
puts "exwiw: schema config is already tidy; nothing to remove."
|
|
118
|
+
else
|
|
119
|
+
result.removed_tables.each do |name|
|
|
120
|
+
puts "exwiw: removed config for collection '#{name}' (no longer exists in the application)."
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
desc "Report how the committed schema config differs from the Mongoid application, without changing it"
|
|
126
|
+
task check_mongoid: :environment do
|
|
127
|
+
require "exwiw"
|
|
128
|
+
|
|
129
|
+
report = Exwiw::SchemaCheck.from_mongoid_application(schema_dir: resolve_schema_dir.call).run
|
|
130
|
+
json = JSON.pretty_generate(report)
|
|
131
|
+
puts json
|
|
132
|
+
# A file too, so a caller need not assume stdout carries only the JSON.
|
|
133
|
+
File.write(ENV["EXWIW_SCHEMA_CHECK_OUTPUT"], json + "\n") if ENV["EXWIW_SCHEMA_CHECK_OUTPUT"]
|
|
134
|
+
|
|
135
|
+
unless Exwiw::SchemaCheck.clean?(report)
|
|
136
|
+
$stderr.puts "exwiw: the schema config is out of date or has undecided masking; " \
|
|
137
|
+
"run `rake exwiw:schema:generate_mongoid exwiw:schema:tidy_mongoid` " \
|
|
138
|
+
"and resolve every `needs_mask_decision` field."
|
|
139
|
+
exit 1
|
|
140
|
+
end
|
|
141
|
+
end
|
|
105
142
|
end
|
|
106
143
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: exwiw
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.9.
|
|
4
|
+
version: 0.9.23
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shia
|
|
@@ -69,6 +69,10 @@ files:
|
|
|
69
69
|
- lib/exwiw/belongs_to.rb
|
|
70
70
|
- lib/exwiw/cli.rb
|
|
71
71
|
- lib/exwiw/config_file.rb
|
|
72
|
+
- lib/exwiw/db_introspector.rb
|
|
73
|
+
- lib/exwiw/db_introspector/mysql_introspector.rb
|
|
74
|
+
- lib/exwiw/db_introspector/postgresql_introspector.rb
|
|
75
|
+
- lib/exwiw/db_schema_generator.rb
|
|
72
76
|
- lib/exwiw/ddl_postprocessor.rb
|
|
73
77
|
- lib/exwiw/default_mask.rb
|
|
74
78
|
- lib/exwiw/determine_table_processing_order.rb
|