Current section
Files
Jump to
Current section
Files
lib/exacto_knife/cli.ex
defmodule ExactoKnife.CLI do
@moduledoc """
Command line interface support
"""
alias ExactoKnife.Refactorings
alias Mix.Tasks.Format
def main(args \\ []) do
case parse_args(args) do
:help ->
IO.puts("""
ExactoKnife Usage:
exacto_knife [REFACTOR] [FILE]
e.g. exacto_knife consolidate_aliases lib/project/stuff.ex
""")
{_, [name, path, args]} ->
update_file(name, path, refactor(name, args))
end
end
defp parse_args(args) do
cmd_opts =
OptionParser.parse(args,
switches: [help: :boolean],
aliases: [h: :help]
)
case cmd_opts do
{[help: true], _, _} ->
:help
{opts, ["rename", path, line, col, new_name], []} ->
{opts, ["rename", path, [{String.to_integer(line), String.to_integer(col)}, new_name]]}
{opts, [refactoring, path], []} ->
{opts, [refactoring, path, []]}
_ ->
:help
end
end
defp formatter_opts_for(file: file) do
Format.formatter_for_file(file) |> elem(1)
end
defp update_file(refactor, path, fun) do
original_content = File.read!(path)
new_content =
original_content
|> Sourceror.parse_string!()
|> fun.()
|> Sourceror.to_string(formatter_opts_for(file: path))
new_content = "#{new_content}\n"
if new_content != original_content do
IO.puts("#{refactor}: saving changes to #{path}.")
File.write!(path, new_content)
else
IO.puts("#{refactor}: No changes made to #{path}.")
end
end
defp refactor(name, args) do
fn quoted -> apply(Refactorings, String.to_atom(name), [quoted | args]) end
end
end