hookup 1.1.0 → 1.2.0

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.
Files changed (4) hide show
  1. data/README.markdown +4 -0
  2. data/hookup.gemspec +2 -2
  3. data/lib/hookup.rb +97 -44
  4. metadata +23 -32
@@ -30,6 +30,10 @@ migrations have been added, deleted, or modified. Deleted and modified
30
30
  migrations are given the `rake db:migrate:down` treatment, then `rake
31
31
  db:migrate` is invoked to bring everything else up to date.
32
32
 
33
+ To force reloading the database if migrating fails, Add
34
+ `--load-schema="rake db:reset"` to the `hookup post-checkout` line in
35
+ `.git/hooks/post-checkout`.
36
+
33
37
  ### Schema Resolving
34
38
 
35
39
  Each time there's a conflict in `db/schema.rb` on the
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "hookup"
5
- s.version = "1.1.0"
5
+ s.version = "1.2.0"
6
6
  s.platform = Gem::Platform::RUBY
7
7
  s.authors = ["Tim Pope"]
8
8
  s.email = ["code@tp"+'ope.net']
9
- s.homepage = ""
9
+ s.homepage = "https://github.com/tpope/hookup"
10
10
  s.summary = %q{Automate the bundle/migration tedium of Rails with Git hooks}
11
11
  s.description = %q{Automatically bundle and migrate your Rails app when switching branches, merging upstream changes, and bisecting.}
12
12
 
@@ -67,68 +67,121 @@ class Hookup
67
67
  protected :append
68
68
 
69
69
  def post_checkout(*args)
70
- old, new = args.shift, args.shift || 'HEAD'
71
- if old == '0000000000000000000000000000000000000000'
72
- old = EMPTY_DIR
73
- elsif old.nil?
74
- old = '@{-1}'
75
- end
76
- bundle(old, new, *args)
77
- migrate(old, new, *args)
70
+ PostCheckout.new(ENV, *args).run
78
71
  end
79
72
 
80
- def bundle(old, new, *args)
81
- return if args.first == '0'
73
+ class PostCheckout
82
74
 
83
- return unless File.exist?('Gemfile')
84
- if %x{git diff --name-only #{old} #{new}} =~ /^Gemfile|\.gemspec$/
85
- begin
86
- # If Bundler in turn spawns Git, it can get confused by $GIT_DIR
87
- git_dir = ENV.delete('GIT_DIR')
88
- %x{bundle check}
89
- unless $?.success?
90
- puts "Bundling..."
91
- system("bundle | grep -v '^Using ' | grep -v ' is complete'")
92
- end
93
- ensure
94
- ENV['GIT_DIR'] = git_dir
75
+ attr_reader :old, :new, :env
76
+
77
+ def partial?
78
+ @partial
79
+ end
80
+
81
+ def initialize(environment, *args)
82
+ @env ||= environment.to_hash.dup
83
+ require 'optparse'
84
+ opts = OptionParser.new
85
+ opts.banner = "Usage: hookup post-checkout <old> <new> <full>"
86
+ opts.on('--load-schema=COMMAND', 'Run COMMAND on migration failure') do |command|
87
+ env['HOOKUP_LOAD_SCHEMA'] = command
88
+ end
89
+ opts.parse!(args)
90
+
91
+ @old = args.shift
92
+ if @old == '0000000000000000000000000000000000000000'
93
+ @old = EMPTY_DIR
94
+ elsif @old.nil?
95
+ @old = '@{-1}'
95
96
  end
97
+ @new = args.shift || 'HEAD'
98
+ @partial = (args.shift == '0')
96
99
  end
97
- end
98
100
 
99
- def migrate(old, new, *args)
100
- return if args.first == '0'
101
+ def run
102
+ return if env['GIT_REFLOG_ACTION'] =~ /^(?:pull|rebase)/
103
+ unless partial?
104
+ bundle
105
+ migrate
106
+ end
107
+ end
101
108
 
102
- schemas = %w(db/schema.rb db/development_structure.sql).select do |schema|
103
- status = %x{git diff --name-status #{old} #{new} -- #{schema}}.chomp
104
- system 'rake', 'db:create' if status =~ /^A/
105
- status !~ /^D/ && !status.empty?
109
+ def bundler?
110
+ File.exist?('Gemfile')
106
111
  end
107
112
 
108
- migrations = %x{git diff --name-status #{old} #{new} -- db/migrate}.scan(/.+/).map {|l| l.split(/\t/) }
109
- begin
110
- migrations.select {|(t,f)| %w(D M).include?(t)}.reverse.each do |type, file|
113
+ def bundle
114
+ return unless bundler?
115
+ if %x{git diff --name-only #{old} #{new}} =~ /^Gemfile|\.gemspec$/
111
116
  begin
112
- system 'git', 'checkout', old, '--', file
113
- unless system 'rake', 'db:migrate:down', "VERSION=#{File.basename(file)}"
114
- raise Error, "Failed to rollback #{File.basename(file)}. Consider rake db:setup"
117
+ # If Bundler in turn spawns Git, it can get confused by $GIT_DIR
118
+ git_dir = ENV.delete('GIT_DIR')
119
+ %x{bundle check}
120
+ unless $?.success?
121
+ puts "Bundling..."
122
+ system("bundle | grep -v '^Using ' | grep -v ' is complete'")
115
123
  end
116
124
  ensure
117
- if type == 'D'
118
- system 'git', 'rm', '--force', '--quiet', '--', file
119
- else
120
- system 'git', 'checkout', new, '--', file
121
- end
125
+ ENV['GIT_DIR'] = git_dir
122
126
  end
123
127
  end
128
+ end
129
+
130
+ def migrate
131
+ schemas = %w(db/schema.rb db/development_structure.sql).select do |schema|
132
+ status = %x{git diff --name-status #{old} #{new} -- #{schema}}.chomp
133
+ rake 'db:create' if status =~ /^A/
134
+ status !~ /^D/ && !status.empty?
135
+ end
124
136
 
125
- if migrations.any? {|(t,f)| %w(A M).include?(t)}
126
- system 'rake', 'db:migrate'
137
+ return if schemas.empty?
138
+
139
+ migrations = %x{git diff --name-status #{old} #{new} -- db/migrate}.scan(/.+/).map {|l| l.split(/\t/) }
140
+ begin
141
+ migrations.select {|(t,f)| %w(D M).include?(t)}.reverse.each do |type, file|
142
+ begin
143
+ system 'git', 'checkout', old, '--', file
144
+ unless rake 'db:migrate:down', "VERSION=#{File.basename(file)}"
145
+ raise Error, "Failed to rollback #{File.basename(file)}"
146
+ end
147
+ ensure
148
+ if type == 'D'
149
+ system 'git', 'rm', '--force', '--quiet', '--', file
150
+ else
151
+ system 'git', 'checkout', new, '--', file
152
+ end
153
+ end
154
+ end
155
+
156
+ if migrations.any? {|(t,f)| %w(A M).include?(t)}
157
+ rake 'db:migrate'
158
+ end
159
+
160
+ ensure
161
+ changes = %x{git diff --name-status #{new} -- #{schemas.join(' ')}}
162
+
163
+ unless changes.empty?
164
+ system 'git', 'checkout', '--', *schemas
165
+
166
+ puts "Schema out of sync."
167
+
168
+ fallback = env['HOOKUP_LOAD_SCHEMA']
169
+ if fallback && fallback != ''
170
+ puts "Trying #{fallback}..."
171
+ system fallback
172
+ end
173
+ end
127
174
  end
175
+ end
128
176
 
129
- ensure
130
- system 'git', 'checkout', '--', *schemas if schemas.any?
177
+ def rake(*args)
178
+ if bundler?
179
+ system 'bundle', 'exec', 'rake', *args
180
+ else
181
+ system 'rake', *args
182
+ end
131
183
  end
184
+
132
185
  end
133
186
 
134
187
  def resolve_schema(a, o, b, marker_size = 7)
metadata CHANGED
@@ -1,29 +1,25 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: hookup
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.0
4
5
  prerelease:
5
- version: 1.1.0
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Tim Pope
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-08-24 00:00:00 -04:00
14
- default_executable:
12
+ date: 2012-10-21 00:00:00.000000000 Z
15
13
  dependencies: []
16
-
17
- description: Automatically bundle and migrate your Rails app when switching branches, merging upstream changes, and bisecting.
18
- email:
14
+ description: Automatically bundle and migrate your Rails app when switching branches,
15
+ merging upstream changes, and bisecting.
16
+ email:
19
17
  - code@tpope.net
20
- executables:
18
+ executables:
21
19
  - hookup
22
20
  extensions: []
23
-
24
21
  extra_rdoc_files: []
25
-
26
- files:
22
+ files:
27
23
  - .gitignore
28
24
  - Gemfile
29
25
  - MIT-LICENSE
@@ -32,33 +28,28 @@ files:
32
28
  - bin/hookup
33
29
  - hookup.gemspec
34
30
  - lib/hookup.rb
35
- has_rdoc: true
36
- homepage: ""
31
+ homepage: https://github.com/tpope/hookup
37
32
  licenses: []
38
-
39
33
  post_install_message:
40
34
  rdoc_options: []
41
-
42
- require_paths:
35
+ require_paths:
43
36
  - lib
44
- required_ruby_version: !ruby/object:Gem::Requirement
37
+ required_ruby_version: !ruby/object:Gem::Requirement
45
38
  none: false
46
- requirements:
47
- - - ">="
48
- - !ruby/object:Gem::Version
49
- version: "0"
50
- required_rubygems_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
44
  none: false
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- version: "0"
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
56
49
  requirements: []
57
-
58
50
  rubyforge_project: hookup
59
- rubygems_version: 1.6.2
51
+ rubygems_version: 1.8.11
60
52
  signing_key:
61
53
  specification_version: 3
62
54
  summary: Automate the bundle/migration tedium of Rails with Git hooks
63
55
  test_files: []
64
-