Skip to content

feat(runtime): add Elixir provider #51

@CalvinAllen

Description

@CalvinAllen

Add Elixir runtime provider to dtvem for managing Elixir and Erlang/OTP versions.

Overview

Implement an Elixir provider that allows users to install, manage, and switch between Elixir versions using dtvem. Elixir requires Erlang/OTP as a dependency, so this provider must handle both runtimes.

Why Elixir Needs Version Management

  • Phoenix Framework: Different versions require different Elixir versions
  • OTP Compatibility: Elixir versions depend on specific Erlang/OTP versions
  • Production Parity: Match development versions to production servers
  • Library Dependencies: Hex packages may require specific Elixir versions
  • Breaking Changes: Language features change between versions
  • asdf Popularity: asdf is extremely popular in Elixir community for exactly this

Implementation Checklist

  • Create src/runtimes/elixir/provider.go
  • Implement all 19 Provider interface methods
  • Add init() function for auto-registration: runtime.Register(NewProvider())
  • Import in src/main.go: _ "github.com/CodingWithCalvin/dtvem/src/runtimes/elixir"
  • Update schemas/runtimes.schema.json to add "elixir" to runtime enum
  • Implement Shims() method to return: ["elixir", "elixirc", "mix", "iex"]
  • Implement ShouldReshimAfter() for mix escript.install commands
  • Handle Erlang/OTP dependency (either bundle or require separate erlang provider)
  • Add detection logic for existing Elixir installations (asdf, kiex, system)
  • Implement download/installation logic from official sources
  • Ensure cross-platform support (Windows, macOS, Linux)
  • Add tests using provider contract harness (internal/runtime/provider_test_harness.go)
  • Update documentation with Elixir examples

Version Sources

Download Sources by Platform

  • All Platforms: Elixir provides precompiled ZIP archives
    • Format: https://github.com/elixir-lang/elixir/releases/download/v{version}/elixir-otp-{otp}.zip
    • Example: https://github.com/elixir-lang/elixir/releases/download/v1.15.7/elixir-otp-26.zip
  • OTP Version: Must match installed Erlang/OTP version
    • Elixir 1.15 requires OTP 24, 25, or 26
    • Elixir 1.14 requires OTP 23, 24, or 25
    • Elixir 1.12 requires OTP 22, 23, or 24

Erlang/OTP Dependency Strategy

Option 1: Bundle Erlang with Elixir (Recommended for v1)

  • Download both Erlang and Elixir for each version
  • Install to ~/.dtvem/versions/elixir/{version}/erlang/ and ~/.dtvem/versions/elixir/{version}/elixir/
  • Set ERTS environment variable to point to bundled Erlang
  • Pros: Guaranteed compatibility, simpler for users
  • Cons: Larger downloads, duplicate Erlang installations

Option 2: Separate Erlang Provider (Future)

  • Create separate erlang provider
  • Elixir provider checks for compatible Erlang version
  • Prompt user to install compatible Erlang if missing
  • Pros: No duplication if user works with Erlang directly
  • Cons: More complex, dependency management

Recommendation: Start with Option 1, add Option 2 later if needed.

Migration Sources

Detect and migrate from:

  • asdf: ~/.asdf/installs/elixir/
  • kiex: ~/.kiex/elixirs/
  • System installations:
    • Windows: Chocolatey installations
    • macOS: Homebrew installations
    • Linux: Package manager installations

Global Package Preservation

During migration, detect and preserve globally installed Mix packages:

  • Detection: mix archive and mix escript from old installation
  • Archives: ~/.mix/archives/
  • Escripts: ~/.mix/escripts/
  • Reinstall: May need to reinstall archives/escripts for new version

Shims to Create

  • elixir - Elixir runtime
  • elixirc - Elixir compiler
  • mix - Build tool and task runner (trigger reshim on escript.install)
  • iex - Interactive Elixir shell

Automatic Reshim Detection

Implement ShouldReshimAfter() to trigger reshim on:

  • mix escript.install - Installs executable scripts
  • mix escript.uninstall - Removes executable scripts
  • Escripts are installed to ~/.mix/escripts/ and are standalone executables

Cross-Platform Considerations

  • Windows:
    • Precompiled ZIP with .bat files
    • May need Erlang Windows installer
    • PATH setup more complex
  • macOS/Linux:
    • Precompiled ZIP with shell scripts
    • May need to compile Erlang from source (or use prebuilt)
  • Erlang Dependencies:
    • Erlang requires various libraries (OpenSSL, ncurses, etc.)
    • May need to document dependency installation

Elixir-OTP Compatibility Matrix

Elixir Version Required OTP Versions
1.16.x 24, 25, 26
1.15.x 24, 25, 26
1.14.x 23, 24, 25
1.13.x 22, 23, 24, 25
1.12.x 22, 23, 24

Testing Requirements

  • Use provider contract harness in runtimes/elixir/provider_test.go
  • Test all 19 interface methods
  • Test version detection from asdf/kiex
  • Test installation on all platforms
  • Test shim creation and execution
  • Test Erlang/OTP bundling or detection
  • Test automatic reshim detection for mix escript.install

Special Considerations

  • Erlang Dependency: Most complex aspect - must ensure compatible Erlang
  • OTP Version: Elixir releases are tagged with compatible OTP versions
    • elixir-otp-26.zip means built for OTP 26
    • Download appropriate version based on installed/bundled Erlang
  • Mix Hex: Package manager (like npm for Node)
    • Packages stored in ~/.hex/
    • Should work across Elixir versions
  • Mix Escript: Executable scripts (like npm global installs)
    • Need reshim detection for these
  • Phoenix Framework: Popular web framework
    • mix phx.new generates projects
    • Archive installed via mix archive.install hex phx_new

Configuration Files

  • Mix config: ~/.mix/ (shared across versions)
  • Hex config: ~/.hex/ (shared across versions)
  • Mix archives: ~/.mix/archives/ (may be version-specific)

Integration with Development Workflows

  • Phoenix LiveView: Hot code reloading depends on Elixir version
  • Umbrella Projects: Multiple apps in one repo, all use same Elixir version
  • CI/CD: Pin both Elixir and Erlang versions for reproducibility

Erlang/OTP Provider (Future)

If we add a standalone erlang provider:

  • Shims: erl, erlc, escript
  • Version sources: https://erlang.org/download/
  • Installation: Prebuilt packages or compile from source
  • Used by: RabbitMQ, CouchDB, ejabberd (not just Elixir)

References

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestproviderRuntime provider implementation

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions