Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/dist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ jobs:
SCCACHE_WEBDAV_USERNAME: ${{ secrets.WPI_ARTIFACTORY_USERNAME }}
SCCACHE_WEBDAV_PASSWORD: ${{ secrets.WPI_ARTIFACTORY_TOKEN }}

- name: Ensure all headers are accounted for
run: |
python -m devtools ci scan-headers

- uses: actions/upload-artifact@v4
with:
name: "pypi-meson-${{ runner.os }}-${{ runner.arch }}-${{ matrix.python_version }}"
Expand Down
20 changes: 20 additions & 0 deletions devtools/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,26 @@ def develop(ctx: Context, package: str):
project.develop()


@main.command()
@click.pass_obj
def scan_headers(ctx: Context):
"""Run scan-headers on all projects"""
ok = True
for project in ctx.subprojects.values():
if project.is_semiwrap_project():
with ctx.handle_exception(f"scan-headers {project.name}"):
if not project.scan_headers():
print(
"- ERROR:",
project.pyproject_path,
"does not wrap/ignore every header!",
)
ok = False

if not ok:
sys.exit(1)


@main.command
@click.argument("package", required=False)
@click.pass_obj
Expand Down
24 changes: 24 additions & 0 deletions devtools/ci.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,27 @@ def build_meson_wheels(ctx: Context, no_test: bool, cross: T.Optional[str]):
)
if not no_test:
project.test(install_requirements=True)


@ci.command()
@click.pass_obj
def scan_headers(ctx: Context):
"""Run scan-headers on all projects"""
ok = True
for project in ctx.subprojects.values():
if project.is_semiwrap_project():
if not project.cfg.ci_scan_headers:
print("- Skipping", project.name, file=sys.stderr)
continue

with ctx.handle_exception(f"scan-headers {project.name}"):
if not project.scan_headers():
print(
"- ERROR:",
project.pyproject_path,
"does not wrap/ignore every header!",
)
ok = False

if not ok:
sys.exit(1)
3 changes: 3 additions & 0 deletions devtools/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ class SubprojectConfig:
#: Whether this should be built on roborio or not
roborio: bool

#: Whether `ci scan-headers` should include this project
ci_scan_headers: bool = True


@dataclasses.dataclass
class Parameters:
Expand Down
13 changes: 13 additions & 0 deletions devtools/subproject.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,19 @@ def develop(self):
def uninstall(self):
run_pip("uninstall", "-y", self.pyproject_name)

def scan_headers(self):
"""Returns True if no headers found or False if missing headers were found"""
result = run_cmd(
sys.executable,
"-m",
"semiwrap",
"scan-headers",
"--check",
cwd=self.path,
check=False,
)
return result.returncode == 0

def update_init(self):
run_cmd(
sys.executable,
Expand Down
4 changes: 2 additions & 2 deletions devtools/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ def parse_input(value: typing.Any, spec: typing.Type[T], fname) -> T:
raise _convert_validation_error(fname, ve) from None


def run_cmd(*args: str, cwd=None):
def run_cmd(*args: str, cwd=None, check=True):
print("+", shlex.join(args))
subprocess.check_call(args, cwd=cwd)
return subprocess.run(args, cwd=cwd, check=check)


def run_pip(*args: str, cwd=None):
Expand Down
4 changes: 4 additions & 0 deletions rdev.toml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ roborio = true
py_version = "wrapper"
roborio = true

# practicality over purity - this is because we use a static
# library that only exists at build time
ci_scan_headers = false

[subprojects."robotpy-apriltag"]
py_version = "wrapper"
roborio = true
Expand Down
16 changes: 16 additions & 0 deletions subprojects/robotpy-cscore/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,22 @@ update_init = [
"cscore"
]

scan_headers_ignore = [
# Only wrapping the C++ API
"cscore.h",
"cscore_c.h",
"cscore_raw.h",

# Not needed
"cameraserver/CameraServerShared.h",
"vision/VisionPipeline.h",
"vision/VisionRunner.h",

# Not wrapping OpenCV or cvnp
"cvnp/*",
"opencv2/*"
]

[tool.semiwrap.extension_modules."cscore._cscore"]
name = "cscore"

Expand Down
1 change: 1 addition & 0 deletions subprojects/robotpy-wpilib/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ LiveWindow = "frc/livewindow/LiveWindow.h"
# frc/motorcontrol
DMC60 = "frc/motorcontrol/DMC60.h"
Jaguar = "frc/motorcontrol/Jaguar.h"
Koors40 = "frc/motorcontrol/Koors40.h"
MotorControllerGroup = "rpy/MotorControllerGroup.h"
NidecBrushless = "frc/motorcontrol/NidecBrushless.h"
PWMMotorController = "frc/motorcontrol/PWMMotorController.h"
Expand Down
6 changes: 6 additions & 0 deletions subprojects/robotpy-wpilib/semiwrap/Koors40.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---

classes:
frc::Koors40:
methods:
Koors40:
Loading