Repository URL to install this package:
|
Version:
1.26.0.dev0+gite506aa5f ▾
|
# Copyright 2015 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).
from collections import namedtuple
from pants.build_graph.target import Target
from pants.util.dirutil import safe_open
class InvalidationReport:
"""Creates a report of all versioned target sets seen in the build."""
class TaskReport:
class TaskEntry(
namedtuple(
"TaskEntry",
["targets_hash", "target_ids", "cache_key_id", "cache_key_hash", "phase", "valid"],
)
):
"""
:param targets_hash: A manufactured id for the versioned target set
:param target_ids: list of string target ids
:param cache_key_id: cache key from the InvalidationCheck
:param cache_key_hash: hash of cache_key from the InvalidationCheck
:param valid: True if the cache_key is valid
"""
def __init__(self, task_name, invocation_id):
self._task_name = task_name
self._invocation_id = invocation_id
self._entries = []
def add(self, targets, cache_key, valid, phase):
# Manufacture an id from a hash of the target ids
targets_hash = Target.identify(targets)
self._entries.append(
self.TaskEntry(
targets_hash=targets_hash,
target_ids=[t.id for t in targets],
cache_key_id=cache_key.id,
cache_key_hash=cache_key.hash,
valid=valid,
phase=phase,
)
)
def report(self, writer):
"""
:param BufferedWriter writer: output for the report
"""
for entry in self._entries:
for target_id in entry.target_ids:
writer.write(
(
"{invocation_id},{task},{targets_hash},{target_id},{cache_key_id},{cache_key_hash},"
+ "{phase},{valid}\n"
).format(
invocation_id=self._invocation_id,
task=self._task_name,
targets_hash=entry.targets_hash,
target_id=target_id,
cache_key_id=entry.cache_key_id,
cache_key_hash=entry.cache_key_hash,
phase=entry.phase,
valid=entry.valid,
)
)
def __init__(self):
self._task_reports = {}
self._invocation_id = 0
self._filename = None
def set_filename(self, filename):
self._filename = filename
def add_task(self, task_name):
self._invocation_id += 1
task_report = self.TaskReport(task_name, self._invocation_id)
self._task_reports[task_name] = task_report
return task_report
def add_vts(self, task_name, targets, cache_key, valid, phase):
"""Add a single VersionedTargetSet entry to the report.
:param InvalidationCacheManager cache_manager:
:param CacheKey cache_key:
:param bool valid:
:param string phase:
"""
if task_name not in self._task_reports:
self.add_task(task_name)
self._task_reports[task_name].add(targets, cache_key, valid, phase)
def report(self, filename=None):
"""Write details of each versioned target to file.
:param string filename: file to write out the report to
Fields in the report:
invocation_id: A sequence number that increases each time a task is invoked
task_name: The name of the task
targets_hash: an id from a hash of all target ids to identify a VersionedTargetSet
target_id: target id
cache_key_id: the Id for the cache key
cache_key_hash: computed hash for the cache key
phase: What part of the validation check the values were captured
valid: True if the cache is valid for the VersionedTargetSet
"""
# TODO(zundel) set report to stream to the file
filename = filename or self._filename
if filename:
# Usually the directory exists from reporting initialization, but not if clean-all was a goal.
with safe_open(filename, "w") as writer:
writer.write(
"invocation_id,task_name,targets_hash,target_id,cache_key_id,cache_key_hash,phase,valid"
+ "\n"
)
for task_report in self._task_reports.values():
task_report.report(writer)