Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 48 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,33 @@

---

## Quickstart
## Install

Requires Python 3.9+.

### Recommended: uv (fast, isolated)

```bash
uv tool install outervoid-dat
```

### pipx (isolated CLI install)

```bash
pipx install outervoid-dat
```

### curl/wget bootstrap (uv → pipx → pip --user)

```bash
curl -fsSL https://raw.githubusercontent.com/Outer-Void/dat/main/install.sh | bash
```

```bash
wget -qO- https://raw.githubusercontent.com/Outer-Void/dat/main/install.sh | bash
```

> Need PDF output? Install with `outervoid-dat[pdf]` (e.g., `uv tool install "outervoid-dat[pdf]"`).

### From source (recommended while 3.x is in flux)

Expand Down Expand Up @@ -157,6 +183,27 @@ Repo link: **LRC — Local Repo Compiler** → [Outer-Void/lrc](https://github.c

---

## Build & Publish

```bash
python -m build
twine check dist/*
```

TestPyPI:

```bash
twine upload --repository-url https://test.pypi.org/legacy/ dist/*
```

PyPI:

```bash
twine upload dist/*
```

---

## Security & Telemetry

- No outbound connections; deterministic local outputs.
Expand All @@ -175,4 +222,3 @@ Repo link: **LRC — Local Repo Compiler** → [Outer-Void/lrc](https://github.c
## License

MIT — see [`LICENSE`](./LICENSE).

2 changes: 1 addition & 1 deletion dat
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import os
import sys
from pathlib import Path

MIN_PY = (3, 8)
MIN_PY = (3, 9)
if sys.version_info < MIN_PY:
raise SystemExit(f"DAT requires Python {MIN_PY[0]}.{MIN_PY[1]}+ (found {sys.version.split()[0]})")

Expand Down
69 changes: 69 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'

PKG_NAME="outervoid-dat"
EXTRAS="${DAT_EXTRAS:-}"

if [[ -n "$EXTRAS" ]]; then
PKG_SPEC="${PKG_NAME}[${EXTRAS}]"
else
PKG_SPEC="${PKG_NAME}"
fi

log() {
printf '%s\n' "$*" >&2
}

ensure_on_path() {
if command -v dat >/dev/null 2>&1; then
return 0
fi
log "⚠️ 'dat' not found on PATH. You may need to add ~/.local/bin or the pipx bin dir."
return 0
}

install_with_uv() {
log "→ Installing via uv tool install: ${PKG_SPEC}"
uv tool install "${PKG_SPEC}"
ensure_on_path
}

install_with_pipx() {
log "→ Installing via pipx: ${PKG_SPEC}"
pipx install "${PKG_SPEC}"
if command -v pipx >/dev/null 2>&1; then
pipx ensurepath >/dev/null 2>&1 || true
fi
ensure_on_path
}

install_with_pip() {
local python_bin="${1}"
log "→ Installing via pip --user: ${PKG_SPEC}"
"${python_bin}" -m pip install --user "${PKG_SPEC}"
ensure_on_path
}

main() {
if command -v uv >/dev/null 2>&1; then
install_with_uv
return 0
fi

if command -v pipx >/dev/null 2>&1; then
install_with_pipx
return 0
fi

local python_bin=""
python_bin="$(command -v python3 || command -v python || true)"
if [[ -z "$python_bin" ]]; then
log "❌ Python not found. Install Python 3.9+ and re-run."
exit 1
fi

install_with_pip "$python_bin"
}

main "$@"
10 changes: 5 additions & 5 deletions install_deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ detect_python() {
log_info "Detecting Python..."

# Try different Python commands in order of preference
for py_cmd in python3.11 python3.10 python3.9 python3.8 python3 python; do
for py_cmd in python3.12 python3.11 python3.10 python3.9 python3 python; do
if command -v "$py_cmd" >/dev/null 2>&1; then
# Check Python version
version=$("$py_cmd" -c "import sys; print(f'{sys.version_info.major}.{sys.version_info.minor}')" 2>/dev/null || echo "0.0")
Expand All @@ -52,18 +52,18 @@ detect_python() {
major=$(echo "$version" | cut -d. -f1)
minor=$(echo "$version" | cut -d. -f2)

if [[ $major -eq 3 ]] && [[ $minor -ge 8 ]]; then
if [[ $major -eq 3 ]] && [[ $minor -ge 9 ]]; then
log_success "Found Python $version using $py_cmd"
printf '%s\n' "$py_cmd"
return 0
else
log_warning "Python $version found but 3.8+ required"
log_warning "Python $version found but 3.9+ required"
fi
fi
done

log_error "No suitable Python 3.8+ installation found"
log_info "Please install Python 3.8 or newer from: https://python.org/downloads/"
log_error "No suitable Python 3.9+ installation found"
log_info "Please install Python 3.9 or newer from: https://python.org/downloads/"
return 1
}

Expand Down
5 changes: 3 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ authors = [
{name = "Outer Void Team, Justadudeinspace", email = "outervoid.blux@gmail.com"}
]
readme = "README.md"
license = {text = "MIT"}
license = "MIT"
license-files = ["LICENSE"]
keywords = ["security", "audit", "dependencies", "vulnerability", "scanner"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
Expand All @@ -28,6 +28,7 @@ dependencies = [
"pyyaml>=5.4.0",
"rich>=10.0.0",
"typer>=0.20.0",
"cryptography>=42.0.0",
]
requires-python = ">=3.9"

Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ packaging>=25.0
pyyaml>=6.0.3
rich>=14.2.0
typer>=0.20.0
cryptography>=42.0.0

# Optional: PDF reporting
# reportlab>=4.4.4
Expand Down
2 changes: 1 addition & 1 deletion scripts/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ bootstrap() {
# --- Python availability check ---
print_step "Checking Python installation..."
if ! command -v "$PYTHON_BIN" >/dev/null 2>&1; then
print_error "Python3 not found. Please install Python 3.8+ first."
print_error "Python3 not found. Please install Python 3.9+ first."

case "$PLATFORM" in
macOS)
Expand Down
2 changes: 1 addition & 1 deletion src/dat/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def repository_root(start: Path | None = None, marker: str = ".git") -> Path:
raise FileNotFoundError(f"No repository root found (looking for '{marker}' marker)")


def ensure_python_version(min_version: tuple[int, int] = (3, 8)) -> None:
def ensure_python_version(min_version: tuple[int, int] = (3, 9)) -> None:
"""
Ensure the current Python version meets minimum requirements.

Expand Down
18 changes: 16 additions & 2 deletions src/dat/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
)
from .integration.signing import sign_artifact
from .logging.audit import append_encrypted_log
from .pdf import write_pdf_report
from .report import (
build_metadata,
calculate_report_fingerprint,
Expand All @@ -52,6 +51,21 @@
no_args_is_help=False, help="DAT - Dev Audit Tool | Enterprise Security Scanning"
)


def _write_pdf_report(
path: Path, result: ScanResult, findings: Iterable[RuleFinding], metadata: dict
) -> None:
try:
from .pdf import write_pdf_report
except ModuleNotFoundError:
console.print(
"[red]PDF output requires ReportLab. Install with "
'`pip install "outervoid-dat[pdf]"`.[/red]'
)
raise typer.Exit(1) from None
write_pdf_report(path, result, findings, metadata)


# =============================================================================
# dat cmd — print main code files (incl. scripts) into a single Markdown file
# =============================================================================
Expand Down Expand Up @@ -740,7 +754,7 @@ def write_report_file(
atomic_write(path, ("\n".join(lines) + "\n").encode("utf-8"))
console.print(f"[green]✓ JSONL report saved:[/green] {path}")
elif format_type == "pdf":
write_pdf_report(path, result, findings, metadata)
_write_pdf_report(path, result, findings, metadata)
console.print(f"[green]✓ PDF report saved:[/green] {path}")
elif format_type in {"md", "markdown"}:
write_markdown_report(path, result, findings, metadata)
Expand Down
Loading