mirror of
https://github.com/ash-project/igniter.git
synced 2024-09-19 21:12:54 +12:00
improvement: support for non-elixir files with create_new_file, update_file, include_existing_file, include_or_create_file, create_or_update_file (#75)
Some checks failed
CI / ash-ci (push) Has been cancelled
Some checks failed
CI / ash-ci (push) Has been cancelled
This commit is contained in:
parent
8002f8526d
commit
f356cce3a4
2 changed files with 150 additions and 49 deletions
137
lib/igniter.ex
137
lib/igniter.ex
|
@ -248,15 +248,20 @@ defmodule Igniter do
|
||||||
Updates a given file's `Rewrite.Source`
|
Updates a given file's `Rewrite.Source`
|
||||||
"""
|
"""
|
||||||
@spec update_file(t(), Path.t(), (Rewrite.Source.t() -> Rewrite.Source.t())) :: t()
|
@spec update_file(t(), Path.t(), (Rewrite.Source.t() -> Rewrite.Source.t())) :: t()
|
||||||
def update_file(igniter, path, updater) do
|
def update_file(igniter, path, updater, opts \\ []) do
|
||||||
|
source_handler = source_handler(path, opts)
|
||||||
|
|
||||||
|
if source_handler == Rewrite.Source.Ex do
|
||||||
|
update_elixir_file(igniter, path, updater)
|
||||||
|
else
|
||||||
if Rewrite.has_source?(igniter.rewrite, path) do
|
if Rewrite.has_source?(igniter.rewrite, path) do
|
||||||
%{igniter | rewrite: Rewrite.update!(igniter.rewrite, path, updater)}
|
%{igniter | rewrite: Rewrite.update!(igniter.rewrite, path, updater)}
|
||||||
else
|
else
|
||||||
if File.exists?(path) do
|
if File.exists?(path) do
|
||||||
source = read_ex_source!(path)
|
source = read_source!(path, source_handler)
|
||||||
|
|
||||||
%{igniter | rewrite: Rewrite.put!(igniter.rewrite, source)}
|
%{igniter | rewrite: Rewrite.put!(igniter.rewrite, source)}
|
||||||
|> format(path)
|
|> maybe_format(path, true, Keyword.put(opts, :source_handler, source_handler))
|
||||||
|> Map.update!(:rewrite, fn rewrite ->
|
|> Map.update!(:rewrite, fn rewrite ->
|
||||||
source = Rewrite.source!(rewrite, path)
|
source = Rewrite.source!(rewrite, path)
|
||||||
Rewrite.update!(rewrite, path, updater.(source))
|
Rewrite.update!(rewrite, path, updater.(source))
|
||||||
|
@ -266,49 +271,28 @@ defmodule Igniter do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@doc "Includes the given elixir file in the project, expecting it to exist. Does nothing if its already been added."
|
@deprecated "Use `include_existing_file/3` instead"
|
||||||
@spec include_existing_elixir_file(t(), Path.t(), opts :: Keyword.t()) :: t()
|
@spec include_existing_elixir_file(t(), Path.t(), opts :: Keyword.t()) :: t()
|
||||||
def include_existing_elixir_file(igniter, path, opts \\ []) do
|
def include_existing_elixir_file(igniter, path, opts \\ []) do
|
||||||
required? = Keyword.get(opts, :required?, false)
|
include_existing_file(igniter, path, Keyword.put(opts, :source_handler, Rewrite.Source.Ex))
|
||||||
|
|
||||||
if Rewrite.has_source?(igniter.rewrite, path) do
|
|
||||||
igniter
|
|
||||||
else
|
|
||||||
if File.exists?(path) do
|
|
||||||
source = read_ex_source!(path)
|
|
||||||
|
|
||||||
%{igniter | rewrite: Rewrite.put!(igniter.rewrite, source)}
|
|
||||||
|> then(fn igniter ->
|
|
||||||
if opts[:format?] do
|
|
||||||
format(igniter, path)
|
|
||||||
else
|
|
||||||
igniter
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
else
|
|
||||||
if required? do
|
|
||||||
add_issue(igniter, "Required #{path} but it did not exist")
|
|
||||||
else
|
|
||||||
igniter
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc "Includes the given file in the project, expecting it to exist. Does nothing if its already been added."
|
@doc "Includes the given file in the project, expecting it to exist. Does nothing if its already been added."
|
||||||
@spec include_existing_file(t(), Path.t(), opts :: Keyword.t()) :: t()
|
@spec include_existing_file(t(), Path.t(), opts :: Keyword.t()) :: t()
|
||||||
def include_existing_file(igniter, path, opts \\ []) do
|
def include_existing_file(igniter, path, opts \\ []) do
|
||||||
required? = Keyword.get(opts, :required?, false)
|
required? = Keyword.get(opts, :required?, false)
|
||||||
|
source_handler = source_handler(path, opts)
|
||||||
|
|
||||||
if Rewrite.has_source?(igniter.rewrite, path) do
|
if Rewrite.has_source?(igniter.rewrite, path) do
|
||||||
igniter
|
igniter
|
||||||
else
|
else
|
||||||
if File.exists?(path) do
|
if File.exists?(path) do
|
||||||
source = Rewrite.Source.read!(path)
|
source = read_source!(path, source_handler)
|
||||||
|
|
||||||
%{igniter | rewrite: Rewrite.put!(igniter.rewrite, source)}
|
%{igniter | rewrite: Rewrite.put!(igniter.rewrite, source)}
|
||||||
|> format(path)
|
|> maybe_format(path, false, opts)
|
||||||
else
|
else
|
||||||
if required? do
|
if required? do
|
||||||
add_issue(igniter, "Required #{path} but it did not exist")
|
add_issue(igniter, "Required #{path} but it did not exist")
|
||||||
|
@ -319,15 +303,23 @@ defmodule Igniter do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc "Includes or creates the given file in the project with the provided contents. Does nothing if its already been added."
|
@deprecated "Use `include_or_create_file/3` instead"
|
||||||
@spec include_or_create_elixir_file(t(), Path.t(), contents :: String.t()) :: t()
|
@spec include_or_create_elixir_file(t(), Path.t(), contents :: String.t()) :: t()
|
||||||
def include_or_create_elixir_file(igniter, path, contents \\ "") do
|
def include_or_create_elixir_file(igniter, path, contents \\ "") do
|
||||||
|
include_or_create_file(igniter, path, contents)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc "Includes or creates the given file in the project with the provided contents. Does nothing if its already been added."
|
||||||
|
@spec include_or_create_file(t(), Path.t(), contents :: String.t()) :: t()
|
||||||
|
def include_or_create_file(igniter, path, contents \\ "") do
|
||||||
if Rewrite.has_source?(igniter.rewrite, path) do
|
if Rewrite.has_source?(igniter.rewrite, path) do
|
||||||
igniter
|
igniter
|
||||||
else
|
else
|
||||||
|
source_handler = source_handler(path)
|
||||||
|
|
||||||
source =
|
source =
|
||||||
try do
|
try do
|
||||||
read_ex_source!(path)
|
read_source!(path, source_handler)
|
||||||
rescue
|
rescue
|
||||||
_ ->
|
_ ->
|
||||||
""
|
""
|
||||||
|
@ -336,7 +328,7 @@ defmodule Igniter do
|
||||||
end
|
end
|
||||||
|
|
||||||
%{igniter | rewrite: Rewrite.put!(igniter.rewrite, source)}
|
%{igniter | rewrite: Rewrite.put!(igniter.rewrite, source)}
|
||||||
|> format(path)
|
|> maybe_format(path, true, source_handler: source_handler)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -375,22 +367,85 @@ defmodule Igniter do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc "Creates a new elixir file in the project with the provided string contents. Adds an error if it already exists."
|
@doc "Creates the given file in the project with the provided string contents, or updates it with a function as in `update_file/3` (or with `zipper_updater()` for elixir files) if it already exists."
|
||||||
|
def create_or_update_file(igniter, path, contents, updater) do
|
||||||
|
if Rewrite.has_source?(igniter.rewrite, path) do
|
||||||
|
igniter
|
||||||
|
|> update_file(path, updater)
|
||||||
|
else
|
||||||
|
source_handler = source_handler(path)
|
||||||
|
|
||||||
|
{created?, source} =
|
||||||
|
try do
|
||||||
|
{false, read_source!(path, source_handler)}
|
||||||
|
rescue
|
||||||
|
_ ->
|
||||||
|
{true,
|
||||||
|
""
|
||||||
|
|> source_handler.from_string(path)
|
||||||
|
|> Rewrite.Source.update(:file_creator, :content, contents)}
|
||||||
|
end
|
||||||
|
|
||||||
|
%{igniter | rewrite: Rewrite.put!(igniter.rewrite, source)}
|
||||||
|
|> maybe_format(path, true, source_handler: source_handler)
|
||||||
|
|> then(fn igniter ->
|
||||||
|
if created? do
|
||||||
|
igniter
|
||||||
|
else
|
||||||
|
update_file(igniter, path, updater)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@deprecated "Use `create_new_file/4`"
|
||||||
@spec create_new_elixir_file(t(), Path.t(), String.t()) :: Igniter.t()
|
@spec create_new_elixir_file(t(), Path.t(), String.t()) :: Igniter.t()
|
||||||
def create_new_elixir_file(igniter, path, contents \\ "") do
|
def create_new_elixir_file(igniter, path, contents \\ "", opts \\ []) do
|
||||||
|
create_new_file(
|
||||||
|
igniter,
|
||||||
|
path,
|
||||||
|
contents,
|
||||||
|
Keyword.put(opts, :source_handler, Rewrite.Source.Ex)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc "Creates a new (non-elixir) file in the project with the provided string contents. Adds an error if it already exists."
|
||||||
|
@spec create_new_file(t(), Path.t(), String.t()) :: Igniter.t()
|
||||||
|
def create_new_file(igniter, path, contents \\ "", opts \\ []) do
|
||||||
|
source_handler = source_handler(path, opts)
|
||||||
|
|
||||||
source =
|
source =
|
||||||
try do
|
try do
|
||||||
source = read_ex_source!(path)
|
source = read_source!(path, source_handler)
|
||||||
Rewrite.Source.add_issue(source, "File already exists")
|
Rewrite.Source.add_issue(source, "File already exists")
|
||||||
rescue
|
rescue
|
||||||
_ ->
|
_ ->
|
||||||
""
|
""
|
||||||
|> Rewrite.Source.Ex.from_string(path)
|
|> source_handler.from_string(path)
|
||||||
|> Rewrite.Source.update(:file_creator, :content, contents)
|
|> Rewrite.Source.update(:file_creator, :content, contents)
|
||||||
end
|
end
|
||||||
|
|
||||||
%{igniter | rewrite: Rewrite.put!(igniter.rewrite, source)}
|
%{igniter | rewrite: Rewrite.put!(igniter.rewrite, source)}
|
||||||
|> format(path)
|
|> maybe_format(path, true, opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp maybe_format(igniter, path, default_bool, opts) do
|
||||||
|
if source_handler(path, opts) == Rewrite.Source.Ex and
|
||||||
|
Keyword.get(opts, :format?, default_bool) do
|
||||||
|
format(igniter, path)
|
||||||
|
else
|
||||||
|
igniter
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp source_handler(path, opts \\ []) do
|
||||||
|
Keyword.get_lazy(opts, :source_handler, fn ->
|
||||||
|
if Path.extname(path) in Rewrite.Source.Ex.extensions() do
|
||||||
|
Rewrite.Source.Ex
|
||||||
|
else
|
||||||
|
Rewrite.Source
|
||||||
|
end
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
@ -980,7 +1035,11 @@ defmodule Igniter do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp read_ex_source!(path) do
|
defp read_ex_source!(path) do
|
||||||
source = Rewrite.Source.Ex.read!(path)
|
read_source!(path, Rewrite.Source.Ex)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp read_source!(path, source_handler \\ Rewrite.Source) do
|
||||||
|
source = source_handler.read!(path)
|
||||||
|
|
||||||
content =
|
content =
|
||||||
source
|
source
|
||||||
|
|
42
test/igniter/code/file_test.exs
Normal file
42
test/igniter/code/file_test.exs
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
defmodule Igniter.Code.FileTest do
|
||||||
|
use ExUnit.Case
|
||||||
|
|
||||||
|
test "files will be created if they do not exist" do
|
||||||
|
%{rewrite: rewrite} =
|
||||||
|
Igniter.new()
|
||||||
|
|> Igniter.create_new_file("lib/foo/bar/something.heex", """
|
||||||
|
<div>Hello</div>
|
||||||
|
""")
|
||||||
|
|> Igniter.prepare_for_write()
|
||||||
|
|
||||||
|
assert rewrite
|
||||||
|
|> Rewrite.source!("lib/foo/bar/something.heex")
|
||||||
|
|> Rewrite.Source.get(:content) == """
|
||||||
|
<div>Hello</div>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
test "files will be read if they exist" do
|
||||||
|
assert %{rewrite: rewrite} =
|
||||||
|
Igniter.new()
|
||||||
|
|> Igniter.include_existing_file("README.md", required?: true)
|
||||||
|
|
||||||
|
assert rewrite
|
||||||
|
|> Rewrite.source!("README.md")
|
||||||
|
|> Rewrite.Source.get(:content) =~ "code generation"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "can update file if it exists" do
|
||||||
|
assert %{rewrite: rewrite} =
|
||||||
|
Igniter.new()
|
||||||
|
|> Igniter.include_existing_file("README.md", required?: true)
|
||||||
|
|> Igniter.update_file("README.md", fn source ->
|
||||||
|
Rewrite.Source.update(source, :content, "Hello Test")
|
||||||
|
end)
|
||||||
|
|> Igniter.prepare_for_write()
|
||||||
|
|
||||||
|
assert rewrite
|
||||||
|
|> Rewrite.source!("README.md")
|
||||||
|
|> Rewrite.Source.get(:content) == "Hello Test"
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue