Current section

Files

Jump to
ex_at_coder lib mix tasks atcoder new.ex
Raw

lib/mix/tasks/atcoder/new.ex

defmodule Mix.Tasks.Atcoder.New do
@shortdoc "指定されたコンテストの問題の雛形を作成します"
use Mix.Task
alias ExAtCoder.Repo
def run([contest | tasks]) do
Application.ensure_all_started(:hackney)
filter =
case tasks do
[] -> fn _ -> true end
_ -> fn {p, _} ->
tasks |> Enum.map(&String.upcase/1) |> Enum.member?(p)
end
end
Repo.contest_tasks(contest)
|> Enum.filter(filter)
|> Enum.each(fn {p, [url]} -> make_code(contest, p, url) end)
Mix.shell().info("✨ Generate code for #{contest}")
Mix.shell().info("👍 Good Luck")
end
defp make_code(contest, problem, url) do
# ディレクトリ作成
dir = "lib/#{contest}"
unless File.exists?(dir) do
Mix.Generator.create_directory(dir)
end
# 提出コード雛形作成
file = dir <> "/#{Macro.underscore(problem)}.ex"
unless File.exists?(file) do
namespace = "#{Macro.camelize(contest)}.#{Macro.camelize(problem)}"
genenrate_code(file, namespace)
end
# テストケース
testcase_dir = dir <> "/test_case"
unless File.exists?(testcase_dir) do
Mix.Generator.create_directory(testcase_dir)
end
yaml = testcase_dir <> "/#{Macro.underscore(problem)}.yml"
unless File.exists?(yaml) do
cases =
Repo.task_cases(url)
|> Enum.map(&testcase_yaml/1)
|> Enum.join("\n")
Mix.Generator.create_file(yaml, cases)
end
end
defp genenrate_code(file, namespace) do
case Application.fetch_env(:ex_at_coder, :template_path) do
:error ->
code = default_template(namespace)
Mix.Generator.create_file(file, code)
{:ok, path} ->
Mix.Generator.copy_template(path, file, [namespace: namespace])
end
end
defp default_template(namespace) do
"""
defmodule #{namespace}.Main do
def main() do
end
end
"""
end
defp testcase_yaml({n, input_output}) when is_list(input_output) do
input = Keyword.get(input_output, :input, "")
output = Keyword.get(input_output, :output, "")
"""
- name: sample#{n}
in: |
#{String.replace(input, "\r\n", "\n ")}
out: |
#{String.replace(output, "\r\n", "\n ")}
"""
end
end