aboutsummaryrefslogtreecommitdiff
path: root/scripts/difftool
diff options
context:
space:
mode:
authorChris Parsons <cparsons@google.com>2022-01-07 10:56:53 -0500
committerChris Parsons <cparsons@google.com>2022-01-10 19:55:48 -0500
commit36843a623fd92694025a42cdba4b0bdc5b0e0aaa (patch)
tree7a860c9a158990df94b0f2e35bbc1e6941e2eeb5 /scripts/difftool
parent5cf1acfa781f3ee876468e2746bf2faf07a2d96f (diff)
downloadbazel-36843a623fd92694025a42cdba4b0bdc5b0e0aaa.tar.gz
Improve difftool usability
- Have collect.py save the target file so it need not be entered as an arg to difftool - Allow for usecase of analyzing actions for nonbuilding artifacts (the artifacts are not generated and therefore are not collected, but are present in the ninja file) Test: Manual Change-Id: Id857fe38c0da23b4b66043eb552ebee85bf55fef
Diffstat (limited to 'scripts/difftool')
-rwxr-xr-xscripts/difftool/collect.py32
-rwxr-xr-xscripts/difftool/difftool.py69
2 files changed, 67 insertions, 34 deletions
diff --git a/scripts/difftool/collect.py b/scripts/difftool/collect.py
index 11db040d..c4601df4 100755
--- a/scripts/difftool/collect.py
+++ b/scripts/difftool/collect.py
@@ -43,35 +43,41 @@ def main():
parser.add_argument("ninja_file",
help="the path to the root ninja file of the build " +
"to be analyzed. Ex: out/combined-aosp_flame.ninja")
- parser.add_argument("output_file",
- help="the path to the output artifact to be analyzed. " +
- "Ex: out/path/to/foo.so")
parser.add_argument("dest_directory",
help="directory to copy build-related information for " +
"later difftool comparison. Ex: /tmp/buildArtifacts")
+ parser.add_argument("--file", dest="output_file", default=None,
+ help="the path to the output artifact to be analyzed. " +
+ "Ex: out/path/to/foo.so")
args = parser.parse_args()
dest = args.dest_directory
- output_file = pathlib.Path(args.output_file)
if not os.path.isdir(dest):
raise Exception("invalid destination directory " + dest)
- if not output_file.is_file():
- raise Exception("Expected file %s was not found. " % output_file)
- main_ninja_basename = pathlib.Path(args.ninja_file).name
+ collection_info_filepath = ""
+ if args.output_file is not None:
+ output_file = pathlib.Path(args.output_file)
+ if not output_file.is_file():
+ raise Exception("Expected file %s was not found. " % output_file)
+ output_file_dest = pathlib.Path(dest).joinpath(output_file)
+ output_file_dest.parent.mkdir(parents=True, exist_ok=True)
+ shutil.copy2(output_file, output_file_dest)
+ collection_info_filepath = str(output_file)
+
+ ninja_file = pathlib.Path(args.ninja_file)
+ main_ninja_basename = ninja_file.name
+
shutil.copy2(args.ninja_file, os.path.join(dest, main_ninja_basename))
- for subninja_file in subninja_files(args.ninja_file):
+ for subninja_file in subninja_files(ninja_file):
parent_dir = pathlib.Path(subninja_file).parent
dest_dir = os.path.join(dest, parent_dir)
pathlib.Path(dest_dir).mkdir(parents=True, exist_ok=True)
shutil.copy2(subninja_file, os.path.join(dest, subninja_file))
- output_file_dest = pathlib.Path(dest).joinpath(output_file)
-
- output_file_dest.parent.mkdir(parents=True)
- shutil.copy2(output_file, output_file_dest)
- pathlib.Path(dest).joinpath("collection_info").write_text(main_ninja_basename)
+ collection_info = main_ninja_basename + "\n" + collection_info_filepath
+ pathlib.Path(dest).joinpath("collection_info").write_text(collection_info)
if __name__ == "__main__":
main()
diff --git a/scripts/difftool/difftool.py b/scripts/difftool/difftool.py
index 971c306c..e9f5b224 100755
--- a/scripts/difftool/difftool.py
+++ b/scripts/difftool/difftool.py
@@ -69,6 +69,11 @@ def file_differences(left_path, right_path):
Returns the empty list if these files are deemed "similar enough"."""
errors = []
+ if not left_path.is_file():
+ errors += ["%s does not exist" % left_path]
+ if not right_path.is_file():
+ errors += ["%s does not exist" % right_path]
+
result = subprocess.run(["diff", str(left_path), str(right_path)],
check=False, capture_output=True, encoding="utf-8")
if result.returncode != 0:
@@ -77,13 +82,19 @@ def file_differences(left_path, right_path):
def parse_collection_info(info_file_path):
+ """Parses the collection info file at the given path and returns details."""
if not info_file_path.is_file():
- raise Exception("Expected file %s was not found. " +
- "Did you run collect.py for this " +
- "directory?" % info_file_path)
+ raise Exception("Expected file %s was not found. " % info_file_path +
+ "Did you run collect.py for this directory?")
+
+ info_contents = info_file_path.read_text().splitlines()
+ ninja_path = pathlib.Path(info_contents[0])
+ target_file = None
+
+ if len(info_contents) > 1 and info_contents[1]:
+ target_file = info_contents[1]
- ninja_path = pathlib.Path(info_file_path.read_text())
- return ninja_path
+ return (ninja_path, target_file)
def main():
@@ -95,36 +106,50 @@ def main():
help="the 'left' directory to compare build outputs " +
"from. This must be the target of an invocation of " +
"collect.py.")
- parser.add_argument("left_output_file",
+ parser.add_argument("--left_file", dest="left_file", default=None,
help="the output file (relative to execution root) for " +
"the 'left' build invocation.")
parser.add_argument("right_dir",
help="the 'right' directory to compare build outputs " +
"from. This must be the target of an invocation of " +
"collect.py.")
- parser.add_argument("right_output_file",
+ parser.add_argument("--right_file", dest="right_file", default=None,
help="the output file (relative to execution root) " +
"for the 'right' build invocation.")
+ parser.add_argument("--allow_missing_file",
+ action=argparse.BooleanOptionalAction,
+ default=False,
+ help="allow a missing output file; this is useful to " +
+ "compare actions even in the absence of an output file.")
args = parser.parse_args()
mode = args.mode
-
- left_path = pathlib.Path(args.left_dir).joinpath(args.left_output_file)
- right_path = pathlib.Path(args.right_dir).joinpath(args.right_output_file)
- if not left_path.is_file():
- raise RuntimeError("Expected file %s was not found. " % left_path)
- if not right_path.is_file():
- raise RuntimeError("Expected file %s was not found. " % right_path)
-
left_diffinfo = pathlib.Path(args.left_dir).joinpath(
_COLLECTION_INFO_FILENAME)
right_diffinfo = pathlib.Path(args.right_dir).joinpath(
_COLLECTION_INFO_FILENAME)
- left_ninja_path = pathlib.Path(args.left_dir).joinpath(
- parse_collection_info(left_diffinfo))
- right_ninja_path = pathlib.Path(args.right_dir).joinpath(
- parse_collection_info(right_diffinfo))
+ left_ninja_name, left_file = parse_collection_info(left_diffinfo)
+ right_ninja_name, right_file = parse_collection_info(right_diffinfo)
+ if args.left_file:
+ left_file = args.left_file
+ if args.right_file:
+ right_file = args.right_file
+
+ if left_file is None:
+ raise Exception("No left file specified. Either run collect.py with a " +
+ "target file, or specify --left_file.")
+ if right_file is None:
+ raise Exception("No right file specified. Either run collect.py with a " +
+ "target file, or specify --right_file.")
+
+ left_path = pathlib.Path(args.left_dir).joinpath(left_file)
+ right_path = pathlib.Path(args.right_dir).joinpath(right_file)
+ if not args.allow_missing_file:
+ if not left_path.is_file():
+ raise RuntimeError("Expected file %s was not found. " % left_path)
+ if not right_path.is_file():
+ raise RuntimeError("Expected file %s was not found. " % right_path)
file_diff_errors = file_differences(left_path, right_path)
@@ -132,13 +157,15 @@ def main():
for err in file_diff_errors:
print(err)
if mode == "rich":
+ left_ninja_path = pathlib.Path(args.left_dir).joinpath(left_ninja_name)
+ right_ninja_path = pathlib.Path(args.right_dir).joinpath(right_ninja_name)
print("======== ACTION COMPARISON: ========")
print("=== LEFT:\n")
- left_command = collect_commands(left_ninja_path, args.left_output_file)
+ left_command = collect_commands(left_ninja_path, left_file)
print(left_command.splitlines()[-1])
print()
print("=== RIGHT:\n")
- right_command = collect_commands(right_ninja_path, args.right_output_file)
+ right_command = collect_commands(right_ninja_path, right_file)
print(right_command.splitlines()[-1])
print()
sys.exit(1)