bash-merge 7.1.3 → 7.1.4
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 +1 -1
- data/lib/bash/merge/provider.rb +61 -4
- data/lib/bash/merge/test_harness_identity.rb +63 -0
- data/lib/bash/merge/version.rb +1 -1
- 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: 3e3f73ff82048635caccf19c960791ce05565f83e3c393b6dc175d4d2d16b417
|
|
4
|
+
data.tar.gz: 96404acb74336004facfe0222183882909c23bc1de2c5ec827769c769de4b6f8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1abeafbfc3c7485a49ca9f4f45853f888f95040dd895b7df7fea1f6584fb08565711abeb41dbd4e4abae9d0b13b6166fb2f973fd6ca531838d6e9865bc1b63d9
|
|
7
|
+
data.tar.gz: 2eab528d0568ae00321490ad534bf41ac3bcbd2aab46355be98b034f6238a869648a03f9c89f5d81990706acec19c12fe3f15cacd29a57bb6292058f60144e18
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/README.md
CHANGED
|
@@ -403,7 +403,7 @@ If none of the available licenses suit your use case, please [contact us](mailto
|
|
|
403
403
|
[📌gitmoji]: https://gitmoji.dev
|
|
404
404
|
[📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
|
|
405
405
|
[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
406
|
-
[🧮kloc-img]: https://img.shields.io/badge/KLOC-
|
|
406
|
+
[🧮kloc-img]: https://img.shields.io/badge/KLOC-1.305-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
|
|
407
407
|
[🔐security]: https://github.com/structuredmerge/structuredmerge-ruby/blob/main/SECURITY.md
|
|
408
408
|
[🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
|
|
409
409
|
[📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
|
data/lib/bash/merge/provider.rb
CHANGED
|
@@ -5,6 +5,7 @@ require 'json'
|
|
|
5
5
|
require 'ast/merge/source_render'
|
|
6
6
|
require_relative 'node_wrapper'
|
|
7
7
|
require_relative 'file_analysis'
|
|
8
|
+
require_relative 'test_harness_identity'
|
|
8
9
|
|
|
9
10
|
module Bash
|
|
10
11
|
# Registration and source-preserving workflow implementation for Bash.
|
|
@@ -22,8 +23,9 @@ module Bash
|
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
# Base-aware, source-preserving provider for native top-level Bash owners.
|
|
25
|
-
# Functions
|
|
26
|
-
# top-level form must remain identical
|
|
26
|
+
# Functions, assignments, and literal-title test_expect_success calls have
|
|
27
|
+
# stable AST identities. Every other top-level form must remain identical
|
|
28
|
+
# across all revisions in a composite.
|
|
27
29
|
# rubocop:disable Metrics/AbcSize, Metrics/ClassLength, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/ParameterLists, Metrics/PerceivedComplexity -- provider decisions, source plans, and verification form one boundary
|
|
28
30
|
class Provider
|
|
29
31
|
DEFAULT_PROFILE = :source_preserving
|
|
@@ -42,7 +44,7 @@ module Bash
|
|
|
42
44
|
backends: [TREE_SITTER_BACKEND.id.to_sym],
|
|
43
45
|
profiles: [DEFAULT_PROFILE],
|
|
44
46
|
role: :workflow,
|
|
45
|
-
ast_ownership: :
|
|
47
|
+
ast_ownership: :stable_functions_assignments_and_literal_test_titles,
|
|
46
48
|
source_preservation: %i[exact_source declaration_fragments line_provenance reparse semantic_verification]
|
|
47
49
|
}.freeze
|
|
48
50
|
end
|
|
@@ -103,6 +105,9 @@ module Bash
|
|
|
103
105
|
ownership_failure = unstable_ownership_failure(request, documents)
|
|
104
106
|
return ownership_failure if ownership_failure
|
|
105
107
|
|
|
108
|
+
ownership_failure = test_harness_ownership_failure(request, documents)
|
|
109
|
+
return ownership_failure if ownership_failure
|
|
110
|
+
|
|
106
111
|
decision = decide(documents, include_unmanaged_conflict: true)
|
|
107
112
|
return render_conflicts(request, documents, decision) unless decision.conflicts.empty?
|
|
108
113
|
|
|
@@ -212,6 +217,8 @@ module Bash
|
|
|
212
217
|
elsif wrapper.variable_assignment?
|
|
213
218
|
name = wrapper.variable_name
|
|
214
219
|
name && [:variable_assignment, name]
|
|
220
|
+
elsif (identity = TestHarnessIdentity.for(wrapper))
|
|
221
|
+
[:test_harness_call, *identity]
|
|
215
222
|
else
|
|
216
223
|
wrapper.signature
|
|
217
224
|
end
|
|
@@ -396,7 +403,57 @@ module Bash
|
|
|
396
403
|
end
|
|
397
404
|
|
|
398
405
|
def stable_signature?(signature)
|
|
399
|
-
%i[function variable_assignment].include?(signature.first)
|
|
406
|
+
%i[function variable_assignment test_harness_call].include?(signature.first)
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
def test_harness_ownership_failure(request, documents)
|
|
410
|
+
sequences = documents.transform_values do |document|
|
|
411
|
+
document.owners.filter_map do |owner|
|
|
412
|
+
owner.id if owner.signature.first == :test_harness_call
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
base = sequences.fetch(:base)
|
|
416
|
+
invalid_role = %i[ours theirs].find do |role|
|
|
417
|
+
sequence = sequences.fetch(role)
|
|
418
|
+
sequence.length < base.length || sequence.first(base.length) != base
|
|
419
|
+
end
|
|
420
|
+
changed_role = %i[ours theirs].find { |role| sequences.fetch(role) != base }
|
|
421
|
+
return unless invalid_role || changed_role
|
|
422
|
+
|
|
423
|
+
reason = if invalid_role
|
|
424
|
+
:non_append_only_test_harness_change
|
|
425
|
+
else
|
|
426
|
+
:test_harness_addition_requires_ordered_rendering
|
|
427
|
+
end
|
|
428
|
+
source_role = invalid_role || changed_role
|
|
429
|
+
|
|
430
|
+
signature_digest = Digest::SHA256.hexdigest(JSON.generate(Ast::Merge.json_ready(sequences)))
|
|
431
|
+
conflict = {
|
|
432
|
+
conflict_id: "bash-test-ownership-#{signature_digest[0, 16]}",
|
|
433
|
+
category: :unproven_ast_ownership,
|
|
434
|
+
path: '<test_expect_success-sequence>',
|
|
435
|
+
owner_id: nil,
|
|
436
|
+
source_role: source_role,
|
|
437
|
+
identities: sequences,
|
|
438
|
+
reason: reason
|
|
439
|
+
}.freeze
|
|
440
|
+
decision = Decision.new(changes: [], conflicts: [conflict], choices: {})
|
|
441
|
+
rendered = render_plan(request, [whole_document_conflict(request, decision)])
|
|
442
|
+
failure(
|
|
443
|
+
:merge3,
|
|
444
|
+
request,
|
|
445
|
+
category: :unproven_ast_ownership,
|
|
446
|
+
message: 'Literal-title test_expect_success membership changes require ordered insertion rendering.',
|
|
447
|
+
conflicts: [conflict],
|
|
448
|
+
conflicted_output: rendered.content,
|
|
449
|
+
render_report: render_report(rendered, :full_file_conflict),
|
|
450
|
+
verification: { base_participated: true },
|
|
451
|
+
fallbacks: [{
|
|
452
|
+
from: :test_harness_ast_ownership,
|
|
453
|
+
to: :full_file_conflict,
|
|
454
|
+
reason: reason
|
|
455
|
+
}]
|
|
456
|
+
)
|
|
400
457
|
end
|
|
401
458
|
|
|
402
459
|
def side_change(base, side)
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bash
|
|
4
|
+
module Merge
|
|
5
|
+
# Extracts bounded AST identities for Git-style shell test harness calls.
|
|
6
|
+
class TestHarnessIdentity
|
|
7
|
+
class << self
|
|
8
|
+
def for(wrapper)
|
|
9
|
+
return unless wrapper.command? && wrapper.command_name == 'test_expect_success'
|
|
10
|
+
|
|
11
|
+
identity = literal_identity(wrapper)
|
|
12
|
+
[:test_expect_success, *identity] if identity
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def literal_identity(wrapper)
|
|
18
|
+
arguments = command_argument_nodes(wrapper.node)
|
|
19
|
+
return [source_for(wrapper, arguments.first)] if simple_literal_title?(arguments)
|
|
20
|
+
return unless qualified_literal_title?(arguments)
|
|
21
|
+
|
|
22
|
+
arguments.first(2).map { |argument| source_for(wrapper, argument) }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def command_argument_nodes(node)
|
|
26
|
+
children = node.children.select(&:named?)
|
|
27
|
+
command_index = children.index { |child| %w[word command_name].include?(child.type.to_s) }
|
|
28
|
+
return [] unless command_index
|
|
29
|
+
|
|
30
|
+
arguments = children.drop(command_index + 1)
|
|
31
|
+
arguments.any? { |child| child.type.to_s.include?('redirect') } ? [] : arguments
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def simple_literal_title?(arguments)
|
|
35
|
+
arguments.length == 2 && literal_title?(arguments.first)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def qualified_literal_title?(arguments)
|
|
39
|
+
arguments.length == 3 &&
|
|
40
|
+
literal_prerequisite?(arguments[0]) &&
|
|
41
|
+
literal_title?(arguments[1])
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def literal_prerequisite?(argument)
|
|
45
|
+
argument.type.to_s == 'word' && argument.children.none?(&:named?)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def literal_title?(argument)
|
|
49
|
+
return true if argument.type.to_s == 'raw_string'
|
|
50
|
+
return false unless argument.type.to_s == 'string'
|
|
51
|
+
|
|
52
|
+
argument.children.select(&:named?).all? { |child| child.type.to_s == 'string_content' }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def source_for(wrapper, node)
|
|
56
|
+
start_offset = node.start_byte - wrapper.start_byte
|
|
57
|
+
end_offset = node.end_byte - wrapper.start_byte
|
|
58
|
+
wrapper.source_text.byteslice(start_offset...end_offset).to_s
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
data/lib/bash/merge/version.rb
CHANGED
|
@@ -5,7 +5,7 @@ module Bash
|
|
|
5
5
|
# Version namespace for this gem.
|
|
6
6
|
module Version
|
|
7
7
|
# Current gem version.
|
|
8
|
-
VERSION = '7.1.
|
|
8
|
+
VERSION = '7.1.4'
|
|
9
9
|
end
|
|
10
10
|
# Current gem version exposed at the traditional constant location.
|
|
11
11
|
VERSION = Version::VERSION # Traditional Constant Location
|
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bash-merge
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 7.1.
|
|
4
|
+
version: 7.1.4
|
|
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.4
|
|
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.4
|
|
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.4
|
|
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.4
|
|
68
68
|
- !ruby/object:Gem::Dependency
|
|
69
69
|
name: version_gem
|
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -94,7 +94,7 @@ dependencies:
|
|
|
94
94
|
version: '3.0'
|
|
95
95
|
- - ">="
|
|
96
96
|
- !ruby/object:Gem::Version
|
|
97
|
-
version: 3.0.
|
|
97
|
+
version: 3.0.7
|
|
98
98
|
type: :development
|
|
99
99
|
prerelease: false
|
|
100
100
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -104,7 +104,7 @@ dependencies:
|
|
|
104
104
|
version: '3.0'
|
|
105
105
|
- - ">="
|
|
106
106
|
- !ruby/object:Gem::Version
|
|
107
|
-
version: 3.0.
|
|
107
|
+
version: 3.0.7
|
|
108
108
|
- !ruby/object:Gem::Dependency
|
|
109
109
|
name: bundler-audit
|
|
110
110
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -202,7 +202,7 @@ dependencies:
|
|
|
202
202
|
version: '2.0'
|
|
203
203
|
- - ">="
|
|
204
204
|
- !ruby/object:Gem::Version
|
|
205
|
-
version: 2.0.
|
|
205
|
+
version: 2.0.20
|
|
206
206
|
type: :development
|
|
207
207
|
prerelease: false
|
|
208
208
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -212,7 +212,7 @@ dependencies:
|
|
|
212
212
|
version: '2.0'
|
|
213
213
|
- - ">="
|
|
214
214
|
- !ruby/object:Gem::Version
|
|
215
|
-
version: 2.0.
|
|
215
|
+
version: 2.0.20
|
|
216
216
|
- !ruby/object:Gem::Dependency
|
|
217
217
|
name: turbo_tests2
|
|
218
218
|
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.6
|
|
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.6
|
|
236
236
|
- !ruby/object:Gem::Dependency
|
|
237
237
|
name: ruby-progressbar
|
|
238
238
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -276,7 +276,7 @@ dependencies:
|
|
|
276
276
|
version: '2.0'
|
|
277
277
|
- - ">="
|
|
278
278
|
- !ruby/object:Gem::Version
|
|
279
|
-
version: 2.0.
|
|
279
|
+
version: 2.0.12
|
|
280
280
|
type: :development
|
|
281
281
|
prerelease: false
|
|
282
282
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -286,7 +286,7 @@ dependencies:
|
|
|
286
286
|
version: '2.0'
|
|
287
287
|
- - ">="
|
|
288
288
|
- !ruby/object:Gem::Version
|
|
289
|
-
version: 2.0.
|
|
289
|
+
version: 2.0.12
|
|
290
290
|
description: "☯️ Bash statement, comment, freeze-block, and template merge behavior
|
|
291
291
|
for Structured Merge."
|
|
292
292
|
email:
|
|
@@ -308,6 +308,7 @@ files:
|
|
|
308
308
|
- lib/bash/merge/node_wrapper.rb
|
|
309
309
|
- lib/bash/merge/provider.rb
|
|
310
310
|
- lib/bash/merge/smart_merger.rb
|
|
311
|
+
- lib/bash/merge/test_harness_identity.rb
|
|
311
312
|
- lib/bash/merge/version.rb
|
|
312
313
|
- sig/bash/merge.rbs
|
|
313
314
|
homepage: https://github.com/structuredmerge/structuredmerge-ruby
|
|
@@ -316,10 +317,10 @@ licenses:
|
|
|
316
317
|
- PolyForm-Small-Business-1.0.0
|
|
317
318
|
metadata:
|
|
318
319
|
homepage_uri: https://structuredmerge.org
|
|
319
|
-
source_code_uri: https://github.com/structuredmerge/structuredmerge-ruby/tree/v7.1.
|
|
320
|
-
changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.
|
|
320
|
+
source_code_uri: https://github.com/structuredmerge/structuredmerge-ruby/tree/v7.1.4
|
|
321
|
+
changelog_uri: https://github.com/structuredmerge/structuredmerge-ruby/blob/v7.1.4/CHANGELOG.md
|
|
321
322
|
bug_tracker_uri: https://github.com/structuredmerge/structuredmerge-ruby/issues
|
|
322
|
-
documentation_uri: https://www.rubydoc.info/gems/bash-merge/7.1.
|
|
323
|
+
documentation_uri: https://www.rubydoc.info/gems/bash-merge/7.1.4
|
|
323
324
|
funding_uri: https://github.com/sponsors/pboling
|
|
324
325
|
wiki_uri: https://github.com/structuredmerge/structuredmerge-ruby/wiki
|
|
325
326
|
news_uri: https://www.railsbling.com/tags/bash-merge
|
metadata.gz.sig
CHANGED
|
Binary file
|