sidenotes 0.2.0 → 0.2.1
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 +12 -0
- data/README.md +1 -1
- data/lib/sidenotes/railtie.rb +20 -1
- data/lib/sidenotes/verifier.rb +34 -3
- data/lib/sidenotes/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 49cfca99965003c2f6fbff02ac2d9a930671bec5bb36f0cafecbb03e8c2e47f1
|
|
4
|
+
data.tar.gz: 505db15a10c3df2c3af8d3d3425d1cb3ea4580faf22a24fe0ba10a48dd0c432d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 042f58ab4161438219e6980cd8637bb07395e91bd4240e1c7bc729362c3a27d99b0d67cd2ff91c17103a58deb2fd6fa830de42749bdc1bceadc44fd7c7fb6334
|
|
7
|
+
data.tar.gz: 6e621545a5d90913fa388317bec1fc84bd75c7f0e2407be88f701eeff6d4d957a5f1b949379475b4ae4668edecf6af72dfd42db3adebb19b1b58fdde5f7ff808
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.1] - 2026-05-01
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `sidenotes:verify` now detects pending migrations and reports them as drift (exits 1). This catches the case where a migration file exists but hasn't been applied, where the sidecars and DB happen to match but the test suite would later fail with `ActiveRecord::PendingMigrationError`.
|
|
13
|
+
- Verifier API: `Sidenotes::Verifier#pending_migrations`, `#pending_migrations?`
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- `Verifier#drift?` and `#issue_count` now include pending migrations.
|
|
18
|
+
- Migration context lookup supports both pre-7.2 (`connection.migration_context`) and 7.2+ (`connection_pool.migration_context`) APIs.
|
|
19
|
+
|
|
8
20
|
## [0.2.0] - 2026-04-29
|
|
9
21
|
|
|
10
22
|
### Added
|
data/README.md
CHANGED
|
@@ -79,7 +79,7 @@ rake sidenotes:clean
|
|
|
79
79
|
rake sidenotes:verify
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
Compares each `.annotations/` sidecar file against the live database schema and reports drift (missing/extra columns, indexes, associations, foreign keys, or models without sidecars). Exits with status `1` if any drift
|
|
82
|
+
Compares each `.annotations/` sidecar file against the live database schema and reports drift (missing/extra columns, indexes, associations, foreign keys, or models without sidecars). It also surfaces **pending migrations** — if a migration file exists but hasn't been applied, sidenotes flags it before doing the schema comparison, since the test suite would fail later anyway. Exits with status `1` if any drift or pending migrations are detected, making it suitable for CI:
|
|
83
83
|
|
|
84
84
|
```yaml
|
|
85
85
|
# .github/workflows/ci.yml
|
data/lib/sidenotes/railtie.rb
CHANGED
|
@@ -68,18 +68,37 @@ module Sidenotes
|
|
|
68
68
|
puts "Checking #{verifier.checked_count} model annotations against database..."
|
|
69
69
|
puts
|
|
70
70
|
|
|
71
|
+
print_pending_migrations(verifier) if verifier.pending_migrations?
|
|
72
|
+
print_drifts(verifier)
|
|
73
|
+
print_missing_sidecars(verifier)
|
|
74
|
+
print_summary(verifier)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def self.print_pending_migrations(verifier)
|
|
78
|
+
puts ' PENDING MIGRATIONS detected (run `rails db:migrate` first):'
|
|
79
|
+
verifier.pending_migrations.each do |m|
|
|
80
|
+
puts " - #{m['version']} #{m['name']}"
|
|
81
|
+
end
|
|
82
|
+
puts
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def self.print_drifts(verifier)
|
|
71
86
|
verifier.drifts.each do |drift|
|
|
72
87
|
puts " #{File.basename(drift.sidecar_path)} - DRIFT:"
|
|
73
88
|
drift.issues.each { |issue| puts " #{issue}" }
|
|
74
89
|
puts
|
|
75
90
|
end
|
|
91
|
+
end
|
|
76
92
|
|
|
93
|
+
def self.print_missing_sidecars(verifier)
|
|
77
94
|
verifier.missing_sidecars.each do |name|
|
|
78
95
|
puts " #{name} - MISSING (model exists, no sidecar file)"
|
|
79
96
|
end
|
|
97
|
+
end
|
|
80
98
|
|
|
99
|
+
def self.print_summary(verifier)
|
|
81
100
|
if verifier.drift?
|
|
82
|
-
puts "#{verifier.issue_count} issue(s) found. Run `rake sidenotes:generate` to update."
|
|
101
|
+
puts "#{verifier.issue_count} issue(s) found. Run `rake db:migrate && rake sidenotes:generate` to update."
|
|
83
102
|
else
|
|
84
103
|
puts 'All annotations are up to date.'
|
|
85
104
|
end
|
data/lib/sidenotes/verifier.rb
CHANGED
|
@@ -7,20 +7,37 @@ module Sidenotes
|
|
|
7
7
|
class Verifier
|
|
8
8
|
Drift = Struct.new(:model_name, :sidecar_path, :issues, keyword_init: true)
|
|
9
9
|
|
|
10
|
-
attr_reader :drifts, :missing_sidecars, :checked_count
|
|
10
|
+
attr_reader :drifts, :missing_sidecars, :checked_count, :pending_migrations
|
|
11
11
|
|
|
12
12
|
def initialize
|
|
13
13
|
@drifts = []
|
|
14
14
|
@missing_sidecars = []
|
|
15
15
|
@checked_count = 0
|
|
16
|
+
@pending_migrations = []
|
|
16
17
|
end
|
|
17
18
|
|
|
18
19
|
def verify_all
|
|
20
|
+
check_pending_migrations
|
|
19
21
|
generator = Generator.new
|
|
20
22
|
generator.discover_models.each { |model| verify_model(model) }
|
|
21
23
|
self
|
|
22
24
|
end
|
|
23
25
|
|
|
26
|
+
def check_pending_migrations
|
|
27
|
+
context = migration_context
|
|
28
|
+
return unless context.respond_to?(:pending_migrations)
|
|
29
|
+
|
|
30
|
+
@pending_migrations = context.pending_migrations.map do |m|
|
|
31
|
+
{ 'version' => m.version, 'name' => m.name }
|
|
32
|
+
end
|
|
33
|
+
rescue StandardError => e
|
|
34
|
+
warn "Sidenotes: could not check pending migrations: #{e.message}"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def pending_migrations?
|
|
38
|
+
pending_migrations.any?
|
|
39
|
+
end
|
|
40
|
+
|
|
24
41
|
def verify_model(model)
|
|
25
42
|
inspector = ModelInspector.new(model)
|
|
26
43
|
return unless inspector.inspectable?
|
|
@@ -43,15 +60,29 @@ module Sidenotes
|
|
|
43
60
|
end
|
|
44
61
|
|
|
45
62
|
def drift?
|
|
46
|
-
drifts.any? || missing_sidecars.any?
|
|
63
|
+
drifts.any? || missing_sidecars.any? || pending_migrations?
|
|
47
64
|
end
|
|
48
65
|
|
|
49
66
|
def issue_count
|
|
50
|
-
drifts.sum { |d| d.issues.size } + missing_sidecars.size
|
|
67
|
+
drifts.sum { |d| d.issues.size } + missing_sidecars.size + pending_migrations.size
|
|
51
68
|
end
|
|
52
69
|
|
|
53
70
|
private
|
|
54
71
|
|
|
72
|
+
def migration_context
|
|
73
|
+
return nil unless defined?(ActiveRecord::Base)
|
|
74
|
+
|
|
75
|
+
pool = ActiveRecord::Base.connection_pool
|
|
76
|
+
return pool.migration_context if pool.respond_to?(:migration_context)
|
|
77
|
+
|
|
78
|
+
conn = ActiveRecord::Base.connection
|
|
79
|
+
return conn.migration_context if conn.respond_to?(:migration_context)
|
|
80
|
+
|
|
81
|
+
nil
|
|
82
|
+
rescue StandardError
|
|
83
|
+
nil
|
|
84
|
+
end
|
|
85
|
+
|
|
55
86
|
def sidecar_path_for(model)
|
|
56
87
|
config = Sidenotes.configuration
|
|
57
88
|
File.join(config.output_directory, "#{model.name.underscore}.#{config.file_extension}")
|
data/lib/sidenotes/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sidenotes
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Wes Mason
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-05-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|