Class: Yaml::Merge::SourcePreservingProvider

Inherits:
Object
  • Object
show all
Defined in:
lib/yaml/merge/source_preserving_provider.rb,
sig/yaml/merge.rbs

Overview

Conservative source-preserving provider for top-level YAML mappings. rubocop:disable Metrics/AbcSize, Metrics/ClassLength, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/ParameterLists, Metrics/PerceivedComplexity -- provider validation, planning, rendering, and verification form one safety boundary

Direct Known Subclasses

Provider

Defined Under Namespace

Classes: Decision, Document, Entry

Constant Summary collapse

DEFAULT_PROFILE =
:source_preserving
DIALECTS =
i[yaml].freeze

Instance Method Summary collapse

Instance Method Details

#analyze(request) ⇒ Hash[Symbol, untyped]

Parameters:

  • request (Hash[Symbol, untyped])

Returns:

  • (Hash[Symbol, untyped])


62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/yaml/merge/source_preserving_provider.rb', line 62

def analyze(request)
  document = analyze_role(:source, request.fetch(:source))
  return invalid_document_failure(:analyze, request, [document]) unless document.issues.empty?

  result(
    :analyze,
    request,
    analysis: analysis_payload(document),
    extensions: analysis_extensions(document),
    verification: { source_parsed: true, structurally_unambiguous: true }
  )
end

#backend_id ⇒ Object



38
# File 'lib/yaml/merge/source_preserving_provider.rb', line 38

def backend_id = backend_reference.id.to_sym

#backend_reference ⇒ Object



37
# File 'lib/yaml/merge/source_preserving_provider.rb', line 37

def backend_reference = self.class::BACKEND

#capabilities ⇒ Hash[Symbol, untyped]

Returns:

  • (Hash[Symbol, untyped])


43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/yaml/merge/source_preserving_provider.rb', line 43

def capabilities
  {
    operations: Ast::Merge::ProviderContract::OPERATIONS,
    dialects: DIALECTS,
    backends: [backend_id],
    profiles: [DEFAULT_PROFILE],
    role: role,
    source_preservation: i[
      exact_source
      mapping_entry_fragments
      comment_ownership
      line_provenance
      reparse
      semantic_verification
      ast_attribute_verification
    ]
  }.freeze
end

#diff2(request) ⇒ Hash[Symbol, untyped]

Parameters:

  • request (Hash[Symbol, untyped])

Returns:

  • (Hash[Symbol, untyped])


75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/yaml/merge/source_preserving_provider.rb', line 75

def diff2(request)
  before = analyze_role(:before, request.fetch(:before_source))
  after = analyze_role(:after, request.fetch(:after_source))
  unsafe = [before, after].reject { |document| document.issues.empty? }
  return invalid_document_failure(:diff2, request, unsafe) unless unsafe.empty?

  changes = mapping_changes(before, after)
  result(
    :diff2,
    request,
    diff: { before: analysis_payload(before), after: analysis_payload(after), changes: changes },
    changes: changes,
    verification: { before_parsed: true, after_parsed: true }
  )
end

#family ⇒ String

Returns:

  • (String)


36
# File 'lib/yaml/merge/source_preserving_provider.rb', line 36

def family = 'yaml'

#merge2(request) ⇒ Hash[Symbol, untyped]

Parameters:

  • request (Hash[Symbol, untyped])

Returns:

  • (Hash[Symbol, untyped])


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/yaml/merge/source_preserving_provider.rb', line 91

def merge2(request)
  documents = {
    incoming: analyze_role(:incoming, request.fetch(:incoming_source)),
    current: analyze_role(:current, request.fetch(:current_source))
  }
  unsafe = documents.values.reject { |document| document.issues.empty? }
  return invalid_document_failure(:merge2, request, unsafe) unless unsafe.empty?
  return render_exact_merge2(request, documents) if documents[:incoming].source == documents[:current].source

  merged = recursive_merge2(documents)
  rendered = render_recursive_merge2(request, documents, merged)
  verification = verify_recursive_merge2(rendered, documents)
  return verification_failure(:merge2, request, rendered, [], verification) unless verification[:semantic_match]

  result(
    :merge2,
    request,
    output: rendered.content,
    changes: mapping_changes(documents[:current], analyze_role(:output, rendered.content)),
    render_report: render_report(rendered, :recursive_mapping_composite),
    verification: verification
  )
end

#merge3(request) ⇒ Hash[Symbol, untyped]

Parameters:

  • request (Hash[Symbol, untyped])

Returns:

  • (Hash[Symbol, untyped])


115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/yaml/merge/source_preserving_provider.rb', line 115

def merge3(request)
  documents = i[base ours theirs].to_h do |role|
    [role, analyze_role(role, request.fetch(:"#{role}_source"))]
  end
  exact_role = exact_revision_role(documents)
  return render_exact(request, documents, exact_role) if exact_role

  unsafe = documents.values.reject { |document| document.issues.empty? }
  return structural_conflict(request, documents, unsafe) unless unsafe.empty?
  return unmanaged_conflict(request, documents) unless unmanaged_unchanged?(documents)

  decisions = three_way_decisions(documents)
  conflicts = decisions.select(&:conflict)
  return render_conflicts(request, documents, decisions, conflicts) unless conflicts.empty?

  render_composite(request, documents, decisions)
end

#package_name ⇒ Object



39
# File 'lib/yaml/merge/source_preserving_provider.rb', line 39

def package_name = self.class::PACKAGE_NAME

#package_version ⇒ Object



40
# File 'lib/yaml/merge/source_preserving_provider.rb', line 40

def package_version = self.class::PACKAGE_VERSION

#provider_id ⇒ String

Returns:

  • (String)


35
# File 'lib/yaml/merge/source_preserving_provider.rb', line 35

def provider_id = self.class::PROVIDER_ID

#role ⇒ Object



41
# File 'lib/yaml/merge/source_preserving_provider.rb', line 41

def role = self.class.const_defined?(:ROLE, false) ? self.class::ROLE : :backend