diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index 08ca75da..f2e97e33 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -9,30 +9,44 @@ on: jobs: build: + runs-on: ubuntu-latest - name: Build and test - runs-on: ubuntu-20.04 + env: + MIX_ENV: test + + strategy: + matrix: + elixir: [1.18.4] + otp: [28.0.2] steps: - - uses: actions/checkout@v2 - - name: System dependencies - run: | - sudo apt update - sudo apt install -y inotify-tools - - name: Set up Elixir - uses: erlef/setup-beam@988e02bfe678367a02564f65ca2e37726dc0268f - with: - elixir-version: '1.12.3' # Define the elixir version [required] - otp-version: '24.1' # Define the OTP version [required] - - name: Restore dependencies cache - uses: actions/cache@v2 - with: - path: deps - key: ${{ runner.os }}-mix-${{ hashFiles('**/mix.lock') }} - restore-keys: ${{ runner.os }}-mix- - - name: Install dependencies - run: mix deps.get - - name: Run tests - run: mix test - - name: Run static analytics - run: mix credo suggest --all --strict + - uses: actions/checkout@v4 + - name: System Dependencies + run: | + sudo apt update + sudo apt install -y inotify-tools + - name: Setup Elixir + uses: erlef/setup-beam@v1 + with: + otp-version: ${{ matrix.otp }} + elixir-version: ${{ matrix.elixir }} + - name: Restore dependencies cache + uses: actions/cache@v4 + with: + path: | + deps + _build + key: mix-${{ runner.os }}-${{matrix.elixir}}-${{matrix.otp}}-${{ hashFiles('**/mix.lock') }} + restore-keys: | + mix-${{ runner.os }}-${{matrix.elixir}}-${{matrix.otp}}- + + - name: Install dependencies + run: mix deps.get + - name: Check code format + run: mix format --check-formatted + - name: Run static analysis + run: mix credo --strict + - name: Check for unneeded dependencies + run: mix deps.unlock --check-unused + - name: Run tests + run: mix test diff --git a/CNAME b/CNAME deleted file mode 100644 index adedccf5..00000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -elixirkoans.io diff --git a/LICENSE.md b/LICENSE.md index 21701bcb..5d2a478b 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ The MIT License -Copyright (c) 2015 http://elixirkoans.io +Copyright (c) 2015 Elixir Koans Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/display.ex b/lib/display.ex index 1f57c16f..95d8f427 100644 --- a/lib/display.ex +++ b/lib/display.ex @@ -22,7 +22,7 @@ defmodule Display do end def handle_call(:clear_screen, _from, %{clear_screen: true} = state) do - ANSI.clear <> ANSI.home |> IO.puts() + (ANSI.clear() <> ANSI.home()) |> IO.puts() {:reply, :ok, state} end @@ -58,6 +58,7 @@ defmodule Display do defp format(failure, module, name) do progress_bar = ProgressBar.progress_bar(Tracker.summarize()) progress_bar_underline = String.duplicate("-", String.length(progress_bar)) + """ #{Intro.intro(module, Tracker.visited())} Now meditate upon #{format_module(module)} diff --git a/lib/display/failure.ex b/lib/display/failure.ex index 57f1e627..88845a1f 100644 --- a/lib/display/failure.ex +++ b/lib/display/failure.ex @@ -50,7 +50,7 @@ defmodule Display.Failure do end defp format_error(error) do - trace = System.stacktrace() |> Enum.take(2) + trace = Process.info(self(), :current_stacktrace) |> Enum.take(2) Paint.red(Exception.format(:error, error, trace)) end diff --git a/lib/display/intro.ex b/lib/display/intro.ex index 32ce92d2..85a1c2cb 100644 --- a/lib/display/intro.ex +++ b/lib/display/intro.ex @@ -6,7 +6,7 @@ defmodule Display.Intro do if module in modules do "" else - show_intro(module.intro) + module.intro() |> show_intro() end end diff --git a/lib/display/progress_bar.ex b/lib/display/progress_bar.ex index 71c1cdc0..5fd81a04 100644 --- a/lib/display/progress_bar.ex +++ b/lib/display/progress_bar.ex @@ -6,7 +6,9 @@ defmodule Display.ProgressBar do arrow = calculate_progress(current, total) |> build_arrow progress_percentage = calculate_percentage(current, total) - "|" <> String.pad_trailing(arrow, @progress_bar_length) <> "| #{current} of #{total} -> #{progress_percentage}% complete" + "|" <> + String.pad_trailing(arrow, @progress_bar_length) <> + "| #{current} of #{total} -> #{progress_percentage}% complete" end defp calculate_progress(current, total) do diff --git a/lib/elixir_koans.ex b/lib/elixir_koans.ex index dcf857f7..e1dbffa1 100644 --- a/lib/elixir_koans.ex +++ b/lib/elixir_koans.ex @@ -3,13 +3,11 @@ defmodule ElixirKoans do use Application def start(_type, _args) do - import Supervisor.Spec - children = [ - worker(Display, []), - worker(Tracker, []), - worker(Runner, []), - worker(Watcher, []) + %{id: Display, start: {Display, :start_link, []}}, + %{id: Tracker, start: {Tracker, :start_link, []}}, + %{id: Runner, start: {Runner, :start_link, []}}, + %{id: Watcher, start: {Watcher, :start_link, []}} ] opts = [strategy: :one_for_one, name: ElixirKoans.Supervisor] diff --git a/lib/execute.ex b/lib/execute.ex index 6c462738..aa8af363 100644 --- a/lib/execute.ex +++ b/lib/execute.ex @@ -1,7 +1,8 @@ defmodule Execute do @moduledoc false def run_module(module, callback \\ fn _result, _module, _koan -> nil end) do - Enum.reduce_while(module.all_koans, :passed, fn koan, _ -> + module.all_koans() + |> Enum.reduce_while(:passed, fn koan, _ -> module |> run_koan(koan) |> hook(module, koan, callback) diff --git a/lib/koans/03_numbers.ex b/lib/koans/03_numbers.ex index 9fb3ab23..274923d7 100644 --- a/lib/koans/03_numbers.ex +++ b/lib/koans/03_numbers.ex @@ -110,7 +110,7 @@ defmodule Numbers do end koan "I want the first and last in the range" do - first..last = Range.new(1, 10) + first..last//_step = Range.new(1, 10) assert first == ___ assert last == ___ @@ -124,11 +124,11 @@ defmodule Numbers do assert 0 in range == ___ end - def is_range?(%Range{}), do: true - def is_range?(_), do: false + def range?(%Range{}), do: true + def range?(_), do: false koan "Is this a range?" do - assert is_range?(1..10) == ___ - assert is_range?(0) == ___ + assert range?(1..10) == ___ + assert range?(0) == ___ end end diff --git a/lib/tracker.ex b/lib/tracker.ex index 018dd83b..79c36df8 100644 --- a/lib/tracker.ex +++ b/lib/tracker.ex @@ -18,7 +18,7 @@ defmodule Tracker do def set_total(modules) do total = modules - |> Enum.flat_map(& &1.all_koans) + |> Enum.flat_map(& &1.all_koans()) |> Enum.count() Agent.update(__MODULE__, fn _ -> %Tracker{total: total} end) diff --git a/lib/watcher.ex b/lib/watcher.ex index eadb9a38..bbef3e89 100644 --- a/lib/watcher.ex +++ b/lib/watcher.ex @@ -36,15 +36,8 @@ defmodule Watcher do end end - # Elixir 1.7 deprecates Code.load_file in favor of Code.compile_file. In - # order to avoid the depecation warnings while maintaining backwards - # compatibility, we check the sytem version and execute conditionally. defp portable_load_file(file) do - if Version.match?(System.version(), "~> 1.7") do - Code.compile_file(file) - else - Code.load_file(file) - end + Code.compile_file(file) end defp normalize(file) do diff --git a/mix.exs b/mix.exs index de880795..4c852a21 100644 --- a/mix.exs +++ b/mix.exs @@ -2,21 +2,24 @@ defmodule Koans.Mixfile do use Mix.Project def project do - [app: :elixir_koans, - version: "0.0.1", - elixir: ">= 1.3.0 and < 2.0.0", - elixirc_paths: elixirc_path(Mix.env), - deps: deps()] + [ + app: :elixir_koans, + version: "0.0.1", + elixir: ">= 1.3.0 and < 2.0.0", + elixirc_paths: elixirc_path(Mix.env()), + deps: deps() + ] end def application do - [mod: {ElixirKoans, []}, - applications: [:file_system, :logger]] + [mod: {ElixirKoans, []}, applications: [:file_system, :logger]] end defp deps do - [{:file_system, "~> 0.2"}, - {:credo, "~> 1.7", only: [:dev, :test], runtime: false}] + [ + {:file_system, "~> 1.1"}, + {:credo, "~> 1.7", only: [:dev, :test], runtime: false} + ] end defp elixirc_path(:test), do: ["lib/", "test/support"] diff --git a/mix.lock b/mix.lock index 3acd1054..004414be 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{ - "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, - "credo": {:hex, :credo, "1.7.1", "6e26bbcc9e22eefbff7e43188e69924e78818e2fe6282487d0703652bc20fd62", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "e9871c6095a4c0381c89b6aa98bc6260a8ba6addccf7f6a53da8849c748a58a2"}, - "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, - "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, + "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, + "credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"}, + "file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"}, + "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, } diff --git a/test/executor_test.exs b/test/executor_test.exs index 629c1eea..7248f8f7 100644 --- a/test/executor_test.exs +++ b/test/executor_test.exs @@ -7,7 +7,7 @@ defmodule ExecuteTest do test "stops at the first failing koan" do {:failed, %{file: file, line: line}, SampleKoan, _name} = Execute.run_module(SampleKoan) - assert file == 'test/support/sample_koan.ex' + assert file == ~c'test/support/sample_koan.ex' assert line == 9 end diff --git a/test/test_helper.exs b/test/test_helper.exs index b7c383e4..bad94561 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -6,7 +6,7 @@ defmodule TestHarness do import ExUnit.Assertions def test_all(module, answers) do - module.all_koans + module.all_koans() |> check_answer_count(answers, module) |> Enum.zip(answers) |> run_all(module)