Skip to content
Open
Show file tree
Hide file tree
Changes from 16 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
30 changes: 30 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "py-launch-blueprint",
"build": {
"dockerfile": "Dockerfile",
"context": ".."
},
"postCreateCommand": "just --version",
"mounts": [
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"
],
"remoteUser": "root",
"settings": {
"terminal.integrated.shell.linux": "/bin/bash"
},
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"charliermarsh.ruff",
"matangover.mypy",
"tamasfe.even-better-toml",
"redhat.vscode-yaml",
"eamodio.gitlens",
"streetsidesoftware.code-spell-checker"
]
}
},
"features": {}
}
16 changes: 11 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.15.0
rev: v1.16.0
hooks:
- id: mypy
additional_dependencies: [
Expand All @@ -21,7 +21,7 @@ repos:
- id: check-toml
- id: check-added-large-files
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.11.11
rev: v0.11.12
hooks:
- id: ruff
entry: ruff check --force-exclude --no-cache
Expand Down Expand Up @@ -49,8 +49,14 @@ repos:
types: [python]
pass_filenames: false # Run full test suite
stages: [pre-commit] # Only run on pre-commit


- repo: local
hooks:
- id: check-vscode-extension-sync
name: Check VSCode Extension Sync
entry: uv run --with-editable . scripts/check_extension_sync.py
language: system
types: [json]

# Global Exclusion
# If you want to exclude py_launch_blueprint/_version.py from all pre-commit hooks,
# you can use a global exclusion at the top level of your configuration:
Expand All @@ -62,7 +68,7 @@ repos:
# rev: v4.4.0
# hooks:
# - id: end-of-file-fixer

#
# Hook-Level Exclusion (Recommended Approach)
# For your specific case where the end-of-file-fixer hook is modifying
# py_launch_blue/print_version.py, the most targeted solution is to add an exclusion
Expand Down
4 changes: 4 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -628,5 +628,9 @@ clean-pr-to-testrepo new_repo_name="test-actions-repo":
# just build
# just run

# Check if VSCode recommended extensions are synced with devcontainer
check-extension-sync:
uv run --with-editable . 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) # type: ignore
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__":
main()
Loading