gemstack 0.4.1 → 0.4.2
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 +4 -0
- data/lib/gemstack/cli/template_update.rb +53 -10
- data/lib/gemstack/cli.rb +1 -1
- data/lib/gemstack/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 470fa3d30b1554cfa0aa75c71518f3ec47807a2f09f634c964720133c3cbe0d8
|
|
4
|
+
data.tar.gz: 1b11a77cbac038b67fc22c1b746ef2dd8011bf729a3523b7d99bb32857c62ea5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7f52cbd61e22fc289cc33b7eaa9097ad5b3f8271a5b284599a164bd688547ccbda631268256d78c8f0bee9eb253f3b9b3adc74a86ac085292ffcd6896294f516
|
|
7
|
+
data.tar.gz: ff4886ab02478e6a1355f47fbe0d072886b49be8c8c33060a06b706137f47836dfe31f2ee52db0335c71de9b82a46f980728b1a9a26e5f0614e01c8dd584b741
|
data/CHANGELOG.md
CHANGED
|
@@ -76,7 +76,11 @@ module GemStack
|
|
|
76
76
|
# template unchanged skipped (your edits are yours)
|
|
77
77
|
# new in this version created
|
|
78
78
|
# you never edited the file updated
|
|
79
|
-
# you edited it you choose: overwrite, skip, diff, or save as FILE.new
|
|
79
|
+
# you edited it you choose: merge, overwrite, skip, diff, or save as FILE.new
|
|
80
|
+
#
|
|
81
|
+
# Merge is a three-way merge (git merge-file): the release's changes to the
|
|
82
|
+
# template are applied to your copy, keeping your edits. Where both changed
|
|
83
|
+
# the same lines the file gets <<<<<<< conflict markers to resolve.
|
|
80
84
|
#
|
|
81
85
|
# Apps record the templates they're on in .gemstack/version. Older apps don't,
|
|
82
86
|
# so each file is compared with every earlier release's template: matching
|
|
@@ -88,9 +92,10 @@ module GemStack
|
|
|
88
92
|
# (db/migrations/) are the app's history and never part of an update.
|
|
89
93
|
MANAGED = %w[Gemfile .gemstack/version].freeze
|
|
90
94
|
|
|
91
|
-
# created/updated/saved (as FILE.new) are done;
|
|
92
|
-
#
|
|
93
|
-
|
|
95
|
+
# created/updated/merged/saved (as FILE.new) are done; marked were merged
|
|
96
|
+
# with conflict markers to resolve; conflicts were left for you; removed
|
|
97
|
+
# are files you deleted, which stay deleted.
|
|
98
|
+
Result = Struct.new(:created, :updated, :merged, :marked, :saved, :conflicts, :removed, keyword_init: true)
|
|
94
99
|
|
|
95
100
|
def self.recorded_version(root)
|
|
96
101
|
path = File.join(root, VERSION_FILE)
|
|
@@ -109,7 +114,7 @@ module GemStack
|
|
|
109
114
|
$stdin.gets.to_s.strip.downcase
|
|
110
115
|
}
|
|
111
116
|
@old_templates = old_templates
|
|
112
|
-
@result = Result.new(created: [], updated: [], saved: [], conflicts: [], removed: [])
|
|
117
|
+
@result = Result.new(created: [], updated: [], merged: [], marked: [], saved: [], conflicts: [], removed: [])
|
|
113
118
|
end
|
|
114
119
|
|
|
115
120
|
def run
|
|
@@ -210,7 +215,7 @@ module GemStack
|
|
|
210
215
|
return @result.removed << path if mine.nil?
|
|
211
216
|
return update(path, file, :updated) if olds.include?(mine) # an unedited, older copy
|
|
212
217
|
|
|
213
|
-
conflict(path, file, mine)
|
|
218
|
+
conflict(path, file, mine, olds.compact.uniq)
|
|
214
219
|
end
|
|
215
220
|
|
|
216
221
|
def create(path, file)
|
|
@@ -225,12 +230,16 @@ module GemStack
|
|
|
225
230
|
status("update", path)
|
|
226
231
|
end
|
|
227
232
|
|
|
228
|
-
def conflict(path, file, mine)
|
|
233
|
+
def conflict(path, file, mine, bases)
|
|
229
234
|
return record_conflict(path) unless @interactive
|
|
230
235
|
|
|
231
236
|
loop do
|
|
232
|
-
case @prompt.call("#{path} changed in this version and you edited it — [
|
|
233
|
-
"[d]iff, save as [n]ew file?")
|
|
237
|
+
case @prompt.call("#{path} changed in this version and you edited it — [m]erge (keeps your edits), " \
|
|
238
|
+
"[o]verwrite, [s]kip, [d]iff, save as [n]ew file?")
|
|
239
|
+
when "m"
|
|
240
|
+
return if merge(path, file, mine, bases)
|
|
241
|
+
|
|
242
|
+
@output.puts(" Can't merge: it needs git and the earlier template (not available). Choose another option.")
|
|
234
243
|
when "o" then return update(path, file, :updated)
|
|
235
244
|
when "n" then return save_new(path, file)
|
|
236
245
|
when "d" then @output.puts(diff(mine, file.content, path))
|
|
@@ -239,6 +248,39 @@ module GemStack
|
|
|
239
248
|
end
|
|
240
249
|
end
|
|
241
250
|
|
|
251
|
+
# Applies the release's template changes to your copy. Without a recorded
|
|
252
|
+
# version the starting template isn't known: each earlier release's is
|
|
253
|
+
# tried (newest first) and the merge with the fewest conflicts wins.
|
|
254
|
+
def merge(path, file, mine, bases)
|
|
255
|
+
merges = bases.reverse.filter_map { |base| merge_file(path, mine, base, file.content) }
|
|
256
|
+
return false if merges.empty?
|
|
257
|
+
|
|
258
|
+
text, conflicts = merges.min_by { |_, count| count }
|
|
259
|
+
write(path, AppFile.new(text, file.mode))
|
|
260
|
+
if conflicts.zero?
|
|
261
|
+
@result.merged << path
|
|
262
|
+
status("merge", path)
|
|
263
|
+
else
|
|
264
|
+
@result.marked << path
|
|
265
|
+
status("merge", "#{path} — #{conflicts} conflict#{"s" if conflicts > 1}: resolve the <<<<<<< markers")
|
|
266
|
+
end
|
|
267
|
+
true
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# [merged text, number of conflicts], or nil without git.
|
|
271
|
+
def merge_file(path, mine, base, theirs)
|
|
272
|
+
Dir.mktmpdir("gemstack-merge") do |dir|
|
|
273
|
+
files = { "yours" => mine, "base" => base, "new" => theirs }.map do |name, content|
|
|
274
|
+
File.join(dir, name).tap { |file| File.binwrite(file, content) }
|
|
275
|
+
end
|
|
276
|
+
labels = ["#{path} (yours)", "#{path} (earlier GemStack)", "#{path} (GemStack #{GemStack::VERSION})"]
|
|
277
|
+
out, status = Open3.capture2("git", "merge-file", "-p", *labels.flat_map { |label| ["-L", label] }, *files)
|
|
278
|
+
[out, status.exitstatus] if status.exitstatus.between?(0, 127)
|
|
279
|
+
end
|
|
280
|
+
rescue SystemCallError
|
|
281
|
+
nil
|
|
282
|
+
end
|
|
283
|
+
|
|
242
284
|
def save_new(path, file)
|
|
243
285
|
write("#{path}.new", file)
|
|
244
286
|
@result.saved << path
|
|
@@ -275,7 +317,8 @@ module GemStack
|
|
|
275
317
|
end
|
|
276
318
|
|
|
277
319
|
def report
|
|
278
|
-
done = { "created" => @result.created, "updated" => @result.updated, "
|
|
320
|
+
done = { "created" => @result.created, "updated" => @result.updated, "merged" => @result.merged,
|
|
321
|
+
"merged with conflicts to resolve" => @result.marked, "saved as .new" => @result.saved,
|
|
279
322
|
"left for you" => @result.conflicts }.reject { |_, paths| paths.empty? }
|
|
280
323
|
if done.empty?
|
|
281
324
|
@output.puts(" nothing to update")
|
data/lib/gemstack/cli.rb
CHANGED
|
@@ -241,7 +241,7 @@ module GemStack
|
|
|
241
241
|
are updated, and for ones you edited you choose: overwrite, skip, see the diff, or FILE.new.
|
|
242
242
|
|
|
243
243
|
gemstack update # the latest release
|
|
244
|
-
gemstack update 0.4.
|
|
244
|
+
gemstack update 0.4.2 # a specific version
|
|
245
245
|
gemstack update --templates --dry-run # only the template step, preview
|
|
246
246
|
gemstack update --templates --from 0.3.5
|
|
247
247
|
DESC
|
data/lib/gemstack/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gemstack
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Adware Technologies
|
|
@@ -44,14 +44,14 @@ dependencies:
|
|
|
44
44
|
requirements:
|
|
45
45
|
- - '='
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version: 0.4.
|
|
47
|
+
version: 0.4.2
|
|
48
48
|
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
52
|
- - '='
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version: 0.4.
|
|
54
|
+
version: 0.4.2
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: json
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|