class XcodeArchiveCache::BuildGraph::NodeShaCalculator

Attributes

own_sha[R]

@return [String]

Public Class Methods

new() click to toggle source
# File lib/build_graph/sha_calculator.rb, line 5
def initialize
  @own_sha = calculate_own_sources_sha
end

Public Instance Methods

calculate(node) click to toggle source

@param [XcodeArchiveCache::BuildGraph::Node] node

# File lib/build_graph/sha_calculator.rb, line 11
def calculate(node)
  return if node.sha

  dependency_shas = []
  node.dependencies.each do |dependency_node|
    calculate(dependency_node)
    dependency_shas.push(dependency_node.sha)
  end

  auxiliary_file = Tempfile.new(node.name)
  build_settings = node.build_settings.filtered_to_string
  save_auxiliary_data(build_settings, dependency_shas, auxiliary_file)

  input_paths = list_input_paths(node)
  node.sha = calculate_sha(input_paths + [auxiliary_file.path])
  auxiliary_file.close(true)
end

Private Instance Methods

calculate_own_sources_sha() click to toggle source

@return [String]

# File lib/build_graph/sha_calculator.rb, line 37
def calculate_own_sources_sha
  root = Pathname.new(File.expand_path('../', File.dirname(__FILE__)))
  source_file_glob = File.join(root.realpath.to_s, "**", "*.rb")
  source_file_paths = Dir.glob(source_file_glob)

  calculate_sha(source_file_paths)
end
calculate_sha(file_paths) click to toggle source

@param [Array<String>] file_paths

File paths to include in resulting sha

@return [String] sha256 over specified files

# File lib/build_graph/sha_calculator.rb, line 105
def calculate_sha(file_paths)
  hash = Digest::SHA256.new
  file_paths.map do |path|
    hash << Digest::SHA256.file(path).hexdigest
  end

  hash.to_s
end
list_build_phase_inputs(build_phase) click to toggle source

@param [Xcodeproj::Project::Object::AbstractBuildPhase] build_phase

@return [Array<String>]

List of input file paths for build phase
# File lib/build_graph/sha_calculator.rb, line 69
def list_build_phase_inputs(build_phase)
  build_phase.files_references.map do |file_ref|
    next unless file_ref.is_a?(Xcodeproj::Project::Object::PBXFileReference)

    begin
      path = file_ref.real_path.to_s
    rescue
      next
    end

    if File.file?(path)
      next path
    elsif File.directory?(path)
      # NOTE: find doesn't follow symlinks, shouldn't we follow them?
      next Find.find(path).select {|found| File.file?(found)}
    end

    []
  end
end
list_input_paths(node) click to toggle source

@param [XcodeArchiveCache::BuildGraph::Node] node

@return [Array<String>]

List of input file paths for native target
# File lib/build_graph/sha_calculator.rb, line 50
def list_input_paths(node)
  inputs = []

  node.native_target.build_phases.each do |build_phase|
    inputs << list_build_phase_inputs(build_phase)
  end

  modulemap_file_path = node.original_modulemap_file_path
  inputs << modulemap_file_path if modulemap_file_path

  # file path order should not affect evaluation result
  inputs.flatten.compact.sort
end
save_auxiliary_data(build_settings, dependency_shas, tempfile) click to toggle source

@param [Tempfile] tempfile @param [String] build_settings @param [Array<String>] dependency_shas

# File lib/build_graph/sha_calculator.rb, line 94
def save_auxiliary_data(build_settings, dependency_shas, tempfile)
  file_contents = build_settings + dependency_shas.join("\n") + "\nXCODE-ARCHIVE-CACHE: #{own_sha}\n"
  tempfile << file_contents
  tempfile.flush
end