1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
#!/usr/bin/env python3
import json
import pathlib
import argparse
import subprocess
import tempfile
import sys
# Given a git repository and a base to search for layers (either a layer
# directly, or a directory containing layers), run the patchscript and update
# the specified JSON file.
args = argparse.ArgumentParser(description="Update Patch Metrics")
args.add_argument("-j", "--json", required=True, type=pathlib.Path, help="update specified JSON file")
args.add_argument("-s", "--patchscript", required=True, type=pathlib.Path, help="patchreview script to run")
args.add_argument("-r", "--repo", required=True, type=pathlib.Path, help="repository to use (e.g. path/to/poky)")
args.add_argument("-l", "--layer", type=pathlib.Path, help="layer/repository to scan")
args = args.parse_args()
if not args.repo.is_dir():
print(f"{args.repo} is not a directory")
sys.exit(1)
if not args.layer.is_dir():
print(f"{args.layer} is not a directory")
sys.exit(1)
if not args.patchscript.is_file():
print(f"{args.patchscript} is not a file")
print("Running patchmetrics-update")
if "meta-openembedded" in args.layer.name:
# 2023-01-01, arbitarily chosen
epoch = "1672531200"
else:
# 2011-04-25, Yocto 1.0 release.
epoch = "1301074853"
with tempfile.TemporaryDirectory(prefix="patchmetrics-") as tempname:
tempdir = pathlib.Path(tempname)
layerdir = tempdir / args.layer.relative_to(args.repo)
# Create a temporary clone of the repository as we'll be checking out different revisions
print(f"Making a temporary clone of {args.repo} to {tempdir}")
subprocess.check_call(["git", "clone", "--quiet", args.repo, tempdir])
# Identify what revisions need to be analysed. If we reverse the list, keep
# order, and remove in-place, then iterating through a large number of
# commits is faster.
repo_revisions = subprocess.check_output(["git", "rev-list", "--reverse", "--since", epoch, "origin/master"], universal_newlines=True, cwd=tempdir).strip().split()
revision_count = len(repo_revisions)
if args.json.exists():
with open(args.json) as f:
data = json.load(f)
seen = set()
for i in data:
try:
repo_revisions.remove(i["commit"])
except ValueError:
pass
new_count = len(repo_revisions)
print("Found %s, need to scan %d revisions:\n%s" % (revision_count - new_count, new_count, str(repo_revisions)))
# Run the patchreview script for every revision
for rev in repo_revisions:
print("Processing %s" % rev)
subprocess.check_call(["git", "checkout", "--detach", rev], cwd=tempdir)
subprocess.check_call([args.patchscript, "--json", args.json, layerdir])
print("Finished patchmetrics-update")
|