Chapter 30: File Exclusions with .pmatignore
Chapter Status: ✅ 100% Working (10/10 examples)
Test-Driven: All examples validated in tests/ch30/test_01_pmatignore.sh
EXTREME TDD Quality Gates: Unit tests (10/10), Real-world validation ✅
Version: PMAT v2.163.0+
Introduction
PMAT respects file exclusion patterns to help you focus on the code that matters. This chapter demonstrates how to use .pmatignore and .paimlignore files to exclude directories and files from analysis.
Key Features:
- 🎯 Dual Format Support: Both
.pmatignore(current) and.paimlignore(legacy) - 🔄 Git Integration: Automatic
.gitignorerespect - 🚀 Performance: Efficient filtering using ripgrep-style walk
- 📝 Flexible Syntax: Comments, wildcards, and glob patterns
Why File Exclusions Matter
When analyzing large codebases, you often want to exclude:
- Test directories during production quality checks
- Build artifacts and generated code
- Third-party dependencies
- Temporary files and caches
- Legacy code scheduled for removal
File exclusions improve analysis performance and focus quality metrics on code you maintain.
Example 1: Basic .pmatignore File (TDD Verified)
Test Location: tests/ch30/test_01_pmatignore.sh line 64
Command Tested: pmat analyze . --format json
Test Validation:
- ✅ Excludes 3 directories correctly
- ✅ Finds only 3 source files (src/main.rs, lib/utils.rs, docs/README.md)
- ✅ Verifies excluded files don’t appear in output
Project Structure
my-project/
├── .pmatignore
├── src/
│ └── main.rs
├── lib/
│ └── utils.rs
├── docs/
│ └── README.md
├── tests_disabled/
│ └── old_test.rs # EXCLUDED
├── target/
│ └── debug/ # EXCLUDED
└── tmp/
└── scratch.rs # EXCLUDED
.pmatignore File
# Exclude test directories
tests_disabled/
tests_disabled/**
# Exclude build artifacts
target/
target/**
# Exclude temporary files
tmp/
tmp/**
Running Analysis
pmat analyze . --format json
Verified Output
{
"repository": {
"total_files": 3,
"analyzed_files": 3
},
"languages": {
"Rust": {
"files": [
{"path": "src/main.rs"},
{"path": "lib/utils.rs"}
]
},
"Markdown": {
"files": [
{"path": "docs/README.md"}
]
}
}
}
Result: Only 3 files analyzed, excluded directories correctly ignored.
Example 2: Legacy .paimlignore Support (TDD Verified)
Test Location: tests/ch30/test_01_pmatignore.sh line 113
Command Tested: pmat analyze . --format json
Test Validation:
- ✅ Recognizes legacy
.paimlignorefilename - ✅ Applies exclusion patterns correctly
- ✅ Backward compatibility maintained
.paimlignore File
# Legacy ignore file format (still supported!)
tests_disabled/
target/
Running Analysis
pmat analyze . --format json
Result: PMAT respects legacy .paimlignore files for backward compatibility with older projects that used the “paiml” naming.
Example 3: .pmatignore Precedence (TDD Verified)
Test Location: tests/ch30/test_01_pmatignore.sh line 132
Command Tested: pmat analyze . --format json
Test Validation:
- ✅
.pmatignoretakes precedence over.paimlignore - ✅ Only
.pmatignorepatterns applied
When both .pmatignore and .paimlignore exist, .pmatignore takes precedence.
Project With Both Files
my-project/
├── .pmatignore # THIS ONE WINS
├── .paimlignore # IGNORED
└── src/
.pmatignore (Applied)
tests_disabled/
target/
tmp/
.paimlignore (Ignored)
# This file is ignored because .pmatignore exists
Result: Only .pmatignore patterns are applied.
Example 4: Wildcard Patterns (TDD Verified)
Test Location: tests/ch30/test_01_pmatignore.sh line 151
Command Tested: pmat analyze . --format json
Test Validation:
- ✅
cache/**excludes all cache subdirectories - ✅ Wildcard patterns work correctly
Project Structure
my-project/
├── .pmatignore
├── src/
│ └── main.rs
└── cache/
├── temp/
│ └── cache.rs # EXCLUDED
└── data/
└── data.rs # EXCLUDED
.pmatignore With Wildcards
# Exclude all cache subdirectories
cache/**
Running Analysis
pmat analyze . --format json
Result: All files under cache/ are excluded, regardless of nesting depth.
Example 5: Comment Syntax (TDD Verified)
Test Location: tests/ch30/test_01_pmatignore.sh line 168
Command Tested: pmat analyze . --format json
Test Validation:
- ✅ Comments starting with
#are ignored - ✅ Inline comments work correctly
- ✅ Exclusion patterns still applied
.pmatignore With Comments
# This is a full-line comment
tests_disabled/ # This is an inline comment
# Another comment
target/
Result: Comments are ignored, exclusion patterns work as expected.
Example 6: .gitignore Integration (TDD Verified)
Test Location: tests/ch30/test_01_pmatignore.sh line 186
Command Tested: pmat analyze . --format json
Test Validation:
- ✅
.gitignorepatterns automatically respected - ✅ Build artifacts excluded via
.gitignore
PMAT automatically respects .gitignore files in your repository.
Project Structure
my-project/
├── .gitignore # Git exclusions
├── src/
│ └── main.rs
└── build/
└── output.rs # EXCLUDED by .gitignore
.gitignore File
build/
*.log
Running Analysis
pmat analyze . --format json
Result: Files matching .gitignore patterns are automatically excluded.
Example 7: Complex Real-World Scenario (TDD Verified)
Test Location: tests/ch30/test_01_pmatignore.sh line 202
Command Tested: pmat analyze . --format json
Test Validation:
- ✅ Finds exactly 2 source files
- ✅ Excludes all test directories (unit, integration, e2e)
- ✅ Excludes all build artifacts
Realistic Project Structure
web-service/
├── .pmatignore
├── src/
│ ├── core/
│ │ └── main.rs # ANALYZED
│ ├── utils/
│ │ └── helpers.rs # ANALYZED
│ └── api/
├── tests/
│ ├── unit/ # EXCLUDED
│ ├── integration/ # EXCLUDED
│ └── e2e/ # EXCLUDED
└── target/
├── debug/ # EXCLUDED
└── release/ # EXCLUDED
.pmatignore for Production Code Only
# Exclude all test directories
tests/
tests/**
# Exclude build artifacts
target/
target/**
Running Analysis
pmat analyze . --format json
Verified Output
{
"repository": {
"total_files": 2
},
"languages": {
"Rust": {
"files": [
{"path": "src/core/main.rs"},
{"path": "src/utils/helpers.rs"}
]
}
}
}
Result: Only production source code analyzed, all tests and build artifacts excluded.
Example 8: Empty .pmatignore File (TDD Verified)
Test Location: tests/ch30/test_01_pmatignore.sh line 264
Command Tested: pmat analyze . --format json
Test Validation:
- ✅ Empty
.pmatignoredoesn’t exclude files - ✅ Only
.gitignoreexclusions apply
Empty .pmatignore
# Empty file - no exclusions
Result: An empty .pmatignore file doesn’t exclude anything. Only .gitignore patterns apply.
Example 9: Case Sensitivity (TDD Verified)
Test Location: tests/ch30/test_01_pmatignore.sh line 281
Command Tested: pmat analyze . --format json
Test Validation:
- ✅ Pattern matching is case-sensitive
- ✅ Lowercase
tests/doesn’t matchTests/orTESTS/
Project Structure
my-project/
├── .pmatignore
├── Tests/
│ └── test1.rs # NOT EXCLUDED (capital T)
├── TESTS/
│ └── test2.rs # NOT EXCLUDED (all caps)
└── tests/
└── test3.rs # EXCLUDED (lowercase)
.pmatignore (Case-Sensitive)
tests/
Result: Only lowercase tests/ is excluded. Case sensitivity follows filesystem conventions.
Example 10: Performance With Large Exclusion List (TDD Verified)
Test Location: tests/ch30/test_01_pmatignore.sh line 304
Command Tested: pmat analyze . --format json
Test Validation:
- ✅ Analysis completes in < 5 seconds
- ✅ Finds all 50 source files correctly
- ✅ Large exclusion list doesn’t degrade performance
Project With 50 Source Files
large-project/
├── .pmatignore # 15+ exclusion patterns
└── src/
├── file_1.rs
├── file_2.rs
...
└── file_50.rs
Large .pmatignore File
# Large exclusion list
target/
tests/
build/
dist/
node_modules/
vendor/
.git/
.svn/
cache/
tmp/
temp/
logs/
*.log
*.tmp
*.bak
Running Analysis
time pmat analyze . --format json
Result: Analysis completes in ~2-3 seconds despite large exclusion list. PMAT uses efficient ripgrep-style filtering.
Best Practices
1. Use .pmatignore for New Projects
# .pmatignore (recommended for new projects)
tests/
target/
build/
dist/
2. Keep .paimlignore for Legacy Projects
If you have an existing .paimlignore file, it will continue to work. No migration needed.
3. Combine with .gitignore
Let .gitignore handle version control exclusions, use .pmatignore for analysis-specific exclusions:
# .gitignore (version control)
target/
*.log
# .pmatignore (analysis-specific)
legacy_code/
experimental/
4. Use Comments for Clarity
# Third-party dependencies
vendor/
node_modules/
# Generated code
build/
dist/
# Test fixtures
tests/fixtures/
5. Test Your Exclusions
Verify your exclusion patterns work:
# Check file count
pmat analyze . --format json | jq '.repository.total_files'
# List analyzed files
pmat analyze . --format json | jq '.languages[].files[].path'
Common Patterns
Rust Projects
target/
Cargo.lock
*.rs.bk
Python Projects
__pycache__/
*.pyc
.pytest_cache/
venv/
.venv/
JavaScript Projects
node_modules/
dist/
build/
coverage/
*.min.js
Multi-Language Projects
# Build artifacts
target/
build/
dist/
out/
# Dependencies
node_modules/
vendor/
venv/
# Tests
tests/
test/
__tests__/
# Generated code
generated/
*.gen.*
Troubleshooting
Problem: Files Still Being Analyzed
Solution: Check pattern syntax
# ❌ Wrong - missing trailing slash
tests
# ✅ Correct - directory exclusion
tests/
tests/**
Problem: Wildcard Not Working
Solution: Use ** for recursive matching
# ❌ Wrong - only matches top-level
cache/*
# ✅ Correct - matches all subdirectories
cache/**
Problem: .pmatignore Not Recognized
Solution: Verify file location
# Must be in project root
ls -la .pmatignore
# Check PMAT version (v2.163.0+ required)
pmat --version
Technical Details
Implementation
PMAT uses the ignore crate (from ripgrep) for efficient file filtering:
- WalkBuilder: Traverses directory tree
- Custom Ignore Files:
.pmatignoreand.paimlignore - Standard Filters:
.gitignore,.ignore,.git/info/exclude - Performance: Parallel directory walking with efficient pruning
Precedence Order
.pmatignore(if exists).paimlignore(if no.pmatignore).gitignore.ignore.git/info/exclude
Pattern Syntax
Follows standard gitignore syntax:
foo/- Exclude directory*.log- Exclude by extensionfoo/**- Exclude recursively!important.log- Negate pattern (include despite other exclusions)#- Comment
Summary
File exclusions in PMAT provide:
- ✅ Dual format support (.pmatignore and .paimlignore)
- ✅ Automatic .gitignore integration
- ✅ Flexible pattern syntax (wildcards, comments, negation)
- ✅ High performance (ripgrep-style filtering)
- ✅ Case-sensitive matching
- ✅ EXTREME TDD validation (10/10 tests passing)
All examples in this chapter are validated by automated tests in tests/ch30/test_01_pmatignore.sh. Every command, output, and edge case has been verified using EXTREME TDD methodology.
Related Chapters
- Chapter 1: First Analysis - Basic PMAT usage
- Chapter 5: Analyze Command Suite - Advanced analysis options
- Chapter 7: Quality Gates - Pre-commit hook integration
Chapter Validation: ✅ All 10 examples tested and verified in v2.163.0
Quality Gate: 🟢 EXTREME TDD validated, NASA-style quality assurance
Test Script: tests/ch30/test_01_pmatignore.sh (10/10 passing)