binary-merge 7.1.1 → 7.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cbba43e2ced0cc3c802f60d5b4ac81b997a9e0f3312a79e219b7db09eb87d724
4
- data.tar.gz: 686b68c0d0f824e047fab2caf9381217223ff9efd646c3a9ebe3076f6d27d470
3
+ metadata.gz: e44595c3208c046ae8140cc0151c9202f79173c8bf6a2a0c04ffc9d898320ddf
4
+ data.tar.gz: 5b52152c70810249660103bb8440b3e67f63c8618a12d6b86ca9a14b6b939f7b
5
5
  SHA512:
6
- metadata.gz: c0ad7e02abaa2b03982d1809cb3e3c04c49b3d361b7463e32f0d8a435b7b91fbbec0f4e572f9ef53aa1489235c896a1e975775651a33614bdb1047a7a3f56637
7
- data.tar.gz: 8428f548fc35df0be04e787771f18430460c198b069b05ec4aa52bc09ed23d01ed7e4ae2689d3d2a929cd51a62836b04032b6c7ce4a13a5cdc061bf02f001ae1
6
+ metadata.gz: 172e31e494e2f283239071cee63f26ea8e79948acc06c4f9752713f18d6a3fd3e9da8a5755c5d4e29edf8c0fdd6586434bac4b8b3f5f367d6e49c7397af31e24
7
+ data.tar.gz: 1fcf18dbbaf050c487b8f59eedc442d57b79c1bb8c2240d4ac2a415e431f1fc41dd0e5d726b2c118e2e8cc7c23c77e33b9ac3a39a0fac8994719260e3e1c6727
checksums.yaml.gz.sig CHANGED
Binary file
data/README.md CHANGED
@@ -51,7 +51,7 @@ unsafe mutation diagnostics for schema-specific parser gems such as
51
51
 
52
52
  ### Compatibility
53
53
 
54
- Compatible with MRI Ruby 4.0.0+, and concordant releases of JRuby, and TruffleRuby.
54
+ Compatible with MRI Ruby 4.0.0+, JRuby, and TruffleRuby.
55
55
  CI workflows and Appraisals are generated for MRI Ruby 4.0.0+.
56
56
  This test floor is configured by `ruby.test_minimum` in `.kettle-jem.yml` and
57
57
  may be higher than the gem's runtime compatibility floor when legacy Rubies are
@@ -119,20 +119,12 @@ See [SECURITY.md][🔐security].
119
119
  ## 🤝 Contributing
120
120
 
121
121
  If you need some ideas of where to help, you could work on adding more code coverage,
122
- or if it is already 💯 (see [below](#code-coverage)) check [issues][🤝gh-issues] or [PRs][🤝gh-pulls],
123
- or use the gem and think about how it could be better.
122
+ check [issues][🤝gh-issues] or [PRs][🤝gh-pulls], or use the gem and think about how it could be better.
124
123
 
125
124
  We [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] so if you make changes, remember to update it.
126
125
 
127
126
  See [CONTRIBUTING.md][🤝contributing] for more detailed instructions.
128
127
 
129
- ### Code Coverage
130
-
131
- <details markdown="1">
132
- <summary>Coverage service badges</summary>
133
-
134
- </details>
135
-
136
128
  ## 📌 Versioning
137
129
 
138
130
  This library follows [![Semantic Versioning 2.0.0][📌semver-img]][📌semver] for its public API where practical.
@@ -0,0 +1,208 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Binary
4
+ module Merge
5
+ # Safety-first provider for opaque binary documents.
6
+ # rubocop:disable Metrics/ClassLength, Metrics/MethodLength, Metrics/ParameterLists -- provider operations and envelopes form one cohesive boundary
7
+ class Provider
8
+ def provider_id = 'ruby.binary'
9
+ def family = 'binary'
10
+
11
+ def capabilities
12
+ {
13
+ operations: Ast::Merge::ProviderContract::OPERATIONS,
14
+ dialects: %i[binary],
15
+ backends: %i[raw_bytes],
16
+ profiles: %i[opaque_document],
17
+ role: :workflow,
18
+ source_preservation: %i[exact_source opaque_conflict_retains_ours]
19
+ }.freeze
20
+ end
21
+
22
+ def analyze(request)
23
+ source = request.fetch(:source)
24
+ result(:analyze, request, analysis: { bytesize: source.bytesize, binary: true })
25
+ end
26
+
27
+ def diff2(request)
28
+ before = request.fetch(:before_source)
29
+ after = request.fetch(:after_source)
30
+ changes = before == after ? [] : [classification(before, before, after)]
31
+ result(:diff2, request, changes: changes, diff: { changed: before != after })
32
+ end
33
+
34
+ def merge2(request)
35
+ current = request.fetch(:current_source)
36
+ incoming = request.fetch(:incoming_source)
37
+ rendered = render(request, :ours, current)
38
+ fallback = if current == incoming
39
+ []
40
+ else
41
+ [{
42
+ category: :opaque_binary_preserve_current,
43
+ reason: 'Opaque binary documents cannot be combined safely without a format-specific provider.'
44
+ }]
45
+ end
46
+ result(
47
+ :merge2,
48
+ request,
49
+ output: rendered.content,
50
+ changes: current == incoming ? [] : [classification(current, current, incoming)],
51
+ fallbacks: fallback,
52
+ render_report: render_report(rendered, current == incoming ? :exact_revision : :preserve_current),
53
+ verification: exact_verification(rendered, current)
54
+ )
55
+ end
56
+
57
+ def merge3(request)
58
+ base = request.fetch(:base_source)
59
+ ours = request.fetch(:ours_source)
60
+ theirs = request.fetch(:theirs_source)
61
+ return exact_merge3(request, :ours, ours, base, ours, theirs) if ours == theirs || base == theirs
62
+ return exact_merge3(request, :theirs, theirs, base, ours, theirs) if base == ours
63
+
64
+ conflicted_merge3(request, base, ours, theirs)
65
+ end
66
+
67
+ private
68
+
69
+ def exact_merge3(request, role, output, base, ours, theirs)
70
+ rendered = render(request, role, output)
71
+ result(
72
+ :merge3,
73
+ request,
74
+ output: rendered.content,
75
+ changes: [classification(base, ours, theirs)],
76
+ render_report: render_report(rendered, :exact_revision),
77
+ verification: exact_verification(rendered, output).merge(base_participated: true)
78
+ )
79
+ end
80
+
81
+ def conflicted_merge3(request, base, ours, theirs)
82
+ rendered = render(request, :ours, ours)
83
+ conflict = {
84
+ conflict_id: 'binary-conflict-root',
85
+ category: :opaque_edit_edit,
86
+ path: '',
87
+ change_classification: classification(base, ours, theirs)
88
+ }
89
+ failure(
90
+ :merge3,
91
+ request,
92
+ category: :merge_conflict,
93
+ message: 'Opaque binary content changed independently on both sides; retaining ours without markers.',
94
+ changes: [conflict.fetch(:change_classification)],
95
+ conflicts: [conflict],
96
+ conflicted_output: rendered.content,
97
+ render_report: render_report(rendered, :opaque_conflict_retains_ours),
98
+ verification: { base_participated: true, ours_preserved_exactly: rendered.content == ours }
99
+ )
100
+ end
101
+
102
+ def classification(base, ours, theirs)
103
+ {
104
+ path: '',
105
+ ours: base == ours ? :unchanged : :edited,
106
+ theirs: base == theirs ? :unchanged : :edited
107
+ }.freeze
108
+ end
109
+
110
+ def render(request, role, source)
111
+ Ast::Merge::SourceRender::Renderer.new.render(
112
+ Ast::Merge::SourceRender::Plan.new(
113
+ sources: {
114
+ base: request[:base_source].to_s,
115
+ ours: (request[:ours_source] || request[:current_source]).to_s,
116
+ theirs: request[:theirs_source].to_s
117
+ },
118
+ fragments: [source_fragment(role, source)],
119
+ metadata: { provider_id: provider_id }
120
+ )
121
+ )
122
+ end
123
+
124
+ def source_fragment(role, source)
125
+ if source.empty?
126
+ return Ast::Merge::SourceRender::SynthesizedFragment.new(
127
+ content: '',
128
+ reason: :exact_empty_source,
129
+ producer: provider_id,
130
+ metadata: { source_role: role }
131
+ )
132
+ end
133
+
134
+ Ast::Merge::SourceRender::SourceFragment.new(
135
+ revision: role,
136
+ start_line: 1,
137
+ end_line: [source.lines.length, 1].max,
138
+ metadata: { source_role: role }
139
+ )
140
+ end
141
+
142
+ def render_report(rendered, strategy)
143
+ {
144
+ strategy: strategy,
145
+ line_records: rendered.line_records,
146
+ synthesized_fragments: rendered.synthesized_fragments,
147
+ conflicts: rendered.conflicts,
148
+ verification_input: rendered.verification_input
149
+ }
150
+ end
151
+
152
+ def exact_verification(rendered, source)
153
+ {
154
+ output_reparsed: true,
155
+ semantic_match: rendered.content == source,
156
+ bytes_preserved: rendered.content.b == source.b
157
+ }
158
+ end
159
+
160
+ def result(operation, request, changes: [], fallbacks: [], render_report: {}, verification: {}, **payload)
161
+ Ast::Merge::ProviderResult.build(
162
+ operation: operation,
163
+ success: true,
164
+ envelope: envelope(
165
+ request,
166
+ changes: changes,
167
+ fallbacks: fallbacks,
168
+ render_report: render_report,
169
+ verification: verification
170
+ ),
171
+ **payload
172
+ )
173
+ end
174
+
175
+ def failure(operation, request, category:, message:, changes: [], conflicts: [], render_report: {},
176
+ verification: {}, **payload)
177
+ Ast::Merge::ProviderResult.build(
178
+ operation: operation,
179
+ success: false,
180
+ envelope: envelope(
181
+ request,
182
+ changes: changes,
183
+ conflicts: conflicts,
184
+ diagnostics: [{ category: category, severity: :error, message: message, blocking: true }],
185
+ render_report: render_report,
186
+ verification: verification
187
+ ),
188
+ **payload
189
+ )
190
+ end
191
+
192
+ def envelope(request, **fields)
193
+ {
194
+ provider: {
195
+ provider_id: provider_id,
196
+ family: family,
197
+ dialect: request[:dialect] || :binary,
198
+ backend: request[:backend],
199
+ package: Binary::Merge::PACKAGE_NAME,
200
+ package_version: Binary::Merge::Version::VERSION
201
+ },
202
+ profile: { profile_id: request[:profile_id] || :opaque_document }
203
+ }.merge(fields)
204
+ end
205
+ end
206
+ # rubocop:enable Metrics/ClassLength, Metrics/MethodLength, Metrics/ParameterLists
207
+ end
208
+ end
@@ -5,7 +5,7 @@ module Binary
5
5
  # Version namespace for this gem.
6
6
  module Version
7
7
  # Current gem version.
8
- VERSION = '7.1.1'
8
+ VERSION = '7.1.3'
9
9
  end
10
10
  # Current gem version exposed at the traditional constant location.
11
11
  VERSION = Version::VERSION # Traditional Constant Location
data/lib/binary/merge.rb CHANGED
@@ -1,9 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'tree_haver'
4
+ require 'ast/merge'
4
5
  require_relative 'merge/version'
6
+ require_relative 'merge/provider'
5
7
 
8
+ # Binary preservation contracts and provider registration.
6
9
  module Binary
10
+ # Binary merge reports, diagnostics, and the opaque-document provider.
7
11
  module Merge
8
12
  PACKAGE_NAME = 'binary-merge'
9
13
 
@@ -49,5 +53,15 @@ module Binary
49
53
  diagnostics: []
50
54
  )
51
55
  end
56
+
57
+ def merge_provider
58
+ @merge_provider ||= Provider.new
59
+ end
60
+
61
+ def register_provider!
62
+ Ast::Merge.register_provider(merge_provider, replace: true)
63
+ end
52
64
  end
53
65
  end
66
+
67
+ Binary::Merge.register_provider!
data/sig/binary/merge.rbs CHANGED
@@ -1,5 +1,20 @@
1
1
  module Binary
2
2
  module Merge
3
+ PACKAGE_NAME: String
4
+
5
+ class Provider
6
+ def provider_id: () -> String
7
+ def family: () -> String
8
+ def capabilities: () -> Hash[Symbol, untyped]
9
+ def analyze: (Hash[Symbol, untyped] request) -> Hash[Symbol, untyped]
10
+ def diff2: (Hash[Symbol, untyped] request) -> Hash[Symbol, untyped]
11
+ def merge2: (Hash[Symbol, untyped] request) -> Hash[Symbol, untyped]
12
+ def merge3: (Hash[Symbol, untyped] request) -> Hash[Symbol, untyped]
13
+ end
14
+
15
+ def self.merge_provider: () -> Provider
16
+ def self.register_provider!: () -> Hash[Symbol, untyped]
17
+
3
18
  module Version
4
19
  VERSION: String
5
20
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: binary-merge
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.1.1
4
+ version: 7.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter H. Boling
@@ -37,20 +37,34 @@ cert_chain:
37
37
  -----END CERTIFICATE-----
38
38
  date: 1980-01-02 00:00:00.000000000 Z
39
39
  dependencies:
40
+ - !ruby/object:Gem::Dependency
41
+ name: ast-merge
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - '='
45
+ - !ruby/object:Gem::Version
46
+ version: 7.1.3
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - '='
52
+ - !ruby/object:Gem::Version
53
+ version: 7.1.3
40
54
  - !ruby/object:Gem::Dependency
41
55
  name: tree_haver
42
56
  requirement: !ruby/object:Gem::Requirement
43
57
  requirements:
44
58
  - - '='
45
59
  - !ruby/object:Gem::Version
46
- version: 7.1.1
60
+ version: 7.1.3
47
61
  type: :runtime
48
62
  prerelease: false
49
63
  version_requirements: !ruby/object:Gem::Requirement
50
64
  requirements:
51
65
  - - '='
52
66
  - !ruby/object:Gem::Version
53
- version: 7.1.1
67
+ version: 7.1.3
54
68
  - !ruby/object:Gem::Dependency
55
69
  name: version_gem
56
70
  requirement: !ruby/object:Gem::Requirement
@@ -77,20 +91,20 @@ dependencies:
77
91
  requirements:
78
92
  - - "~>"
79
93
  - !ruby/object:Gem::Version
80
- version: '2.5'
94
+ version: '3.0'
81
95
  - - ">="
82
96
  - !ruby/object:Gem::Version
83
- version: 2.5.17
97
+ version: 3.0.0
84
98
  type: :development
85
99
  prerelease: false
86
100
  version_requirements: !ruby/object:Gem::Requirement
87
101
  requirements:
88
102
  - - "~>"
89
103
  - !ruby/object:Gem::Version
90
- version: '2.5'
104
+ version: '3.0'
91
105
  - - ">="
92
106
  - !ruby/object:Gem::Version
93
- version: 2.5.17
107
+ version: 3.0.0
94
108
  - !ruby/object:Gem::Dependency
95
109
  name: bundler-audit
96
110
  requirement: !ruby/object:Gem::Requirement
@@ -168,7 +182,7 @@ dependencies:
168
182
  version: '3.2'
169
183
  - - ">="
170
184
  - !ruby/object:Gem::Version
171
- version: 3.2.0
185
+ version: 3.2.2
172
186
  type: :development
173
187
  prerelease: false
174
188
  version_requirements: !ruby/object:Gem::Requirement
@@ -178,7 +192,7 @@ dependencies:
178
192
  version: '3.2'
179
193
  - - ">="
180
194
  - !ruby/object:Gem::Version
181
- version: 3.2.0
195
+ version: 3.2.2
182
196
  - !ruby/object:Gem::Dependency
183
197
  name: kettle-test
184
198
  requirement: !ruby/object:Gem::Requirement
@@ -208,7 +222,7 @@ dependencies:
208
222
  version: '3.2'
209
223
  - - ">="
210
224
  - !ruby/object:Gem::Version
211
- version: 3.2.4
225
+ version: 3.2.5
212
226
  type: :development
213
227
  prerelease: false
214
228
  version_requirements: !ruby/object:Gem::Requirement
@@ -218,7 +232,7 @@ dependencies:
218
232
  version: '3.2'
219
233
  - - ">="
220
234
  - !ruby/object:Gem::Version
221
- version: 3.2.4
235
+ version: 3.2.5
222
236
  - !ruby/object:Gem::Dependency
223
237
  name: ruby-progressbar
224
238
  requirement: !ruby/object:Gem::Requirement
@@ -285,6 +299,7 @@ files:
285
299
  - README.md
286
300
  - lib/binary-merge.rb
287
301
  - lib/binary/merge.rb
302
+ - lib/binary/merge/provider.rb
288
303
  - lib/binary/merge/version.rb
289
304
  - sig/binary/merge.rbs
290
305
  homepage: https://github.com/structuredmerge/structuredmerge-ruby
@@ -293,10 +308,10 @@ licenses:
293
308
  - PolyForm-Small-Business-1.0.0
294
309
  metadata:
295
310
  homepage_uri: https://structuredmerge.org
296
- source_code_uri: https://github.com/structuredmerge/structuredmerge-ruby/tree/v7.1.1
297
- changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.1/CHANGELOG.md
311
+ source_code_uri: https://github.com/structuredmerge/structuredmerge-ruby/tree/v7.1.3
312
+ changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.3/CHANGELOG.md
298
313
  bug_tracker_uri: https://github.com/structuredmerge/structuredmerge-ruby/issues
299
- documentation_uri: https://www.rubydoc.info/gems/binary-merge/7.1.1
314
+ documentation_uri: https://www.rubydoc.info/gems/binary-merge/7.1.3
300
315
  funding_uri: https://github.com/sponsors/pboling
301
316
  wiki_uri: https://github.com/structuredmerge/structuredmerge-ruby/wiki
302
317
  news_uri: https://www.railsbling.com/tags/binary-merge
metadata.gz.sig CHANGED
Binary file