Class: Sq::Refinement::AnnotatedTarget

Inherits:
Object
  • Object
show all
Defined in:
lib/sq/refinement/annotated_target.rb

Overview

A target, annotated with any changes

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target:, change_reason:, dependencies: []) ⇒ AnnotatedTarget

Returns a new instance of AnnotatedTarget.



16
17
18
19
20
21
22
23
24
# File 'lib/sq/refinement/annotated_target.rb', line 16

def initialize(target:, change_reason:, dependencies: [])
  @xcode_target = target
  @direct_change_reason = change_reason
  @dependencies = dependencies
  dependencies.each do |dependency|
    dependency.depended_upon_by << self
  end
  @depended_upon_by = []
end

Instance Attribute Details

#depended_upon_byArray<AnnotatedTarget> (readonly)

Returns the list of annotated targets that depend upon this target.

Returns:

  • (Array<AnnotatedTarget>)

    the list of annotated targets that depend upon this target



79
80
81
# File 'lib/sq/refinement/annotated_target.rb', line 79

def depended_upon_by
  @depended_upon_by
end

#dependenciesArray<AnnotatedTarget> (readonly)

Returns the list of annotated targets this target depends upon.

Returns:

  • (Array<AnnotatedTarget>)

    the list of annotated targets this target depends upon



77
78
79
# File 'lib/sq/refinement/annotated_target.rb', line 77

def dependencies
  @dependencies
end

#xcode_targetXcodeproj::Project::AbstactTarget (readonly)

Returns the target in an Xcode project.

Returns:

  • (Xcodeproj::Project::AbstactTarget)

    the target in an Xcode project



10
11
12
# File 'lib/sq/refinement/annotated_target.rb', line 10

def xcode_target
  @xcode_target
end

Instance Method Details

#change_reason(level:) ⇒ Boolean

Returns whether the target has changed, at the given change level.

Parameters:

  • level (Symbol, (:at_most_n_away,Integer))

    change level, e.g. :itself, :at_most_n_away, :full_transitive

Returns:

  • (Boolean)

    whether the target has changed, at the given change level



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/sq/refinement/annotated_target.rb', line 40

def change_reason(level:)
  @change_reason ||= {}
  # need to use this form for memoization, as opposed to ||=,
  # since this will (often) be nil and it makes a significant performance difference
  return @change_reason[level] if @change_reason.key?(level)

  @change_reason[level] =
    case level
    when :itself
      direct_change_reason
    when :full_transitive
      direct_change_reason || Sq::Refinement.map_find(dependencies) do |dependency|
        next unless (dependency_change_reason = dependency.change_reason(level:))

        "dependency #{dependency} changed because #{dependency_change_reason}"
      end
    when proc { |symbol, int| (symbol == :at_most_n_away) && int.is_a?(Integer) }
      distance_from_target = level.last
      raise ArgumentError, "level must be positive, not #{distance_from_target}" if distance_from_target.negative?

      change_reason = direct_change_reason
      if distance_from_target.positive?
        change_reason ||= Sq::Refinement.map_find(dependencies) do |dependency|
          unless (dependency_change_reason = dependency.change_reason(level: [:at_most_n_away, level.last.pred]))
            next
          end

          "dependency #{dependency} changed because #{dependency_change_reason}"
        end
      end
      change_reason
    else
      raise Error, "No known change level #{level.inspect}, only #{CHANGE_LEVELS.inspect} are known"
    end
end