Skip to content

Commit 1fc3dd7

Browse files
jfelchnerShane da Silva
authored and
Shane da Silva
committedMay 14, 2014
Add RailsSchemaUpToDate Hook
Change-Id: I0d72670f215b79a46bce84abaf7f6fcc7a990b37 Reviewed-on: http://gerrit.causes.com/37946 Tested-by: jenkins <jenkins@causes.com> Reviewed-by: Shane da Silva <shane@causes.com>
1 parent d2baf04 commit 1fc3dd7

File tree

3 files changed

+206
-0
lines changed

3 files changed

+206
-0
lines changed
 

‎config/default.yml

+7
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ PreCommit:
102102
description: 'Analyzing with flake8'
103103
include: '**/*.py'
104104

105+
RailsSchemaUpToDate:
106+
description: 'Checking if database schema is up to date'
107+
include:
108+
- 'db/migrate/*.rb'
109+
- 'db/schema.rb'
110+
- 'db/structure.sql'
111+
105112
Rubocop:
106113
description: 'Analyzing with Rubocop'
107114
include:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
module Overcommit::Hook::PreCommit
2+
# Check to see whether the schema file is in line with the migrations
3+
class RailsSchemaUpToDate < Base
4+
def run
5+
if migration_files.any? && schema_files.none?
6+
return :bad, "It looks like you're adding a migration, but did not update the schema file"
7+
elsif migration_files.none? && schema_files.any?
8+
return :bad, "You're trying to change the schema without adding a migration file"
9+
elsif migration_files.any? && schema_files.any?
10+
latest_version = migration_files.map { |file| file[/\d+/] }.sort.last
11+
schema = schema_files.map { |file| File.read(file) }.join
12+
up_to_date = schema.include?(latest_version)
13+
14+
unless up_to_date
15+
return :bad, "The latest migration version you're committing is #{latest_version} but your schema file #{schema_files.join(' or ')} is on a different version."
16+
end
17+
end
18+
19+
:good
20+
end
21+
22+
private
23+
24+
def migration_files
25+
@migration_files ||= applicable_files.select do |file|
26+
file.match %r{db/migrate/.*\.rb}
27+
end
28+
end
29+
30+
def schema_files
31+
@schema_files ||= applicable_files.select do |file|
32+
file.match %r{db/schema\.rb|db/structure.*\.sql}
33+
end
34+
end
35+
end
36+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
require 'spec_helper'
2+
3+
describe Overcommit::Hook::PreCommit::RailsSchemaUpToDate do
4+
let(:config) { Overcommit::ConfigurationLoader.default_configuration }
5+
let(:context) { double('context') }
6+
let(:migration_files) { %w{db/migrate/20140304042233_some_migration.rb
7+
db/migrate/20140305123456_some_migration.rb} }
8+
let(:ruby_schema_file) { 'db/schema.rb' }
9+
let(:sql_schema_file) { 'db/structure.sql' }
10+
11+
subject { described_class.new(config, context) }
12+
13+
context "when a migration was added but the schema wasn't updated" do
14+
before do
15+
subject.stub(:applicable_files).and_return(migration_files)
16+
end
17+
18+
around do |example|
19+
repo do
20+
FileUtils.mkdir_p('db/migrate')
21+
22+
migration_files.each do |migration_file|
23+
File.open(migration_file, 'w') { |f| f.write('migration') }
24+
`git add #{migration_file}`
25+
end
26+
27+
example.run
28+
end
29+
end
30+
31+
it { should fail_hook }
32+
end
33+
34+
context "when a ruby schema file was added but no migration files were" do
35+
before do
36+
subject.stub(:applicable_files).and_return([ruby_schema_file])
37+
end
38+
39+
around do |example|
40+
repo do
41+
FileUtils.mkdir_p('db/migrate')
42+
File.open(ruby_schema_file, 'w') { |f| f.write('schema') }
43+
`git add #{ruby_schema_file}`
44+
example.run
45+
end
46+
end
47+
48+
it { should fail_hook }
49+
end
50+
51+
context "when a SQL schema file was added but no migration files were" do
52+
before do
53+
subject.stub(:applicable_files).and_return([sql_schema_file])
54+
end
55+
56+
around do |example|
57+
repo do
58+
FileUtils.mkdir_p('db/migrate')
59+
File.open(sql_schema_file, 'w') { |f| f.write('schema') }
60+
`git add #{sql_schema_file}`
61+
example.run
62+
end
63+
end
64+
65+
it { should fail_hook }
66+
end
67+
68+
context "when both a Ruby schema file with the latest version and migrations are added" do
69+
before do
70+
subject.stub(:applicable_files).and_return(migration_files << ruby_schema_file)
71+
end
72+
73+
around do |example|
74+
repo do
75+
FileUtils.mkdir_p('db/migrate')
76+
77+
File.open(ruby_schema_file, 'w') { |f| f.write('20140305123456') }
78+
`git add #{ruby_schema_file}`
79+
80+
migration_files.each do |migration_file|
81+
File.open(migration_file, 'w') { |f| f.write('migration') }
82+
`git add #{migration_file}`
83+
end
84+
85+
example.run
86+
end
87+
end
88+
89+
it { should pass }
90+
end
91+
92+
context "when both a Ruby schema file which is not at the latest version and migrations are added" do
93+
before do
94+
subject.stub(:applicable_files).and_return(migration_files << ruby_schema_file)
95+
end
96+
97+
around do |example|
98+
repo do
99+
FileUtils.mkdir_p('db/migrate')
100+
101+
File.open(ruby_schema_file, 'w') { |f| f.write('20140205123456') }
102+
`git add #{ruby_schema_file}`
103+
104+
migration_files.each do |migration_file|
105+
File.open(migration_file, 'w') { |f| f.write('migration') }
106+
`git add #{migration_file}`
107+
end
108+
109+
example.run
110+
end
111+
end
112+
113+
it { should fail_hook }
114+
end
115+
116+
context "when both a SQL schema file with the latest version and migrations are added" do
117+
before do
118+
subject.stub(:applicable_files).and_return(migration_files << sql_schema_file)
119+
end
120+
121+
around do |example|
122+
repo do
123+
FileUtils.mkdir_p('db/migrate')
124+
125+
File.open(sql_schema_file, 'w') { |f| f.write('20140305123456') }
126+
`git add #{sql_schema_file}`
127+
128+
migration_files.each do |migration_file|
129+
File.open(migration_file, 'w') { |f| f.write('migration') }
130+
`git add #{migration_file}`
131+
end
132+
133+
example.run
134+
end
135+
end
136+
137+
it { should pass }
138+
end
139+
140+
context "when both a SQL schema file which is not at the latest version and migrations are added" do
141+
before do
142+
subject.stub(:applicable_files).and_return(migration_files << sql_schema_file)
143+
end
144+
145+
around do |example|
146+
repo do
147+
FileUtils.mkdir_p('db/migrate')
148+
149+
File.open(sql_schema_file, 'w') { |f| f.write('20140205123456') }
150+
`git add #{sql_schema_file}`
151+
152+
migration_files.each do |migration_file|
153+
File.open(migration_file, 'w') { |f| f.write('migration') }
154+
`git add #{migration_file}`
155+
end
156+
157+
example.run
158+
end
159+
end
160+
161+
it { should fail_hook }
162+
end
163+
end

0 commit comments

Comments
 (0)
Please sign in to comment.