After 3 puzzles, I am taking a look at how things are set up, and making a few tweaks.
Projections
My projections just do not work. It gets confused when trying to call :A
on
a test
file, going to or making a source
file instead of jumping to the
appropriate puzzle
file. To alleviate this, I needed to make some alterations:
diff --git a/.projections.json b/.projections.json
index 46d04f5..1ad0e62 100644
--- a/.projections.json
+++ b/.projections.json
@@ -1,29 +1,38 @@
{
- "lib/*.ex": {
- "alternate": "test/{dirname}/{basename}_test.exs",
- "type": "source",
+ "lib/mix/tasks/*.ex": {
+ "type": "task",
"template": [
- "defmodule {camelcase|capitalize|dot} do",
+ "defmodule Mix.Tasks.{camelcase|capitalize|dot} do",
+ " use Mix.Task",
+ " ",
"end"
]
},
- "lib/*.exs": {
- "alternate": "test/{dirname}/{basename}_test.exs",
+ "lib/Y*.ex": {
+ "alternate": "test/Y{dirname}/{basename}_test.exs",
"type": "puzzle",
"template": [
"import AdventOfCode",
"",
"aoc {dirname}, {basename} do",
"",
- " def p1(), do: nil",
+ " def p1(), do: :not_solved",
"",
- " def p2(), do: nil",
+ " def p2(), do: :not_solved",
"",
"end"
]
},
- "test/*_test.exs": {
- "alternate": "lib/{dirname}/{basename}.ex",
+ "lib/Y**/utils/*.ex": {
+ "alternate": "test/Y{dirname}/utils/{basename}_test.exs",
+ "type": "source",
+ "template": [
+ "defmodule AdventOfCode.Y{dirname}.{camelcase|capitalize|dot} do",
+ "end"
+ ]
+ },
+ "test/Y*_test.exs": {
+ "alternate": "lib/Y{dirname}/{basename}.ex",
"type": "test",
"template": [
"defmodule {camelcase|capitalize|dot}Test do",
First, I added a new file type! task
is to easily jump to or spin up any new
mix tasks that I think I might need, which I will talk about below. Secondly, I
moved all the source
files to a utils
directory. This is to keep the ability
to :Esource 2020/new_file
next year, while also fixing jumping from a test
to a puzzle
(jumping from a test
to a source
still works, too). Next, I
updated puzzle
to include the Y
in the path name, so instead of jumping to
Y2019/2
, I can jump to 2019/2
. I also updated the template so the functions
return :not_solved
(for the new mix task below). test
was set up fine, no
problems .
Mix tasks
As I mentioned previously, I wanted a mix
task that would run and print a
given solution. My friends, it is HERE!
defmodule Mix.Tasks.Solution do
use Mix.Task
def run(args) when args == [] do
date = get_date()
run([date.day, date.year])
end
def run([d] = args) when length(args) == 1 do
run([d, get_date().year])
end
def run([d, y | _]) do
if Code.ensure_loaded?(AdventOfCode.module_name(y, d)) do
if function_exported?(AdventOfCode.module_name(y, d), :p1, 0) do
Mix.shell().info("The solution for Y#{y}, D#{d}, P1 is #{AdventOfCode.p1(d, y)}")
end
if function_exported?(AdventOfCode.module_name(y, d), :p2, 0) do
Mix.shell().info("The solution for Y#{y}, D#{d}, P2 is #{AdventOfCode.p2(d, y)}")
end
else
Mix.shell().error("The solution Y#{y}, D#{d} is not available")
end
end
defp get_date() do
Application.load(:tzdata)
:ok = Application.ensure_started(:tzdata)
case DateTime.now("America/Toronto", Tzdata.TimeZoneDatabase) do
{:ok, d} -> d
_ -> Date.utc_today()
end
end
end
This task allows me to run mix solution [d [y]]
to run the solutions for a
given day and year. It is smart enough to check if a solution function exists by
calling function_exported?/3
with my generated module name, and :p1
or
:p2
for each puzzle, and nicely printing the results. If the module doesn’t
exist, an error message is printed instead. I think this task needs some more
work to clean it up, and maybe have a different message if the result is
:not_solved
, but it is good for now.