Skip to content

Latest commit

 

History

History
358 lines (262 loc) · 7.62 KB

File metadata and controls

358 lines (262 loc) · 7.62 KB

Contributing to CreativeOS

Your Creative Nervous System · Contribution guidelines

First off, thank you for considering contributing to CreativeOS! It's people like you that make this tool great.

Table of Contents

Code of Conduct

This project and everyone participating in it is governed by common sense and respect. By participating, you are expected to uphold this standard. Please be respectful, inclusive, and constructive.

Getting Started

Prerequisites

  • Python 3.10 or higher
  • pip (Python package manager)
  • Git
  • A code editor (VS Code recommended)

Fork and Clone

  1. Fork the repository on GitHub
  2. Clone your fork locally:
    git clone https://github.com/YOUR_USERNAME/CreativeOSFolder.git
    cd CreativeOSFolder
  3. Add the upstream remote:
    git remote add upstream https://github.com/JStaRFilms/CreativeOSFolder.git

Development Setup

1. Create Virtual Environment

# Windows
python -m venv venv
venv\Scripts\activate

# macOS/Linux
python3 -m venv venv
source venv/bin/activate

2. Install Dependencies

pip install -r requirements.txt
pip install -e ".[dev]"

3. Install in Development Mode

pip install -e .

4. Set Up Configuration

# Copy the template
copy 00_System\Config\config.json.template 00_System\Config\config.json

# Edit with your paths
notepad 00_System\Config\config.json

5. Run Tests

cd 00_System/Scripts
pytest tests/ -v

6. Run the CLI

# From project root
00_System\Scripts\cos.bat --help

# Or directly with Python
python 00_System/Scripts/manage.py --help

Project Structure

CreativeOS/
├── 00_System/
│   ├── Config/
│   │   ├── config.json          # User configuration (gitignored)
│   │   └── config.json.template # Template for new users
│   ├── Scripts/
│   │   ├── manage.py            # Main CLI entry point
│   │   ├── cos.bat              # Windows batch wrapper
│   │   ├── cos/                 # Modular package (after refactor)
│   │   │   ├── __init__.py
│   │   │   ├── config.py
│   │   │   ├── security.py
│   │   │   ├── file_utils.py
│   │   │   └── commands/
│   │   ├── tests/               # Test suite
│   │   └── requirements.txt
│   └── Templates/
│       ├── Video/
│       ├── Audio/
│       ├── Design/
│       ├── Photo/
│       ├── Code/
│       └── Writing/
├── CHANGELOG.md
├── CONTRIBUTING.md
├── README.md
└── USER MANUAL.md

Coding Standards

Python Style Guide

We follow PEP 8 with a few modifications:

  • Line length: 100 characters (not 79)
  • Quotes: Double quotes for strings, single for characters
  • Imports: Grouped (stdlib, third-party, local)

Type Hints

All functions must have type hints:

def sanitize_path_input(value: str, max_length: int = 100) -> str:
    """Sanitize user input to prevent path traversal attacks."""
    ...

Docstrings

Use Google-style docstrings:

def sync_two_folders(source: str, target: str) -> tuple[list[dict], dict]:
    """Synchronize two folders bidirectionally.
    
    Compares files in both directories and syncs based on modification time.
    Newer files always win.
    
    Args:
        source: Path to source directory
        target: Path to target directory
    
    Returns:
        A tuple containing:
            - List of sync operations performed
            - Dictionary with final state
    
    Raises:
        FileNotFoundError: If source directory doesn't exist
        PermissionError: If unable to read/write files
    """
    ...

Error Handling

  • Use specific exceptions
  • Provide helpful error messages
  • Log errors with context
# Good
if not os.path.exists(project_path):
    raise FileNotFoundError(
        f"Project not found: {project_path}\n"
        f"Make sure you're in a project directory or specify --path"
    )

# Bad
if not os.path.exists(project_path):
    raise Exception("Error")

Security

  • Always sanitize user input before using in paths or commands
  • Never use shell=True with subprocess
  • Validate all URLs before using with git
# Good
safe_name = sanitize_path_input(user_input)
subprocess.run(["git", "clone", validate_git_url(url)], cwd=dest)

# Bad
subprocess.run(f"git clone {user_input}", shell=True)

Commit Guidelines

Commit Message Format

<type>(<scope>): <subject>

<body>

<footer>

Types

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation only
  • style: Formatting, no code change
  • refactor: Code change without fix/feature
  • test: Adding tests
  • chore: Maintenance tasks

Examples

feat(sync): add conflict resolution for same mtime

When two files have identical modification times, compare content
to determine which version to keep.

Closes #42
fix(security): prevent path traversal in project names

Added sanitize_path_input() to strip path separators and
validate against reserved names.

Pull Request Process

Before Submitting

  1. Update from upstream:

    git fetch upstream
    git checkout main
    git merge upstream/main
  2. Create feature branch:

    git checkout -b feature/your-feature-name
  3. Make your changes following coding standards

  4. Run tests:

    pytest tests/ -v
    pytest tests/ --cov=cos --cov-report=term-missing
  5. Update documentation if needed

Submitting

  1. Push to your fork:

    git push origin feature/your-feature-name
  2. Open a Pull Request on GitHub

  3. Fill in the PR template:

    • Description of changes
    • Related issue (if any)
    • Testing performed
    • Screenshots (if applicable)

Review Process

  • PRs require at least one approval
  • All tests must pass
  • No merge conflicts
  • Documentation updated (if applicable)

Testing

Running Tests

# All tests
pytest tests/ -v

# Specific test file
pytest tests/test_security.py -v

# With coverage
pytest tests/ --cov=cos --cov-report=html

Writing Tests

  • Place tests in 00_System/Scripts/tests/
  • Name test files test_*.py
  • Name test classes Test*
  • Name test methods test_*
class TestSanitizePathInput:
    """Tests for sanitize_path_input function."""
    
    def test_valid_name_unchanged(self):
        """Valid names should pass through unchanged."""
        assert sanitize_path_input("My Project") == "My Project"
    
    def test_rejects_path_traversal(self):
        """Path traversal attempts should be rejected."""
        with pytest.raises(ValueError, match="path separator"):
            sanitize_path_input("../../../etc/passwd")

Documentation

What to Document

  • New features: Update USER MANUAL.md
  • API changes: Update docstrings
  • Configuration: Update README.md
  • Architecture: Update this file

Style

  • Use clear, simple language
  • Include code examples
  • Add screenshots for UI features
  • Keep line length under 80 characters in docs

Questions?

Feel free to open an issue with the "question" label, or start a discussion in the GitHub Discussions section.


Thank you for contributing! 🎉