mirror of
https://github.com/home-assistant/core.git
synced 2026-05-08 17:49:37 +01:00
125 lines
3.6 KiB
Python
Executable File
125 lines
3.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Generate .github/copilot-instructions.md from AGENTS.md and skills.
|
|
|
|
Necessary until copilot can handle skills.
|
|
"""
|
|
|
|
from pathlib import Path
|
|
import sys
|
|
|
|
GENERATED_MESSAGE = (
|
|
f"<!-- Automatically generated by {Path(__file__).name}, do not edit -->\n\n"
|
|
)
|
|
|
|
AGENTS_FILE = Path("AGENTS.md")
|
|
OUTPUT_FILE = Path(".github/copilot-instructions.md")
|
|
INTEGRATION_SKILL_FILE = Path(".claude/skills/ha-integration-knowledge/SKILL.md")
|
|
INTEGRATION_PATH_SPECIFIC_OUTPUT_FILE = Path(
|
|
".github/instructions/integrations.instructions.md"
|
|
)
|
|
|
|
COPILOT_SPECIFIC_INSTRUCTIONS = """
|
|
# Copilot code review instructions
|
|
|
|
- Start review comments with a short, one-sentence summary of the suggested fix.
|
|
- Do not comment on code style, formatting or linting issues.
|
|
- A Pull Request with a dependency version bump should only contain changes required for the version bump. If the PR includes other changes, request that they are removed from the PR.
|
|
"""
|
|
|
|
INTEGRATION_PATH_SPECIFIC_INSTRUCTIONS = """---
|
|
applyTo: "homeassistant/components/**, tests/components/**"
|
|
excludeAgent: "cloud-agent"
|
|
---
|
|
"""
|
|
|
|
|
|
def _strip_frontmatter(text: str) -> str:
|
|
"""Strip YAML frontmatter from the start of a markdown document."""
|
|
if not text.startswith("---\n"):
|
|
return text
|
|
|
|
end = text.find("\n---\n", 4)
|
|
if end == -1:
|
|
return text
|
|
|
|
return text[end + len("\n---\n") :].lstrip("\n")
|
|
|
|
|
|
def generate_integration_path_specific_instructions() -> str:
|
|
"""Generate instructions for integration paths."""
|
|
if not INTEGRATION_SKILL_FILE.exists():
|
|
print(f"Error: {INTEGRATION_SKILL_FILE} not found")
|
|
sys.exit(1)
|
|
|
|
skill_content = _strip_frontmatter(INTEGRATION_SKILL_FILE.read_text())
|
|
|
|
return (
|
|
INTEGRATION_PATH_SPECIFIC_INSTRUCTIONS
|
|
+ "\n"
|
|
+ GENERATED_MESSAGE
|
|
+ "\n"
|
|
+ skill_content
|
|
)
|
|
|
|
|
|
def generate_output() -> str:
|
|
"""Generate the copilot-instructions.md content."""
|
|
if not AGENTS_FILE.exists():
|
|
print(f"Error: {AGENTS_FILE} not found")
|
|
sys.exit(1)
|
|
|
|
output_parts: list[str] = [GENERATED_MESSAGE, COPILOT_SPECIFIC_INSTRUCTIONS]
|
|
|
|
# Add AGENTS.md content
|
|
agents_content = AGENTS_FILE.read_text()
|
|
output_parts.append(agents_content.strip())
|
|
output_parts.append("")
|
|
|
|
return "\n".join(output_parts)
|
|
|
|
|
|
def check_file(path: Path, expected_content: str):
|
|
"""Check if the file exists and has the expected content."""
|
|
if not path.exists():
|
|
print(f"Error: {path} does not exist")
|
|
sys.exit(1)
|
|
|
|
existing = path.read_text()
|
|
if existing != expected_content:
|
|
print(f"Error: {path} is out of date")
|
|
print("Please run: python -m script.gen_copilot_instructions")
|
|
sys.exit(1)
|
|
|
|
print(f"{path} is up to date")
|
|
|
|
|
|
def main(validate: bool = False) -> int:
|
|
"""Run the script."""
|
|
if not Path("homeassistant").is_dir():
|
|
print("Run this from HA root dir")
|
|
return 1
|
|
|
|
main_content = generate_output()
|
|
integration_path_specific_content = (
|
|
generate_integration_path_specific_instructions()
|
|
)
|
|
|
|
if validate:
|
|
check_file(OUTPUT_FILE, main_content)
|
|
check_file(
|
|
INTEGRATION_PATH_SPECIFIC_OUTPUT_FILE, integration_path_specific_content
|
|
)
|
|
return 0
|
|
|
|
OUTPUT_FILE.write_text(main_content)
|
|
print(f"Generated {OUTPUT_FILE}")
|
|
|
|
INTEGRATION_PATH_SPECIFIC_OUTPUT_FILE.write_text(integration_path_specific_content)
|
|
print(f"Generated {INTEGRATION_PATH_SPECIFIC_OUTPUT_FILE}")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
_validate = len(sys.argv) > 1 and sys.argv[1] == "validate"
|
|
sys.exit(main(_validate))
|