Metadata-Version: 2.4
Name: biocheck-cli
Version: 0.2.0
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Classifier: Intended Audience :: Science/Research
Classifier: Environment :: Console
License-File: LICENSE
Summary: Fast linter and auto-fixer for bioinformatics and genomics files
Keywords: bioinformatics,genomics,linter,vcf,fastq,fasta,bed
Author: BioCheck Contributors
License: MIT
Requires-Python: >=3.8
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://github.com/zh3li/BioCheck
Project-URL: Issues, https://github.com/zh3li/BioCheck/issues
Project-URL: Repository, https://github.com/zh3li/BioCheck

<div align="center">

# 🧬 BioCheck

**The `ruff` of Bioinformatics — Blazingly Fast Linter & Auto-Fixer for Genomics Files**

[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![PyPI](https://img.shields.io/pypi/v/biocheck-cli.svg)](https://pypi.org/project/biocheck-cli/)
![Platform: Linux | macOS | Windows](https://img.shields.io/badge/Platform-Linux%20%7C%20macOS%20%7C%20Windows-lightgrey.svg)

*Catch syntax errors, delimiter corruption, and chromosome mismatches in 0.1s before wasting an 8-hour Slurm job.*

</div>

---

## Why BioCheck?

Formatting errors are a notorious source of pipeline failures on HPC clusters:
* **Delimiter corruption:** A VCF, BED, or GTF file has spaces instead of tabs on line 14,200.
* **Chromosome style mismatch:** Reference index uses `chr1`, but your file uses `1`, resulting in zero matches.
* **FASTQ desynchronization:** Sequence length does not match quality string length (`len(seq) != len(qual)`).
* **Windows line endings:** Invisible carriage returns (`\r\n`) breaking Linux tools.
* **Inverted or negative coordinates:** 0-based vs 1-based bounds errors (`start > end` or `start < 0`).

Existing validators are fragmented across multiple programming languages, require complex compilation, and cannot fix anything.

BioCheck is a single standalone binary. It inspects files at high throughput, displays clear diagnostics with line pointers, and automatically repairs formatting errors with `biocheck fix`.

---

## Quick Start

BioCheck installs as a single standalone executable (`biocheck`) — no Python packages, Perl scripts, or shared libraries required at runtime.

### Option 1: Python / pip (Recommended)

Pre-compiled binary wheels are published to PyPI from release tags (Linux x86_64/aarch64, macOS, Windows) — zero compiler or Rust installation required:

```bash
pip install biocheck-cli

# Verify installation (installed command is 'biocheck')
biocheck --version
```

> *Note: The PyPI package is named `biocheck-cli` to distinguish it from an unrelated project on PyPI, but the command-line executable installed into your environment is `biocheck`.*

### Option 2: Standalone Binary (Direct Download)

For environments without Python, standalone binaries can be downloaded directly from [GitHub Releases](https://github.com/zh3li/BioCheck/releases):

```bash
# Linux (x86_64)
curl -L -o biocheck https://github.com/zh3li/BioCheck/releases/download/v0.2.0/biocheck-linux-x86_64
chmod +x biocheck
sudo mv biocheck /usr/local/bin/

# Verify installation
biocheck --version
```

### Option 3: Build from Source (macOS, Windows, or Linux)

If you have the Rust toolchain installed (Rust 1.85 or newer, required by edition 2024):

```bash
git clone https://github.com/zh3li/BioCheck.git
cd BioCheck
cargo build --release
# Executable is located at ./target/release/biocheck
```

---

## Platform Support

| Platform | `pip install biocheck-cli` | Standalone Binary | Source (`cargo build`) |
| :--- | :---: | :---: | :---: |
| **Linux (x86_64 / aarch64)** | Pre-compiled wheel (zero setup) | GitHub Releases | Supported |
| **macOS (Intel / Apple Silicon)** | Pre-compiled wheel | GitHub Releases | Supported |
| **Windows (x64)** | Pre-compiled wheel | GitHub Releases | Supported |

---

## CLI Usage

### 1. Check Files or Directories
BioCheck automatically detects file formats and transparently handles `.gz` / `.bgz` compressed files:

```bash
# Check a single file
biocheck check sample.vcf

# Check an entire directory
biocheck check data/
```

#### Diagnostic Output:
```text
error[VCF001]: Inconsistent delimiter: spaces detected instead of tab ('\t')
  --> data/cohort.vcf:142:5
      |
  142 | chr1    10050    rs123    A    G    .    PASS    DP=20
      |     ^^^^
      |
  = help: Run `biocheck fix <file>` to replace spaces with tabs

warning[VCF005]: Inconsistent chromosome naming convention
  --> data/cohort.vcf:305:1
      |
  305 | 1	15000	rs456	C	T	.	PASS	DP=18
      | ^^^^
      |
  = help: Run `biocheck fix --chr-style ucsc <file>` to standardize contig names

Checked 2 files: 1 error, 1 warning in 0.02s
```

---

### 2. Auto-Fix Formatting Errors (`biocheck fix`)

Unlike legacy validators that only complain and crash, BioCheck automatically repairs common formatting issues:

```bash
# Convert spaces to tabs and strip CRLF line endings
biocheck fix corrupted.vcf -o clean.vcf

# Standardize chromosome contigs (force UCSC 'chr1' or Ensembl '1')
biocheck fix sample.bed --chr-style ucsc -o clean.bed

# Coordinate-sort the file
biocheck fix unsorted.vcf --sort -o sorted.vcf

# Drop incomplete trailing reads from truncated FASTQ downloads
biocheck fix truncated.fastq -o fixed.fastq

# Clean and format FASTA sequence lines
biocheck fix genome.fasta --clean-fasta -o cleaned.fasta

# Modify in-place atomically
biocheck fix --in-place data/sample.vcf
```

---

### 3. Pipeline & CI/CD Integration

```bash
# Quiet mode: returns exit code (0 = clean, 1 = errors)
biocheck check -q input.fastq.gz

# Machine-readable JSON output
biocheck check --output-format json data/ > report.json

# Compact single-line output (IDE & editor friendly)
biocheck check --output-format compact data/
```

---

## Performance Comparison

Informal, single-machine measurements scanning a 3.2 GB Human Reference FASTA (`GRCh38.fa`); treat as indicative rather than authoritative:

| Tool | Language | Scan Time | Memory Usage | Auto-Fix? |
| :--- | :--- | :---: | :---: | :---: |
| **BioCheck** | **Rust** | **0.82s** | **18 MB** | **Yes (`biocheck fix`)** |
| SeqKit (`seqkit fq2fa`) | Go | 1.95s | 42 MB | No |
| BioPython (`SeqIO.parse`) | Python | 48.6s | 280 MB | No |
| Custom Python script | Python | 32.1s | 65 MB | No |

---

## Supported Formats & Rules

Run `biocheck rules` to inspect the rule index:

| Code | Format | Rule Description | Auto-Fixable? |
| :--- | :--- | :--- | :---: |
| `VCF001` | VCF | Inconsistent delimiter (spaces detected instead of tabs) | Yes |
| `VCF002` | VCF | Missing or malformed `#CHROM` header line | No |
| `VCF003` | VCF | Invalid 1-based coordinate (`POS <= 0`) | No |
| `VCF004` | VCF | Unsorted coordinates (POS regression or non-contiguous contig blocks) | Yes (`--sort`) |
| `VCF005` | VCF | Inconsistent chromosome naming (`chr1` vs `1` mixed) | Yes (`--chr-style`) |
| `VCF006` | VCF | Invalid REF allele (empty or non-IUPAC bases) | No |
| `VCF007` | VCF | Missing `##fileformat=VCFv4.x` declaration | No |
| `VCF008` | VCF | Record contains fewer than 8 mandatory fields | No |
| `VCF009` | VCF | Blank line inside VCF data section | Yes |
| `FQ001` | FASTQ | Line 1 of record does not start with `@` | No |
| `FQ002` | FASTQ | Line 3 of record does not start with `+` | No |
| `FQ003` | FASTQ | Sequence length and quality score string length mismatch | No |
| `FQ004` | FASTQ | Invalid nucleotide character in sequence | No |
| `FQ005` | FASTQ | Quality score byte outside standard Phred+33 range | No |
| `FQ006` | FASTQ | Truncated FASTQ record at EOF | Yes |
| `FA001` | FASTA | File does not begin with header `>` | No |
| `FA002` | FASTA | Empty sequence identifier on header line | No |
| `FA003` | FASTA | Duplicate sequence identifier found | No |
| `FA004` | FASTA | Empty sequence body | No |
| `FA005` | FASTA | Internal whitespace or tab in sequence | Yes (`--clean-fasta`) |
| `FA006` | FASTA | Invalid character in sequence | No |
| `BED001` | BED | Delimiter violation: spaces instead of tabs | Yes |
| `BED002` | BED | Fewer than 3 required columns (`chrom`, `start`, `end`) | No |
| `BED003` | BED | Non-integer coordinates | No |
| `BED004` | BED | Negative start coordinate (`start < 0`) | No |
| `BED005` | BED | Inverted interval (`start > end`; `start == end` is a valid zero-length feature) | No |
| `BED006` | BED | Inconsistent chromosome naming convention | Yes (`--chr-style`) |
| `BED007` | BED | Invalid strand character (must be `+`, `-`, or `.`) | No |
| `BED008` | BED | Unsorted BED records | Yes (`--sort`) |
| `GFF001` | GFF/GTF | Record does not have exactly 9 fields | No |
| `GFF002` | GFF/GTF | Delimiter violation: spaces instead of tabs | Yes |
| `GFF003` | GFF/GTF | Non-integer coordinates | No |
| `GFF004` | GFF/GTF | Start coordinate `< 1` (GFF is 1-based) | No |
| `GFF005` | GFF/GTF | Inverted interval (`start > end`) | No |
| `GFF006` | GFF/GTF | Invalid strand value (`+`, `-`, `.`, `?`) | No |
| `GFF007` | GFF/GTF | Invalid phase (`0`/`1`/`2` required for CDS, `.` otherwise) | No |
| `GFF008` | GFF/GTF | Inconsistent chromosome naming | Yes (`--chr-style`) |
| `SAM001` | SAM | Record has fewer than 11 mandatory fields | No |
| `SAM002` | SAM | Invalid FLAG value (not an integer in 0–65535, or reserved bits set) | No |
| `SAM003` | SAM | Non-integer POS coordinate | No |
| `SAM004` | SAM | SEQ and QUAL length mismatch | No |
| `SAM005` | SAM | Inconsistent chromosome naming in RNAME | No |
| `SAM006` | SAM | Invalid MAPQ value (must be 0–255) | No |
| `SAM007` | SAM | Invalid CIGAR string | No |
| `SAM008` | SAM | Invalid QUAL field (non-`*` while SEQ is `*`, or byte outside 33–126) | No |
| `SAM009` | SAM | Record order violates `@HD SO:coordinate` | No |
| `SAM010` | SAM | RNAME not declared in the `@SQ` header | No |
| `GLB001` | ALL | Windows CRLF (`\r\n`) line endings detected | Yes |
| `GLB002` | ALL | Failed to read file (I/O error or corrupt/truncated gzip) | No |
| `GLB003` | ALL | Invalid non-UTF-8 character detected | No |
| `GLB004` | ALL | Unknown or unsupported file format | No |

---

## Pre-Commit Hook Integration

Add BioCheck to your `.pre-commit-config.yaml` to prevent invalid files from being committed:

```yaml
repos:
  - repo: https://github.com/zh3li/BioCheck
    rev: v0.2.0
    hooks:
      - id: biocheck
```

---

## Nextflow Pre-Flight Recipe

Add BioCheck as a fast pre-flight validation step in Nextflow pipelines:

```groovy
process PREFLIGHT_CHECK {
    tag "$meta.id"
    
    input:
    tuple val(meta), path(reads)

    script:
    """
    biocheck check -q ${reads}
    """
}
```

---

## License

Licensed under the [MIT License](LICENSE).

