Skip to content

Commit

Permalink
Add mix task, update test, and readme
Browse files Browse the repository at this point in the history
  • Loading branch information
ckoch-cars committed Sep 18, 2021
1 parent 7dbe07a commit e00edef
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 61 deletions.
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,26 @@ to a new file/module. At this time, ExFactor cannot change the function arity.

### Example
```elixir
mix exfactor -m MyApp.MyMod -f [my_func: 2] -mm MyApp.MyNewMod -mf :my_new_func
mix ex_factor.refactor --module TestModule.Here --function my_func --arity 1 --target NewModule.Test
```

## Roadmap

- [] Write the module code to rename usages of the refactored function
- [] Update .exs files too?
- [] Write tests to ensure we can find modules within and across umbrella apps.
- [X] Write a mix task to invoke the Refactorer
- [] ElixirLS integration for VSCode?
- [] Add configuration hooks?
- [] find dead functions
- [] find module attrs and also move them?
- [] find types referenced in the moved specs
- [] find private functions references in refactored fn bodies.
- [] update test file refs by CLI option
- [] format changes
- [] CLI output, list files changed and created.
- [] dry-run option
- [] ElixirLS integration for VSCode?
- [] Write the module code to rename usages of the refactored function


## Installation

Expand All @@ -36,3 +45,4 @@ Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_do
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at [https://hexdocs.pm/ex_factor](https://hexdocs.pm/ex_factor).

REFACTORY, just in case.
28 changes: 23 additions & 5 deletions lib/mix/tasks/ex_factor/refactor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,32 @@ defmodule Mix.Tasks.ExFactor.Refactor do
use Mix.Task

def run(argv) do
{opts, _extra_opts} = OptionParser.parse(argv, switches: [arity: :integer, module: :string, function: :string, target: :string, key: :string])
|> IO.inspect(label: "OptionParser")
# opts = Mix.shell().info(Enum.join(argv, " "))
opts
{parsed_opts, _, _} = OptionParser.parse(argv, strict:
[
arity: :integer,
dry_run: :boolean,
function: :string,
key: :string,
module: :string,
source_path: :string,
target: :string,
target_path: :string
]
)

parsed_opts
|> IO.inspect(label: "PARSED ARGS")

# Mix.Task.run("app.start")
parsed_opts
|> options()
|> ExFactor.refactor()
end

ExFactor.refactor(opts)
defp options(opts) do
opts
|> Keyword.put(:source_function, Keyword.fetch!(opts, :function))
|> Keyword.put(:source_module, Keyword.fetch!(opts, :module))
|> Keyword.put(:target_module, Keyword.fetch!(opts, :target))
end
end
30 changes: 23 additions & 7 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@ defmodule ExFactor.MixProject do
def project do
[
app: :ex_factor,
version: "0.1.0",
elixir: "~> 1.11",
name: "ExFactor",
version: "0.2.0",
elixir: "~> 1.12",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
deps: deps()
deps: deps(),
description: description(),
package: package(),
source_url: "https://github.com/ckochx/ex_factor"
]
end

# Run "mix help compile.app" to learn about applications.
def application do
[
extra_applications: [:logger]
Expand All @@ -24,11 +27,24 @@ defmodule ExFactor.MixProject do
# defp elixirc_paths(_), do: ["lib"]
defp elixirc_paths(_), do: ["lib", "test"]

# Run "mix help deps" to learn about dependencies.
defp description do
"ExFactor is a refactoring helper."
end

defp deps do
[]
end

# Run "mix help deps" to learn about dependencies.
defp package() do
[
# {:dep_from_hexpm, "~> 0.3.0"},
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
name: "ExFactor",
# These are the default files included in the package
# files: ~w(lib priv .formatter.exs mix.exs README* readme* LICENSE*
# license* CHANGELOG* changelog* src),
licenses: ["CC-BY-NC-ND-4.0"],
links: %{"GitHub" => "https://github.com/ckochx/ex_factor"}

]
end
end
93 changes: 47 additions & 46 deletions test/ex_factor/extractor_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ defmodule ExFactor.ExtractorTest do

setup_all do
File.mkdir_p("test/tmp")
File.mkdir_p("lib/ex_factor/tmp")

on_exit(fn ->
File.rm_rf("test/tmp")
File.rm_rf("lib/ex_factor/tmp")
end)
end

Expand Down Expand Up @@ -98,54 +100,54 @@ defmodule ExFactor.ExtractorTest do
end

test "write a new file with the function, infer some defaults" do
File.rm("lib/ex_factor/source_module.ex")
File.rm("lib/ex_factor/target_module.ex")
File.rm("lib/ex_factor/tmp/source_module.ex")
File.rm("lib/ex_factor/tmp/target_module.ex")

content = """
defmodule ExFactor.SourceModule do
defmodule ExFactor.Tmp.SourceModule do
@somedoc "This is somedoc"
def pub1(arg1) do
:ok
end
end
"""

File.write("lib/ex_factor/source_module.ex", content)
File.write("lib/ex_factor/tmp/source_module.ex", content)

opts = [
target_module: ExFactor.TargetModule,
source_module: ExFactor.SourceModule,
target_module: ExFactor.Tmp.TargetModule,
source_module: ExFactor.Tmp.SourceModule,
source_function: :pub1,
arity: 1
]

Extractor.emplace(opts)

file = File.read!("lib/ex_factor/target_module.ex")
file = File.read!("lib/ex_factor/tmp/target_module.ex")
assert file =~ "def(pub1(arg1))"
assert file =~ "defmodule(ExFactor.TargetModule) do"
assert file =~ "defmodule(ExFactor.Tmp.TargetModule) do"

File.rm("lib/ex_factor/source_module.ex")
File.rm("lib/ex_factor/target_module.ex")
File.rm("lib/ex_factor/tmp/source_module.ex")
File.rm("lib/ex_factor/tmp/target_module.ex")
end

test "write the function into an existing module" do
File.rm("lib/ex_factor/source_module.ex")
File.rm("lib/ex_factor/target_module.ex")
File.rm("lib/ex_factor/tmp/source_module.ex")
File.rm("lib/ex_factor/tmp/target_module.ex")

content = """
defmodule ExFactor.SourceModule do
defmodule ExFactor.Tmp.SourceModule do
@somedoc "This is somedoc"
def refactor1(arg1) do
:ok
end
end
"""

File.write("test/tmp/source_module.ex", content)
File.write("lib/ex_factor/tmp/source_module.ex", content)

content = """
defmodule ExFactor.TargetModule do
defmodule ExFactor.Tmp.TargetModule do
@somedoc "This is somedoc TargetModule"
# this is a comment, it will get elided
def pub_exists(arg_exists) do
Expand All @@ -154,43 +156,43 @@ defmodule ExFactor.ExtractorTest do
end
"""

File.write("lib/ex_factor/target_module.ex", content)
File.write("lib/ex_factor/tmp/target_module.ex", content)

opts = [
target_module: ExFactor.TargetModule,
source_module: ExFactor.SourceModule,
target_module: ExFactor.Tmp.TargetModule,
source_module: ExFactor.Tmp.SourceModule,
source_function: :refactor1,
arity: 1
]

Extractor.emplace(opts)

file = File.read!("lib/ex_factor/target_module.ex")
file = File.read!("lib/ex_factor/tmp/target_module.ex")
assert file =~ "def(refactor1(arg1)) do"
assert file =~ "def pub_exists(arg_exists) do"
assert file =~ "defmodule ExFactor.TargetModule do"
assert file =~ "defmodule ExFactor.Tmp.TargetModule do"

File.rm("lib/ex_factor/source_module.ex")
File.rm("lib/ex_factor/target_module.ex")
File.rm("lib/ex_factor/tmp/source_module.ex")
File.rm("lib/ex_factor/tmp/target_module.ex")
end

test "write multiple functions, into an existing module" do
File.rm("lib/ex_factor/source_module.ex")
File.rm("lib/ex_factor/target_module.ex")
File.rm("lib/ex_factor/tmp/source_module.ex")
File.rm("lib/ex_factor/tmp/target_module.ex")

content = """
defmodule ExFactor.SourceModule do
defmodule ExFactor.Tmp.SourceModule do
@somedoc "This is somedoc"
def refactor1(arg1) do
:ok
end
end
"""

File.write("lib/ex_factor/source_module.ex", content)
File.write("lib/ex_factor/tmp/source_module.ex", content)

content = """
defmodule ExFactor.TargetModule do
defmodule ExFactor.Tmp.TargetModule do
@somedoc "This is somedoc TargetModule"
# this is a comment, it will get elided
def pub_exists(arg_exists) do
Expand All @@ -202,33 +204,33 @@ defmodule ExFactor.ExtractorTest do
end
"""

File.write("lib/ex_factor/target_module.ex", content)
File.write("lib/ex_factor/tmp/target_module.ex", content)

opts = [
target_module: ExFactor.TargetModule,
source_module: ExFactor.SourceModule,
target_module: ExFactor.Tmp.TargetModule,
source_module: ExFactor.Tmp.SourceModule,
source_function: :refactor1,
arity: 1
]

Extractor.emplace(opts)

file = File.read!("lib/ex_factor/target_module.ex")
file = File.read!("lib/ex_factor/tmp/target_module.ex")
assert file =~ "def(refactor1(arg1)) do"
assert file =~ "def pub_exists(arg_exists) do"
assert file =~ "def pub_exists(:error) do"
assert file =~ "defmodule ExFactor.TargetModule do"
assert file =~ "defmodule ExFactor.Tmp.TargetModule do"

File.rm("lib/ex_factor/source_module.ex")
File.rm("lib/ex_factor/target_module.ex")
File.rm("lib/ex_factor/tmp/source_module.ex")
File.rm("lib/ex_factor/tmp/target_module.ex")
end

test "write multiple functions and their docs, into an existing module" do
File.rm("lib/ex_factor/source_module.ex")
File.rm("lib/ex_factor/target_module.ex")
File.rm("lib/ex_factor/tmp/source_module.ex")
File.rm("lib/ex_factor/tmp/target_module.ex")

content = """
defmodule ExFactor.SourceModule do
defmodule ExFactor.Tmp.SourceModule do
@somedoc "This is somedoc"
@doc "this is some documentation for refactor1/1"
def refactor1(arg1) do
Expand All @@ -240,10 +242,10 @@ defmodule ExFactor.ExtractorTest do
end
"""

File.write("lib/ex_factor/source_module.ex", content)
File.write("lib/ex_factor/tmp/source_module.ex", content)

content = """
defmodule ExFactor.TargetModule do
defmodule ExFactor.Tmp.TargetModule do
@moduledoc false
@somedoc "This is somedoc TargetModule"
@doc "some docs"
Expand All @@ -256,25 +258,24 @@ defmodule ExFactor.ExtractorTest do
end
"""

File.write("lib/ex_factor/target_module.ex", content)
File.write("lib/ex_factor/tmp/target_module.ex", content)

opts = [
target_module: ExFactor.TargetModule,
source_module: ExFactor.SourceModule,
target_module: ExFactor.Tmp.TargetModule,
source_module: ExFactor.Tmp.SourceModule,
source_function: :refactor1,
arity: 1
]

Extractor.emplace(opts)

file = File.read!("lib/ex_factor/target_module.ex")
|> IO.inspect(label: "")
file = File.read!("lib/ex_factor/tmp/target_module.ex")
assert file =~ "def(refactor1(arg1)) do"
assert file =~ "def(refactor1([])) do"
assert file =~ " @doc \"some docs\""

File.rm("lib/ex_factor/source_module.ex")
File.rm("lib/ex_factor/target_module.ex")
File.rm("lib/ex_factor/tmp/source_module.ex")
File.rm("lib/ex_factor/tmp/target_module.ex")
end
end
end

0 comments on commit e00edef

Please sign in to comment.