MixGleam

repository·main·Indexed 42 days ago

https://github.com/gleam-lang/mix_gleam

An Elixir archive that integrates the Gleam compiler and dependency management into the Elixir Mix build tool. It allows developers to work with both Elixir and Gleam code in the same project, providing tasks such as `mix compile.gleam`, `mix gleam.deps.get`, and `mix gleam.test` for running tests with gleeunit.

Tokens
2.9K
Snippets
17
Records
19
Agent score
53%

What's inside MixGleam

  1. Set up Gleam dependencies and directory structure

    main

    After configuring mix.exs, follow these steps to prepare your project for Gleam code:

    1. Add Gleam dependencies: Add gleam_stdlib and gleeunit to your deps function in mix.exs.
    2. Create source directory: Create a src directory for your Gleam files.
    3. Update .gitignore: Add the build directory to your .gitignore to prevent Gleam build artefacts from being committed.

    Dependency Configuration Example

    # in mix.exs
    # ...
      defp deps do
        [
          # ...
          {:gleam_stdlib, "~> 0.34 or ~> 1.0"},
          {:gleeunit, "~> 1.0", only: [:dev, :test], runtime: false},
          # ...
        ]
      end

    Directory Setup

    $ mkdir src
  2. Configure mix.exs to use MixGleam

    main

    To enable Gleam support in your Elixir project, update your mix.exs file with the following configuration. This allows Mix to use the Gleam compiler and manage Gleam dependencies.

    Required Configuration

    Add mix_gleam to your archives, add :gleam to your compilers, and update your aliases to include gleam.deps.get.

    Note on erlc_paths:

    • For Gleam < v0.25.0, include "build/dev/erlang/#{@app}/build".
    • For Gleam >= v0.25.0, use "build/dev/erlang/#{@app}/_gleam_artefacts".

    Note on prune_code_paths:

    • For Elixir >= v1.15.0, you must set prune_code_paths: false in your project function.

    Full Example Configuration

    # in mix.exs
    # ...
      @app :my_gleam_app
    
      def project do
        [
          app: @app,
          # ...
          archives: [mix_gleam: "~> 0.6"],
          compilers: [:gleam | Mix.compilers()],
          aliases: [
            # Or add this to your aliases function
            "deps.get": ["deps.get", "gleam.deps.get"]
          ],
          erlc_paths: [
            "build/dev/erlang/#{@app}/_gleam_artefacts",
            # For Gleam < v0.25.0
            "build/dev/erlang/#{@app}/build"
          ],
          erlc_include_path: "build/dev/erlang/#{@app}/include",
          # For Elixir >= v1.15.0
          prune_code_paths: false,
          # ...
        ]
      end
    # ...
    # in mix.exs
    # ...
      @app :my_gleam_app
    
      def project do
        [
          app: @app,
          # ...
          archives: [mix_gleam: "~> 0.6"],
          compilers: [:gleam | Mix.compilers()],
          aliases: [
            # Or add this to your aliases function
            "deps.get": ["deps.get", "gleam.deps.get"]
          ],
          erlc_paths: [
            "build/dev/erlang/#{@app}/_gleam_artefacts",
            # For Gleam < v0.25.0
            "build/dev/erlang/#{@app}/build"
          ],
          erlc_include_path: "build/dev/erlang/#{@app}/include",
          # For Elixir >= v1.15.0
          prune_code_paths: false,
          # ...
        ]
      end
    # ...
  3. Install MixGleam archive

    main

    To use Gleam within an Elixir project, you must first install the Gleam compiler on your machine and then install the MixGleam archive via Hex.

    Install from Hex

    mix archive.install hex mix_gleam

    Install from source

    If you need to install or update from the source repository:

    mix archive.uninstall mix_gleam
    git clone https://github.com/gleam-lang/mix_gleam.git
    cd mix_gleam
    MIX_ENV=prod mix do archive.build, archive.install
    mix archive.install hex mix_gleam
  4. Configure Gleam dependencies to be fetched via mix.exs

    main

    To ensure that Gleam subdependencies are correctly fetched and prepared for compilation from Gleam into Erlang, you should extend the standard deps.get task. This is done by adding an alias to your project's mix.exs file so that running mix deps.get automatically triggers gleam.deps.get.

    This task recursively ensures all subdependencies are fetched before Mix begins its own compilation process.

    def project do
      [
        aliases: ["deps.get": ["deps.get", "gleam.deps.get"]],
      ]
    end
  5. Create a new Gleam project

    main

    The mix gleam.new task is currently unimplemented. To start a new Gleam project, you should use the standard Elixir mix new command and then manually configure your mix.exs file using the template provided by mix_gleam.

    When implemented, the command will follow this signature:

    mix gleam.new PATH [--app APP] [--module MODULE] [--sup] [--umbrella]

    Arguments and flags:

    • PATH: The path where the project will be created.
    • --app APP: Specifies the application name (defaults to the path name).
    • --module MODULE: Specifies the module name (defaults to the path name).
    • --sup: Enables a supervision tree.
    • --umbrella: Creates an umbrella project.
    mix new my_gleam_app
    # Then manually update mix.exs with MixGleam configuration
  6. Configure a Mix project for Gleam

    main

    To use Gleam within an Elixir project, your mix.exs file must be configured to include the :gleam compiler and set specific Erlang paths where Gleam artefacts are located.

    Key configuration requirements:

    • Compilers: Add :gleam to the compilers list.
    • Erlang Paths: Include build/dev/erlang/[your_app]/_gleam_artefacts in erlc_paths.
    • Legacy Gleam Support: For Gleam versions < v0.25.0, you must also include build/dev/erlang/[your_app]/build in erlc_paths.
    • Prune Code Paths: For Elixir versions >= v1.15.0, set prune_code_paths: false in the project configuration.
    • Aliases: It is recommended to add "deps.get": ["deps.get", "gleam.deps.get"] to your aliases to ensure Gleam dependencies are fetched alongside Elixir dependencies.
    defmodule YourApp.MixProject do
      use Mix.Project
    
      @app :your_app
      @version "0.1.0"
    
      def project do
        [
          app: @app,
          version: @version,
          elixir: "~> 1.15",
          name: "#{@app}",
          archives: [mix_gleam: "~> 0.6.2"],
          compilers: [:gleam] ++ Mix.compilers(),
          aliases: [
            "deps.get": ["deps.get", "gleam.deps.get"]
          ],
          erlc_paths: [
            "build/dev/erlang/#{@app}/_gleam_artefacts",
            # For Gleam < v0.25.0
            "build/dev/erlang/#{@app}/build"
          ],
          erlc_include_path: "build/dev/erlang/#{@app}/include",
          # For Elixir >= v1.15.0
          prune_code_paths: false,
          start_permanent: Mix.env() == :prod,
          deps: deps()
        ]
      end
    
      def application do
        [extra_applications: [:logger]]
      end
    
      defp deps do
        [
          {:gleam_stdlib, "~> 0.32"}
        ]
      end
    end
  7. Configure gleeunit dependency for Gleam tests

    main

    To enable Gleam testing via mix gleam.test, add gleeunit to your mix.exs dependencies. It is recommended to restrict it to :dev and :test environments and set runtime: false to avoid including it in production builds.

    defp deps() do
      [
        {:gleeunit, "~> 0.5", only: [:dev, :test], runtime: false}
      ]
    end
  8. Add Gleam compilation to your Mix project

    main

    To enable Gleam compilation within your Elixir Mix project, add :gleam to the compilers list in your mix.exs file. This ensures that Gleam source files are compiled into Erlang before Mix's standard compilation process.

    def project do
      [
        compilers: [:gleam] ++ Mix.compilers(),
      ]
    end
  9. Get a `mix.exs` template for Gleam projects

    main

    Since mix gleam.new is not yet functional, you can use the retro flag (or follow the help output) to print a template for a mix.exs file that is compatible with Gleam. This template shows how to integrate MixGleam into your Elixir project configuration.

    mix gleam.new PATH --retro