Commit 857f89d7 authored by Henrique Nakashima's avatar Henrique Nakashima Committed by Commit Bot

[Lorenz] Write git metadata to dependency graph .jsons

This makes it possible to know what revision a graph corresponds to,
so that users know how old the graph they are viewing is and makes it
possible to track regressions.

Bug: 1115268
Change-Id: Iedceabe885d90b14bb639e810dcaa75f48be844a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2353292Reviewed-by: default avatarMohamed Heikal <mheikal@chromium.org>
Commit-Queue: Henrique Nakashima <hnakashima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#821836}
parent 41099f7c
......@@ -10,14 +10,13 @@ import math
import multiprocessing
import pathlib
import os
import subprocess
import sys
from typing import List, Tuple
import class_dependency
import package_dependency
import serialization
import subprocess_utils
SRC_PATH = pathlib.Path(__file__).resolve().parents[3] # src/
JDEPS_PATH = SRC_PATH.joinpath('third_party/jdk/current/bin/jdeps')
......@@ -89,28 +88,11 @@ class JavaClassJdepsParser(object):
from_node.add_nested_class(nested_to)
def _run_command(command: List[str]) -> str:
"""Runs a command and returns the output.
Raises an exception and prints the command output if the command fails."""
try:
run_result = subprocess.run(command,
capture_output=True,
text=True,
check=True)
except subprocess.CalledProcessError as e:
print(f'{command} failed with code {e.returncode}.', file=sys.stderr)
print(f'\nSTDERR:\n{e.stderr}', file=sys.stderr)
print(f'\nSTDOUT:\n{e.stdout}', file=sys.stderr)
raise
return run_result.stdout
def _run_jdeps(jdeps_path: str, filepath: pathlib.Path) -> str:
"""Runs jdeps on the given filepath and returns the output."""
print(f'Running jdeps and parsing output for {filepath}')
return _run_command([jdeps_path, '-R', '-verbose:class', filepath])
return subprocess_utils.run_command(
[jdeps_path, '-R', '-verbose:class', filepath])
def _run_gn_desc_list_dependencies(build_output_dir: str, target: str,
......@@ -118,7 +100,7 @@ def _run_gn_desc_list_dependencies(build_output_dir: str, target: str,
"""Runs gn desc to list all jars that a target depends on.
This includes direct and indirect dependencies."""
return _run_command(
return subprocess_utils.run_command(
[gn_path, 'desc', '--all', build_output_dir, target, 'deps'])
......@@ -191,7 +173,7 @@ def main():
help='Path to the gn executable.')
arguments = arg_parser.parse_args()
# gn must be run from inside the git checkout.
# gn and git must be run from inside the git checkout.
os.chdir(SRC_PATH)
print('Getting list of dependency jars...')
......
# Lint as: python3
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Helper module for retrieving git metadata."""
import re
import subprocess_utils
def get_last_commit_hash() -> str:
"""Get the git hash of the last git commit to the git repo.
The cwd must be a git repository.
"""
return _get_last_commit_with_format('%H')
def get_last_commit_time() -> str:
"""Get the commit date/time of the last git commit to the git repo.
The cwd must be a git repository.
"""
return _get_last_commit_with_format('%cd')
def get_last_commit_cr_position() -> str:
"""Get the cr position of the last git commit to the git repo.
This is the number that follows "Cr-Commit-Position:". In the absence of
this value, returns an empty string.
The cwd must be a chromium git repository.
"""
description: str = _get_last_commit_with_format('%b')
# Will capture from
# '[lines...]Cr-Commit-Position: refs/heads/master@{#123456}' the string
# '123456'.
CR_POSITION_REGEX = r'Cr-Commit-Position: .*{#([0-9]+)}'
match: re.Match = re.search(CR_POSITION_REGEX, description)
if match is None:
return ''
return match.group(1)
def _get_last_commit_with_format(format: str) -> str:
output_str: str = subprocess_utils.run_command(
['git', 'show', '--no-patch', f'--pretty=format:{format}'])
return output_str.strip('\n')
......@@ -12,7 +12,13 @@ EDGES = 'edges'
BEGIN = 'begin'
END = 'end'
# Build metadata attributes.
COMMIT_HASH = 'commit_hash'
COMMIT_CR_POSITION = 'commit_cr_position'
COMMIT_TIME = 'commit_time'
# Miscellaneous attributes.
PACKAGE_GRAPH = 'package_graph'
CLASS_GRAPH = 'class_graph'
BUILD_METADATA = 'build_metadata'
META = 'meta'
......@@ -8,6 +8,7 @@ from typing import Dict, Tuple
import class_dependency
import class_json_consts
import git_utils
import graph
import json_consts
import package_dependency
......@@ -92,6 +93,17 @@ def create_class_graph_from_json_obj(
return class_graph
def create_build_metadata() -> Dict:
"""Creates metadata about the build the graph was extracted from.
"""
return {
json_consts.COMMIT_HASH: git_utils.get_last_commit_hash(),
json_consts.COMMIT_CR_POSITION:
git_utils.get_last_commit_cr_position(),
json_consts.COMMIT_TIME: git_utils.get_last_commit_time(),
}
def dump_class_and_package_graphs_to_file(
class_graph: class_dependency.JavaClassDependencyGraph,
package_graph: package_dependency.JavaPackageDependencyGraph,
......@@ -113,6 +125,7 @@ def dump_class_and_package_graphs_to_file(
json_obj = {
json_consts.CLASS_GRAPH: create_json_obj_from_graph(class_graph),
json_consts.PACKAGE_GRAPH: create_json_obj_from_graph(package_graph),
json_consts.BUILD_METADATA: create_build_metadata(),
}
with open(filename, 'w') as json_file:
json.dump(json_obj, json_file, separators=(',', ':'))
......
#!/usr/bin/env python3
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Utils to run subprocesses."""
import subprocess
import sys
from typing import List
def run_command(command: List[str]) -> str:
"""Runs a command and returns the output.
Raises an exception and prints the command output if the command fails."""
try:
run_result = subprocess.run(command,
capture_output=True,
text=True,
check=True)
except subprocess.CalledProcessError as e:
print(f'{command} failed with code {e.returncode}.', file=sys.stderr)
print(f'\nSTDERR:\n{e.stderr}', file=sys.stderr)
print(f'\nSTDOUT:\n{e.stdout}', file=sys.stderr)
raise
return run_result.stdout
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment