plain-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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.md +2 -10
- data/lib/plain/merge/provider.rb +205 -0
- data/lib/plain/merge/version.rb +1 -1
- data/lib/plain/merge.rb +12 -0
- data/sig/plain/merge.rbs +13 -0
- data.tar.gz.sig +0 -0
- metadata +17 -16
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: eb21dc58d45117871ad2b96d9adaff4775cfdc8e5267e5742a3cf71d09b1ea2c
|
|
4
|
+
data.tar.gz: 896051c7f24220265b0086912e9d91f77ab28e94914720b1b4e795016029d981
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bb3a96716022df3e9ce9ed6a63638a1c913ec0de744bc74b3c70625a2774a57cac56d17fd9fb766be3528512fa5eed7082f0640561b083718155c722b420eb05
|
|
7
|
+
data.tar.gz: a06b47194805436a93962350698b6f898a9f66cab476fb8929c2c7eedef2a6d1b0d3b4da3142f3cb25bc8424159041fd54fbceddcaf3c410343753e80c0a9fdf
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/README.md
CHANGED
|
@@ -51,7 +51,7 @@ callers can enter plain text analysis through
|
|
|
51
51
|
|
|
52
52
|
### Compatibility
|
|
53
53
|
|
|
54
|
-
Compatible with MRI Ruby 4.0.0+,
|
|
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
|
|
@@ -118,20 +118,12 @@ See [SECURITY.md][🔐security].
|
|
|
118
118
|
## 🤝 Contributing
|
|
119
119
|
|
|
120
120
|
If you need some ideas of where to help, you could work on adding more code coverage,
|
|
121
|
-
|
|
122
|
-
or use the gem and think about how it could be better.
|
|
121
|
+
check [issues][🤝gh-issues] or [PRs][🤝gh-pulls], or use the gem and think about how it could be better.
|
|
123
122
|
|
|
124
123
|
We [![Keep A Changelog][📗keep-changelog-img]][📗keep-changelog] so if you make changes, remember to update it.
|
|
125
124
|
|
|
126
125
|
See [CONTRIBUTING.md][🤝contributing] for more detailed instructions.
|
|
127
126
|
|
|
128
|
-
### Code Coverage
|
|
129
|
-
|
|
130
|
-
<details markdown="1">
|
|
131
|
-
<summary>Coverage service badges</summary>
|
|
132
|
-
|
|
133
|
-
</details>
|
|
134
|
-
|
|
135
127
|
## 📌 Versioning
|
|
136
128
|
|
|
137
129
|
This library follows [![Semantic Versioning 2.0.0][📌semver-img]][📌semver] for its public API where practical.
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Plain
|
|
4
|
+
module Merge
|
|
5
|
+
# Coarse whole-document provider for unstructured plain text.
|
|
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.text'
|
|
9
|
+
def family = 'text'
|
|
10
|
+
|
|
11
|
+
def capabilities
|
|
12
|
+
{
|
|
13
|
+
operations: Ast::Merge::ProviderContract::OPERATIONS,
|
|
14
|
+
dialects: %i[text],
|
|
15
|
+
backends: [Plain::Merge::BACKEND_REFERENCE.id.to_sym],
|
|
16
|
+
profiles: %i[coarse_document],
|
|
17
|
+
role: :workflow,
|
|
18
|
+
source_preservation: %i[exact_source whole_document_conflict]
|
|
19
|
+
}.freeze
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def analyze(request)
|
|
23
|
+
result(:analyze, request, analysis: Plain::Merge.analyze_text(request.fetch(:source)))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def diff2(request)
|
|
27
|
+
before = request.fetch(:before_source)
|
|
28
|
+
after = request.fetch(:after_source)
|
|
29
|
+
changes = before == after ? [] : [classification(before, before, after)]
|
|
30
|
+
result(:diff2, request, changes: changes, diff: { before: before, after: after, changes: changes })
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def merge2(request)
|
|
34
|
+
merged = Plain::Merge.merge_text(request.fetch(:incoming_source), request.fetch(:current_source))
|
|
35
|
+
result(
|
|
36
|
+
:merge2,
|
|
37
|
+
request,
|
|
38
|
+
output: merged.fetch(:output),
|
|
39
|
+
render_report: { strategy: :normalized_block_merge },
|
|
40
|
+
verification: { output_rendered: true }
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def merge3(request)
|
|
45
|
+
base = request.fetch(:base_source)
|
|
46
|
+
ours = request.fetch(:ours_source)
|
|
47
|
+
theirs = request.fetch(:theirs_source)
|
|
48
|
+
return exact_merge3(request, :ours, ours, base, ours, theirs) if ours == theirs || base == theirs
|
|
49
|
+
return exact_merge3(request, :theirs, theirs, base, ours, theirs) if base == ours
|
|
50
|
+
|
|
51
|
+
conflicted_merge3(request, base, ours, theirs)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def exact_merge3(request, role, output, base, ours, theirs)
|
|
57
|
+
rendered = render(request, [source_fragment(role, output)])
|
|
58
|
+
result(
|
|
59
|
+
:merge3,
|
|
60
|
+
request,
|
|
61
|
+
output: rendered.content,
|
|
62
|
+
changes: [classification(base, ours, theirs)],
|
|
63
|
+
render_report: render_report(rendered, :exact_revision),
|
|
64
|
+
verification: { base_participated: true, output_reparsed: true, semantic_match: rendered.content == output }
|
|
65
|
+
)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def conflicted_merge3(request, base, ours, theirs)
|
|
69
|
+
conflict = {
|
|
70
|
+
conflict_id: 'text-conflict-root',
|
|
71
|
+
category: :edit_edit,
|
|
72
|
+
path: '',
|
|
73
|
+
change_classification: classification(base, ours, theirs)
|
|
74
|
+
}
|
|
75
|
+
rendered = render(
|
|
76
|
+
request,
|
|
77
|
+
[
|
|
78
|
+
Ast::Merge::SourceRender::ConflictFragment.new(
|
|
79
|
+
conflict_id: conflict.fetch(:conflict_id),
|
|
80
|
+
base: [conflict_side(:base, base)],
|
|
81
|
+
ours: [conflict_side(:ours, ours)],
|
|
82
|
+
theirs: [conflict_side(:theirs, theirs)],
|
|
83
|
+
labels: request.fetch(:labels, {}),
|
|
84
|
+
marker_size: request.fetch(:conflict_marker_size, 7),
|
|
85
|
+
metadata: { path: '', category: :edit_edit }
|
|
86
|
+
)
|
|
87
|
+
]
|
|
88
|
+
)
|
|
89
|
+
failure(
|
|
90
|
+
:merge3,
|
|
91
|
+
request,
|
|
92
|
+
category: :merge_conflict,
|
|
93
|
+
message: 'Plain text changed independently on both sides.',
|
|
94
|
+
changes: [conflict.fetch(:change_classification)],
|
|
95
|
+
conflicts: [conflict],
|
|
96
|
+
conflicted_output: rendered.content,
|
|
97
|
+
render_report: render_report(rendered, :whole_document_conflict),
|
|
98
|
+
verification: { base_participated: true }
|
|
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, fragments)
|
|
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].to_s,
|
|
116
|
+
theirs: request[:theirs_source].to_s
|
|
117
|
+
},
|
|
118
|
+
fragments: fragments,
|
|
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 conflict_side(role, source)
|
|
143
|
+
return source_fragment(role, source) if !source.empty? && source.end_with?("\n")
|
|
144
|
+
|
|
145
|
+
Ast::Merge::SourceRender::SynthesizedFragment.new(
|
|
146
|
+
content: source.empty? ? '' : "#{source}\n",
|
|
147
|
+
reason: :conflict_line_boundary,
|
|
148
|
+
producer: provider_id,
|
|
149
|
+
metadata: { source_role: role, copied_source: true }
|
|
150
|
+
)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def render_report(rendered, strategy)
|
|
154
|
+
{
|
|
155
|
+
strategy: strategy,
|
|
156
|
+
line_records: rendered.line_records,
|
|
157
|
+
synthesized_fragments: rendered.synthesized_fragments,
|
|
158
|
+
conflicts: rendered.conflicts,
|
|
159
|
+
verification_input: rendered.verification_input
|
|
160
|
+
}
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def result(operation, request, changes: [], render_report: {}, verification: {}, **payload)
|
|
164
|
+
Ast::Merge::ProviderResult.build(
|
|
165
|
+
operation: operation,
|
|
166
|
+
success: true,
|
|
167
|
+
envelope: envelope(request, changes: changes, render_report: render_report, verification: verification),
|
|
168
|
+
**payload
|
|
169
|
+
)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def failure(operation, request, category:, message:, changes: [], conflicts: [], render_report: {},
|
|
173
|
+
verification: {}, **payload)
|
|
174
|
+
Ast::Merge::ProviderResult.build(
|
|
175
|
+
operation: operation,
|
|
176
|
+
success: false,
|
|
177
|
+
envelope: envelope(
|
|
178
|
+
request,
|
|
179
|
+
changes: changes,
|
|
180
|
+
conflicts: conflicts,
|
|
181
|
+
diagnostics: [{ category: category, severity: :error, message: message, blocking: true }],
|
|
182
|
+
render_report: render_report,
|
|
183
|
+
verification: verification
|
|
184
|
+
),
|
|
185
|
+
**payload
|
|
186
|
+
)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def envelope(request, **fields)
|
|
190
|
+
{
|
|
191
|
+
provider: {
|
|
192
|
+
provider_id: provider_id,
|
|
193
|
+
family: family,
|
|
194
|
+
dialect: request[:dialect] || :text,
|
|
195
|
+
backend: request[:backend],
|
|
196
|
+
package: Plain::Merge::PACKAGE_NAME,
|
|
197
|
+
package_version: Plain::Merge::Version::VERSION
|
|
198
|
+
},
|
|
199
|
+
profile: { profile_id: request[:profile_id] || :coarse_document }
|
|
200
|
+
}.merge(fields)
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
# rubocop:enable Metrics/ClassLength, Metrics/MethodLength, Metrics/ParameterLists
|
|
204
|
+
end
|
|
205
|
+
end
|
data/lib/plain/merge/version.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Plain
|
|
|
5
5
|
# Version namespace for this gem.
|
|
6
6
|
module Version
|
|
7
7
|
# Current gem version.
|
|
8
|
-
VERSION = '7.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/plain/merge.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'ast/merge'
|
|
3
4
|
require 'tree_haver'
|
|
4
5
|
require_relative 'merge/version'
|
|
5
6
|
|
|
@@ -13,6 +14,8 @@ module Plain
|
|
|
13
14
|
position: 0.15
|
|
14
15
|
}.freeze
|
|
15
16
|
|
|
17
|
+
autoload :Provider, 'plain/merge/provider'
|
|
18
|
+
|
|
16
19
|
module_function
|
|
17
20
|
|
|
18
21
|
def text_feature_profile
|
|
@@ -23,6 +26,14 @@ module Plain
|
|
|
23
26
|
}
|
|
24
27
|
end
|
|
25
28
|
|
|
29
|
+
def merge_provider
|
|
30
|
+
@merge_provider ||= Provider.new
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def register_provider!(replace: false)
|
|
34
|
+
Ast::Merge.register_provider(merge_provider, replace: replace)
|
|
35
|
+
end
|
|
36
|
+
|
|
26
37
|
def text_parse_request(source)
|
|
27
38
|
TreeHaver::ParserRequest.new(source: source, language: 'text')
|
|
28
39
|
end
|
|
@@ -263,3 +274,4 @@ end
|
|
|
263
274
|
|
|
264
275
|
require_relative 'merge/backend'
|
|
265
276
|
Plain::Merge.register_backend!
|
|
277
|
+
Plain::Merge.register_provider!
|
data/sig/plain/merge.rbs
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
module Plain
|
|
2
2
|
module Merge
|
|
3
|
+
class Provider
|
|
4
|
+
def provider_id: () -> String
|
|
5
|
+
def family: () -> String
|
|
6
|
+
def capabilities: () -> Ast::Merge::provider_capabilities
|
|
7
|
+
def analyze: (Ast::Merge::provider_request request) -> Ast::Merge::provider_result
|
|
8
|
+
def diff2: (Ast::Merge::provider_request request) -> Ast::Merge::provider_result
|
|
9
|
+
def merge2: (Ast::Merge::provider_request request) -> Ast::Merge::provider_result
|
|
10
|
+
def merge3: (Ast::Merge::provider_request request) -> Ast::Merge::provider_result
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.merge_provider: () -> Provider
|
|
14
|
+
def self.register_provider!: (?replace: bool) -> Ast::Merge::_MergeProvider
|
|
15
|
+
|
|
3
16
|
module Version
|
|
4
17
|
VERSION: String
|
|
5
18
|
end
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: plain-merge
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 7.1.
|
|
4
|
+
version: 7.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter H. Boling
|
|
@@ -43,28 +43,28 @@ dependencies:
|
|
|
43
43
|
requirements:
|
|
44
44
|
- - '='
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: 7.1.
|
|
46
|
+
version: 7.1.3
|
|
47
47
|
type: :runtime
|
|
48
48
|
prerelease: false
|
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
51
|
- - '='
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: 7.1.
|
|
53
|
+
version: 7.1.3
|
|
54
54
|
- !ruby/object:Gem::Dependency
|
|
55
55
|
name: tree_haver
|
|
56
56
|
requirement: !ruby/object:Gem::Requirement
|
|
57
57
|
requirements:
|
|
58
58
|
- - '='
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
|
-
version: 7.1.
|
|
60
|
+
version: 7.1.3
|
|
61
61
|
type: :runtime
|
|
62
62
|
prerelease: false
|
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
|
64
64
|
requirements:
|
|
65
65
|
- - '='
|
|
66
66
|
- !ruby/object:Gem::Version
|
|
67
|
-
version: 7.1.
|
|
67
|
+
version: 7.1.3
|
|
68
68
|
- !ruby/object:Gem::Dependency
|
|
69
69
|
name: version_gem
|
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -91,20 +91,20 @@ dependencies:
|
|
|
91
91
|
requirements:
|
|
92
92
|
- - "~>"
|
|
93
93
|
- !ruby/object:Gem::Version
|
|
94
|
-
version: '
|
|
94
|
+
version: '3.0'
|
|
95
95
|
- - ">="
|
|
96
96
|
- !ruby/object:Gem::Version
|
|
97
|
-
version:
|
|
97
|
+
version: 3.0.0
|
|
98
98
|
type: :development
|
|
99
99
|
prerelease: false
|
|
100
100
|
version_requirements: !ruby/object:Gem::Requirement
|
|
101
101
|
requirements:
|
|
102
102
|
- - "~>"
|
|
103
103
|
- !ruby/object:Gem::Version
|
|
104
|
-
version: '
|
|
104
|
+
version: '3.0'
|
|
105
105
|
- - ">="
|
|
106
106
|
- !ruby/object:Gem::Version
|
|
107
|
-
version:
|
|
107
|
+
version: 3.0.0
|
|
108
108
|
- !ruby/object:Gem::Dependency
|
|
109
109
|
name: bundler-audit
|
|
110
110
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -182,7 +182,7 @@ dependencies:
|
|
|
182
182
|
version: '3.2'
|
|
183
183
|
- - ">="
|
|
184
184
|
- !ruby/object:Gem::Version
|
|
185
|
-
version: 3.2.
|
|
185
|
+
version: 3.2.2
|
|
186
186
|
type: :development
|
|
187
187
|
prerelease: false
|
|
188
188
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -192,7 +192,7 @@ dependencies:
|
|
|
192
192
|
version: '3.2'
|
|
193
193
|
- - ">="
|
|
194
194
|
- !ruby/object:Gem::Version
|
|
195
|
-
version: 3.2.
|
|
195
|
+
version: 3.2.2
|
|
196
196
|
- !ruby/object:Gem::Dependency
|
|
197
197
|
name: kettle-test
|
|
198
198
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -222,7 +222,7 @@ dependencies:
|
|
|
222
222
|
version: '3.2'
|
|
223
223
|
- - ">="
|
|
224
224
|
- !ruby/object:Gem::Version
|
|
225
|
-
version: 3.2.
|
|
225
|
+
version: 3.2.5
|
|
226
226
|
type: :development
|
|
227
227
|
prerelease: false
|
|
228
228
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -232,7 +232,7 @@ dependencies:
|
|
|
232
232
|
version: '3.2'
|
|
233
233
|
- - ">="
|
|
234
234
|
- !ruby/object:Gem::Version
|
|
235
|
-
version: 3.2.
|
|
235
|
+
version: 3.2.5
|
|
236
236
|
- !ruby/object:Gem::Dependency
|
|
237
237
|
name: ruby-progressbar
|
|
238
238
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -300,6 +300,7 @@ files:
|
|
|
300
300
|
- lib/plain-merge.rb
|
|
301
301
|
- lib/plain/merge.rb
|
|
302
302
|
- lib/plain/merge/backend.rb
|
|
303
|
+
- lib/plain/merge/provider.rb
|
|
303
304
|
- lib/plain/merge/version.rb
|
|
304
305
|
- sig/plain/merge.rbs
|
|
305
306
|
homepage: https://github.com/structuredmerge/structuredmerge-ruby
|
|
@@ -308,10 +309,10 @@ licenses:
|
|
|
308
309
|
- PolyForm-Small-Business-1.0.0
|
|
309
310
|
metadata:
|
|
310
311
|
homepage_uri: https://structuredmerge.org
|
|
311
|
-
source_code_uri: https://github.com/structuredmerge/structuredmerge-ruby/tree/v7.1.
|
|
312
|
-
changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.
|
|
312
|
+
source_code_uri: https://github.com/structuredmerge/structuredmerge-ruby/tree/v7.1.3
|
|
313
|
+
changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.3/CHANGELOG.md
|
|
313
314
|
bug_tracker_uri: https://github.com/structuredmerge/structuredmerge-ruby/issues
|
|
314
|
-
documentation_uri: https://www.rubydoc.info/gems/plain-merge/7.1.
|
|
315
|
+
documentation_uri: https://www.rubydoc.info/gems/plain-merge/7.1.3
|
|
315
316
|
funding_uri: https://github.com/sponsors/pboling
|
|
316
317
|
wiki_uri: https://github.com/structuredmerge/structuredmerge-ruby/wiki
|
|
317
318
|
news_uri: https://www.railsbling.com/tags/plain-merge
|
metadata.gz.sig
CHANGED
|
Binary file
|