Module: Polyrun::Partition::TimingKeys

Defined in:
lib/polyrun/partition/timing_keys.rb

Overview

Normalizes partition item keys and timing JSON keys for file vs experimental example granularity.

  • file — one item per spec file; keys are absolute paths (see #canonical_file_path).

  • example — one item per example (RSpec-style path:line); keys are “#{absolute_path}:#{line}”.

Class Method Summary collapse

Class Method Details

.canonical_file_path(abs_path) ⇒ Object

Resolves the parent directory with File.realpath so /var/... and /private/var/... (macOS tmpdirs) and symlink segments map to one key for the same file.



16
17
18
19
20
21
22
# File 'lib/polyrun/partition/timing_keys.rb', line 16

def canonical_file_path(abs_path)
  dir = File.dirname(abs_path)
  base = File.basename(abs_path)
  File.join(File.realpath(dir), base)
rescue SystemCallError
  abs_path
end

.file_part_for_constraint(item) ⇒ Object

File path only (for partition constraints) when item is path:line.



35
36
37
38
39
40
41
# File 'lib/polyrun/partition/timing_keys.rb', line 35

def file_part_for_constraint(item)
  s = item.to_s
  m = s.match(/\A(.+):(\d+)\z/)
  return nil unless m && m[2].match?(/\A\d+\z/)

  m[1]
end

.load_costs_json_file(path, granularity, root: nil) ⇒ Object

Loads merged timing JSON (+path => seconds+ or path:line => seconds).

Parameters:

  • root (String, nil) (defaults to: nil)

    directory for normalizing relative keys (default: Dir.pwd). Use the same working directory (or pass the same root as Plan+‘s root) as when generating the timing file so keys align.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/polyrun/partition/timing_keys.rb', line 61

def load_costs_json_file(path, granularity, root: nil)
  abs = File.expand_path(path.to_s, Dir.pwd)
  return {} unless File.file?(abs)

  data = JSON.parse(File.read(abs))
  return {} unless data.is_a?(Hash)

  g = normalize_granularity(granularity)
  root = File.expand_path(root || Dir.pwd)
  out = {}
  data.each do |k, v|
    key = normalize_locator(k.to_s, root, g)
    fv = v.to_f
    if out.key?(key) && out[key] != fv
      Polyrun::Log.warn(
        "polyrun: timing JSON duplicate key #{key.inspect} after normalize (#{out[key]} vs #{fv}); using #{fv}"
      )
    end
    out[key] = fv
  end
  out
end

.normalize_granularity(value) ⇒ :file, :example

Returns:

  • (:file, :example)


25
26
27
28
29
30
31
32
# File 'lib/polyrun/partition/timing_keys.rb', line 25

def normalize_granularity(value)
  case value.to_s.strip.downcase
  when "example", "examples"
    :example
  else
    :file
  end
end

.normalize_locator(raw, root, granularity) ⇒ Object

Normalize a path or path:line locator relative to root for cost maps and Plan items.



44
45
46
47
48
49
50
51
52
53
54
# File 'lib/polyrun/partition/timing_keys.rb', line 44

def normalize_locator(raw, root, granularity)
  s = raw.to_s.strip
  return canonical_file_path(File.expand_path(s, root)) if s.empty?

  if granularity == :example && (m = s.match(/\A(.+):(\d+)\z/)) && m[2].match?(/\A\d+\z/)
    fp = canonical_file_path(File.expand_path(m[1], root))
    return "#{fp}:#{m[2]}"
  end

  canonical_file_path(File.expand_path(s, root))
end