mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-23 01:21:42 +00:00
[build] Use pathlib in pre-generation scripts (#6745)
This commit is contained in:
2
.github/workflows/pregenerate.yml
vendored
2
.github/workflows/pregenerate.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
- name: Run ntcore
|
||||
run: ./ntcore/generate_topics.py
|
||||
- name: Run wpimath
|
||||
run: ./wpimath/generate_numbers.py && ./wpimath/generate_quickbuf.py protoc protoc-gen-quickbuf-1.3.3-linux-x86_64.exe
|
||||
run: ./wpimath/generate_numbers.py && ./wpimath/generate_quickbuf.py --quickbuf_plugin=protoc-gen-quickbuf-1.3.3-linux-x86_64.exe
|
||||
- name: Run HIDs
|
||||
run: ./wpilibj/generate_hids.py && ./wpilibc/generate_hids.py && ./wpilibNewCommands/generate_hids.py
|
||||
- name: Add untracked files to index so they count as changes
|
||||
|
||||
@@ -3,22 +3,23 @@
|
||||
# Copyright (c) FIRST and other WPILib contributors.
|
||||
# Open Source Software; you can modify and/or share it under the terms of
|
||||
# the WPILib BSD license file in the root directory of this project.
|
||||
import pathlib
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
|
||||
def main():
|
||||
def generate_usage_reporting(output_directory: Path, template_directory: Path):
|
||||
# Gets the folder this script is in (the hal/ directory)
|
||||
HAL_ROOT = pathlib.Path(__file__).parent
|
||||
java_package = "edu/wpi/first/hal"
|
||||
# fmt: off
|
||||
(HAL_ROOT / "src/generated/main/native/include/hal").mkdir(parents=True, exist_ok=True)
|
||||
(HAL_ROOT / f"src/generated/main/java/{java_package}").mkdir(parents=True, exist_ok=True)
|
||||
(output_directory / "main/native/include/hal").mkdir(parents=True, exist_ok=True)
|
||||
(output_directory / f"main/java/{java_package}").mkdir(parents=True, exist_ok=True)
|
||||
# fmt: on
|
||||
usage_reporting_types_cpp = []
|
||||
usage_reporting_instances_cpp = []
|
||||
usage_reporting_types = []
|
||||
usage_reporting_instances = []
|
||||
with open(HAL_ROOT / "src/generate/Instances.txt") as instances:
|
||||
with (template_directory / "Instances.txt").open(encoding="utf-8") as instances:
|
||||
for instance in instances:
|
||||
usage_reporting_instances_cpp.append(f" {instance.strip()},")
|
||||
usage_reporting_instances.append(
|
||||
@@ -26,7 +27,9 @@ def main():
|
||||
f" public static final int {instance.strip()};"
|
||||
)
|
||||
|
||||
with open(HAL_ROOT / "src/generate/ResourceType.txt") as resource_types:
|
||||
with (template_directory / "ResourceType.txt").open(
|
||||
encoding="utf-8"
|
||||
) as resource_types:
|
||||
for resource_type in resource_types:
|
||||
usage_reporting_types_cpp.append(f" {resource_type.strip()},")
|
||||
usage_reporting_types.append(
|
||||
@@ -34,7 +37,9 @@ def main():
|
||||
f" public static final int {resource_type.strip()};"
|
||||
)
|
||||
|
||||
with open(HAL_ROOT / "src/generate/FRCNetComm.java.in") as java_usage_reporting:
|
||||
with (template_directory / "FRCNetComm.java.in").open(
|
||||
encoding="utf-8"
|
||||
) as java_usage_reporting:
|
||||
contents = (
|
||||
# fmt: off
|
||||
java_usage_reporting.read()
|
||||
@@ -43,12 +48,12 @@ def main():
|
||||
# fmt: on
|
||||
)
|
||||
|
||||
with open(
|
||||
HAL_ROOT / f"src/generated/main/java/{java_package}/FRCNetComm.java", "w"
|
||||
) as java_out:
|
||||
java_out.write(contents)
|
||||
frc_net_comm = output_directory / f"main/java/{java_package}/FRCNetComm.java"
|
||||
frc_net_comm.write_text(contents, encoding="utf-8")
|
||||
|
||||
with open(HAL_ROOT / "src/generate/FRCUsageReporting.h.in") as cpp_usage_reporting:
|
||||
with (template_directory / "FRCUsageReporting.h.in").open(
|
||||
encoding="utf-8"
|
||||
) as cpp_usage_reporting:
|
||||
contents = (
|
||||
# fmt: off
|
||||
cpp_usage_reporting.read()
|
||||
@@ -57,11 +62,33 @@ def main():
|
||||
# fmt: on
|
||||
)
|
||||
|
||||
with open(
|
||||
HAL_ROOT / "src/generated/main/native/include/hal/FRCUsageReporting.h", "w"
|
||||
) as cpp_out:
|
||||
cpp_out.write(contents)
|
||||
usage_reporting_hdr = (
|
||||
output_directory / "main/native/include/hal/FRCUsageReporting.h"
|
||||
)
|
||||
usage_reporting_hdr.write_text(contents, encoding="utf-8")
|
||||
|
||||
|
||||
def main(argv):
|
||||
|
||||
dirname = Path(__file__).parent
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--output_directory",
|
||||
help="Optional. If set, will output the generated files to this directory, otherwise it will use a path relative to the script",
|
||||
default=dirname / "src/generated",
|
||||
type=Path,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--template_root",
|
||||
help="Optional. If set, will use this directory as the root for the jinja templates",
|
||||
default=dirname / "src/generate",
|
||||
type=Path,
|
||||
)
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
generate_usage_reporting(args.output_directory, args.template_root)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main(sys.argv[1:])
|
||||
|
||||
@@ -1,47 +1,39 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Dict, Any
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
from jinja2.environment import Template
|
||||
|
||||
|
||||
def Output(outPath, outfn, contents):
|
||||
if not os.path.exists(outPath):
|
||||
os.makedirs(outPath)
|
||||
|
||||
outpathname = f"{outPath}/{outfn}"
|
||||
|
||||
if os.path.exists(outpathname):
|
||||
with open(outpathname, "r") as f:
|
||||
if f.read() == contents:
|
||||
return
|
||||
|
||||
# File either doesn't exist or has different contents
|
||||
with open(outpathname, "w", newline="\n") as f:
|
||||
f.write(contents)
|
||||
def Output(output_dir: Path, controller_name: str, contents: str):
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
output_file = output_dir / controller_name
|
||||
output_file.write_text(contents, encoding="utf-8")
|
||||
|
||||
|
||||
def main():
|
||||
dirname, _ = os.path.split(os.path.abspath(__file__))
|
||||
|
||||
with open(f"{dirname}/src/generate/types.json") as f:
|
||||
def generate_topics(
|
||||
output_directory: Path, template_root: Path, types_schema_file: Path
|
||||
):
|
||||
with (types_schema_file).open(encoding="utf-8") as f:
|
||||
types = json.load(f)
|
||||
|
||||
# Java files
|
||||
java_template_directory = template_root / "main/java"
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(f"{dirname}/src/generate/main/java"), autoescape=False
|
||||
loader=FileSystemLoader(java_template_directory), autoescape=False
|
||||
)
|
||||
rootPath = f"{dirname}/src/generated/main/java/edu/wpi/first/networktables"
|
||||
for fn in glob.glob(f"{dirname}/src/generate/main/java/*.jinja"):
|
||||
template = env.get_template(os.path.basename(fn))
|
||||
outfn = os.path.basename(fn)[:-6] # drop ".jinja"
|
||||
if os.path.basename(fn).startswith("NetworkTable") or os.path.basename(
|
||||
fn
|
||||
).startswith("Generic"):
|
||||
|
||||
generated_output_dir = output_directory / "main/java/edu/wpi/first/networktables"
|
||||
for fn in java_template_directory.glob("*.jinja"):
|
||||
template = env.get_template(fn.name)
|
||||
outfn = fn.stem
|
||||
if outfn.startswith("NetworkTable") or outfn.startswith("Generic"):
|
||||
output = template.render(types=types)
|
||||
Output(rootPath, outfn, output)
|
||||
Output(generated_output_dir, outfn, output)
|
||||
else:
|
||||
for replacements in types:
|
||||
output = template.render(replacements)
|
||||
@@ -49,79 +41,116 @@ def main():
|
||||
outfn2 = f"Timestamped{replacements['TypeName']}.java"
|
||||
else:
|
||||
outfn2 = f"{replacements['TypeName']}{outfn}"
|
||||
Output(rootPath, outfn2, output)
|
||||
Output(generated_output_dir, outfn2, output)
|
||||
|
||||
# C++ classes
|
||||
cpp_subdirectory = "main/native/include/networktables"
|
||||
cpp_template_directory = template_root / cpp_subdirectory
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(
|
||||
f"{dirname}/src/generate/main/native/include/networktables"
|
||||
),
|
||||
loader=FileSystemLoader(cpp_template_directory),
|
||||
autoescape=False,
|
||||
)
|
||||
rootPath = f"{dirname}/src/generated/main/native/include/networktables"
|
||||
for fn in glob.glob(
|
||||
f"{dirname}/src/generate/main/native/include/networktables/*.jinja"
|
||||
):
|
||||
template = env.get_template(os.path.basename(fn))
|
||||
outfn = os.path.basename(fn)[:-6] # drop ".jinja"
|
||||
|
||||
generated_output_dir = output_directory / cpp_subdirectory
|
||||
for fn in cpp_template_directory.glob("*.jinja"):
|
||||
template = env.get_template(fn.name)
|
||||
outfn = fn.stem # drop ".jinja"
|
||||
for replacements in types:
|
||||
output = template.render(replacements)
|
||||
outfn2 = f"{replacements['TypeName']}{outfn}"
|
||||
Output(rootPath, outfn2, output)
|
||||
Output(generated_output_dir, outfn2, output)
|
||||
|
||||
# C++ handle API (header)
|
||||
hdr_subdirectory = "main/native/include"
|
||||
hdr_template_directory = template_root / hdr_subdirectory
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(f"{dirname}/src/generate/main/native/include"),
|
||||
loader=FileSystemLoader(hdr_template_directory),
|
||||
autoescape=False,
|
||||
)
|
||||
template = env.get_template("ntcore_cpp_types.h.jinja")
|
||||
output = template.render(types=types)
|
||||
Output(
|
||||
f"{dirname}/src/generated/main/native/include",
|
||||
output_directory / hdr_subdirectory,
|
||||
"ntcore_cpp_types.h",
|
||||
output,
|
||||
)
|
||||
|
||||
# C++ handle API (source)
|
||||
cpp_subdirectory = "main/native/cpp"
|
||||
cpp_template_directory = template_root / cpp_subdirectory
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(f"{dirname}/src/generate/main/native/cpp"),
|
||||
loader=FileSystemLoader(cpp_template_directory),
|
||||
autoescape=False,
|
||||
)
|
||||
template = env.get_template("ntcore_cpp_types.cpp.jinja")
|
||||
output = template.render(types=types)
|
||||
Output(f"{dirname}/src/generated/main/native/cpp", "ntcore_cpp_types.cpp", output)
|
||||
Output(
|
||||
output_directory / cpp_subdirectory,
|
||||
"ntcore_cpp_types.cpp",
|
||||
output,
|
||||
)
|
||||
|
||||
# C handle API (header)
|
||||
hdr_subdirectory = "main/native/include"
|
||||
hdr_template_directory = template_root / hdr_subdirectory
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(f"{dirname}/src/generate/main/native/include"),
|
||||
loader=FileSystemLoader(hdr_template_directory),
|
||||
autoescape=False,
|
||||
)
|
||||
template = env.get_template("ntcore_c_types.h.jinja")
|
||||
output = template.render(types=types)
|
||||
Output(
|
||||
f"{dirname}/src/generated/main/native/include",
|
||||
"ntcore_c_types.h",
|
||||
output,
|
||||
)
|
||||
Output(output_directory / hdr_subdirectory, "ntcore_c_types.h", output)
|
||||
|
||||
# C handle API (source)
|
||||
c_subdirectory = "main/native/cpp"
|
||||
c_template_directory = template_root / c_subdirectory
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(f"{dirname}/src/generate/main/native/cpp"),
|
||||
loader=FileSystemLoader(c_template_directory),
|
||||
autoescape=False,
|
||||
)
|
||||
template = env.get_template("ntcore_c_types.cpp.jinja")
|
||||
output = template.render(types=types)
|
||||
Output(f"{dirname}/src/generated/main/native/cpp", "ntcore_c_types.cpp", output)
|
||||
Output(output_directory / c_subdirectory, "ntcore_c_types.cpp", output)
|
||||
|
||||
# JNI
|
||||
jni_subdirectory = "main/native/cpp/jni"
|
||||
jni_template_directory = template_root / jni_subdirectory
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(f"{dirname}/src/generate/main/native/cpp/jni"),
|
||||
loader=FileSystemLoader(jni_template_directory),
|
||||
autoescape=False,
|
||||
)
|
||||
template = env.get_template("types_jni.cpp.jinja")
|
||||
output = template.render(types=types)
|
||||
Output(f"{dirname}/src/generated/main/native/cpp/jni", "types_jni.cpp", output)
|
||||
Output(output_directory / jni_subdirectory, "types_jni.cpp", output)
|
||||
|
||||
|
||||
def main(argv):
|
||||
script_path = Path(__file__).resolve()
|
||||
dirname = script_path.parent
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--output_directory",
|
||||
help="Optional. If set, will output the generated files to this directory, otherwise it will use a path relative to the script",
|
||||
default=dirname / "src/generated",
|
||||
type=Path,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--types_schema_file",
|
||||
help="Optional. If set, this file will be used to load the types schema",
|
||||
default=dirname / "src/generate/types.json",
|
||||
type=Path,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--template_root",
|
||||
help="Optional. If set, will use this directory as the root for the jinja templates",
|
||||
default=dirname / "src/generate",
|
||||
type=Path,
|
||||
)
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
generate_topics(args.output_directory, args.template_root, args.types_schema_file)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main(sys.argv[1:])
|
||||
|
||||
@@ -4,85 +4,92 @@
|
||||
# Open Source Software; you can modify and/or share it under the terms of
|
||||
# the WPILib BSD license file in the root directory of this project.
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
|
||||
def write_controller_file(outPath, controllerName, contents):
|
||||
if not os.path.exists(outPath):
|
||||
os.makedirs(outPath)
|
||||
|
||||
outpathname = f"{outPath}/{controllerName}"
|
||||
|
||||
if os.path.exists(outpathname):
|
||||
with open(outpathname, "r") as f:
|
||||
if f.read() == contents:
|
||||
return
|
||||
|
||||
# File either doesn't exist or has different contents
|
||||
with open(outpathname, "w", newline="\n") as f:
|
||||
f.write(contents)
|
||||
def write_controller_file(output_dir: Path, controller_name: str, contents: str):
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
output_file = output_dir / controller_name
|
||||
output_file.write_text(contents, encoding="utf-8")
|
||||
|
||||
|
||||
def main():
|
||||
dirname, _ = os.path.split(os.path.abspath(__file__))
|
||||
|
||||
with open("wpilibj/src/generate/hids.json") as f:
|
||||
def generate_hids(output_directory: Path, template_directory: Path, schema_file: Path):
|
||||
with schema_file.open(encoding="utf-8") as f:
|
||||
controllers = json.load(f)
|
||||
|
||||
# Java files
|
||||
java_subdirectory = "main/java/edu/wpi/first/wpilibj2/command/button"
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(
|
||||
f"{dirname}/src/generate/main/java/edu/wpi/first/wpilibj2/command/button"
|
||||
),
|
||||
loader=FileSystemLoader(template_directory / java_subdirectory),
|
||||
autoescape=False,
|
||||
keep_trailing_newline=True,
|
||||
)
|
||||
rootPath = (
|
||||
f"{dirname}/src/generated/main/java/edu/wpi/first/wpilibj2/command/button"
|
||||
)
|
||||
root_path = output_directory / java_subdirectory
|
||||
template = env.get_template("commandhid.java.jinja")
|
||||
for controller in controllers:
|
||||
controllerName = os.path.basename(
|
||||
f"Command{controller['ConsoleName']}Controller.java"
|
||||
)
|
||||
controllerName = f"Command{controller['ConsoleName']}Controller.java"
|
||||
output = template.render(controller)
|
||||
write_controller_file(rootPath, controllerName, output)
|
||||
write_controller_file(root_path, controllerName, output)
|
||||
|
||||
# C++ headers
|
||||
hdr_subdirectory = "main/native/include/frc2/command/button"
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(
|
||||
f"{dirname}/src/generate/main/native/include/frc2/command/button"
|
||||
),
|
||||
loader=FileSystemLoader(template_directory / hdr_subdirectory),
|
||||
autoescape=False,
|
||||
keep_trailing_newline=True,
|
||||
)
|
||||
rootPath = f"{dirname}/src/generated/main/native/include/frc2/command/button"
|
||||
root_path = output_directory / hdr_subdirectory
|
||||
template = env.get_template("commandhid.h.jinja")
|
||||
for controller in controllers:
|
||||
controllerName = os.path.basename(
|
||||
f"Command{controller['ConsoleName']}Controller.h"
|
||||
)
|
||||
controllerName = f"Command{controller['ConsoleName']}Controller.h"
|
||||
output = template.render(controller)
|
||||
write_controller_file(rootPath, controllerName, output)
|
||||
write_controller_file(root_path, controllerName, output)
|
||||
|
||||
# C++ files
|
||||
cpp_subdirectory = "main/native/cpp/frc2/command/button"
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(
|
||||
f"{dirname}/src/generate/main/native/cpp/frc2/command/button"
|
||||
),
|
||||
loader=FileSystemLoader(template_directory / cpp_subdirectory),
|
||||
autoescape=False,
|
||||
)
|
||||
rootPath = f"{dirname}/src/generated/main/native/cpp/frc2/command/button"
|
||||
root_path = output_directory / cpp_subdirectory
|
||||
template = env.get_template("commandhid.cpp.jinja")
|
||||
for controller in controllers:
|
||||
controllerName = os.path.basename(
|
||||
f"Command{controller['ConsoleName']}Controller.cpp"
|
||||
)
|
||||
controllerName = f"Command{controller['ConsoleName']}Controller.cpp"
|
||||
output = template.render(controller)
|
||||
write_controller_file(rootPath, controllerName, output)
|
||||
write_controller_file(root_path, controllerName, output)
|
||||
|
||||
|
||||
def main(argv):
|
||||
script_path = Path(__file__).resolve()
|
||||
dirname = script_path.parent
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--output_directory",
|
||||
help="Optional. If set, will output the generated files to this directory, otherwise it will use a path relative to the script",
|
||||
default=dirname / "src/generated",
|
||||
type=Path,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--template_root",
|
||||
help="Optional. If set, will use this directory as the root for the jinja templates",
|
||||
default=dirname / "src/generate",
|
||||
type=Path,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--schema_file",
|
||||
help="Optional. If set, will use this file for the joystick schema",
|
||||
default="wpilibj/src/generate/hids.json",
|
||||
type=Path,
|
||||
)
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
generate_hids(args.output_directory, args.template_root, args.schema_file)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main(sys.argv[1:])
|
||||
|
||||
@@ -4,87 +4,105 @@
|
||||
# Open Source Software; you can modify and/or share it under the terms of
|
||||
# the WPILib BSD license file in the root directory of this project.
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
|
||||
def write_controller_file(outPath, controllerName, contents):
|
||||
if not os.path.exists(outPath):
|
||||
os.makedirs(outPath)
|
||||
|
||||
outpathname = f"{outPath}/{controllerName}"
|
||||
|
||||
if os.path.exists(outpathname):
|
||||
with open(outpathname, "r") as f:
|
||||
if f.read() == contents:
|
||||
return
|
||||
|
||||
# File either doesn't exist or has different contents
|
||||
with open(outpathname, "w", newline="\n") as f:
|
||||
f.write(contents)
|
||||
def write_controller_file(output_dir: Path, controller_name: str, contents: str):
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
output_file = output_dir / controller_name
|
||||
output_file.write_text(contents, encoding="utf-8")
|
||||
|
||||
|
||||
def main():
|
||||
dirname, _ = os.path.split(os.path.abspath(__file__))
|
||||
|
||||
with open("wpilibj/src/generate/hids.json") as f:
|
||||
def generate_hids(output_directory: Path, template_directory: Path, schema_file: Path):
|
||||
with schema_file.open(encoding="utf-8") as f:
|
||||
controllers = json.load(f)
|
||||
|
||||
# C++ headers
|
||||
hdr_subdirectory = "main/native/include/frc"
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(f"{dirname}/src/generate/main/native/include/frc"),
|
||||
loader=FileSystemLoader(template_directory / hdr_subdirectory),
|
||||
autoescape=False,
|
||||
keep_trailing_newline=True,
|
||||
)
|
||||
rootPath = f"{dirname}/src/generated/main/native/include/frc"
|
||||
root_path = output_directory / hdr_subdirectory
|
||||
template = env.get_template("hid.h.jinja")
|
||||
for controller in controllers:
|
||||
controllerName = os.path.basename(f"{controller['ConsoleName']}Controller.h")
|
||||
controllerName = f"{controller['ConsoleName']}Controller.h"
|
||||
output = template.render(controller)
|
||||
write_controller_file(rootPath, controllerName, output)
|
||||
write_controller_file(root_path, controllerName, output)
|
||||
|
||||
# C++ files
|
||||
cpp_subdirectory = "main/native/cpp"
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(f"{dirname}/src/generate/main/native/cpp"),
|
||||
loader=FileSystemLoader(template_directory / cpp_subdirectory),
|
||||
autoescape=False,
|
||||
)
|
||||
rootPath = f"{dirname}/src/generated/main/native/cpp"
|
||||
root_path = output_directory / cpp_subdirectory
|
||||
template = env.get_template("hid.cpp.jinja")
|
||||
for controller in controllers:
|
||||
controllerName = os.path.basename(f"{controller['ConsoleName']}Controller.cpp")
|
||||
controllerName = f"{controller['ConsoleName']}Controller.cpp"
|
||||
output = template.render(controller)
|
||||
write_controller_file(rootPath, controllerName, output)
|
||||
write_controller_file(root_path, controllerName, output)
|
||||
|
||||
# C++ simulation headers
|
||||
sim_hdr_subdirectory = "main/native/include/frc/simulation"
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(
|
||||
f"{dirname}/src/generate/main/native/include/frc/simulation"
|
||||
),
|
||||
loader=FileSystemLoader(template_directory / sim_hdr_subdirectory),
|
||||
autoescape=False,
|
||||
keep_trailing_newline=True,
|
||||
)
|
||||
rootPath = f"{dirname}/src/generated/main/native/include/frc/simulation"
|
||||
root_path = output_directory / sim_hdr_subdirectory
|
||||
template = env.get_template("hidsim.h.jinja")
|
||||
for controller in controllers:
|
||||
controllerName = os.path.basename(f"{controller['ConsoleName']}ControllerSim.h")
|
||||
controllerName = f"{controller['ConsoleName']}ControllerSim.h"
|
||||
output = template.render(controller)
|
||||
write_controller_file(rootPath, controllerName, output)
|
||||
write_controller_file(root_path, controllerName, output)
|
||||
|
||||
# C++ simulation files
|
||||
sim_cpp_subdirectory = "main/native/cpp/simulation"
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(f"{dirname}/src/generate/main/native/cpp/simulation"),
|
||||
loader=FileSystemLoader(template_directory / sim_cpp_subdirectory),
|
||||
autoescape=False,
|
||||
)
|
||||
rootPath = f"{dirname}/src/generated/main/native/cpp/simulation"
|
||||
root_path = output_directory / sim_cpp_subdirectory
|
||||
template = env.get_template("hidsim.cpp.jinja")
|
||||
for controller in controllers:
|
||||
controllerName = os.path.basename(
|
||||
f"{controller['ConsoleName']}ControllerSim.cpp"
|
||||
)
|
||||
controllerName = f"{controller['ConsoleName']}ControllerSim.cpp"
|
||||
output = template.render(controller)
|
||||
write_controller_file(rootPath, controllerName, output)
|
||||
write_controller_file(root_path, controllerName, output)
|
||||
|
||||
|
||||
def main(argv):
|
||||
script_path = Path(__file__).resolve()
|
||||
dirname = script_path.parent
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--output_directory",
|
||||
help="Optional. If set, will output the generated files to this directory, otherwise it will use a path relative to the script",
|
||||
default=dirname / "src/generated",
|
||||
type=Path,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--template_root",
|
||||
help="Optional. If set, will use this directory as the root for the jinja templates",
|
||||
default=dirname / "src/generate",
|
||||
type=Path,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--schema_file",
|
||||
help="Optional. If set, will use this file for the joystick schema",
|
||||
default="wpilibj/src/generate/hids.json",
|
||||
type=Path,
|
||||
)
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
generate_hids(args.output_directory, args.template_root, args.schema_file)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main(sys.argv[1:])
|
||||
|
||||
@@ -4,56 +4,66 @@
|
||||
# Open Source Software; you can modify and/or share it under the terms of
|
||||
# the WPILib BSD license file in the root directory of this project.
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
|
||||
|
||||
def write_controller_file(outPath, controllerName, contents):
|
||||
if not os.path.exists(outPath):
|
||||
os.makedirs(outPath)
|
||||
|
||||
outpathname = f"{outPath}/{controllerName}"
|
||||
|
||||
if os.path.exists(outpathname):
|
||||
with open(outpathname, "r") as f:
|
||||
if f.read() == contents:
|
||||
return
|
||||
|
||||
# File either doesn't exist or has different contents
|
||||
with open(outpathname, "w", newline="\n") as f:
|
||||
f.write(contents)
|
||||
def write_controller_file(output_dir: Path, controller_name: str, contents: str):
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
output_file = output_dir / controller_name
|
||||
output_file.write_text(contents, encoding="utf-8")
|
||||
|
||||
|
||||
def main():
|
||||
dirname, _ = os.path.split(os.path.abspath(__file__))
|
||||
|
||||
with open(f"{dirname}/src/generate/hids.json") as f:
|
||||
def generate_hids(output_directory: Path, template_directory: Path):
|
||||
with (template_directory / "hids.json").open(encoding="utf-8") as f:
|
||||
controllers = json.load(f)
|
||||
|
||||
# Java files
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(f"{dirname}/src/generate/"),
|
||||
loader=FileSystemLoader(template_directory),
|
||||
autoescape=False,
|
||||
keep_trailing_newline=True,
|
||||
)
|
||||
rootPath = f"{dirname}/src/generated/main/java/edu/wpi/first/wpilibj"
|
||||
rootPath = output_directory / "main/java/edu/wpi/first/wpilibj"
|
||||
template = env.get_template("hid.java.jinja")
|
||||
for controller in controllers:
|
||||
controllerName = os.path.basename(f"{controller['ConsoleName']}Controller.java")
|
||||
controllerName = f"{controller['ConsoleName']}Controller.java"
|
||||
output = template.render(controller)
|
||||
write_controller_file(rootPath, controllerName, output)
|
||||
|
||||
# Java simulation files
|
||||
rootPath = f"{dirname}/src/generated/main/java/edu/wpi/first/wpilibj/simulation"
|
||||
rootPath = output_directory / "main/java/edu/wpi/first/wpilibj/simulation"
|
||||
template = env.get_template("hidsim.java.jinja")
|
||||
for controller in controllers:
|
||||
controllerName = os.path.basename(
|
||||
f"{controller['ConsoleName']}ControllerSim.java"
|
||||
)
|
||||
controllerName = f"{controller['ConsoleName']}ControllerSim.java"
|
||||
output = template.render(controller)
|
||||
write_controller_file(rootPath, controllerName, output)
|
||||
|
||||
|
||||
def main(argv):
|
||||
script_path = Path(__file__).resolve()
|
||||
dirname = script_path.parent
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--output_directory",
|
||||
help="Optional. If set, will output the generated files to this directory, otherwise it will use a path relative to the script",
|
||||
default=dirname / "src/generated",
|
||||
type=Path,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--template_root",
|
||||
help="Optional. If set, will use this directory as the root for the jinja templates",
|
||||
default=dirname / "src/generate",
|
||||
type=Path,
|
||||
)
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
generate_hids(args.output_directory, args.template_root)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main(sys.argv[1:])
|
||||
|
||||
@@ -4,50 +4,61 @@
|
||||
# Open Source Software; you can modify and/or share it under the terms of
|
||||
# the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def output(outPath, outfn, contents):
|
||||
if not os.path.exists(outPath):
|
||||
os.makedirs(outPath)
|
||||
|
||||
outpathname = f"{outPath}/{outfn}"
|
||||
|
||||
if os.path.exists(outpathname):
|
||||
with open(outpathname, "r") as f:
|
||||
if f.read() == contents:
|
||||
return
|
||||
|
||||
# File either doesn't exist or has different contents
|
||||
with open(outpathname, "w", newline="\n") as f:
|
||||
f.write(contents)
|
||||
def output(output_dir: Path, outfn: str, contents: str):
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
output_file = output_dir / outfn
|
||||
output_file.write_text(contents, encoding="utf-8")
|
||||
|
||||
|
||||
def main():
|
||||
def generate_numbers(output_directory: Path, template_root: Path):
|
||||
MAX_NUM = 20
|
||||
|
||||
dirname, _ = os.path.split(os.path.abspath(__file__))
|
||||
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(f"{dirname}/src/generate/main/java"),
|
||||
loader=FileSystemLoader(template_root / "main/java"),
|
||||
autoescape=False,
|
||||
keep_trailing_newline=True,
|
||||
)
|
||||
|
||||
template = env.get_template("GenericNumber.java.jinja")
|
||||
rootPath = f"{dirname}/src/generated/main/java/edu/wpi/first/math/numbers"
|
||||
rootPath = output_directory / "main/java/edu/wpi/first/math/numbers"
|
||||
|
||||
for i in range(MAX_NUM + 1):
|
||||
contents = template.render(num=i)
|
||||
output(rootPath, f"N{i}.java", contents)
|
||||
|
||||
template = env.get_template("Nat.java.jinja")
|
||||
rootPath = f"{dirname}/src/generated/main/java/edu/wpi/first/math"
|
||||
rootPath = output_directory / "main/java/edu/wpi/first/math"
|
||||
contents = template.render(nums=range(MAX_NUM + 1))
|
||||
output(rootPath, "Nat.java", contents)
|
||||
|
||||
|
||||
def main(argv):
|
||||
script_path = Path(__file__).resolve()
|
||||
dirname = script_path.parent
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--output_directory",
|
||||
help="Optional. If set, will output the generated files to this directory, otherwise it will use a path relative to the script",
|
||||
default=dirname / "src/generated",
|
||||
type=Path,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--template_root",
|
||||
help="Optional. If set, will use this directory as the root for the jinja templates",
|
||||
default=dirname / "src/generate",
|
||||
type=Path,
|
||||
)
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
generate_numbers(args.output_directory, args.template_root)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main(sys.argv[1:])
|
||||
|
||||
@@ -3,31 +3,73 @@
|
||||
# Copyright (c) FIRST and other WPILib contributors.
|
||||
# Open Source Software; you can modify and/or share it under the terms of
|
||||
# the WPILib BSD license file in the root directory of this project.
|
||||
import os.path
|
||||
import subprocess
|
||||
import sys
|
||||
from glob import glob
|
||||
import argparse
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
if __name__ == "__main__":
|
||||
proto_files = glob("wpimath/src/main/proto/*.proto")
|
||||
|
||||
def generate_quickbuf(
|
||||
protoc, quickbuf_plugin: Path, output_directory: Path, proto_dir: Path
|
||||
):
|
||||
proto_files = proto_dir.glob("*.proto")
|
||||
for path in proto_files:
|
||||
absolute_filename = os.path.abspath(path)
|
||||
absolute_dir, filename = os.path.split(absolute_filename)
|
||||
absolute_filename = path.absolute()
|
||||
subprocess.run(
|
||||
[
|
||||
sys.argv[1],
|
||||
f"--plugin=protoc-gen-quickbuf={sys.argv[2]}",
|
||||
f"--quickbuf_out=gen_descriptors=true:{os.path.abspath('./wpimath/src/generated/main/java')}",
|
||||
f"-I{absolute_dir}",
|
||||
protoc,
|
||||
f"--plugin=protoc-gen-quickbuf={quickbuf_plugin}",
|
||||
f"--quickbuf_out=gen_descriptors=true:{output_directory.absolute()}",
|
||||
f"-I{absolute_filename.parent}",
|
||||
absolute_filename,
|
||||
]
|
||||
)
|
||||
java_files = glob("wpimath/src/generated/main/java/edu/wpi/first/math/proto/*.java")
|
||||
java_files = (output_directory / "edu/wpi/first/math/proto").glob("*.java")
|
||||
for java_file in java_files:
|
||||
with open(java_file) as file:
|
||||
content = file.read()
|
||||
with open(java_file, "tw") as file:
|
||||
file.write(
|
||||
"// Copyright (c) FIRST and other WPILib contributors.\n// Open Source Software; you can modify and/or share it under the terms of\n// the WPILib BSD license file in the root directory of this project.\n"
|
||||
+ content
|
||||
)
|
||||
with (java_file).open(encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
|
||||
java_file.write_text(
|
||||
"// Copyright (c) FIRST and other WPILib contributors.\n// Open Source Software; you can modify and/or share it under the terms of\n// the WPILib BSD license file in the root directory of this project.\n"
|
||||
+ content,
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
|
||||
def main(argv):
|
||||
script_path = Path(__file__).resolve()
|
||||
dirname = script_path.parent
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--protoc",
|
||||
help="Protoc executable command",
|
||||
default="protoc",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--quickbuf_plugin",
|
||||
help="Path to the quickbuf protoc plugin",
|
||||
required=True,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output_directory",
|
||||
help="Optional. If set, will output the generated files to this directory, otherwise it will use a path relative to the script",
|
||||
default=dirname / "src/generated/main/java",
|
||||
type=Path,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--proto_directory",
|
||||
help="Optional. If set, will use this directory to glob for protobuf files",
|
||||
default=dirname / "src/main/proto",
|
||||
type=Path,
|
||||
)
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
generate_quickbuf(
|
||||
args.protoc, args.quickbuf_plugin, args.output_directory, args.proto_directory
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv[1:])
|
||||
|
||||
Reference in New Issue
Block a user