Skip to content

Commit aacb86a

Browse files
committed
chore: unify include analysis loading logic and support direct URLs
1 parent fa84c60 commit aacb86a

13 files changed

Lines changed: 83 additions & 103 deletions

add_to_remove_include.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from common import IgnoresConfiguration, IncludeChange
1010
from filter_include_changes import Change, filter_changes
11-
from include_analysis import IncludeAnalysisOutput, ParseError, parse_raw_include_analysis_output
11+
from include_analysis import IncludeAnalysisOutput, ParseError, load_include_analysis
1212
from list_includers import list_includers
1313
from list_transitive_includes import list_transitive_includes
1414
from typing import Dict, Iterator, List, Set, Tuple
@@ -97,7 +97,7 @@ def main():
9797
)
9898
parser.add_argument(
9999
"include_analysis_output",
100-
type=argparse.FileType("r"),
100+
type=str,
101101
help="The include analysis output to use.",
102102
)
103103
parser.add_argument("filename", help="File that has the include to be removed.")
@@ -111,7 +111,7 @@ def main():
111111
args = parser.parse_args()
112112

113113
try:
114-
include_analysis = parse_raw_include_analysis_output(args.include_analysis_output.read())
114+
include_analysis = load_include_analysis(args.include_analysis_output)
115115
except ParseError as e:
116116
message = str(e)
117117
print("error: Could not parse include analysis output file")

extract_archived_include_analysis.py

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,10 @@
33
import argparse
44
import logging
55
import os
6-
import re
76
import sys
87
import urllib.request
98

10-
DATA_REGEX = re.compile(r".*<script>\n?(data = .*?)<\/script>", re.DOTALL)
11-
12-
13-
def extract_include_analysis(contents: str) -> str:
14-
data_match = DATA_REGEX.match(contents)
15-
16-
if data_match:
17-
return data_match.group(1).strip()
18-
19-
return ""
9+
from utils import extract_include_analysis
2010

2111

2212
def main():

extract_include_analysis_edges.py

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,14 @@
66
import os
77
import re
88
import sys
9-
import urllib.request
109
from datetime import datetime
1110

12-
from include_analysis import IncludeAnalysisOutput, ParseError, parse_raw_include_analysis_output
11+
from include_analysis import IncludeAnalysisOutput, ParseError, load_include_analysis
1312
from suggest_include_changes import filter_filenames
1413
from utils import (
1514
get_include_analysis_edge_expanded_sizes,
1615
get_include_analysis_edge_prevalence,
1716
get_include_analysis_edges_centrality,
18-
get_latest_include_analysis,
1917
)
2018

2119

@@ -65,7 +63,7 @@ def main():
6563
parser = argparse.ArgumentParser(description="Extract include edges from include analysis, with filtering")
6664
parser.add_argument(
6765
"include_analysis_output",
68-
type=argparse.FileType("r"),
66+
type=str,
6967
nargs="?",
7068
help="The include analysis output to use.",
7169
)
@@ -93,14 +91,8 @@ def main():
9391
level=logging.DEBUG if args.verbose else logging.WARNING if args.quiet else logging.INFO,
9492
)
9593

96-
# If the user specified an include analysis output file, use that instead of fetching it
97-
if args.include_analysis_output:
98-
raw_include_analysis = args.include_analysis_output.read()
99-
else:
100-
raw_include_analysis = get_latest_include_analysis()
101-
10294
try:
103-
include_analysis = parse_raw_include_analysis_output(raw_include_analysis)
95+
include_analysis = load_include_analysis(args.include_analysis_output)
10496
except ParseError as e:
10597
message = str(e)
10698
print("error: Could not parse include analysis output file")

include_analysis.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import json
22
import re
3+
import sys
4+
import urllib.request
35
from typing import Dict, List, Optional, TypedDict
46

7+
DATA_REGEX = re.compile(r".*<script>\n?(data = .*?)<\/script>", re.DOTALL)
58
GENERATED_FILE_PREFIX_REGEX = re.compile(r"^(out/[\w-]+/gen/).*$")
69
SYSROOT_REGEX = re.compile(r"^(build/linux/[\w-]+/)usr/include/([\w-]+)/sys/.*$")
710

@@ -124,3 +127,41 @@ def parse_raw_include_analysis_output(output: str) -> Optional[IncludeAnalysisOu
124127
parsed_output["sysroot_platform"] = sysroot_platform
125128

126129
return parsed_output
130+
131+
132+
def get_latest_include_analysis():
133+
response = urllib.request.urlopen(
134+
"https://commondatastorage.googleapis.com/chromium-browser-clang/include-analysis.js"
135+
)
136+
137+
return response.read().decode("utf8")
138+
139+
140+
def extract_include_analysis(contents: str) -> str:
141+
data_match = DATA_REGEX.match(contents)
142+
143+
if data_match:
144+
return data_match.group(1).strip()
145+
146+
return ""
147+
148+
149+
def load_include_analysis(include_analysis_path: Optional[str]) -> IncludeAnalysisOutput:
150+
# If the user specified an include analysis output file, use that instead of fetching it
151+
if include_analysis_path:
152+
if include_analysis_path.startswith("https://"):
153+
include_analysis_response = urllib.request.urlopen(include_analysis_path)
154+
include_analysis_contents = include_analysis_response.read().decode("utf8")
155+
raw_include_analysis = extract_include_analysis(include_analysis_contents)
156+
157+
if not raw_include_analysis:
158+
raise RuntimeError(f"Could not extract include analysis from {include_analysis_path}")
159+
elif include_analysis_path == "-":
160+
raw_include_analysis = sys.stdin.read()
161+
else:
162+
with open(include_analysis_path, "r") as f:
163+
raw_include_analysis = f.read()
164+
else:
165+
raw_include_analysis = get_latest_include_analysis()
166+
167+
return parse_raw_include_analysis_output(raw_include_analysis)

include_analysis_diff.py

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@
1010
from datetime import datetime
1111

1212
from extract_archived_include_analysis import extract_include_analysis
13-
from include_analysis import IncludeAnalysisOutput, ParseError, parse_raw_include_analysis_output
13+
from include_analysis import (
14+
IncludeAnalysisOutput,
15+
ParseError,
16+
load_include_analysis,
17+
parse_raw_include_analysis_output,
18+
)
1419
from suggest_include_changes import filter_filenames
15-
from utils import get_latest_include_analysis
1620

1721
CHROMIUM_INCLUDE_ANALYSIS_BASE_URL = "https://commondatastorage.googleapis.com/chromium-browser-clang"
1822
HREF_REGEX = re.compile(r"<a href=\"(.*?)\">", re.DOTALL)
@@ -220,13 +224,13 @@ def main():
220224
)
221225
parser.add_argument(
222226
"include_analysis_output",
223-
type=argparse.FileType("r"),
227+
type=str,
224228
nargs="?",
225229
help="The include analysis output to use.",
226230
)
227231
parser.add_argument(
228232
"previous_include_analysis_output",
229-
type=argparse.FileType("r"),
233+
type=str,
230234
nargs="?",
231235
help="The previous include analysis output to use. If provided, the diff will only be between these two files.",
232236
)
@@ -264,14 +268,8 @@ def main():
264268
level=logging.DEBUG if args.verbose else logging.WARNING if args.quiet else logging.INFO,
265269
)
266270

267-
# If the user specified an include analysis output file, use that instead of fetching it
268-
if args.include_analysis_output:
269-
raw_include_analysis = args.include_analysis_output.read()
270-
else:
271-
raw_include_analysis = get_latest_include_analysis()
272-
273271
try:
274-
include_analysis = parse_raw_include_analysis_output(raw_include_analysis)
272+
include_analysis = load_include_analysis(args.include_analysis_output)
275273
except ParseError as e:
276274
message = str(e)
277275
print("error: Could not parse include analysis output file")
@@ -280,10 +278,8 @@ def main():
280278
return 2
281279

282280
if args.previous_include_analysis_output:
283-
raw_previous_include_analysis = args.previous_include_analysis_output.read()
284-
285281
try:
286-
previous_include_analysis = parse_raw_include_analysis_output(raw_previous_include_analysis)
282+
previous_include_analysis = load_include_analysis(args.previous_include_analysis_output)
287283
except ParseError as e:
288284
message = str(e)
289285
print("error: Could not parse include analysis output file")

list_includers.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
from common import IgnoresConfiguration, IncludeChange
1010
from filter_include_changes import Change, filter_changes
11-
from include_analysis import IncludeAnalysisOutput, ParseError, parse_raw_include_analysis_output
11+
from include_analysis import IncludeAnalysisOutput, ParseError, load_include_analysis
1212
from typing import Iterator, List, Tuple
1313
from utils import (
1414
get_include_analysis_edges_centrality,
@@ -17,7 +17,6 @@
1717
get_include_analysis_edge_includer_size,
1818
get_include_analysis_edge_prevalence,
1919
get_include_analysis_edge_sizes,
20-
get_latest_include_analysis,
2120
load_config,
2221
normalize_include_path,
2322
)
@@ -106,7 +105,7 @@ def main():
106105
parser = argparse.ArgumentParser(description="List includers of a file")
107106
parser.add_argument(
108107
"include_analysis_output",
109-
type=argparse.FileType("r"),
108+
type=str,
110109
nargs="?",
111110
help="The include analysis output to use.",
112111
)
@@ -136,14 +135,8 @@ def main():
136135
parser.add_argument("--verbose", action="store_true", default=False, help="Enable verbose logging.")
137136
args = parser.parse_args()
138137

139-
# If the user specified an include analysis output file, use that instead of fetching it
140-
if args.include_analysis_output:
141-
raw_include_analysis = args.include_analysis_output.read()
142-
else:
143-
raw_include_analysis = get_latest_include_analysis()
144-
145138
try:
146-
include_analysis = parse_raw_include_analysis_output(raw_include_analysis)
139+
include_analysis = load_include_analysis(args.include_analysis_output)
147140
except ParseError as e:
148141
message = str(e)
149142
print("error: Could not parse include analysis output file")

list_transitive_includes.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from common import FilteredIncludeChangeList, IgnoresConfiguration, IncludeChange
1111
from filter_include_changes import Change, filter_changes
12-
from include_analysis import IncludeAnalysisOutput, ParseError, parse_raw_include_analysis_output
12+
from include_analysis import IncludeAnalysisOutput, ParseError, load_include_analysis
1313
from typing import Dict, Iterator, List, Tuple
1414
from utils import (
1515
get_include_analysis_edges_centrality,
@@ -19,7 +19,6 @@
1919
get_include_analysis_edge_prevalence,
2020
get_include_analysis_edge_sizes,
2121
get_include_file_size,
22-
get_latest_include_analysis,
2322
load_config,
2423
normalize_include_path,
2524
)
@@ -141,7 +140,7 @@ def main():
141140
parser = argparse.ArgumentParser(description="List transitive (and direct) includes of a file")
142141
parser.add_argument(
143142
"include_analysis_output",
144-
type=argparse.FileType("r"),
143+
type=str,
145144
nargs="?",
146145
help="The include analysis output to use.",
147146
)
@@ -179,14 +178,8 @@ def main():
179178
print("error: --apply-changes option requires --include-changes")
180179
return 1
181180

182-
# If the user specified an include analysis output file, use that instead of fetching it
183-
if args.include_analysis_output:
184-
raw_include_analysis = args.include_analysis_output.read()
185-
else:
186-
raw_include_analysis = get_latest_include_analysis()
187-
188181
try:
189-
include_analysis = parse_raw_include_analysis_output(raw_include_analysis)
182+
include_analysis = load_include_analysis(args.include_analysis_output)
190183
except ParseError as e:
191184
message = str(e)
192185
print("error: Could not parse include analysis output file")

minimum_edge_cut.py

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,9 @@
88

99
import networkx as nx
1010

11-
from include_analysis import IncludeAnalysisOutput, ParseError, parse_raw_include_analysis_output
11+
from include_analysis import IncludeAnalysisOutput, ParseError, load_include_analysis
1212
from typing import Iterator, Tuple
13-
from utils import (
14-
create_graph_from_include_analysis,
15-
get_include_analysis_edge_prevalence,
16-
get_latest_include_analysis,
17-
)
13+
from utils import create_graph_from_include_analysis, get_include_analysis_edge_prevalence
1814

1915

2016
def minimum_edge_cut(
@@ -69,9 +65,9 @@ def main():
6965
parser = argparse.ArgumentParser(description="Find the minimum edge cut between two files")
7066
parser.add_argument(
7167
"include_analysis_output",
72-
type=argparse.FileType("r"),
68+
type=str,
7369
nargs="?",
74-
help="The include analysis output to use.",
70+
help="The include analysis output to use (can be a file path or URL). If not specified, pulls the latest.",
7571
)
7672
parser.add_argument("source", help="Source file.")
7773
parser.add_argument("target", help="Target file.")
@@ -86,14 +82,8 @@ def main():
8682
parser.add_argument("--verbose", action="store_true", default=False, help="Enable verbose logging.")
8783
args = parser.parse_args()
8884

89-
# If the user specified an include analysis output file, use that instead of fetching it
90-
if args.include_analysis_output:
91-
raw_include_analysis = args.include_analysis_output.read()
92-
else:
93-
raw_include_analysis = get_latest_include_analysis()
94-
9585
try:
96-
include_analysis = parse_raw_include_analysis_output(raw_include_analysis)
86+
include_analysis = load_include_analysis(args.include_analysis_output)
9787
except ParseError as e:
9888
message = str(e)
9989
print("error: Could not parse include analysis output file")

recalculate_expanded_sizes.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111
import time
1212
from itertools import batched
1313

14-
from common import FilteredIncludeChangeList, IgnoresConfiguration, IncludeChange
14+
from common import FilteredIncludeChangeList, IgnoresConfiguration
1515
from filter_include_changes import Change, filter_changes
1616
from list_transitive_includes import list_transitive_includes
17-
from include_analysis import IncludeAnalysisOutput, ParseError, parse_raw_include_analysis_output
17+
from include_analysis import IncludeAnalysisOutput, ParseError, load_include_analysis
1818
from typing import Callable, Dict, Iterator, List, Tuple
1919
from utils import get_worker_count, load_config
2020

@@ -180,7 +180,7 @@ def main():
180180
)
181181
parser.add_argument(
182182
"include_analysis_output",
183-
type=argparse.FileType("r"),
183+
type=str,
184184
help="The include analysis output to use.",
185185
)
186186
parser.add_argument(
@@ -198,7 +198,7 @@ def main():
198198
args = parser.parse_args()
199199

200200
try:
201-
include_analysis = parse_raw_include_analysis_output(args.include_analysis_output.read())
201+
include_analysis = load_include_analysis(args.include_analysis_output)
202202
except ParseError as e:
203203
message = str(e)
204204
print("error: Could not parse include analysis output file")

set_edge_weights.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from common import IgnoresConfiguration, IncludeChange
1111
from filter_include_changes import Change, filter_changes
12-
from include_analysis import IncludeAnalysisOutput, ParseError, parse_raw_include_analysis_output
12+
from include_analysis import IncludeAnalysisOutput, ParseError, load_include_analysis
1313
from utils import (
1414
get_include_analysis_edges_centrality,
1515
get_include_analysis_edge_expanded_sizes,
@@ -83,7 +83,7 @@ def main():
8383
)
8484
parser.add_argument(
8585
"include_analysis_output",
86-
type=argparse.FileType("r"),
86+
type=str,
8787
help="The include analysis output to use.",
8888
)
8989
parser.add_argument(
@@ -101,7 +101,7 @@ def main():
101101
args = parser.parse_args()
102102

103103
try:
104-
include_analysis = parse_raw_include_analysis_output(args.include_analysis_output.read())
104+
include_analysis = load_include_analysis(args.include_analysis_output)
105105
except ParseError as e:
106106
message = str(e)
107107
print("error: Could not parse include analysis output file")

0 commit comments

Comments
 (0)