in sapp/analysis_output.py [0:0]
def from_directories(cls, directories: List[str]) -> "AnalysisOutput":
"""
Aggregates several analysis output directories (each of which may themselves be sharded)
into one AnalysisOutput object. Used for distributed runs of Zoncolan.
Only supports `filename_spec` in the metadata.json to declare analysis output;
`filename_glob` and legacy `filenames` are not supported.
Metadata is naively merged.
"""
main_metadata = None
filename_specs = []
for directory in directories:
if not os.path.isdir(directory):
raise AnalysisOutputError(f"`{directory}` is not a directory")
metadata = {}
for file in glob(os.path.join(directory, METADATA_GLOB)):
with open(file) as f:
metadata.update(json.load(f))
if "filename_spec" in metadata:
filename_specs.append(
os.path.join(directory, os.path.basename(metadata["filename_spec"]))
)
repo_root = metadata.get("repo_root")
analysis_root = metadata["root"]
rules = {rule["code"]: rule for rule in metadata.get("rules", [])}
this_metadata = Metadata(
analysis_tool_version=metadata["version"],
commit_hash=metadata.get("commit"),
analysis_root=analysis_root,
repo_roots=[repo_root],
job_instance=metadata.get("job_instance"),
tool=metadata.get("tool"),
repository_name=metadata.get("repository_name"),
project=metadata.get("project"),
rules=rules,
type_intervals=cls._get_interval_dict(metadata),
)
if not main_metadata:
main_metadata = this_metadata
else:
main_metadata = main_metadata.merge(this_metadata)
return cls(
filename_specs=filename_specs,
metadata=main_metadata,
)