Skip to content

Commit

Permalink
elixir tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jaredLunde committed May 15, 2024
1 parent b0a9ad9 commit f230972
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 6 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ related to this tool.

- [x] Automatically detect the runtime and framework used by your project
- [x] Use version managers like [asdf](https://github.com/asdf-vm), nvm, rbenv, and pyenv to install the correct version of the runtime
- [x] Make a best effort to detect any install, build, and run commands
- [x] Make a best effort to detect any install, build, and start commands
- [x] Generate a Dockerfile with sensible defaults that are configurable via [Docker Build Args](https://docs.docker.com/build/guide/build-args/)
- [x] Support for a wide range of the most popular languages and frameworks including Next.js, Phoenix, Spring Boot, Django, and more
- [x] Use Debian Slim as the runtime image for a smaller image size and better security, while still supporting the most common dependencies and avoiding deployment headaches caused by Alpine Linux gotchas
- [x] Includes `wget` in the runtime image for adding health checks to services, e.g. `wget -nv -t1 --spider 'http://localhost:8080/healthz' || exit 1`
- [x] Use multi-stage builds to reduce the size of the final image
- [x] Run the application as a non-root user for better security
- [x] Supports multi-platform images that run on both x86 and ARM CPU architectures

## Supported Runtimes
Expand Down Expand Up @@ -105,8 +106,8 @@ For example, if it finds a `package.json` file, it will assume the project is a
a `next.config.js` file is present, in which case it will assume the project is a Next.js project.

From there, it will read any `.tool-versions` or other version manager files to determine the correct version
of the runtime to install. It will then make a best effort to detect any install, build, and run commands.
For example, a `serve`, `start`, `start:prod` command in a `package.json` file will be used as the run command.
of the runtime to install. It will then make a best effort to detect any install, build, and start commands.
For example, a `serve`, `start`, `start:prod` command in a `package.json` file will be used as the start command.

Runtimes are matched against in the order they appear when you run `new-dockerfile --runtime list`.

Expand Down
7 changes: 4 additions & 3 deletions node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ related to this tool.

- [x] Automatically detect the runtime and framework used by your project
- [x] Use version managers like [asdf](https://github.com/asdf-vm), nvm, rbenv, and pyenv to install the correct version of the runtime
- [x] Make a best effort to detect any install, build, and run commands
- [x] Make a best effort to detect any install, build, and start commands
- [x] Generate a Dockerfile with sensible defaults that are configurable via [Docker Build Args](https://docs.docker.com/build/guide/build-args/)
- [x] Support for a wide range of the most popular languages and frameworks including Next.js, Phoenix, Spring Boot, Django, and more
- [x] Use Debian Slim as the runtime image for a smaller image size and better security, while still supporting the most common dependencies and avoiding deployment headaches caused by Alpine Linux gotchas
- [x] Includes `wget` in the runtime image for adding health checks to services, e.g. `wget -nv -t1 --spider 'http://localhost:8080/healthz' || exit 1`
- [x] Use multi-stage builds to reduce the size of the final image
- [x] Run the application as a non-root user for better security
- [x] Supports multi-platform images that run on both x86 and ARM CPU architectures

## Supported Runtimes
Expand Down Expand Up @@ -93,8 +94,8 @@ For example, if it finds a `package.json` file, it will assume the project is a
a `next.config.js` file is present, in which case it will assume the project is a Next.js project.

From there, it will read any `.tool-versions` or other version manager files to determine the correct version
of the runtime to install. It will then make a best effort to detect any install, build, and run commands.
For example, a `serve`, `start`, `start:prod` command in a `package.json` file will be used as the run command.
of the runtime to install. It will then make a best effort to detect any install, build, and start commands.
For example, a `serve`, `start`, `start:prod` command in a `package.json` file will be used as the start command.

Runtimes are matched against in the order they appear when you run `new-dockerfile --runtime list`.

Expand Down
4 changes: 4 additions & 0 deletions runtime/elixir.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,10 @@ func isPhoenixProject(path string) bool {
}

func findBinName(path string) (string, error) {
if _, err := os.Stat(filepath.Join(path, "mix.exs")); err != nil {
return "", nil
}

configFile, err := os.Open(filepath.Join(path, "mix.exs"))
if err != nil {
return "", err
Expand Down
100 changes: 100 additions & 0 deletions runtime/elixir_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package runtime_test

import (
"regexp"
"strings"
"testing"

"github.com/flexstack/new-dockerfile/runtime"
)

func TestElixirMatch(t *testing.T) {
tests := []struct {
name string
path string
expected bool
}{
{
name: "Elixir project",
path: "../testdata/elixir",
expected: true,
},
{
name: "Elixir project with .tool-versions",
path: "../testdata/elixir-tool-versions",
expected: true,
},
{
name: "Not a Elixir project",
path: "../testdata/deno",
expected: false,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
elixir := &runtime.Elixir{Log: logger}
if elixir.Match(test.path) != test.expected {
t.Errorf("expected %v, got %v", test.expected, elixir.Match(test.path))
}
})
}
}

func TestElixirGenerateDockerfile(t *testing.T) {
tests := []struct {
name string
path string
expected []any
}{
{
name: "Elixir project",
path: "../testdata/elixir",
expected: []any{`ARG VERSION=1.10`, `ARG OTP_VERSION=22`, `ARG BIN_NAME=hello`},
},
{
name: "Elixir project with .tool-versions",
path: "../testdata/elixir-tool-versions",
expected: []any{`ARG VERSION=1.11`, `ARG OTP_VERSION=23`, `ARG BIN_NAME=hello`},
},
{
name: "Not a Elixir project",
path: "../testdata/deno",
expected: []any{`ARG VERSION=1.12`, `ARG OTP_VERSION=26`, regexp.MustCompile(`^ARG BIN_NAME=$`)},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
elixir := &runtime.Elixir{Log: logger}
dockerfile, err := elixir.GenerateDockerfile(test.path)
if err != nil {
t.Errorf("unexpected error: %v", err)
}

for _, line := range test.expected {
found := false
lines := strings.Split(string(dockerfile), "\n")

for _, l := range lines {
switch v := line.(type) {
case string:
if strings.Contains(l, v) {
found = true
break
}
case *regexp.Regexp:
if v.MatchString(l) {
found = true
break
}
}
}

if !found {
t.Errorf("expected %v, not found in %v", line, string(dockerfile))
}
}
})
}
}
2 changes: 2 additions & 0 deletions testdata/elixir-tool-versions/.tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
elixir 1.11
erlang 23.2.1
15 changes: 15 additions & 0 deletions testdata/elixir-tool-versions/mix.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
defmodule Hello.MixProject do
use Mix.Project

def project do
[
app: :hello,
version: "0.1.0",
elixir: "~> 1.14",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
aliases: aliases(),
deps: deps()
]
end
end
1 change: 1 addition & 0 deletions testdata/elixir/.elixir-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.10
1 change: 1 addition & 0 deletions testdata/elixir/.erlang-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22.3.2
15 changes: 15 additions & 0 deletions testdata/elixir/mix.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
defmodule Hello.MixProject do
use Mix.Project

def project do
[
app: :hello,
version: "0.1.0",
elixir: "~> 1.14",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
aliases: aliases(),
deps: deps()
]
end
end

0 comments on commit f230972

Please sign in to comment.