A Python linter for Umbrel app stores and applications
Project description
ulint
A linter for Umbrel apps written in Python.
Features
- YAML Validation: validation of
umbrel-app.ymlandumbrel-app-store.ymlfiles - Docker Compose Validation: validation of Docker Compose files with security checks
- Directory Structure Validation: validation of proper app directory structure
- Security Checks: validation of potential security vulnerabilities
Installation
Installation via uv
# using uv tool
uv tool install ulint
# using uvx
uvx ulint --help
# using pipx
pipx install ulint
# using pip
pip install ulint
Build from Source
This project uses uv as the package manager. Make sure you have uv installed, then:
# Clone the repository
git clone http://github.com/Mr-Sunglasses/ulint
cd ulint
# Install dependencies
uv sync
# Install the package in development mode
uv pip install -e .
Usage
Command Line Interface
# Lint all apps in a directory
ulint lint /path/to/app-store
# Lint a specific app
umbrel-linter lint /path/to/app-store --app my-app
# Lint with specific options
umbrel-linter lint /path/to/app-store \
--log-level error \
--strict \
--skip-architectures \
--format json
Available Commands
lint: Main linting commandversion: Show version informationconfig: Show configuration information
Command Options
--app, -a: Specific app ID to lint--log-level, -l: Log level (error, warning, info)--strict, -s: Treat warnings as errors--skip-architectures: Skip checking Docker image architectures--new-submission: This is a new app submission--pr-url: Pull request URL for new submissions--store-type: App store type (official, community)--format, -f: Output format (rich, json, plain)--verbose, -v: Verbose output
Programmatic Usage
from umbrel_linter import UmbrelLinter
from umbrel_linter.core.models import LinterConfig, LintingContext
from pathlib import Path
# Create linter with configuration
config = LinterConfig(
check_image_architectures=True,
log_level="warning",
strict_mode=False
)
linter = UmbrelLinter(config)
# Lint a specific app
result = linter.lint_app(Path("/path/to/app-store"), "my-app")
# Check results
if result.has_errors():
print(f"Found {result.total_errors} errors")
for error in result.errors:
print(f"{error.severity}: {error.title} - {error.message}")
Configuration
The linter can be configured through the LinterConfig class:
from umbrel_linter.core.models import LinterConfig, Severity
config = LinterConfig(
check_image_architectures=True, # Check Docker image architectures
log_level=Severity.WARNING, # Minimum log level
strict_mode=False, # Treat warnings as errors
ignore_patterns=["*.tmp"] # File patterns to ignore
)
Error Types
The linter identifies various types of issues:
YAML Validation Errors
- Invalid YAML syntax
- Missing required fields
- Invalid field types
- Schema validation failures
Docker Compose Validation Errors
- Invalid image names and tags
- Security vulnerabilities (Docker socket mounting, root user)
- Invalid volume mounts
- Missing required files/directories
- Invalid port mappings
- Incorrect app proxy configuration
Directory Structure Errors
- Empty directories without
.gitkeepfiles - Missing required files
Security Warnings
- Docker socket mounting
- Root user usage
- Host network mode
- Insecure volume mounts
Development
Setting up Development Environment
# Install development dependencies
uv sync --dev
# Run tests
uv run pytest
# Run linting
uv run ruff check .
uv run black .
# Run type checking
uv run mypy .
Running Tests
# Run all tests
uv run pytest
# Run with coverage
uv run pytest --cov=umbrel_linter
# Run specific test file
uv run pytest tests/test_models.py
Code Quality
The project uses several tools for code quality:
- Black: Code formatting
- Ruff: Fast Python linter
- MyPy: Static type checking
- Pytest: Testing framework
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file umbrel_linter-0.1.0.tar.gz.
File metadata
- Download URL: umbrel_linter-0.1.0.tar.gz
- Upload date:
- Size: 93.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1fbd5a5a80c4ad27871e27a5fffc68181f18f7ad1596f32d39f0fdb5ecce0d90
|
|
| MD5 |
9bca505aa577a8eff31a9d8205ea9a28
|
|
| BLAKE2b-256 |
d96145f4e84f5c8a7340fe76e8d1ce540ecc8e7c5f55d2c65296e4af0d9d4e7d
|
File details
Details for the file umbrel_linter-0.1.0-py3-none-any.whl.
File metadata
- Download URL: umbrel_linter-0.1.0-py3-none-any.whl
- Upload date:
- Size: 34.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aba94d98e6c4da0dda6e64c0ea953c5174f1e27bfb2761ba5c2d291c3a414b5a
|
|
| MD5 |
77a99446f5736bc2e2b5bd7b1d783347
|
|
| BLAKE2b-256 |
0b57efea80e97e1cf3aced3cfeaaf387e77d54de7b63181bc5d117a764f98c7f
|