All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[1.5.0] - 2026-05-19

Changed

  • Development versions upgraded: Erlang 28.1 + Elixir 1.19.5 (OTP 28)
    • Internal development now uses latest stable OTP/Elixir
    • Minimum packagable OTP remains at 25 (ERTS repository unchanged)
    • Minimum OTP to run mix batamanta remains at 25
  • CI matrix updated: Elixir 1.15.8/OTP 26.2.5 + Elixir 1.19.5/OTP 28.1
  • CI caching: Mix and Cargo dependency caching added for faster runs
  • CI artifacts: Built binaries are now uploaded as artifacts for debugging
  • CI cleanup: Simplified cleanup step — only clears ERTS cache, not project build artifacts

Fixed

  • Escript wrapper args (critical): Arguments wrapped by the shell wrapper script no longer carry literal double-quote characters. \"$arg\" in the wrapper injected "status" (with literal quotes) instead of status. Replaced with shift/set -- pattern using "$@" — fixes all CLI subcommands in escript-mode binaries.
  • Release daemon args: Missing -extra -- separator before user arguments in the daemon spawn path caused erlexec to interpret user args as its own flags. Added -extra -- before forwarding, matching the non-daemon path.
  • Unless-else style: Three unless condition do :ok else ... end blocks in EscriptPackager inverted to if condition do ... else :ok end (Credo compliance).
  • LibcDetector: ldd --version detection now works on CachyOS and other rolling-release distributions (OTP 28 handles edge cases gracefully)
  • RustTemplate: Removed stale P1 FIX markers; build.rs now panics with a clear error if the payload is missing instead of silently skipping
  • mix.exs: Removed stale P2 FIX comment about rust.test alias (implementation was already correct)
  • ex_doc: Updated from ~> 0.34 to ~> 0.40

Quality

  • Format: ✅ clean
  • Credo --strict: ✅ 0 issues (340 mods/funs)
  • Compile --warnings-as-errors: ✅ 0 warnings
  • Tests: 199 passing, 3 excluded (integration)

[1.4.0] - 2026-04-07

Added

  • Build Environment Isolation: Introduced Batamanta.EnvCleaner to isolate the build process from version managers (asdf, mise, kerl, etc.). This ensures that the Erlang/Elixir version used for compilation matches the target ERTS, preventing "corrupt atom table" errors.
  • Shared Environment Logic: Both Escript and Release pipelines now share a sanitized environment containing only essential system variables (HOME, USER, TMPDIR, LANG, SHELL, TERM, SSH_AUTH_SOCK).
  • Detailed Build Logs: Improved error reporting for mix release failures by capturing and displaying the full compiler output in case of status non-zero.

Fixed

  • Version Manager Interference: Fixed a critical bug where asdf shims in the PATH would cause mix to use a different ERTS version than the one intended for packaging.
  • Legacy Elixir Compatibility: Replaced File.executable?/1 (introduced in Elixir 1.16) with File.regular?/1 to maintain compatibility with Elixir 1.15.x.
  • Typo cleanup: Corrected multiple instances of BatmanManta namespace typos to Batamanta.
  • Credo & Code Quality: Refactored system_paths/0 in EnvCleaner to reduce cyclomatic complexity and flattened nested logic in clean_mix_build_artifacts.

[1.3.0] - 2026-03-25

Added

  • Temporary Files Cleanup: Batamanta now automatically cleans up internal temporary artifacts (bat_cargo_cache, bat_pkg_*, bat_build_*) after each compilation to keep /tmp empty while strictly preserving the ERTS cache.

Fixed

  • Daemon Initialization Crash (Crítical / undef): Reimplemented the spawn_detached hook in Rust to fully inherit the parent environment (std::env::vars()) and properly map argv[0]. Fixing an elusive bug where the BEAM VM crashed on spawn in Daemon mode due to a missing environment block.
  • Daemon Logging Isolation: spawn_detached no longer strictly forces a dup2 redirect to /dev/null for standard file descriptors, allowing application logs to correctly print to the terminal prior to background detachment. Perfectly compatible with CI Smoke Tests.
  • Dialyzer & Compiler Specs: Resolved compiler typing violations related to {error, _} on detect_host in Target and removed unused legacy branches.
  • Cleaned Test Coverage: Updated multiple test namespaces (Baton -> Batamanta) and expanded coverage for internal functions.

[1.2.1] - 2026-03-23

Fixed

  • Execution Mode vs Format Nomenclature: Corrected confusing naming - renamed execution_mode to format in configuration and documentation
  • Daemon Mode macOS Support: Fixed daemon spawning to work on both Linux and macOS (uses fork() + setsid() via libc)
  • Banner Positioning: Improved banner display to work consistently whether terminal is fresh or has existing output

[1.2.0] - 2026-03-23

Added

  • Escript Support: New format: :escript option to build lightweight escripts instead of full OTP releases
  • Auto-detection: Automatically detects escript format when project has :escript config in mix.exs
  • CLI Override: --format option to override format detection from command line
  • Dynamic Version Detection: Fixed hardcoded version 0.1.0 in Rust wrapper, now reads version from start_erl.data
  • Smoke Tests: Added test_escript smoke test project for escript builds
  • Retry Logic for Downloads: ERTS downloads now retry up to 3 times with exponential backoff (1s, 2s, 4s) on network failures
  • Cache Lock Mechanism: File-based locking prevents race conditions when multiple processes try to download ERTS simultaneously
  • Improved Tar Error Parsing: Extract-specific error messages for tar failures (permission denied, disk full, corrupted archive, etc.)
  • zstd Dependency Check: Packager now raises a clear error with installation instructions if zstd is not found
  • Integration Tests: New FetcherIntegrationTest module for tests requiring network access (excluded by default, run with mix test --include integration)

Changed

  • Compilation Without --warnings-as-errors: EscriptBuilder no longer fails on compiler warnings, improving build reliability across different OTP versions
  • EscriptBuilder Validation: Improved escript validation using File.read/1 with proper ELF/shebang magic byte detection
  • LibcDetector Refactoring: Consolidated regex patterns for OS detection, renamed is_musl_distro? to musl_distro? for Credo compliance
  • Smaller Binaries: Escript format produces ~60-70% smaller binaries than release format
  • EscriptPackager: New module for packaging escripts with minimal ERTS
  • EscriptBuilder: New module for building escripts via mix escript.build
  • Rust Template: Updated to support both :release and :escript output formats via BATAMANTA_FORMAT env var
  • Banner Positioning: Improved banner display to work consistently whether terminal is fresh or has existing output

Fixed

  • Cache Race Conditions: TOCTOU race condition in check_erts_cache now protected by file locks
  • Tar Error Messages: Better error messages when tar extraction fails, including "Permission denied", "Disk full", etc.
  • Download Retry Pattern: Fixed pattern matching to handle both :ok (file downloads) and {:ok, body} (manifest downloads) return values
  • Version Detection: Release version is now dynamically detected from releases/start_erl.data instead of being hardcoded

[1.1.0] - 2026-03-19

Added

  • OTP Version Control: Users can specify exact OTP versions in config (otp_version: "28.1") or via CLI (--otp-version)
  • Explicit vs Auto Mode: Explicit mode uses exact version (fails if unavailable), auto mode uses conservative fallback
  • Smoke Tests: Added test_cli, test_tui, and test_daemon smoke test projects
  • CI Matrix: Comprehensive CI with tests on Elixir 1.15/1.18 and OTP 25/28

Fixed

  • MANIFEST JSON Parser: Rewrote broken parser that incorrectly handled nested JSON structures
  • Release Path: Fixed get_release_path/1 to correctly use _build/prod/rel/<app>
  • Duplicate Logging: Removed duplicate ERTS cached messages during build
  • Version Resolution: Improved generate_version_variants/1 with proper fallbacks
  • TUI Key Handling: Fixed crash when pressing keys (handles <<key, "\n">> pattern)
  • Application Start: Fixed Application behaviour to return proper {:ok, pid} tuple

Changed

  • generate_version_variants/1 refactored to reduce nesting depth (Credo compliance)
  • CI simplified to focus on reliable tests (removed problematic macOS ARM64 cross-compile)

[1.0.1] - 2026-03-09

Fixed

  • Linux auto-detection: Automatically detects between glibc and musl based on distribution
  • Arch Linux support: Fixed compilation on Arch-based distributions (CachyOS, Manjaro, etc.)
  • Terminal cleanup: Improved ANSI sequence cleanup on exit
  • ERTS embedded: Now uses the ERTS embedded in the release instead of downloading external one, fixing "Exec format error"

Changed

  • Default Linux target changed from musl to gnu for better compatibility
  • Uses ctrlc instead of signal-hook for better cross-platform support

[1.0.0] - 2026-03-08

Added

  • Monolithic Binary Generation: Core capability to wrap Elixir releases and the Erlang Runtime System (ERTS) into a single, static executable.
  • Dynamic ERTS Management: Automatically fetches and caches compatible ERTS versions from Hex.pm or Beam Machine based on the target system.
  • Cross-Platform Support: Built-in support for multiple targets including x86_64-linux-musl, x86_64-pc-windows-msvc, x86_64-apple-darwin, and aarch64-apple-darwin.
  • Rust-powered Dispenser: A high-performance Rust wrapper that handles payload extraction, signal proxying, and secure execution.
  • Static Compilation: Generates binaries with zero external dependencies (no Erlang or Elixir needed on the target host).
  • Binary Minification: Integrated support for strip and upx to significantly reduce the final executable size.
  • Smart Native Fallback: Intelligent detection to use the local native ERTS when building for the same host OS to ensure perfect compatibility.
  • Clean Task: Provided mix batamanta.clean to manage and clear the local ERTS cache.
  • CLI Arg Handling: Support for passing plain arguments directly to the Erlang VM for portable CLI tools.
  • RAII Cleanup: Support for automatically removing temporary extraction files when the application exits.

Improved

  • Idiomatic Refactor: Completely refactored the codebase to use modern Elixir patterns (pipelines, pattern matching, with statements).
  • Documentation: Comprehensive documentation in both English (primary) and Spanish, including detailed architecture guides and usage examples.
  • Error Handling: Migrated to result-tuple based error propagation ({:ok, term} | {:error, reason}) for more reliable orchestration.

  • Unit Testing: Full test suite covering target resolution, packaging logic, and cache management.
  • CI/CD Integration: Pre-configured GitHub Actions to validate compatibility across multiple Elixir and OTP versions.