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
23 changes: 23 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# .github/workflows/test.yml
name: Tests

on:
push:
pull_request:

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install pytest
run: pip install pytest

- name: Run tests
run: pytest host/tests/ -v
62 changes: 62 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.pyo
*.pyd

# Distribution / packaging
dist/
build/
*.egg-info/
*.egg
.eggs/
wheels/

# Virtual environments
.venv/
venv/
env/
ENV/

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage
.tox/
.nox/
.coverage
.coverage.*
coverage.xml
*.cover
htmlcov/
.pytest_cache/
.hypothesis/

# Type checking
.mypy_cache/
.dmypy.json
.pyre/
.pytype/

# CLI specific
*.log
*.pid

# Environment / secrets
.env
.env.*
*.env
!.env.example

# IDEs
.idea/
.vscode/
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# S130 Development tools V1.1.0
# S130 Development tools V1.2.0

## Version Notes: v1.2.0
- Cleaned up repo root checks from Henry's merge
- Removed repo root checks from `srlaunch`.
- Added `host/srutils.py` for common logic between `srpkg` and `srbuild`
- Added toml param file generation and autofilling, as well as autofilling a main file template in `srpkg`
- Added integration tests for `srpkg` and `srlaunch`
Comment on lines +3 to +8
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The v1.2.0 notes claim “Added integration tests for srpkg and srlaunch”, but this PR adds integration tests for srpkg and srbuild (and no srlaunch tests are present under host/tests). Please update the version notes to match what was actually added, or add the missing srlaunch tests if intended.

Copilot uses AI. Check for mistakes.

## Introduction
This repository contains high-level development tools for Sunswift embedded and DDS projects. It is separated into host/ and target/. host/ contains the dev tools we are using during development time on our host machines. target/ contains scripts that should be run on the target (NVIDIA Drive THOR computer). It is intended to be a submodule in the SR-Mjolnir repository.


Expand Down Expand Up @@ -150,5 +158,4 @@ Then just `Ctrl-C` to shut down all nodes gracefully. It's that easy guys.

## Contributors
Ryan Wong || z5417983

Henry Jiang || z5416365
71 changes: 13 additions & 58 deletions host/srbuild
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

###############################################################################
# Sunswift High Level build tool
# Version: V2.0
# Version: V2.1
# Date: 7/01/2026
# Author: Ryan Wong
#
# Wrapper around CMake to allow you to intuitevly build and install all, one, or some targets
# Wrapper around CMake to allow you to intuitively build and install all, one, or some targets
#
#
# Usage:
Expand All @@ -16,70 +16,23 @@
###############################################################################

import argparse
import os
import sys
import subprocess
import time
import shutil
from typing import Optional
from pathlib import Path
from srutils import resolve_repo_root, validate_repo_root, die

CWD = Path.cwd().resolve()
REPO_ROOT = Path()
BUILD_DIR_PATH = Path()
CMAKELISTS_PATH = Path()
INSTALL_PREFIX = Path()
MARKER_FILE = ".sunswift-evsn"

# =================================================================================================
# HELPERS
# =================================================================================================

def die(msg: str) -> None:
"""Kills script and prints out msg"""
print(msg)
sys.exit(1)

def git_toplevel(path: Path) -> Path:
try:
result = subprocess.run(
["git", "-C", str(path), "rev-parse", "--show-toplevel"],
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
)
except FileNotFoundError:
die("Error: git not found; cannot determine repository root")
except subprocess.CalledProcessError:
die("Error: not a git repository (or any of the parent directories)")
root = result.stdout.strip()
if not root:
die("Error: git returned empty repository root")
return Path(root).resolve()

def resolve_repo_root(cli_root: Optional[str]) -> Path:
env_root = os.environ.get("SR_REPO_ROOT")
if cli_root:
candidate = Path(cli_root).expanduser().resolve()
elif env_root:
candidate = Path(env_root).expanduser().resolve()
else:
return git_toplevel(CWD)

if not candidate.exists() or not candidate.is_dir():
die("Error: repo root does not exist or is not a directory")
git_root = git_toplevel(candidate)
if git_root != candidate:
die("Error: repo root is not a git repository root")
return candidate

def validate_repo_root(repo_root: Path) -> None:
if not (repo_root / "src").exists() and not (repo_root / "core").exists():
die("Error: repository root missing src/ or core/")
if not (repo_root / MARKER_FILE).exists():
die(f"Error: marker file '{MARKER_FILE}' not found in repository root")

def safe_rmdir(path: Path) -> bool:
"""Absolutely every error check again just to confirm before deletion.
In case any bugs in error checking happen before. Then deletes specified dir
Expand Down Expand Up @@ -151,7 +104,7 @@ def build(targets: Optional[list[str]], jobs: int) -> None:
jobs (int): number of jobs to run in parallel
"""
print("============= Building Targets ===============")
jobs_str = f"-j{jobs}"
jobs_str = f"{jobs}"
start_time = time.time()
# Build targets
try:
Expand All @@ -166,7 +119,7 @@ def build(targets: Optional[list[str]], jobs: int) -> None:
# If someone is using --target, build times probably tiny anyway
for target in targets:
subprocess.run([
"cmake", "--build", str(BUILD_DIR_PATH), "--target", target, "--", jobs_str
"cmake", "--build", str(BUILD_DIR_PATH), "--target", target, "-j", jobs_str
], check=True)
except subprocess.CalledProcessError:
die(f"Build: Error building targets")
Expand Down Expand Up @@ -246,10 +199,6 @@ def main():

common_flags = argparse.ArgumentParser(add_help=False)
common_flags.add_argument("--jobs", "-j", default=8, type=int, help="Number of parallel jobs Make runs. Default=8")
parser.add_argument(
"--repo-root",
help="Path to repository root (or set SR_REPO_ROOT). Defaults to git root.",
)

level1_junction = parser.add_subparsers(dest="command", required=True)
command_all = level1_junction.add_parser("all", parents=[common_flags], help="Build and install all targets")
Expand All @@ -260,8 +209,14 @@ def main():

### SANITY CHECK - immediately fail if not used within repository
global REPO_ROOT, BUILD_DIR_PATH, CMAKELISTS_PATH, INSTALL_PREFIX
REPO_ROOT = resolve_repo_root(args.repo_root)
validate_repo_root(REPO_ROOT)
try:
REPO_ROOT = resolve_repo_root(CWD)
except Exception as exc:
die(str(exc))
try:
validate_repo_root(REPO_ROOT)
except Exception as exc:
die(str(exc))
BUILD_DIR_PATH = REPO_ROOT / "build"
CMAKELISTS_PATH = REPO_ROOT / "CMakeLists.txt"
INSTALL_PREFIX = REPO_ROOT / "deploy"
Expand Down
Loading
Loading