Simpler progressbar and handle --koan=<KOAN> better
This commit is contained in:
@@ -2,8 +2,7 @@ defmodule Display do
|
||||
alias IO.ANSI
|
||||
@current_dir File.cwd!
|
||||
@no_value :ex_unit_no_meaningful_value
|
||||
@window_width 40
|
||||
@half_window 20
|
||||
@progress_bar_length 30
|
||||
|
||||
def invalid_koan(koan, modules) do
|
||||
koans_names = module_names(modules)
|
||||
@@ -31,45 +30,22 @@ defmodule Display do
|
||||
end
|
||||
|
||||
defp bar() do
|
||||
String.duplicate("-", @window_width + 1)
|
||||
"----------------------------------------"
|
||||
end
|
||||
|
||||
def progress_bar(%{current: current, total: total}) do
|
||||
progress = caluculate_progress(current, total)
|
||||
progress_notification = "(#{current}/#{total})"
|
||||
arrow = caluculate_progress(current, total) |> build_arrow
|
||||
|
||||
if current/total < 0.5 do
|
||||
left_progress(progress_notification, progress)
|
||||
else
|
||||
right_progress(progress_notification, progress)
|
||||
end
|
||||
"|" <> String.ljust(arrow, @progress_bar_length) <> "| #{current} of #{total}"
|
||||
end
|
||||
|
||||
defp caluculate_progress(current, total) do
|
||||
round( Float.floor((current/total) * @window_width))
|
||||
round( (current/total) * @progress_bar_length)
|
||||
end
|
||||
|
||||
def left_progress(progress_notification, progress) do
|
||||
left = String.ljust("#{arrow(progress)}", @half_window - 1)
|
||||
right = String.ljust(progress_notification, @half_window)
|
||||
|
||||
in_bars(left<>right)
|
||||
end
|
||||
|
||||
def right_progress(progress_notification, progress) do
|
||||
arrow_length = progress - @half_window - 1
|
||||
left = String.ljust(progress_notification, @half_window - 1, ?=)
|
||||
right = String.ljust(arrow(arrow_length), @half_window)
|
||||
|
||||
in_bars(left<>right)
|
||||
end
|
||||
|
||||
defp in_bars(thing) do
|
||||
"|" <> thing <> "|"
|
||||
end
|
||||
|
||||
defp arrow(length) do
|
||||
String.duplicate("=", length) <> ">"
|
||||
defp build_arrow(0), do: ""
|
||||
defp build_arrow(length) do
|
||||
String.duplicate("=", length-1) <> ">"
|
||||
end
|
||||
|
||||
def show_compile_error(error) do
|
||||
@@ -95,14 +71,9 @@ defmodule Display do
|
||||
#{format_red(message)}
|
||||
"""
|
||||
end
|
||||
|
||||
defp format_failure(%{error: %ExUnit.AssertionError{expr: expr}, file: file, line: line}) do
|
||||
"""
|
||||
#{format_cyan("Assertion failed in #{file}:#{line}")}
|
||||
#{format_red(Macro.to_string(expr))}
|
||||
"""
|
||||
format_assertion_error(expr, file, line)
|
||||
end
|
||||
|
||||
defp format_failure(%{error: error, file: file, line: line}) do
|
||||
"""
|
||||
#{format_cyan("Error in #{file}:#{line}")}
|
||||
@@ -110,6 +81,14 @@ defmodule Display do
|
||||
"""
|
||||
end
|
||||
|
||||
defp format_assertion_error(error, file, line) do
|
||||
"""
|
||||
#{format_cyan("Assertion failed in #{file}:#{line}")}
|
||||
#{format_red(Macro.to_string(error))}
|
||||
"""
|
||||
end
|
||||
|
||||
|
||||
defp format_error(error) do
|
||||
trace = System.stacktrace |> Enum.take(2)
|
||||
format_red(Exception.format(:error, error, trace))
|
||||
|
||||
@@ -2,14 +2,31 @@ defmodule Mix.Tasks.Meditate do
|
||||
use Mix.Task
|
||||
alias Options
|
||||
|
||||
@modules [
|
||||
Equalities,
|
||||
Strings,
|
||||
Tuples,
|
||||
Lists,
|
||||
Maps,
|
||||
Structs,
|
||||
PatternMatching,
|
||||
Functions,
|
||||
Enums,
|
||||
Processes,
|
||||
Tasks,
|
||||
Agents,
|
||||
]
|
||||
|
||||
def run(args) do
|
||||
Application.ensure_all_started(:elixir_koans)
|
||||
Code.compiler_options(ignore_module_conflict: true)
|
||||
Watcher.start
|
||||
|
||||
Tracker.start(Runner.modules)
|
||||
Options.start(args)
|
||||
Runner.run
|
||||
|
||||
modules = Runner.modules_to_run
|
||||
Tracker.start(modules)
|
||||
Runner.run(modules)
|
||||
|
||||
:timer.sleep(:infinity)
|
||||
end
|
||||
|
||||
@@ -17,19 +17,13 @@ defmodule Runner do
|
||||
def koan?(koan), do: Enum.member?(@modules, koan)
|
||||
def modules, do: @modules
|
||||
|
||||
def run do
|
||||
Options.initial_koan
|
||||
|>run
|
||||
end
|
||||
def modules_to_run, do: Options.initial_koan |> modules_to_run
|
||||
def modules_to_run(start_module), do: Enum.drop_while(@modules, &(&1 != start_module))
|
||||
|
||||
def run(start_module) when start_module in @modules, do: run(start_module, @modules)
|
||||
def run(start_module), do: Display.invalid_koan(start_module, @modules)
|
||||
|
||||
def run(start_module, modules) do
|
||||
def run(modules) do
|
||||
Display.clear_screen()
|
||||
|
||||
modules
|
||||
|> Enum.drop_while( &(&1 != start_module))
|
||||
|> Enum.take_while( &(run_module(&1) == :passed))
|
||||
end
|
||||
|
||||
@@ -38,7 +32,6 @@ defmodule Runner do
|
||||
|> Display.considering
|
||||
|> Execute.run_module(&track/2)
|
||||
|> display
|
||||
|
||||
end
|
||||
|
||||
defp track(:passed, koan), do: Tracker.completed(koan)
|
||||
|
||||
@@ -7,6 +7,7 @@ defmodule Watcher do
|
||||
Code.load_file(file)
|
||||
|> Enum.map(&(elem(&1, 0)))
|
||||
|> Enum.find(&Runner.koan?/1)
|
||||
|> Runner.modules_to_run
|
||||
|> Runner.run
|
||||
rescue
|
||||
e -> Display.show_compile_error(e)
|
||||
|
||||
Reference in New Issue
Block a user