Skip to content
Open
Show file tree
Hide file tree
Changes from 4 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
24 changes: 24 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "PyLaunch Blueprint",
"build": {
"dockerfile": "Dockerfile",
"context": ".."
},
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"ms-python.black-formatter",
"charliermarsh.ruff",
"matangover.mypy",
"tamasfe.even-better-toml",
"redhat.vscode-yaml",
"eamodio.gitlens",
"streetsidesoftware.code-spell-checker"
]
}
},
"postCreateCommand": "bash .devcontainer/setup.sh",
"remoteUser": "vscode"
}
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,4 @@ jobs:
# run: |
# uv pip install build twine
# python -m build
# twine upload dist/*
# twine upload dist/*
10 changes: 8 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
Expand Down Expand Up @@ -47,4 +46,11 @@ repos:
language: system
types: [python]
pass_filenames: false # Run full test suite
stages: [pre-commit] # Only run on pre-commit
stages: [pre-commit] # Only run on commit
- repo: local
hooks:
- id: check-vscode-extension-sync
name: Check VSCode Extension Sync
entry: uvx scripts/check_extension_sync.py
language: system
types: [json]
24 changes: 18 additions & 6 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -299,13 +299,21 @@ debug-info:
# Update CONTRIBUTORS.md file
[group('build')]
@contributors:
update-contributors:
echo "Updating CONTRIBUTORS.md..."
# Cross-platform way to update CONTRIBUTORS.md using git shortlog
echo "# Contributors" > CONTRIBUTORS.md
echo "" >> CONTRIBUTORS.md
git shortlog -sne >> CONTRIBUTORS.md
echo "✓ Contributors list updated"
if [ "$$OS" = "Windows_NT" ]; then \
powershell -File scripts/update_contributors.ps1; \
else \
echo "{{YELLOW}}TODO: Add macOS/Linux command to update CONTRIBUTORS.md here{{NC}}"; \
# Example placeholder: ./scripts/update_contributors.sh
fi
echo "{{CHECK}} Contributors list updated"

# # Generate changelog from conventional commits
# changelog:
# echo "Generating changelog..."
# command -v cog >/dev/null 2>&1 || { echo "{{RED}}Error: Cocogitto (cog) is not installed{{NC}}"; exit 1; }
# cog changelog --at=HEAD
# echo "{{GREEN}}✓{{NC}} Changelog generated"

# Verify commit messages follow conventional commit format
[group('pre-commit')]
Expand Down Expand Up @@ -628,5 +636,9 @@ clean-pr-to-testrepo new_repo_name="test-actions-repo":
# just build
# just run

# Check if VSCode recommended extensions are synced with devcontainerm
check-extension-sync:
uv run scripts/check_extension_sync.py

# Alias for dev (full developer cycle: format → lint → test → build)
alias cycle := dev
59 changes: 59 additions & 0 deletions scripts/check_extension_sync.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env python3

import json
import sys
from pathlib import Path
from typing import Dict, Set, Any

EXTENSIONS_FILE = Path(".vscode/extensions.json")
DEVCONTAINER_FILE = Path(".devcontainer/devcontainer.json")


def load_json(file_path: Path) -> Dict[str, Any]:
try:
with open(file_path) as f:
return json.load(f)
except FileNotFoundError:
print(f"❌ Error: {file_path} not found.")
sys.exit(2)
except json.JSONDecodeError as e:
print(f"❌ Error parsing {file_path}: {e}")
sys.exit(2)


def extract_recommended_extensions(data: Dict[str, Any]) -> Set[str]:
return set(data.get("recommendations", []))


def extract_devcontainer_extensions(data: Dict[str, Any]) -> Set[str]:
try:
return set(
ext if isinstance(ext, str) else ext["id"]
for ext in data["customizations"]["vscode"]["extensions"]
)
except KeyError:
return set()


def main() -> None:
vscode_data = load_json(EXTENSIONS_FILE)
devcontainer_data = load_json(DEVCONTAINER_FILE)

vscode_exts = extract_recommended_extensions(vscode_data)
dev_exts = extract_devcontainer_extensions(devcontainer_data)

missing = vscode_exts - dev_exts

if missing:
print("❌ VSCode extensions not synced with devcontainer configuration!\n")
print("Missing from .devcontainer/devcontainer.json:")
for ext in sorted(missing):
print(f"- {ext}")
print("\nTo fix: Add these extensions to the `customizations.vscode.extensions` array in `.devcontainer/devcontainer.json`")
sys.exit(1)

print("✅ VSCode extensions are in sync.")
sys.exit(0)


if __name__ == "__main__":
Loading