git-merge-structure-sql 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 106ff7bb28c70bd2a3ddab8ada1e1055cd3018acc97bfc7b51163c72033c69bf
4
+ data.tar.gz: 8b3c3484f05e9419128172bc743457580a7b23f280295a5769c99d61366fdb33
5
+ SHA512:
6
+ metadata.gz: ef8055e769b186b91c73278f4a5f50670999a33615b2b059b6c7e6d7d187d1d1a7ef80605473057837daa33f2e2a3fbb32503eee3828600861ec942315ffc0be
7
+ data.tar.gz: 80003f7b2921cdc9cd2923a6670cc9a125c27209ec7fc72cb8870cd282dbfa4eb8bcdf62f0782580c2cf320566c3d8eeed70184cfc3cb2f86a0309b7e383a753
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.5.1
7
+ before_install: gem install bundler -v 1.16.6
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in git-merge-structure-sql.gemspec
6
+ gemspec
@@ -0,0 +1,31 @@
1
+ # git-merge-structure-sql
2
+
3
+ This is a merge driver for Git that resolves trivial parts of
4
+ merge conflicts in a db/structure.sql file of Rails.
5
+
6
+ Currently only PostgreSQL and MySQL dump formats are supported.
7
+
8
+ ## Installation
9
+
10
+ Run this:
11
+
12
+ $ gem install git-merge-structure-sql
13
+
14
+ And enable it yourself in your Git configuration, or let it do that
15
+ for you by this command:
16
+
17
+ $ git-merge-structure-sql --install
18
+
19
+ This adds necessary settings to your
20
+ `~/.gitconfig`/`$XDG_CONFIG_HOME/git/config` and the default
21
+ gitattributes(5) file to enable the merge driver for structure.sql
22
+ files.
23
+
24
+ ## Usage
25
+
26
+ Once enabled, Git should call this driver as necessary when it needs
27
+ to merge changes made in structure.sql.
28
+
29
+ ## Contributing
30
+
31
+ Bug reports and pull requests are welcome on GitHub at https://github.com/knu/git-merge-structure-sql.
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "git/merge/structure/sql"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "git-merge-structure-sql"
4
+
5
+ StructureSqlMergeDriver.new.main(*ARGV)
@@ -0,0 +1,33 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "git-merge-structure-sql"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "git-merge-structure-sql"
8
+ spec.version = StructureSqlMergeDriver::VERSION
9
+ spec.authors = ["Akinori MUSHA"]
10
+ spec.email = ["knu@idaemons.org"]
11
+
12
+ spec.summary = %q{git merge driver for db/structure.sql in a Rails project}
13
+ spec.homepage = "https://github.com/knu/git-merge-structure-sql"
14
+
15
+ if spec.respond_to?(:metadata)
16
+ spec.metadata["homepage_uri"] = spec.homepage
17
+ spec.metadata["source_code_uri"] = spec.homepage
18
+ spec.metadata["changelog_uri"] = "https://github.com/knu/git-merge-structure-sql/blob/master/CHANGELOG.md"
19
+ end
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
24
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
25
+ end
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_development_dependency "bundler", "~> 1.16"
31
+ spec.add_development_dependency "rake", "~> 10.0"
32
+ spec.add_development_dependency "minitest", "~> 5.0"
33
+ end
@@ -0,0 +1,232 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ #
4
+ # git-merge-structure-sql - git merge driver for db/structure.sql in a Rails project
5
+ #
6
+ # How to use:
7
+ # $ git-merge-structure-sql --install
8
+ #
9
+ # Copyright (c) 2018 Akinori MUSHA
10
+ #
11
+ # All rights reserved.
12
+ #
13
+ # Redistribution and use in source and binary forms, with or without
14
+ # modification, are permitted provided that the following conditions
15
+ # are met:
16
+ # 1. Redistributions of source code must retain the above copyright
17
+ # notice, this list of conditions and the following disclaimer.
18
+ # 2. Redistributions in binary form must reproduce the above copyright
19
+ # notice, this list of conditions and the following disclaimer in the
20
+ # documentation and/or other materials provided with the distribution.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28
+ # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
+ # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
+ # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
+ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
+ # SUCH DAMAGE.
33
+ #
34
+
35
+ class StructureSqlMergeDriver
36
+ VERSION = '1.0.0'
37
+ VARIANTS = []
38
+
39
+ module PostgreSQL
40
+ RE_VERSION = /^\('(\d+)'\)[,;]\n/
41
+ RE_VERSIONS = /^INSERT INTO "schema_migrations" \(version\) VALUES\n\K#{RE_VERSION}+/
42
+
43
+ class << self
44
+ def match?(content)
45
+ RE_VERSIONS === content
46
+ end
47
+
48
+ def merge!(*contents)
49
+ merge_versions!(*contents)
50
+ end
51
+
52
+ private
53
+
54
+ def merge_versions!(*contents)
55
+ replacement = format_versions(
56
+ contents.inject([]) { |versions, content|
57
+ versions | content[RE_VERSIONS].scan(RE_VERSION).flatten
58
+ }.sort
59
+ )
60
+
61
+ contents.each { |content|
62
+ content.sub!(RE_VERSIONS, replacement)
63
+ }
64
+ end
65
+
66
+ def format_versions(versions)
67
+ versions.map { |version| "('%s')" % version }.join(",\n") << ";\n"
68
+ end
69
+ end
70
+
71
+ VARIANTS << self
72
+ end
73
+
74
+ module MySQL
75
+ class << self
76
+ RE_DUMP_TIMESTAMP = /^-- Dump completed on \K.+$/
77
+ RE_AUTO_INCREMENT_VALUE = /^\)(?= ).*\K AUTO_INCREMENT=\d+(?=.*;$)/
78
+ RE_VERSION = /^INSERT INTO schema_migrations \(version\) VALUES \('(\d+)'\);\s+/
79
+ RE_VERSIONS = /#{RE_VERSION}+/
80
+
81
+ def match?(content)
82
+ /^-- MySQL dump / === content
83
+ end
84
+
85
+ def merge!(*contents)
86
+ merge_dump_timestamps!(*contents)
87
+ scrub_auto_increment_values!(*contents)
88
+ merge_versions!(*contents)
89
+ end
90
+
91
+ private
92
+
93
+ def merge_dump_timestamps!(*contents)
94
+ replacement = contents.inject('') { |timestamp, content|
95
+ [timestamp, *content.scan(RE_DUMP_TIMESTAMP)].max rescue ''
96
+ }
97
+
98
+ unless replacement.empty?
99
+ contents.each { |content|
100
+ content.gsub!(RE_DUMP_TIMESTAMP, replacement)
101
+ }
102
+ end
103
+ end
104
+
105
+ def scrub_auto_increment_values!(*contents)
106
+ contents.each { |content|
107
+ content.gsub!(RE_AUTO_INCREMENT_VALUE, '')
108
+ }
109
+ end
110
+
111
+ def merge_versions!(*contents)
112
+ replacement = format_versions(
113
+ contents.inject([]) { |versions, content|
114
+ versions | content.scan(RE_VERSION).flatten
115
+ }.sort
116
+ )
117
+
118
+ contents.each { |content|
119
+ content.sub!(RE_VERSIONS, replacement)
120
+ }
121
+ end
122
+
123
+ def format_versions(versions)
124
+ versions.map { |version| "INSERT INTO schema_migrations (version) VALUES ('%s');\n\n" % version }.join
125
+ end
126
+ end
127
+
128
+ VARIANTS << self
129
+ end
130
+
131
+ def system!(*args)
132
+ system(*args) or exit $?.exitstatus
133
+ end
134
+
135
+ def main(*argv)
136
+ require 'optparse'
137
+ require 'shellwords'
138
+
139
+ myname = File.basename($0)
140
+ driver_name = 'merge-structure-sql'
141
+
142
+ banner = <<~EOF
143
+ #{myname} - git merge driver for db/structure.sql in a Rails project #{VERSION}
144
+
145
+ usage: #{myname} <current-file> <base-file> <other-file>
146
+ #{myname} --install
147
+ EOF
148
+
149
+ install = false
150
+
151
+ opts = OptionParser.new(banner) { |opts|
152
+ opts.version = VERSION
153
+ opts.summary_indent = ''
154
+ opts.summary_width = 24
155
+
156
+ opts.on('--install',
157
+ "Enable this merge driver in Git") { |val|
158
+ install = val
159
+ }
160
+ }
161
+
162
+ files = opts.order(argv)
163
+
164
+ if install
165
+ puts "Registering the \"#{driver_name}\" driver in your git configuration"
166
+
167
+ system!(*%W[
168
+ git config --global merge.#{driver_name}.name
169
+ #{'Rails structure.sql merge driver'}
170
+ ])
171
+ system!(*%W[
172
+ git config --global merge.#{driver_name}.driver
173
+ #{"#{myname.shellescape} %A %O %B"}
174
+ ])
175
+
176
+ attributes_file = `git config --global core.attributesfile`.chomp
177
+ attributes_file =
178
+ if $?.success?
179
+ File.expand_path(attributes_file)
180
+ else
181
+ [
182
+ [File.join(ENV['XDG_CONFIG_HOME'] || '~/.config', 'git'), 'attributes'],
183
+ ['~', '.gitattributes']
184
+ ].find { |dir, file|
185
+ if File.directory?(File.expand_path(dir))
186
+ system!(*%W[
187
+ git config --global core.attributesfile #{File.join(dir, file)}
188
+ ])
189
+ break File.expand_path(file, dir)
190
+ end
191
+ } or raise "don't you have home?"
192
+ end
193
+
194
+ File.open(attributes_file, 'r+') { |f|
195
+ pattern = /^\s*structure.sql\s+(?:\S+\s+)*merge=#{Regexp.quote(driver_name)}(?:\s|$)/
196
+ break if f.any? { |line| pattern === line }
197
+
198
+ puts "Enabling the \"#{driver_name}\" driver for structure.sql"
199
+ f.puts "\nstructure.sql merge=#{driver_name}"
200
+ }
201
+
202
+ exit
203
+ end
204
+
205
+ unless files.size == 3
206
+ STDERR.print opts.help
207
+ exit 64
208
+ end
209
+
210
+ contents = files.map { |file| File.read(file) }
211
+
212
+ sample = contents[0]
213
+ if variant = VARIANTS.find { |v| v.match?(sample) }
214
+ variant.merge!(*contents)
215
+
216
+ files.zip(contents) do |file, content|
217
+ File.write(file, content)
218
+ end
219
+ else
220
+ STDERR.puts "#{myname}: Unsupported format; falling back to git-merge-file(1)"
221
+ end
222
+
223
+ exec(*%W[git merge-file -q], *files)
224
+ rescue => e
225
+ STDERR.puts "#{myname}: #{e.message}"
226
+ exit 1
227
+ end
228
+ end
229
+
230
+ if $0 == __FILE__
231
+ StructureSqlMergeDriver.new.main(*ARGV)
232
+ end
metadata ADDED
@@ -0,0 +1,99 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git-merge-structure-sql
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Akinori MUSHA
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-11-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ description:
56
+ email:
57
+ - knu@idaemons.org
58
+ executables:
59
+ - git-merge-structure-sql
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".travis.yml"
65
+ - Gemfile
66
+ - README.md
67
+ - Rakefile
68
+ - bin/console
69
+ - bin/setup
70
+ - exe/git-merge-structure-sql
71
+ - git-merge-structure-sql.gemspec
72
+ - lib/git-merge-structure-sql.rb
73
+ homepage: https://github.com/knu/git-merge-structure-sql
74
+ licenses: []
75
+ metadata:
76
+ homepage_uri: https://github.com/knu/git-merge-structure-sql
77
+ source_code_uri: https://github.com/knu/git-merge-structure-sql
78
+ changelog_uri: https://github.com/knu/git-merge-structure-sql/blob/master/CHANGELOG.md
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.7.6
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: git merge driver for db/structure.sql in a Rails project
99
+ test_files: []