Pigweed IDE (pw_ide) Engineering Guidelines
This document provides foundational principles and technical requirements for AI agents contributing to pw_ide. This document extends the top-level GEMINI.md guidance with additional instructions more specific to the files contained under this subdirectory.
Core Principles
1. Single Responsibility & Conciseness
- Decompose Logic: Each function, class, or Bazel rule must have one clear responsibility. Decompose complex logic into small, reusable, and focused helper functions.
- Explicit over Clever: Prioritize readability and explicit intent over “magic” behavior. Use descriptive naming that explains what data represents, rather than its type.
- Pure Functions: Prefer extracting logic into pure functions with no side effects to simplify reasoning and testing.
2. Mandatory & Focused Testing
- No Unverified Changes: All new features, refactors, and bug fixes must include automated tests.
- Granular Tests: Each test case should verify a single, specific behavior. Use descriptive names that clearly state the test's intent.
- Tools:
- Python: Use
unittest with pyfakefs for robust filesystem mocking. - Starlark: Use
unittest.make for all Starlark logic verification.
Python Guidelines
1. Path Manipulation with pathlib
- Use
Path Objects: Use pathlib.Path exclusively for path operations. Avoid os.path and string-based path manipulation. - Maintain Type Integrity: Keep paths as
Path objects throughout the application logic. Convert to strings only at serialization boundaries or when required by external APIs. - Portability: Ensure paths in generated project files are relative to the workspace root, not absolute.
2. Pattern Matching with re
- Prefer Regex for Complexity: For all but the simplest string checks, use the
re package. Regular expressions yield faster and more concise code for complex pattern matching.
3. Error Handling
- Exceptions Over Return Codes: Raise descriptive exceptions to handle errors. Avoid returning
None or error codes, which clutter the “happy path” and are easily ignored.
Bazel & Starlark Guidelines
1. Performance & Efficiency
- Minimize Depset Conversions: Converting a
depset to a list (via .to_list()) is an $O(N)$ operation. Perform this conversion exactly once if needed, and never inside a loop. - $O(1)$ Lookups: Use dictionaries for mapping and filtering to avoid nested loops ($O(M \times N)$).
2. Safety & Correctness
- Explicit Copies: Use
dict() to create shallow copies of dictionaries to prevent shared state bugs. - No Recursion: Starlark does not support recursion; use iterative stacks or queues for graph traversal.
- Explicit Aspect Traversal: Be specific in
attr_aspects when writing aspects; avoid the ["*"] wildcard to prevent issues with internal Bazel dependencies.