Refactor: streamline contributing guidelines

This commit is contained in:
arabcoders 2026-01-02 21:04:43 +03:00
parent a21fbbc2cc
commit 8e91eb4ac7

View file

@ -1,715 +1,149 @@
# Contributing to YTPTube # Contributing to YTPTube
Thank you for your interest in contributing to **YTPTube**! We welcome contributions from the community to help improve this project. YTPTube is a **personal-first project**. While contributions are welcome, **all final decisions rest with the maintainer**.
This document provides guidelines and instructions for contributing to the project. ## Core Principles
## Table of Contents * **The maintainer has final say** on all changes and project direction.
* This project is built **for personal use first**. Community contributions are secondary.
* **All contributions require prior discussion and approval.**
* **All pull requests must target the `dev` branch** never `master`.
* Contributions must align with the project's goals, architecture, and coding standards.
- [Contributing to YTPTube](#contributing-to-ytptube) **Opening a PR without prior approval will result in immediate closure without review.**
- [Table of Contents](#table-of-contents)
- [Code of Conduct](#code-of-conduct)
- [Getting Started](#getting-started)
- [Prerequisites](#prerequisites)
- [Backend Requirements](#backend-requirements)
- [Frontend Requirements](#frontend-requirements)
- [Optional Tools](#optional-tools)
- [Installing Required Package Managers](#installing-required-package-managers)
- [Installing uv (Python Package Manager)](#installing-uv-python-package-manager)
- [Installing pnpm (Node.js Package Manager)](#installing-pnpm-nodejs-package-manager)
- [Cloning the Repository](#cloning-the-repository)
- [Development Setup](#development-setup)
- [Backend Setup (Python)](#backend-setup-python)
- [Frontend Setup (Node.js)](#frontend-setup-nodejs)
- [Development Workflow](#development-workflow)
- [Working on a Feature or Bug Fix](#working-on-a-feature-or-bug-fix)
- [Branching Strategy](#branching-strategy)
- [Important Rules:](#important-rules)
- [Branch Naming Conventions:](#branch-naming-conventions)
- [Testing Requirements](#testing-requirements)
- [Backend Testing (Python)](#backend-testing-python)
- [Frontend Testing (TypeScript/Vue)](#frontend-testing-typescriptvue)
- [Test Coverage Expectations](#test-coverage-expectations)
- [Code Quality and Linting](#code-quality-and-linting)
- [Backend (Python)](#backend-python)
- [Frontend (TypeScript/Vue)](#frontend-typescriptvue)
- [Code Quality Checklist](#code-quality-checklist)
- [Pre-commit Hooks](#pre-commit-hooks)
- [Setting Up Pre-commit Hooks](#setting-up-pre-commit-hooks)
- [Before Submitting](#before-submitting)
- [Pull Request Guidelines](#pull-request-guidelines)
- [Creating a Pull Request](#creating-a-pull-request)
- [PR Review Process](#pr-review-process)
- [After Your PR is Merged](#after-your-pr-is-merged)
- [Code Style](#code-style)
- [Python Code Style](#python-code-style)
- [TypeScript/Vue Code Style](#typescriptvue-code-style)
- [Getting Help](#getting-help)
- [Resources](#resources)
- [Ask Questions](#ask-questions)
- [Reporting Bugs](#reporting-bugs)
- [License](#license)
--- ---
## Code of Conduct ## Contribution Process
Please be respectful and constructive in all interactions. We aim to maintain a welcoming and inclusive community. ### 1. Start a Discussion
--- Before writing any code, **propose your idea** through one of these channels:
## Getting Started * Open a **GitHub Issue** for bug fixes or small features
* Start a **GitHub Discussion** for larger changes or questions
### Prerequisites **Include in your proposal:**
* **What** you want to change
* **Why** it's needed or beneficial
* Bug fixes and functional improvements are prioritized
* Performance enhancements with measurable impact
* Features that align with the project's core purpose
* **Not acceptable:** Personal UI/UX preferences, stylistic changes, or "I think it looks better" rationale
* **How** you plan to implement it (high-level approach)
* Any relevant context or use cases
Before you begin, ensure you have the following tools installed on your system: ### 2. Wait for Approval
#### Backend Requirements * Only proceed after **explicit approval** from the maintainer to not waste effort.
* The maintainer may suggest modifications or alternative approaches.
* Not all proposals will be accepted this protects project coherence.
- **Python 3.13+**: YTPTube requires Python 3.13 or higher ### 3. Develop Your Changes
- **uv**: Modern Python package manager and virtual environment tool
#### Frontend Requirements
- **Node.js 18+**: Required for the Nuxt/Vue frontend
- **pnpm**: Fast, disk space efficient package manager
#### Optional Tools
- **Git**: Version control
- **Docker**: For containerized development (optional)
- **ffmpeg**: Required for video player functionality
### Installing Required Package Managers
#### Installing uv (Python Package Manager)
**uv** is a fast Python package installer and resolver written in Rust. It's used for managing Python dependencies and virtual environments.
**On Linux/macOS:**
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```
**On Windows (PowerShell):**
```powershell
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
```
**Using pip:**
```bash
pip install uv
```
**Verify installation:**
```bash
uv --version
```
For more information, visit: https://github.com/astral-sh/uv
#### Installing pnpm (Node.js Package Manager)
**pnpm** is a fast, disk space efficient package manager for Node.js.
**Using npm:**
```bash
npm install -g pnpm
```
**Using Homebrew (macOS):**
```bash
brew install pnpm
```
**Using Scoop (Windows):**
```bash
scoop install pnpm
```
**Using standalone script:**
```bash
curl -fsSL https://get.pnpm.io/install.sh | sh -
```
**Verify installation:**
```bash
pnpm --version
```
For more information, visit: https://pnpm.io/installation
### Cloning the Repository
Clone the repository to your local machine:
```bash
git clone https://github.com/arabcoders/ytptube.git
cd ytptube
```
**Important**: Always work on the `dev` branch, not `master`/`main`:
```bash
git checkout dev
```
---
## Development Setup
### Backend Setup (Python)
1. **Navigate to the project root:**
```bash
cd ytptube
```
2. **Install Python dependencies using uv:**
```bash
uv sync
```
This will:
- Create a virtual environment (`.venv/`)
- Install all dependencies from `pyproject.toml`
- Install development dependencies
3. **Install development dependencies:**
Development dependencies are defined in `pyproject.toml` under `[dependency-groups]`:
```bash
uv sync --group dev
```
4. **Verify installation:**
```bash
uv run python --version
uv run pytest --version
```
5. **Run the backend development server:**
```bash
uv run app/main.py
```
The backend API will be available at `http://localhost:8081`
### Frontend Setup (Node.js)
1. **Navigate to the UI directory:**
```bash
cd ui
```
2. **Install Node.js dependencies using pnpm:**
```bash
pnpm install
```
> [!NOTE]
> Create a `.env` file in the `ui/` directory based on `.env.example` to configure environment variables.
> to link the frontend to the backend API.
3. **Run the frontend development server:**
```bash
pnpm dev
```
The frontend will be available at `http://localhost:8082` (or the port shown in the terminal)
4. **Verify the setup:**
```bash
pnpm run typecheck
pnpm run lint
```
---
## Development Workflow
### Working on a Feature or Bug Fix
1. **Ensure you're on the `dev` branch:**
**Branch from `dev`:**
```bash ```bash
git checkout dev git checkout dev
git pull origin dev git pull origin dev
git checkout -b feature/descriptive-name
``` ```
2. **Create a feature branch:** **Follow project standards:**
* Match existing code style and conventions
* Add or update tests for all changes:
* New features **MUST** include tests
* Bug fixes **MUST** include a regression test
* Ensure all linting and tests pass
* Keep changes focused and atomic
```bash ### 4. Submit a Pull Request
git checkout -b feature/your-feature-name
# or
git checkout -b fix/bug-description
```
3. **Make your changes** **Target the `dev` branch:**
* Reference the approved issue or discussion number
* Provide a clear description of what changed and why
* List any breaking changes or migration steps
* Ensure CI checks pass
4. **Test your changes** (see [Testing Requirements](#testing-requirements)) **PR template checklist:**
- [ ] Discussed and approved beforehand
5. **Run code quality checks** (see [Code Quality and Linting](#code-quality-and-linting)) - [ ] Targets `dev` branch
- [ ] Tests added/updated and passing
6. **Commit your changes:** - [ ] Linting passes
- [ ] Documentation updated (if needed)
```bash
git add .
git commit -m "feat: add new feature description"
# or
git commit -m "fix: fix bug description"
```
7. **Push to your fork:**
```bash
git push origin feature/your-feature-name
```
8. **Create a Pull Request** targeting the `dev` branch
--- ---
## Branching Strategy ## Automatic Rejections
**YTPTube uses a two-branch strategy:** The following will be **closed immediately without review**:
- **`master`**: Production-ready code. Only maintainers merge to this branch. * PRs opened without prior discussion and approval
- **`dev`**: Development branch. **All contributions must target this branch.** * PRs targeting `master` instead of `dev`
* Large refactors or architectural changes without approval
* Fully AI-generated code without meaningful human oversight
* Changes that don't align with project goals or philosophy
* PRs where the contributor cannot explain or justify the changes
### Important Rules: ---
- ✅ **DO**: Create feature branches from `dev` ## AI-Assisted Development
- ✅ **DO**: Submit pull requests to `dev`
- ❌ **DON'T**: Submit pull requests to `master`/`main`
- ❌ **DON'T**: Commit directly to `dev` (use feature branches)
### Branch Naming Conventions: AI tools are **permitted** as development aids, but **you remain fully responsible** for all submitted code.
- `feature/description` - For new features ### Acceptable Use
- `fix/description` - For bug fixes
- `refactor/description` - For code refactoring AI-assisted code is welcome **when**:
- `docs/description` - For documentation updates
- `test/description` - For test additions/improvements * You **fully understand** every line being submitted
* The code **seamlessly integrates** with existing patterns and style
* You have **reviewed, tested, and validated** the output yourself
* **Comprehensive tests** are included (not AI-generated stubs)
* The code is **indistinguishable in quality** from hand-written contributions
* You can **explain and defend** design decisions in the PR
**AI is a tool, not a substitute for understanding.**
### Not Acceptable
The following will be rejected:
* Fully AI-generated PRs with minimal human review
* Code that introduces new patterns or abstractions without approval
* "Prompt-dump" output that doesn't match project conventions
* Changes the contributor cannot explain or justify
* AI-generated test suites that don't meaningfully validate behavior
### Disclosure
You are **not required** to disclose AI usage. However, if code quality suggests pure AI generation without human oversight, the PR will be closed.
**You are accountable for correctness, maintainability, and alignment regardless of how the code was created.**
--- ---
## Testing Requirements ## Testing Requirements
**All code changes must include appropriate tests.** This ensures code quality and prevents regressions. All contributions must include appropriate tests:
### Backend Testing (Python) * **New features:** Full test coverage including edge cases
* **Bug fixes:** Regression test that fails before the fix and passes after
* **Refactors:** Existing tests must continue to pass
* **Performance changes:** Benchmarks or performance tests when applicable
Tests are located in `app/tests/` and use **pytest**. Tests should be clear, maintainable, and actually validate the intended behavior.
**Running tests:**
```bash
# Run all tests
uv run pytest
# Run specific test file
uv run pytest app/tests/test_download.py
# Run with verbose output
uv run pytest -v
# Run with coverage
uv run pytest --cov=app --cov-report=html
```
**Creating new tests:**
1. Create a test file in `app/tests/` with the prefix `test_`
2. Use pytest conventions:
```python
import pytest
from app.library.YourModule import YourClass
class TestYourClass:
def test_feature_name(self):
"""Test description."""
# Arrange
instance = YourClass()
# Act
result = instance.method()
# Assert
assert result == expected_value
@pytest.mark.asyncio
async def test_async_feature(self):
"""Test async functionality."""
result = await async_function()
assert result is not None
```
**Testing Singleton Classes:**
When testing singleton classes, always reset the singleton instance:
```python
from app.library.Presets import Presets
class TestPresets:
def setup_method(self):
"""Reset singleton before each test."""
Presets._reset_singleton()
def teardown_method(self):
"""Reset singleton after each test."""
Presets._reset_singleton()
```
### Frontend Testing (TypeScript/Vue)
Tests are located in `ui/tests/` and use **Vitest**.
**Running tests:**
```bash
cd ui
# Run all tests
pnpm test
# Run in watch mode
pnpm test:watch
# Run with coverage
pnpm run test --coverage
```
**Creating new tests:**
```typescript
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import YourComponent from '~/components/YourComponent.vue'
describe('YourComponent', () => {
it('renders correctly', () => {
const wrapper = mount(YourComponent)
expect(wrapper.exists()).toBe(true)
})
it('handles user interaction', async () => {
const wrapper = mount(YourComponent)
await wrapper.find('button').trigger('click')
expect(wrapper.emitted('event-name')).toBeTruthy()
})
})
```
### Test Coverage Expectations
- **New features**: Must include comprehensive tests
- **Bug fixes**: Must include a test that reproduces the bug
- **Refactoring**: Existing tests should still pass
- **Coverage goal**: Aim for >80% code coverage on new code
--- ---
## Code Quality and Linting ## Questions?
### Backend (Python) * Check existing **Issues** and **Discussions** first
* Join the project **Discord** for real-time discussion
YTPTube uses **Ruff** for linting and formatting Python code. * Be patient, this is a personal project with limited maintenance time
**Running Ruff:**
```bash
# Check for linting issues
uv run ruff check app/
# Auto-fix linting issues
uv run ruff check --fix app/
# Format code
uv run ruff format app/
# Check specific file
uv run ruff check app/library/Download.py
uv run ruff check --fix app/library/Download.py
```
**Configuration:**
Ruff configuration is in `pyproject.toml` under `[tool.ruff]`.
### Frontend (TypeScript/Vue)
The frontend uses **ESLint** for linting and **TypeScript** for type checking.
**Running checks:**
```bash
cd ui
# Type checking
pnpm run typecheck
# Linting
pnpm run lint
# Auto-fix linting issues
pnpm run lint:fix
```
### Code Quality Checklist
Before committing, ensure:
- ✅ All tests pass (`uv run pytest` and `pnpm test`)
- ✅ No linting errors (`ruff check` and `pnpm run lint`)
- ✅ TypeScript compilation succeeds (`pnpm run typecheck`)
- ✅ Code is formatted properly
- ✅ No unused imports or variables
- ✅ Type hints are present (Python 3.13+)
---
## Pre-commit Hooks
YTPTube uses a custom shell script-based pre-commit hook that runs all checks in parallel for faster execution.
### Setting Up Pre-commit Hooks
1. **Create the pre-commit hook script:**
Create a file at `.git/hooks/pre-commit` with the following content:
```bash
#!/bin/sh
set -eu
REPO_ROOT=$(git rev-parse --show-toplevel)
cd "$REPO_ROOT" || exit 1
PIDS_FILE=$(mktemp)
trap 'rm -f "$PIDS_FILE"' EXIT
export CI=1
run_step() {
local label="$1"
shift
echo "🔹 Starting $label..." >&2
(
if ! "$@"; then
echo "❌ [$label] failed. Commit aborted." >&2
exit 1
else
echo "✅ [$label] passed." >&2
fi
) &
echo $! >>"$PIDS_FILE"
}
run_step "Ruff (Python linter)" uv run ruff check app/
run_step "PyTest" uv run pytest app/ -q
run_step "ESLint" pnpm --dir ./ui run lint
run_step "Vitest" pnpm --dir ./ui run test
fail=0
while read -r pid; do
if ! wait "$pid"; then
fail=1
fi
done <"$PIDS_FILE"
if [ "$fail" -eq 1 ]; then
echo "❌ One or more checks failed. Commit aborted." >&2
exit 1
fi
echo "✅ All checks passed. Commit allowed."
exit 0
```
2. **Make the hook executable:**
```bash
chmod +x .git/hooks/pre-commit
```
3. **Test the hook:**
```bash
# Test manually
.git/hooks/pre-commit
# Or make a test commit
git commit --allow-empty -m "test: verify pre-commit hook"
```
---
### Before Submitting
✅ **Checklist:**
- [ ] Code is on a feature branch created from `dev`
- [ ] All tests pass locally
- [ ] Code passes linting and formatting checks
- [ ] TypeScript types are properly defined (no `any`) without justification
- [ ] New features include tests
- [ ] Documentation is updated (if applicable)
- [ ] Commit messages are clear and descriptive
- [ ] Pre-commit hooks pass
---
## Pull Request Guidelines
### Creating a Pull Request
1. **Push your branch to GitHub:**
```bash
git push origin feature/your-feature-name
```
2. **Open a Pull Request on GitHub**
3. **Target the `dev` branch** (not `master`)
4. **Fill out the PR template** with:
- Description of changes
- Related issue numbers (if applicable)
- Testing performed
- Screenshots (for UI changes)
- Breaking changes (if any)
### PR Review Process
1. **Automated Checks**: CI pipeline runs tests and linting
2. **Code Review**: Maintainers review your code
3. **Feedback**: Address any requested changes
4. **Approval**: Once approved, maintainers will merge
### After Your PR is Merged
1. **Delete your feature branch** (optional but recommended)
2. **Pull the latest `dev` branch:**
```bash
git checkout dev
git pull origin dev
```
3. **Celebrate!** Thank you for contributing!
---
## Code Style
### Python Code Style
- **Line length**: 120 characters
- **Indentation**: 4 spaces
- **Quotes**: Double quotes for strings
- **Type hints**: Use Python 3.13+ type hints
- **Imports**: Absolute imports from `app.library`
- **Comparison**: Use Yoda comparisons for literals (`"value" == variable`)
**Example:**
```python
from app.library.Download import Download
from app.library.ItemDTO import ItemDTO
async def process_download(item: ItemDTO) -> bool:
"""Process a download item."""
try:
if "pending" == item.status: # Yoda comparison
result = await Download.start(item)
return result.success
except Exception as e:
LOG.error(f"Download failed: {e}")
return False
```
### TypeScript/Vue Code Style
- **Type safety**: No `any` types without justification
- **Explicit imports**: Import all Vue functions explicitly
- **Component structure**: Use `<script setup lang="ts">`
- **Props/Emits**: Always type-define
**Example:**
```vue
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import type { DownloadItem } from '~/types/download'
const props = defineProps<{
items: Array<DownloadItem>
}>()
const emit = defineEmits<{
(e: 'itemSelected', item: DownloadItem): void
}>()
const selectedItem = ref<DownloadItem | null>(null)
</script>
```
---
## Getting Help
### Resources
- **API Docs**: See [API.md](API.md) for API reference
- **FAQ**: Check [FAQ.md](FAQ.md) for common questions
- **Issues**: Browse existing [GitHub Issues](https://github.com/arabcoders/ytptube/issues)
### Ask Questions
- **GitHub Discussions**: For general questions and discussions
- **GitHub Issues**: For bug reports and feature requests
- **Pull Requests**: For code review and implementation questions
- **Discord**: Join our community on Discord (link in README)
### Reporting Bugs
When reporting bugs, please include:
1. **Description**: Clear description of the issue
2. **Steps to Reproduce**: Detailed steps to reproduce the bug
3. **Expected Behavior**: What you expected to happen
4. **Actual Behavior**: What actually happened
5. **Environment**: OS, Python version, Node version, etc.
6. **Logs**: Relevant error messages or logs
7. **Screenshots**: If applicable
--- ---
## License ## License
By contributing to YTPTube, you agree that your contributions will be licensed under the [MIT License](LICENSE). By contributing, you agree that your code will be licensed under the project's **MIT License**.
--- Thank you for respecting this contribution process. It helps maintain project quality and the maintainer's sanity.
Thank you for contributing to YTPTube! Your efforts help make this project better for everyone.