feat: add clipboard copy support with -c/--copy and --copy-only flags #154
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # .github/workflows/ci.yml | |
| name: treemapper CI | |
| permissions: | |
| contents: read | |
| security-events: write # For CodeQL | |
| 'on': | |
| pull_request: | |
| branches: ['**'] | |
| push: | |
| branches: | |
| - main | |
| jobs: | |
| # ============================================================================ | |
| # Pre-commit checks (fast feedback) | |
| # ============================================================================ | |
| pre-commit: | |
| name: Pre-commit hooks | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.12' | |
| - name: Cache pre-commit | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/pre-commit | |
| key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }} | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install pre-commit | |
| - name: Run pre-commit | |
| run: pre-commit run --all-files | |
| # ============================================================================ | |
| # Linting and Type Checking | |
| # ============================================================================ | |
| lint-type-check: | |
| name: Lint & Type Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v6 | |
| - name: Set up Python 3.11 | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.11' | |
| - name: Cache pip Dependencies | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-lint-pip-${{ hashFiles('**/pyproject.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-lint-pip- | |
| - name: Install Linters and Type Checker | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install .[dev] | |
| - name: Run Linters and Formatters Check | |
| run: | | |
| ruff check src tests | |
| black --check src tests | |
| - name: Run Type Checker (Mypy) | |
| run: | | |
| mypy src tests | |
| # ============================================================================ | |
| # Cross-platform Testing | |
| # ============================================================================ | |
| test: | |
| needs: [pre-commit, lint-type-check] | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| python-version: [3.9, '3.10', '3.11', '3.12', '3.13'] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v6 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Cache pip Dependencies | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/pip | |
| key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{ hashFiles('**/pyproject.toml') }} | |
| restore-keys: | | |
| ${{ runner.os }}-pip-${{ matrix.python-version }}- | |
| ${{ runner.os }}-pip- | |
| - name: Install Dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e .[dev] | |
| - name: Run Tests with Coverage | |
| shell: bash | |
| run: | | |
| pytest -v --cov=src/treemapper --cov-report=xml \ | |
| --cov-report=term-missing --cov-branch --junitxml=test-results.xml | |
| - name: Coverage report with threshold | |
| if: runner.os == 'Linux' && matrix.python-version == '3.12' | |
| run: | | |
| coverage report --fail-under=80 --skip-covered --show-missing | |
| - name: Upload coverage reports to Codecov | |
| if: runner.os == 'Linux' && matrix.python-version == '3.12' | |
| uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: ./coverage.xml | |
| flags: integration | |
| fail_ci_if_error: false | |
| verbose: true | |
| - name: Upload coverage for SonarCloud | |
| uses: actions/upload-artifact@v6 | |
| if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12' | |
| with: | |
| name: coverage-report | |
| path: | | |
| coverage.xml | |
| test-results.xml | |
| retention-days: 1 | |
| # ============================================================================ | |
| # PyPy Compatibility Testing | |
| # ============================================================================ | |
| test-pypy: | |
| needs: [pre-commit, lint-type-check] | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: [pypy-3.9, pypy-3.10] | |
| steps: | |
| - name: Checkout Code | |
| uses: actions/checkout@v6 | |
| - name: Set up PyPy ${{ matrix.python-version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Cache pip Dependencies | |
| uses: actions/cache@v5 | |
| with: | |
| path: ~/.cache/pip | |
| key: pypy-${{ matrix.python-version }}-pip-${{ hashFiles('**/pyproject.toml') }} | |
| restore-keys: | | |
| pypy-${{ matrix.python-version }}-pip- | |
| - name: Install Dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e . | |
| pip install pytest pytest-cov | |
| - name: Run Tests | |
| run: | | |
| pytest -v | |
| # ============================================================================ | |
| # Mutation Testing (test effectiveness validation) | |
| # Evidence: Mutation score correlates with real fault detection | |
| # ============================================================================ | |
| mutation-testing: | |
| name: Mutation Testing | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.12' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e .[dev] | |
| pip install mutmut | |
| - name: Run mutation testing | |
| run: | | |
| mutmut run . || true | |
| mutmut results || true | |
| continue-on-error: true | |
| # ============================================================================ | |
| # Complexity & Maintainability Metrics | |
| # Evidence: Cyclomatic complexity correlates with defect density | |
| # ============================================================================ | |
| complexity-checks: | |
| name: Complexity & Maintainability Analysis | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.12' | |
| - name: Install radon | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install radon | |
| - name: Check cyclomatic complexity | |
| run: | | |
| echo "=== Cyclomatic Complexity Report ===" | |
| radon cc src/treemapper/ --min B --show-complexity --total-average | |
| - name: Check maintainability index | |
| run: | | |
| echo "=== Maintainability Index Report ===" | |
| radon mi src/treemapper/ --min B --show | |
| - name: Fail on high complexity | |
| run: | | |
| radon cc src/treemapper/ --min C --total-average || \ | |
| (echo "High complexity detected" && exit 1) | |
| # ============================================================================ | |
| # Architecture & Import Contracts | |
| # Evidence: Coupling/architecture violations correlate with defect density | |
| # ============================================================================ | |
| architecture-checks: | |
| name: Architecture & Import Contracts | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.12' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e .[dev] | |
| pip install import-linter | |
| - name: Create import contracts file | |
| run: | | |
| cat > .importlinter <<EOF | |
| [importlinter] | |
| root_package = treemapper | |
| [importlinter:contract:1] | |
| name = CLI should not import writer directly | |
| type = forbidden | |
| source_modules = | |
| treemapper.cli | |
| forbidden_modules = | |
| treemapper.writer | |
| [importlinter:contract:2] | |
| name = Tree building should not import CLI | |
| type = forbidden | |
| source_modules = | |
| treemapper.tree | |
| forbidden_modules = | |
| treemapper.cli | |
| EOF | |
| - name: Check import contracts | |
| run: lint-imports | |
| continue-on-error: true | |
| # ============================================================================ | |
| # SonarCloud Quality Gate | |
| # Evidence: Complexity/duplication metrics correlate with defect density | |
| # ============================================================================ | |
| sonarcloud: | |
| name: SonarCloud Analysis | |
| runs-on: ubuntu-latest | |
| needs: test | |
| if: github.event_name == 'pull_request' || github.ref == 'refs/heads/main' | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Download coverage reports | |
| uses: actions/download-artifact@v7 | |
| with: | |
| name: coverage-report | |
| path: . | |
| - name: Verify coverage files exist | |
| run: | | |
| echo "=== Checking for coverage files ===" | |
| ls -lh coverage.xml test-results.xml || true | |
| echo "=== Coverage.xml source paths ===" | |
| head -10 coverage.xml || true | |
| - name: Create sonar-project.properties | |
| run: | | |
| cat > sonar-project.properties <<EOF | |
| sonar.projectKey=nikolay-e_treemapper | |
| sonar.organization=nikolay-e | |
| sonar.sources=src/treemapper | |
| sonar.tests=tests | |
| sonar.python.coverage.reportPaths=coverage.xml | |
| sonar.python.xunit.reportPath=test-results.xml | |
| sonar.python.version=3.9,3.10,3.11,3.12,3.13 | |
| EOF | |
| - name: SonarCloud Scan | |
| uses: SonarSource/sonarcloud-github-action@ba3875ecf642b2129de2b589510c81a8b53dbf4e # master | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
| continue-on-error: true |