.bashrsignore File Reference

The .bashrsignore file allows you to exclude specific files from linting, providing a proper way to handle false positives and intentional violations.

Overview

When bashrs lints a file, it first checks for a .bashrsignore file in the project hierarchy. If the file matches a pattern in .bashrsignore, it is skipped with a message explaining which pattern matched.

This is essential for:

  • Vendor scripts: Third-party scripts that shouldn't be modified
  • Metrics/telemetry: Scripts that intentionally use timestamps
  • Legacy code: Scripts with known issues being addressed separately
  • Generated files: Auto-generated scripts that will be regenerated

File Format

The .bashrsignore file uses gitignore-style syntax:

# .bashrsignore

# Comments start with #
# Empty lines are ignored

# Simple filename
record-metric.sh

# Glob patterns
vendor/*.sh
**/generated/*.sh

# Directory patterns
scripts/legacy/**

# Negation (re-include previously excluded)
!vendor/important.sh

Syntax Reference

PatternDescriptionExample
file.shExact filenameMatches file.sh
*.shWildcardMatches any .sh file
**/*.shRecursive wildcardMatches .sh files in any directory
dir/*Directory contentsMatches files in dir/
!patternNegationRe-includes previously excluded files
# commentCommentIgnored by parser

CLI Flags

--no-ignore

Disable .bashrsignore processing and lint all files:

 Lint even if file is in .bashrsignore
bashrs lint scripts/record-metric.sh --no-ignore

--ignore-file <FILE>

Use a custom ignore file instead of .bashrsignore:

 Use project-specific ignore file
bashrs lint script.sh --ignore-file .lint-ignore

 Use absolute path
bashrs lint script.sh --ignore-file /etc/bashrs/global-ignore

File Discovery

bashrs searches for .bashrsignore in the following order:

  1. Custom path (if --ignore-file specified)
  2. Same directory as the input file
  3. Parent directories (walking up to root)
  4. Current working directory

This allows project-level and repository-level ignore files.

Example: Metrics Recording Script

A common use case is excluding metrics recording scripts that intentionally use timestamps:

# .bashrsignore

# Metrics recording script from paiml-mcp-agent-toolkit
# Rationale: DET002 (timestamps) and SEC010 (paths) are false positives
# The script intentionally uses timestamps - that's its PURPOSE
scripts/record-metric.sh

Example: Vendor Directory

Exclude entire vendor directories while keeping specific important files:

# .bashrsignore

# Exclude all vendor scripts
vendor/**/*.sh

# But keep our customized installer
!vendor/custom-installer.sh

Example: Generated Files

Exclude auto-generated files that will be regenerated:

# .bashrsignore

# Generated by build process - will be regenerated
build/generated/**/*.sh
dist/**/*.sh

# Test fixtures (intentionally contain violations)
tests/fixtures/bad-*.sh

Best Practices

1. Document Rationale

Always include comments explaining WHY a file is excluded:

# .bashrsignore

# BAD: No explanation
scripts/deploy.sh

# GOOD: Clear rationale
# Legacy deployment script - DET002/SEC010 false positives
# Tracked in Issue #123 for proper refactoring
scripts/deploy.sh

2. Be Specific

Prefer specific patterns over broad ones:

# BAD: Too broad
*.sh

# GOOD: Specific exclusions
vendor/legacy/*.sh
scripts/record-metric.sh

3. Version Control

Always commit .bashrsignore to version control for audit trail:

git add .bashrsignore
git commit -m "Add .bashrsignore for metrics scripts (Issue #58)"

4. Review Periodically

Review .bashrsignore regularly to ensure exclusions are still needed:

 List all ignored files
cat .bashrsignore | grep -v '^#' | grep -v '^$'

Comparison with Inline Suppression

Feature.bashrsignoreInline Suppression
ScopeEntire fileSingle line/file
SyntaxGlob patterns# bashrs disable-*
Use caseVendor files, false positivesIntentional violations
VisibilityCentralizedIn-file

Use .bashrsignore when:

  • The entire file should be excluded
  • You cannot modify the file (vendor)
  • Multiple rules are violated

Use inline suppression when:

  • Only specific lines need suppression
  • You want documentation in-place
  • The file is under your control

Integration with CI/CD

Pre-commit Hook

# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: bashrs-lint
        name: bashrs lint
        entry: bashrs lint
        language: system
        files: \\.sh$
        # .bashrsignore is automatically respected

GitHub Actions

# .github/workflows/lint.yml
- name: Lint shell scripts
  run: |
    # .bashrsignore is automatically respected
    find . -name "*.sh" -exec bashrs lint {} \;

Troubleshooting

File not being ignored

  1. Check pattern syntax:

     Verify pattern
    cat .bashrsignore | grep "your-file"
    
  2. Check file location relative to .bashrsignore:

     .bashrsignore patterns are relative to its location
    ls -la .bashrsignore
    
  3. Use --no-ignore to verify the file has violations:

    bashrs lint file.sh --no-ignore
    

Pattern not matching

Test patterns with the glob crate's behavior:

 Exact match
scripts/record-metric.sh

 NOT: scripts/*/record-metric.sh (unless ** is used)
**/record-metric.sh