Skip to content
This repository was archived by the owner on Jan 23, 2026. It is now read-only.
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
108 changes: 108 additions & 0 deletions .cursor/rules/creating-new-drivers.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
---
description: when the user is requesting to create, improve or document a new driver
alwaysApply: false
---
# Creating New Drivers

When asked to create a new driver, follow these steps:

## 1. Use the Driver Creation Script
Always use the provided script: `./__templates__/create_driver.sh`

## 2. Required Information
Before creating a driver, ask the user for:
- **Driver Package Name**: The package name (e.g., `mydriver`, `custom-power`, `device-controller`)
- Should be lowercase with hyphens for multi-word names
- Examples from existing drivers: `network`, `iscsi`, `ridesx`, `opendal`, `shell`, `gpiod`, `http-power`, `tasmota`, `tftp`, `uboot`, `snmp`, `sdwire`, `probe-rs`, `can`, `composite`, `corellium`, `dutlink`, `energenie`, `flashers`, `http`, `power`, `pyserial`, `qemu`, `ustreamer`, `yepkit`
- **Driver Class Name**: The main driver class in CamelCase (e.g., `MyDriver`, `CustomPower`, `DeviceController`)
- Should be descriptive and end with appropriate suffix based on functionality
- Examples: `TcpNetwork`, `ISCSI`, `RideSXDriver`, `Opendal`, `Shell`, `HttpPower`, `TasmotaPower`, `Tftp`, `UbootConsole`, `SNMPServer`, `SDWire`, `ProbeRs`, `Can`, `Composite`, `Corellium`, `Dutlink`, `EnerGenie`, `QemuFlasher`, `UStreamer`, `Ykush`
- **Author Name**: Full name of the author
- **Author Email**: Email address of the author

## 3. Command Format
```bash
./__templates__/create_driver.sh <driver_package> <DriverClass> "<Author Name>" "<author@email.com>"
```
Always try to obtain the Author Name and Email from git, by checking the git configuration.
## 4. Examples
```bash
# Network driver
./__templates__/create_driver.sh network TcpNetwork "John Doe" "john@example.com"

# Power management driver
./__templates__/create_driver.sh custom-power CustomPowerDriver "Jane Smith" "jane@example.com"

# Device control driver
./__templates__/create_driver.sh device-controller DeviceController "Bob Wilson" "bob@example.com"
```

## 5. After Creation
Once the driver is created:
1. Navigate to the new driver directory: `packages/jumpstarter-driver-<driver_package>/`
2. Review the generated files and customize as needed
3. Implement the driver logic in `driver.py`
4. Add tests in `driver_test.py`
5. Update the README.md with specific documentation
6. Test the driver: `make pkg-test-<driver_package>`

## 6. Driver Naming Conventions
- **Package names**: lowercase with hyphens (e.g., `my-driver`)
- **Class names**: CamelCase with descriptive suffixes:
- Power drivers: `*Power` (e.g., `TasmotaPower`, `HttpPower`)
- Network drivers: `*Network` (e.g., `TcpNetwork`, `UdpNetwork`)
- Flasher drivers: `*Flasher` (e.g., `QemuFlasher`)
- Console drivers: `*Console` (e.g., `UbootConsole`)
- Server drivers: `*Server` (e.g., `HttpServer`, `SNMPServer`)
- Generic drivers: descriptive name (e.g., `ISCSI`, `Shell`, `Tftp`)

## 7. Directory Structure
The script creates:
```
packages/jumpstarter-driver-<driver_package>/
├── jumpstarter_driver_<driver_package>/
│ ├── __init__.py
│ ├── client.py
│ ├── driver.py
│ └── driver_test.py
├── examples/
│ └── exporter.yaml
├── .gitignore
├── pyproject.toml
└── README.md
```

## 8. Documentation
The script automatically creates:
- A README.md with basic documentation
- A symlink in `docs/source/reference/package-apis/drivers/` pointing to the README
- Template files for all necessary components
- A good example of documentation is in `docs/source/reference/package-apis/drivers/gpiod.md` and also `docs/source/reference/package-apis/drivers/pyserial.md`

## Code Style and Testing

- Follow existing code style (validate with `make lint`, fix with `make lint-fix`)
- Perform static type checking with `make ty-pkg-${package_name}`
- Add comprehensive tests and update documentation
- Verify all tests pass (`make test-pkg-${package_name}` or `make test`)

Comment thread
mangelajo marked this conversation as resolved.
## Contributing Guidelines

- Focus on a single issue per driver
- Use clear, descriptive commit messages
- Reference issue numbers when applicable
- Follow conventional commit format when possible
- Ensure all tests pass before submitting PRs

# Driver client CLIs

Some drivers implement known classes that provide a CLI interface for the driver, but other
clients implement their own CLI interface that will appear in the `j` command inside a `jmp shell`.

Good examples can be found in `packages/jumpstarter-driver-shell/jumpstarter_driver_shell/client.py`, `packages/jumpstarter-driver-pyserial/jumpstarter_driver_pyserial/client.py` or `packages/jumpstarter-driver-probe-rs/jumpstarter_driver_probe_rs/client.py`.

# Composite drivers

Drives which have children drivers should be composite drivers, and the client interface should
inherit from `CompositeClient` in jumpstarter_driver_composite.client, also the pyproject.toml should
have a dependency on `jumpstarter-driver-composite`.
162 changes: 162 additions & 0 deletions .cursor/rules/project-structure.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
---
alwaysApply: true
---

# Project Structure

This project follows a monorepo structure with a top-level `pyproject.toml` that manages all packages using UV workspace.

## Top-Level Structure

```
jumpstarter/
├── pyproject.toml # Main workspace configuration
├── packages/ # All Python packages
├── examples/ # Example applications
├── docs/ # Documentation
├── __templates__/ # Templates for creating new drivers
└── .cursor/ # Cursor AI rules
```

## Workspace Configuration

The project uses **UV workspace** for dependency management:

- **Top-level `pyproject.toml`**: Defines the workspace and includes all packages
- **Workspace members**: All packages in `packages/*` and `examples/*` are included
- **Dependency groups**: Shared development dependencies (docs, dev)
- **Tool configuration**: Ruff, typos, coverage, pytest settings

## Package Structure

### Core Packages

- **`jumpstarter/`**: Main library with client, config, and common functionality
- **`jumpstarter-protocol/`**: gRPC protocol definitions (excluded from linting)
- **`jumpstarter-kubernetes/`**: Kubernetes integration
- **`jumpstarter-testing/`**: Testing utilities
- **`jumpstarter-imagehash/`**: Image hashing utilities

### CLI Packages

- **`jumpstarter-cli/`**: Main CLI application
- **`jumpstarter-cli-admin/`**: Administrative CLI commands
- **`jumpstarter-cli-common/`**: Shared CLI utilities
- **`jumpstarter-cli-driver/`**: Driver-specific CLI commands

### Driver Packages

All driver packages follow the pattern `jumpstarter-driver-<name>/`:

- **`jumpstarter-driver-network/`**: Network interface drivers (TCP, UDP, Unix, etc.)
- **`jumpstarter-driver-power/`**: Power management drivers
- **`jumpstarter-driver-*`**: Various hardware-specific drivers

### Utility Packages

- **`jumpstarter-all/`**: Meta-package that includes all components
- **`hatch-pin-jumpstarter/`**: Custom Hatch build hook

## Package Structure

Each package follows this structure:

```
packages/jumpstarter-driver-<name>/
├── jumpstarter_driver_<name>/ # Main Python package
│ ├── __init__.py
│ ├── driver.py # Driver implementation
│ ├── client.py # Client implementation
│ └── driver_test.py # Tests
├── examples/ # Example configurations
│ └── exporter.yaml
├── pyproject.toml # Package configuration
├── README.md # Package documentation
└── .gitignore
```

## Package Configuration

Each package's `pyproject.toml` includes:

- **Project metadata**: Name, description, authors, license, please note that this repo only accepts Apache-2.0 license.
- **Dependencies**: Runtime and development dependencies
- **Entry points**: Driver and adapter registrations
- **Build system**: Hatch with custom hooks
- **Version management**: VCS-based versioning from root

## Examples Structure

```
examples/
├── automotive/ # Automotive testing example
│ ├── jumpstarter_example_automotive/
│ ├── pyproject.toml
│ └── README.md
└── soc-pytest/ # SoC testing example
├── jumpstarter_example_soc_pytest/
├── pyproject.toml
└── README.md
```

## Development Workflow

### Creating New Packages

1. **Drivers**: Use `./__templates__/create_driver.sh` (see creating-new-drivers.mdc)
2. **Other packages**: Create manually following existing patterns

### Package Dependencies

- **Core packages**: Depend on `jumpstarter-protocol`
- **Driver packages**: Depend on `jumpstarter` and specific hardware libraries
- **CLI packages**: Depend on `jumpstarter` and `jumpstarter-cli-common`
- **Examples**: Depend on relevant driver packages

### Testing

- **Package tests**: `make test-pkg-<package_name>`
- **All tests**: `make test`
- **Coverage**: Configured per package with HTML and XML reports

### Linting and Formatting

- **Ruff**: Code formatting and linting (excludes `jumpstarter-protocol`), `make lint` and `make lint-fix` are available.
- **Typos**: Spell checking
- **Pre-commit**: Automated checks

## Key Conventions

1. **Naming**: Package names use hyphens, module names use underscores
2. **Entry points**: Drivers register via `jumpstarter.drivers` entry point
3. **Versioning**: All packages share the same version from VCS
4. **Documentation**: Each package has its own README.md, and when it's a driver we make a symlink in `docs/source/reference/package-apis/drivers/` pointing to the README.md for the driver.
5. **Testing**: Comprehensive test coverage required, but always try to focus on starting a server and client to test it e2e. Mock sometimes when there is too much dependency on system tools/services/compatibility issues between MacOs/Linux.
6. **Dependencies**: Minimal, focused dependencies per package

## Build and Distribution

- **Build system**: Hatch with custom `hatch-pin-jumpstarter` hook
- **Version source**: VCS (Git) with root-level version management
- **Distribution**: Individual packages published separately
- **Workspace**: UV manages dependencies across all packages

## Running tests

When running tests you should use the `make pkg-test-<package_name>` command.

## Running type checking

When running type checking you should use the `make pkg-ty-<package_name>` command,
never invoke pytest manually. Use this because it will be more reliable and
install the right dependencies.

## Running linting

When running linting you should use the `make lint-fix`command.

## Running python manually

If you need to run python code manually to check if it works, you should use `uv run python3`
to make sure you get the venv from uv, you may need to run `make sync` first to get all
the dependencies in place.
11 changes: 7 additions & 4 deletions __templates__/create_driver.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ set -euxv
if [ "$#" -ne 4 ]; then
echo "Illegal number of parameters"
echo "Usage: create_driver.sh <driver_name> <driver_class> <author_name> <author_email>"
echo "Example: create_driver.sh mydriver MyDriver \"John Something\" john@somewhere.com"
echo "Example: create_driver.sh my-driver MyDriver \"John Something\" john@somewhere.com"
exit 1
fi

Expand All @@ -20,6 +20,9 @@ export DRIVER_CLASS=$2
export AUTHOR_NAME=$3
export AUTHOR_EMAIL=$4

# Convert hyphens to underscores for Python module name
export DRIVER_MODULE_NAME=$(echo "${DRIVER_NAME}" | sed 's/-/_/g')

# MacOS has a different syntax for sed -i, we either use gsed (GNU sed) or apply the right -i syntax
if command -v gsed &> /dev/null; then
sed_cmd="gsed"
Expand All @@ -31,7 +34,7 @@ fi

# create the driver directory
DRIVER_DIRECTORY=packages/jumpstarter-driver-${DRIVER_NAME}
MODULE_DIRECTORY=${DRIVER_DIRECTORY}/jumpstarter_driver_${DRIVER_NAME}
MODULE_DIRECTORY=${DRIVER_DIRECTORY}/jumpstarter_driver_${DRIVER_MODULE_NAME}
# create the module directories
mkdir -p ${MODULE_DIRECTORY}
mkdir -p ${DRIVER_DIRECTORY}/examples
Expand Down Expand Up @@ -61,7 +64,7 @@ Example configuration:
```yaml
export:
${DRIVER_NAME}:
type: jumpstarter_driver_${DRIVER_NAME}.driver.${DRIVER_CLASS}
type: jumpstarter_driver_${DRIVER_MODULE_NAME}.driver.${DRIVER_CLASS}
config:
# Add required config parameters here
```
Expand All @@ -71,7 +74,7 @@ export:
Add API documentation here.
EOF
# Need to expand variables after EOF to prevent early expansion
$sed_cmd "s/\${DRIVER_CLASS}/${DRIVER_CLASS}/g; s/\${DRIVER_NAME}/${DRIVER_NAME}/g" "${README_FILE}"
$sed_cmd "s/\${DRIVER_CLASS}/${DRIVER_CLASS}/g; s/\${DRIVER_NAME}/${DRIVER_NAME}/g; s/\${DRIVER_MODULE_NAME}/${DRIVER_MODULE_NAME}/g" "${README_FILE}"
echo "README.md file content:"
cat "${README_FILE}"

Expand Down
16 changes: 16 additions & 0 deletions docs/source/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,22 @@ If you have questions, reach out in our Matrix chat or open an issue on GitHub.

We welcome bug fixes, features, and improvements to the core codebase.


## AI Assistants

This project accepts contributions from AI assistants, although you should be careful when creating code from AI assistants,
and figure out if the code you are submitting could infringe any licensing, for example, reusing code from other incompatible
GPL licenses, you should do your due diligence.

This project includes cursor rules to help Cursor AI understand our codebase and development patterns. When working with Cursor AI:

- **Driver Creation**: If asked to create a new driver, Cursor will guide you through the process using our `create_driver.sh` script
- **Code Style**: Cursor will follow our established patterns and conventions
- **Testing**: Cursor will remind you to add tests and run our test suite

The cursor rules are located in `.cursor/rules/` directory, with specific guidance for driver creation in `.cursor/rules/creating-new-drivers.mdc`.


### Contributing Drivers

To create a new driver scaffold:
Expand Down
Loading