Skip to content

Commit

Permalink
fix: better elixir docs and defaults (#1207)
Browse files Browse the repository at this point in the history
* docs: improve elixir build documentation

* fix: better elixir defaults, missing packages

* lint fix

* update elixir snapshot tests

* fix: revert ecto.setup change

* fix: wrong location for reverted logic

* fix: one more time :/

* fix: adding ecto setup back in

* style: docs lint fix

---------

Co-authored-by: Jake Runzer <[email protected]>
  • Loading branch information
iloveitaly and coffee-cup authored Nov 15, 2024
1 parent f3989cd commit cc3e10c
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 17 deletions.
29 changes: 26 additions & 3 deletions docs/pages/docs/providers/elixir.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,27 @@ Elixir is detected if a `mix.exs` file is found.
The following Elixir versions are available

- `latest` (Default)
- `1.17`
- `1.16`
- `1.15`
- `1.14`
- `1.13`
- `1.12`
- `1.11`
- `1.10`
- `1.9`

The version can be overridden by

- Elixir version is extracted from the `mix.exs` file automatically
- Setting the `NIXPACKS_ELIXIR_VERSION` environment variable
- Setting the version in a `.elixir-version` file

```
The OTP version is automatically set and cannot currently be customized.

The default install script is:

```shell
MIX_ENV=prod

mix local.hex --force
Expand All @@ -31,13 +41,26 @@ mix deps.get --only prod

## Build

```
```shell
mix compile
mix assets.deploy
mix ecto.deploy # if available
```

If you are building outside of a live environment, you may want to omit `ecto.deploy` (which can sometimes rely on a
database connection) which you can do by overriding the build command.

## Start

```
```shell
mix phx.server
```

## Environment Variables

The following environment variables are set by default:

```shell
MIX_ENV=prod
ELIXIR_ERL_OPTIONS="+fnu"
```
53 changes: 41 additions & 12 deletions src/providers/elixir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::nixpacks::{
use anyhow::Result;
use regex::{Match, Regex};
const DEFAULT_ELIXIR_PKG_NAME: &str = "elixir";
const ELIXIR_NIXPKGS_ARCHIVE: &str = "ef99fa5c5ed624460217c31ac4271cfb5cb2502c";
const ELIXIR_NIXPKGS_ARCHIVE: &str = "c5702bd28cbde41a191a9c2a00501f18941efbd0";

pub struct ElixirProvider {}

Expand All @@ -25,17 +25,11 @@ impl Provider for ElixirProvider {
}

fn get_build_plan(&self, app: &App, env: &Environment) -> Result<Option<BuildPlan>> {
let mut plan = BuildPlan::default();

plan.add_variables(EnvironmentVariables::from([(
"MIX_ENV".to_string(),
"prod".to_string(),
)]));
let setup = self.setup(app, env)?.unwrap_or_default();

let elixir_pkg = ElixirProvider::get_nix_elixir_package(app, env)?;
let mut setup_phase = Phase::setup(Some(vec![elixir_pkg]));
setup_phase.set_nix_archive(ELIXIR_NIXPKGS_ARCHIVE.to_string());
plan.add_phase(setup_phase);
let mut plan = BuildPlan::default();
plan.add_variables(ElixirProvider::default_elixir_environment_variables());
plan.add_phase(setup);

// Install Phase
let mut install_phase = Phase::install(Some("mix local.hex --force".to_string()));
Expand All @@ -54,6 +48,7 @@ impl Provider for ElixirProvider {
if mix_exs_content.contains("postgrex") && mix_exs_content.contains("ecto") {
build_phase.add_cmd("mix ecto.setup");
}

plan.add_phase(build_phase);

// Start Phase
Expand All @@ -65,6 +60,36 @@ impl Provider for ElixirProvider {
}

impl ElixirProvider {
fn setup(&self, app: &App, env: &Environment) -> Result<Option<Phase>> {
let elixir_pkg = ElixirProvider::get_nix_elixir_package(app, env)?;
// TODO should try to extract and optionally set the OTP version
let mut setup = Phase::setup(Some(vec![elixir_pkg]));
setup.set_nix_archive(ELIXIR_NIXPKGS_ARCHIVE.to_string());

// Many Elixir packages need some C headers to be available
setup.add_pkgs_libs(vec!["stdenv.cc.cc.lib".to_string()]);
setup.add_nix_pkgs(&[Pkg::new("gcc")]);

Ok(Some(setup))
}

fn default_elixir_environment_variables() -> EnvironmentVariables {
let var_map = vec![
("MIX_ENV", "prod"),
// required to avoid the following error:
// warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell) or set the ELIXIR_ERL_OPTIONS="+fnu" environment variable
("ELIXIR_ERL_OPTIONS", "+fnu"),
];

let mut env_vars = EnvironmentVariables::new();

for (key, value) in var_map {
env_vars.insert(key.to_owned(), value.to_owned());
}

env_vars
}

fn get_nix_elixir_package(app: &App, env: &Environment) -> Result<Pkg> {
fn as_default(v: Option<Match>) -> &str {
match v {
Expand All @@ -89,6 +114,8 @@ impl ElixirProvider {
.map(|c| c.get(2).unwrap().as_str().to_owned())
};

// TODO next, let's try .tool-version

// If it's still none, return default
if custom_version.is_none() {
return Ok(Pkg::new(DEFAULT_ELIXIR_PKG_NAME));
Expand Down Expand Up @@ -116,8 +143,10 @@ impl ElixirProvider {
("1", "11") => Ok(Pkg::new("elixir_1_11")),
("1", "12") => Ok(Pkg::new("elixir_1_12")),
("1", "13") => Ok(Pkg::new("elixir_1_13")),
("1", "14") => Ok(Pkg::new("elixir")),
("1", "14") => Ok(Pkg::new("elixir_1_14")),
("1", "15") => Ok(Pkg::new("elixir_1_15")),
("1", "16") => Ok(Pkg::new("elixir_1_16")),
("1", "17") => Ok(Pkg::new("elixir_1_17")),
_ => Ok(Pkg::new(DEFAULT_ELIXIR_PKG_NAME)),
}
}
Expand Down
8 changes: 7 additions & 1 deletion tests/snapshots/generate_plan_tests__elixir_ecto.snap
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
---
source: tests/generate_plan_tests.rs
expression: plan
snapshot_kind: text
---
{
"providers": [],
"buildImage": "[build_image]",
"variables": {
"ELIXIR_ERL_OPTIONS": "+fnu",
"MIX_ENV": "prod",
"NIXPACKS_METADATA": "elixir"
},
Expand Down Expand Up @@ -34,7 +36,11 @@ expression: plan
"setup": {
"name": "setup",
"nixPkgs": [
"elixir_1_13"
"elixir_1_13",
"gcc"
],
"nixLibs": [
"stdenv.cc.cc.lib"
],
"nixOverlays": [],
"nixpkgsArchive": "[archive]"
Expand Down
7 changes: 6 additions & 1 deletion tests/snapshots/generate_plan_tests__elixir_phx_no_ecto.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ expression: plan
"providers": [],
"buildImage": "[build_image]",
"variables": {
"ELIXIR_ERL_OPTIONS": "+fnu",
"MIX_ENV": "prod",
"NIXPACKS_METADATA": "elixir"
},
Expand Down Expand Up @@ -34,7 +35,11 @@ expression: plan
"setup": {
"name": "setup",
"nixPkgs": [
"elixir"
"elixir_1_14",
"gcc"
],
"nixLibs": [
"stdenv.cc.cc.lib"
],
"nixOverlays": [],
"nixpkgsArchive": "[archive]"
Expand Down

0 comments on commit cc3e10c

Please sign in to comment.