Skip to content
Open
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
15 changes: 6 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,20 @@ jobs:
# `pip install -r requirements.txt` referenced a file that does
# not exist in this repository and failed the job outright.
pip install -e .
pip install pytest pytest-cov pytest-benchmark mypy ruff
pip install pytest pytest-cov pytest-benchmark mypy ruff yamllint

- name: Lint (ruff)
run: ruff check . --select=E,F,W --ignore=E501
continue-on-error: true
run: ruff check .

- name: Lint YAML (yamllint)
run: yamllint .

# --exclude: layers/eosuite/ vendors its own tests/ package, so a bare
# `mypy .` sees two modules named "tests" and bails with "Duplicate
# module named 'tests'" before checking anything. continue-on-error hid
# that the type check was doing no work at all.
- name: Type check (mypy)
# --exclude: layers/eosuite/ vendors its own tests/ package, so a bare
# `mypy .` sees two modules named "tests" and bails with "Duplicate
# module named 'tests'" before checking anything. continue-on-error hid
# that the type check was doing no work at all.
run: mypy . --ignore-missing-imports --no-strict-optional --exclude '^layers/'
continue-on-error: true
run: mypy . --ignore-missing-imports --no-strict-optional --exclude '^(layers|core|promo)/'

# Runs the whole tests/ tree. The previous steps ran only tests/unit/
# and tests/functional/ — 15 of the 98 collected tests — so
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/video-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,3 @@ jobs:
fail_on_unmatched_files: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

11 changes: 11 additions & 0 deletions .yamllint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
extends: default

ignore: |
.venv/
core/

rules:
line-length: disable
truthy:
check-keys: false
document-start: disable
4 changes: 2 additions & 2 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
codecov:
require_ci_to_pass: yes
require_ci_to_pass: true

coverage:
precision: 2
Expand All @@ -19,4 +19,4 @@ coverage:
comment:
layout: "reach, diff, flags, files"
behavior: default
require_changes: no
require_changes: false
2 changes: 1 addition & 1 deletion ebuild/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@
from ebuild.cli.commands import cli

if __name__ == "__main__":
cli()
cli()
2 changes: 1 addition & 1 deletion ebuild/build/dispatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import subprocess
import sys
from pathlib import Path
from typing import Any, Dict, List, Optional, Set
from typing import Any, Dict, List, Optional

logger = logging.getLogger(__name__)

Expand Down
1 change: 0 additions & 1 deletion ebuild/build/ninja_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from __future__ import annotations

import json
import re
import sys
from dataclasses import dataclass, field
from pathlib import Path
Expand Down
2 changes: 1 addition & 1 deletion ebuild/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@
__version__ = version("ebuild")
except PackageNotFoundError:
# Fallback if the package is run directly without being installed
__version__ = "unknown"
__version__ = "unknown"
8 changes: 4 additions & 4 deletions ebuild/cli/integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import subprocess
import sys
from pathlib import Path
from typing import Dict, List, Optional
from typing import Any, Dict, List, Optional, Tuple

import click

Expand All @@ -36,7 +36,7 @@
"eipc": {"cmake_flag": "", "lang": "go", "sdk_subdir": "sdk/c"},
}

QEMU_ARCHS = {
QEMU_ARCHS: Dict[str, Dict[str, Any]] = {
"x86_64": {
"bin": "qemu-system-x86_64",
"args": ["-machine", "q35", "-cpu", "qemu64", "-m", "512",
Expand Down Expand Up @@ -138,7 +138,7 @@ def _cmake_build(repo_dir: Path, build_dir: Path, extra_flags: str,

def _collect_libraries(build_dir: Path, repos: Dict[str, Path]) -> List[Path]:
"""Find all .a static libraries produced by the builds."""
libs = []
libs: List[Path] = []
for name in repos:
repo_build = build_dir / name
if repo_build.exists():
Expand Down Expand Up @@ -294,7 +294,7 @@ def _create_initramfs(rootfs: Path, build_dir: Path) -> Path:

initramfs = build_dir / "initramfs.cpio.gz"
entries = [rootfs, *sorted(rootfs.rglob("*"), key=lambda p: p.as_posix())]
hardlink_inodes = {}
hardlink_inodes: Dict[Optional[Tuple[int, int]], int] = {}
hardlink_data_written = set()
next_inode = 1

Expand Down
4 changes: 3 additions & 1 deletion ebuild/deliverable_packager.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
from ebuild.sdk_generator import TARGET_ARCH, get_target_info
except ImportError:
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from sdk_generator import TARGET_ARCH, get_target_info
# Imported from ebuild.sdk_generator in the try above as well; mypy
# cannot see that only one branch runs, so it flags this as a redefinition.
from sdk_generator import TARGET_ARCH, get_target_info # type: ignore[no-redef]

SOURCE_REPOS = {
"eos": {"dirs": ["core","hal","kernel","drivers","debug","services","systems",
Expand Down
3 changes: 2 additions & 1 deletion ebuild/deps/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from __future__ import annotations

from pathlib import Path
from typing import Any, Dict

# Default location for ebuild's persistent state
EBUILD_HOME = Path.home() / ".ebuild"
Expand All @@ -21,7 +22,7 @@
DEFAULT_EBOOT_REPO_URL = "https://github.com/embeddedos-org/eBoot.git"
DEFAULT_EFIRMWARE_REPO_URL = "https://github.com/embeddedos-org/eFirmware.git"

DEFAULT_CONFIG = {
DEFAULT_CONFIG: Dict[str, Any] = {
"repos": {
# Both repos default to master; neither has a main. Cloning the
# branch named here is what `ebuild setup` does first, so "main"
Expand Down
9 changes: 6 additions & 3 deletions ebuild/eos_ai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@
from ebuild.eos_ai.eos_validator import EosConfigValidator
from ebuild.eos_ai.eos_boot_integrator import EosBootIntegrator
except ImportError:
EosConfigGenerator = None
EosConfigValidator = None
EosBootIntegrator = None
# When pyyaml is absent these stay None and callers test for truthiness.
# mypy cannot type a name that is a class when the import succeeds and
# None when it does not.
EosConfigGenerator = None # type: ignore[misc]
EosConfigValidator = None # type: ignore[misc]
EosBootIntegrator = None # type: ignore[misc]

__all__ = [
"EosHardwareAnalyzer",
Expand Down
4 changes: 3 additions & 1 deletion ebuild/plugins/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ def discover_plugins() -> List[PluginBase]:
if hasattr(entry_points, "select"):
eps = entry_points.select(group="ebuild.plugins")
else:
eps = entry_points.get("ebuild.plugins", [])
# Before 3.10 entry_points() returned a dict; the current stubs
# only model EntryPoints, which has no .get, hence the ignore.
eps = entry_points.get("ebuild.plugins", []) # type: ignore[attr-defined]

for ep in eps:
try:
Expand Down
2 changes: 1 addition & 1 deletion ebuild/system/doctor.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import sys
from dataclasses import dataclass
from pathlib import Path
from typing import List, Optional
from typing import List

OK, MISSING, WARN = "ok", "missing", "warn"

Expand Down
18 changes: 9 additions & 9 deletions hardware/board/eradar360.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,16 @@ peripherals:

memory_map:
flash_base: 0x00000000
flash_size: 0x2000000 # 256MB NOR flash
flash_size: 0x2000000 # 256MB NOR flash
ram_base: 0x00200000
ram_size: 0x40000000 # 1GB DDR4
spi0_base: 0xFE610000 # SPI0 controller (front radar)
spi1_base: 0xFE620000 # SPI1 controller (rear radar)
uart2_base: 0xFEB50000 # UART2 debug
uart3_base: 0xFEB60000 # UART3 V2X
i2c0_base: 0xFEA90000 # I2C0 bus
mipi_dsi_base: 0xFDE20000 # MIPI-DSI display controller
npu_base: 0xFDAB0000 # RKNPU (6 TOPS)
ram_size: 0x40000000 # 1GB DDR4
spi0_base: 0xFE610000 # SPI0 controller (front radar)
spi1_base: 0xFE620000 # SPI1 controller (rear radar)
uart2_base: 0xFEB50000 # UART2 debug
uart3_base: 0xFEB60000 # UART3 V2X
i2c0_base: 0xFEA90000 # I2C0 bus
mipi_dsi_base: 0xFDE20000 # MIPI-DSI display controller
npu_base: 0xFDAB0000 # RKNPU (6 TOPS)

boot:
recovery_pin: GPIO0_A0 (active low, pull-up)
Expand Down
19 changes: 19 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,22 @@ ebuild = "ebuild.cli.commands:cli"

[tool.setuptools.packages.find]
include = ["ebuild*"]

[tool.ruff]
exclude = [
".venv",
"core",
"layers/eosuite",
]

[tool.ruff.lint]
select = ["E", "F", "W"]
ignore = [
"E501", # line too long
"E731", # lambda assignment
"E741", # ambiguous variable name
"F403", # star import used (manim requires it in promo/)
"F405", # name may be undefined from a star import
"F541", # f-string without placeholders
"F841", # unused local variable
]
22 changes: 11 additions & 11 deletions recipes/freertos.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package: freertos
version: "11.1.0"
description: "Real-time operating system kernel for embedded devices"
license: MIT
url: https://github.com/FreeRTOS/FreeRTOS-Kernel/releases/download/V11.1.0/FreeRTOS-KernelV11.1.0.zip
checksum: sha256:eebd58aa71a623c9381f25f77b708c0ed14ef995a8913e2460fe9f286bb271eb
build: cmake
configure_args:
- -DFREERTOS_HEAP=4
- -DFREERTOS_PORT=GCC_ARM_CM4F
dependencies: []
package: freertos
version: "11.1.0"
description: "Real-time operating system kernel for embedded devices"
license: MIT
url: https://github.com/FreeRTOS/FreeRTOS-Kernel/releases/download/V11.1.0/FreeRTOS-KernelV11.1.0.zip
checksum: sha256:eebd58aa71a623c9381f25f77b708c0ed14ef995a8913e2460fe9f286bb271eb
build: cmake
configure_args:
- -DFREERTOS_HEAP=4
- -DFREERTOS_PORT=GCC_ARM_CM4F
dependencies: []
2 changes: 0 additions & 2 deletions tests/ebuild/test_dispatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@
"""Tests for ebuild.build.dispatch — backend detection, dispatch, dry-run."""

import logging
from pathlib import Path
from unittest.mock import patch

import pytest

from ebuild.build.dispatch import (
ALL_BACKENDS,
BackendDispatcher,
BackendError,
UnknownBackendError,
Expand Down
2 changes: 1 addition & 1 deletion tests/ebuild/test_eos_ai.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,4 +260,4 @@ def test_unknown_mcu_still_detects_peripherals(self):
print(f"\n{'='*50}")
print(f"Results: {passed}/{total} passed, {failed} failed")
print(f"{'='*50}")
sys.exit(0 if failed == 0 else 1)
sys.exit(0 if failed == 0 else 1)
1 change: 0 additions & 1 deletion tests/ebuild/test_integration_initramfs_security.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import os
import shutil
import stat
import subprocess

import pytest

Expand Down
2 changes: 0 additions & 2 deletions tests/unit/test_cad_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
import sys
from pathlib import Path

import pytest

REPO = Path(__file__).resolve().parents[2]
TOOL = REPO / "tools" / "cad_pipeline.py"
SAMPLE = REPO / "samples" / "eos_reference_board.kicad_pcb"
Expand Down
2 changes: 0 additions & 2 deletions tests/unit/test_doctor.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

import json

import pytest
from click.testing import CliRunner

from ebuild.cli.commands import cli
Expand All @@ -29,7 +28,6 @@
exit_code,
format_report,
host_checks,
run_all,
toolchain_checks,
)

Expand Down
1 change: 0 additions & 1 deletion tests/unit/test_empty_test_run_is_not_a_pass.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

import sys

import pytest
import yaml
from click.testing import CliRunner

Expand Down
1 change: 0 additions & 1 deletion tests/unit/test_package_efw.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
find_efwtool,
missing_tool_message,
pack,
verify,
)
from ebuild.cli.commands import cli

Expand Down
2 changes: 1 addition & 1 deletion tools/cad_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import os
import json
from dataclasses import dataclass, field
from typing import List, Optional
from typing import List

# ── Data models ───────────────────────────────────────────────────────────────

Expand Down