Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/dotnet/private/generate_resources_tool.py
4502 views
1
#!/usr/bin/env python3
2
"""Generate C# ResourceUtilities partial class with embedded JS resources.
3
4
Usage:
5
generate_resources_tool.py --output path/to/ResourceUtilities.g.cs \
6
--input Ident1=path/to/file1.js \
7
--input Ident2=path/to/file2.js ...
8
9
Each identifier becomes a const string in ResourceUtilities class.
10
The content is emitted as a C# raw string literal using 5-quotes.
11
12
Todo:
13
It would be nice to convert this small single-file utility to .NET10/C#,
14
so it would work like `dotnet run generate_resources.cs -- <args>`.
15
Meaning .NET developers can easily support it.
16
"""
17
18
import argparse
19
import os
20
import sys
21
22
23
def parse_args(argv: list[str]) -> argparse.Namespace:
24
parser = argparse.ArgumentParser()
25
parser.add_argument("--output", required=True)
26
parser.add_argument("--input", action="append", default=[], help="IDENT=path")
27
return parser.parse_args(argv)
28
29
30
def parse_input_spec(spec: str) -> tuple[str, str]:
31
if "=" not in spec:
32
raise ValueError(f"Invalid --input value, expected IDENT=path, got: {spec}")
33
ident, path = spec.split("=", 1)
34
ident = ident.strip()
35
path = path.strip()
36
if not ident:
37
raise ValueError(f"Empty identifier in --input value: {spec}")
38
if not path:
39
raise ValueError(f"Empty path in --input value: {spec}")
40
return ident, path
41
42
43
def generate(output: str, inputs: list[tuple[str, str]]) -> None:
44
props: list[str] = []
45
for prop_name, path in inputs:
46
with open(path, encoding="utf-8") as f:
47
content = f.read()
48
# Use a C# raw string literal with five quotes. For a valid raw
49
# literal, the content must start on a new line and the closing
50
# quotes must be on their own line as well. We assume the content
51
# does not contain a sequence of five consecutive double quotes.
52
#
53
# Resulting C# will look like:
54
# """""
55
# <content>
56
# """""
57
literal = '"""""\n' + content + '\n"""""'
58
props.append(f" internal const string {prop_name} = {literal};")
59
60
lines: list[str] = []
61
lines.append("// <auto-generated />")
62
lines.append("namespace OpenQA.Selenium.Internal;")
63
lines.append("")
64
lines.append("internal static partial class ResourceUtilities")
65
lines.append("{")
66
for p in props:
67
lines.append(p)
68
lines.append("}")
69
lines.append("")
70
71
os.makedirs(os.path.dirname(output), exist_ok=True)
72
with open(output, "w", encoding="utf-8", newline="\n") as f:
73
f.write("\n".join(lines))
74
75
76
def main(argv: list[str]) -> int:
77
args = parse_args(argv)
78
inputs: list[tuple[str, str]] = []
79
for spec in args.input:
80
ident, path = parse_input_spec(spec)
81
inputs.append((ident, path))
82
generate(args.output, inputs)
83
return 0
84
85
86
if __name__ == "__main__":
87
raise SystemExit(main(sys.argv[1:]))
88
89