Skip to content

Commit b56ebec

Browse files
committed
Extract common code for archive- and escript-related tasks
1 parent d4894f8 commit b56ebec

File tree

7 files changed

+89
-67
lines changed

7 files changed

+89
-67
lines changed

lib/mix/lib/mix/local_utils.ex

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
defmodule Mix.Local.Utils do
2+
@moduledoc """
3+
This module collects pieces of common functionality utilized by archive- and escript-related
4+
tasks.
5+
"""
6+
7+
@doc """
8+
Print a list of items in a uniform way. Used for printing the list of installed archives and
9+
escripts.
10+
11+
## Options
12+
13+
* `:empty_message` - the message to print when there are no items
14+
* `:footnote` - the message to print after the list
15+
16+
"""
17+
def print_list([], options) do
18+
Mix.shell.info Keyword.get(options, :empty_message, "No items found.")
19+
end
20+
21+
def print_list(items, options) do
22+
Enum.each items, fn item -> Mix.shell.info ["* ", item] end
23+
Mix.shell.info Keyword.get(options, :footnote, "")
24+
end
25+
26+
@doc """
27+
A common implementation for uninstalling archives, scripts, etc.
28+
29+
## Options
30+
31+
* `:item_name` - the name of the item being uninstalled. Also the name of the task which is used
32+
to print a list of all such items
33+
* `:item_plural` - plural of item name
34+
35+
"""
36+
def uninstall(argv, root, options) do
37+
{_, argv, _} = OptionParser.parse(argv)
38+
39+
item_name = Keyword.fetch!(options, :item_name)
40+
item_plural = Keyword.fetch!(options, :item_plural)
41+
42+
if name = List.first(argv) do
43+
path = Path.join(root, name)
44+
if File.regular?(path) do
45+
if should_uninstall?(path, item_name), do: File.rm!(path)
46+
else
47+
Mix.shell.error "Could not find a local #{item_name} named #{inspect name}. "<>
48+
"Existing #{item_plural} are:"
49+
Mix.Task.run item_name
50+
end
51+
else
52+
Mix.raise "No #{item_name} was given to #{item_name}.uninstall"
53+
end
54+
end
55+
56+
@doc """
57+
Parse `path_or_url` as a URI and return its base name.
58+
"""
59+
def basename(path_or_url) do
60+
if path = URI.parse(path_or_url).path do
61+
Path.basename(path)
62+
else
63+
Mix.raise "Expected #{inspect path_or_url} to be a url or a local file path"
64+
end
65+
end
66+
67+
defp should_uninstall?(path, item_name) do
68+
Mix.shell.yes?("Are you sure you want to uninstall #{item_name} #{path}?")
69+
end
70+
end

lib/mix/lib/mix/tasks/archive.ex

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,10 @@ defmodule Mix.Tasks.Archive do
2121
Mix.Local.archives_path
2222
|> Path.join("*.ez")
2323
|> Path.wildcard()
24+
|> Enum.map(&Path.basename/1)
2425

25-
if archives == [] do
26-
Mix.shell.info "No archives currently installed."
27-
else
28-
Enum.each archives, fn archive ->
29-
Mix.shell.info "* #{Path.basename(archive)}"
30-
end
31-
32-
Mix.shell.info "Archives installed at: #{Mix.Local.archives_path}"
33-
end
26+
Mix.Local.Utils.print_list(archives,
27+
empty_message: "No archives currently installed.",
28+
footnote: "Archives installed at: #{Mix.Local.archives_path}")
3429
end
3530
end

lib/mix/lib/mix/tasks/archive.install.ex

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,9 @@ defmodule Mix.Tasks.Archive.Install do
3434
{opts, argv, _} = OptionParser.parse(argv, switches: @switches)
3535

3636
if src = List.first(argv) do
37-
%URI{path: path} = URI.parse(src)
38-
39-
case Path.extname(path) do
37+
case Path.extname(Mix.Local.Utils.basename(src)) do
4038
".ez" -> install_archive(src, opts)
41-
_ -> Mix.raise "\"mix archive.install\" doesn't know how to install #{inspect path}"
39+
_ -> Mix.raise "\"mix archive.install\" doesn't know how to install #{inspect src}"
4240
end
4341
else
4442
src = Mix.Archive.name(Mix.Project.config[:app], Mix.Project.config[:version])
@@ -57,7 +55,7 @@ defmodule Mix.Tasks.Archive.Install do
5755

5856
if opts[:force] || should_install?(src, previous) do
5957
dirname = Mix.Local.archives_path
60-
archive = Path.join(dirname, basename(src))
58+
archive = Path.join(dirname, Mix.Local.Utils.basename(src))
6159
check_file_exists!(src, archive)
6260

6361
case Mix.Utils.read_path(src, opts) do
@@ -91,14 +89,6 @@ defmodule Mix.Tasks.Archive.Install do
9189
end
9290
end
9391

94-
defp basename(path) do
95-
if path = URI.parse(path).path do
96-
Path.basename(path)
97-
else
98-
Mix.raise "Expected #{inspect path} to be a url or a local file path"
99-
end
100-
end
101-
10292
defp should_install?(src, []) do
10393
Mix.shell.yes?("Are you sure you want to install archive #{inspect src}?")
10494
end

lib/mix/lib/mix/tasks/archive.uninstall.ex

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,8 @@ defmodule Mix.Tasks.Archive.Uninstall do
1111
"""
1212
@spec run(OptionParser.argv) :: :ok
1313
def run(argv) do
14-
{_, argv, _} = OptionParser.parse(argv)
15-
16-
if name = List.first(argv) do
17-
path = Path.join(Mix.Local.archives_path, name)
18-
if File.regular?(path) do
19-
File.rm!(path)
20-
else
21-
Mix.shell.error "Could not find a local archive named #{inspect name}. "<>
22-
"Existing archives are:"
23-
Mix.Task.run "archive"
24-
end
25-
else
26-
Mix.raise "No archive was given to archive.uninstall"
27-
end
14+
Mix.Local.Utils.uninstall(argv, Mix.Local.archives_path,
15+
item_name: "archive",
16+
item_plural: "archives")
2817
end
2918
end

lib/mix/lib/mix/tasks/escript.ex

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,12 @@ defmodule Mix.Tasks.Escript do
1818

1919
escripts =
2020
escripts_path
21-
|> list_dir
21+
|> list_dir()
2222
|> Enum.filter(fn filename -> executable?(Path.join([escripts_path, filename])) end)
2323

24-
if escripts == [] do
25-
Mix.shell.info "No escripts currently installed."
26-
else
27-
Enum.each escripts, fn filename ->
28-
Mix.shell.info "* #{filename}"
29-
end
30-
31-
Mix.shell.info "Escripts installed at: #{escripts_path}"
32-
end
24+
Mix.Local.Utils.print_list(escripts,
25+
empty_message: "No escripts currently installed.",
26+
footnote: "Escripts installed at: #{escripts_path}")
3327
end
3428

3529
defp list_dir(path) do

lib/mix/lib/mix/tasks/escript.install.ex

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ defmodule Mix.Tasks.Escript.Install do
6363
@escript_file_mode 0o555 # only read and execute permissions
6464

6565
defp install_escript(src, opts) do
66-
dst = Path.join([Mix.Local.escripts_path, basename(src)])
66+
dst = Path.join([Mix.Local.escripts_path, Mix.Local.Utils.basename(src)])
6767
if opts[:force] || should_install?(src, File.exists?(dst)) do
6868
File.rm(dst)
6969
if Mix.Utils.copy_path!(src, dst, opts) do
@@ -87,15 +87,10 @@ defmodule Mix.Tasks.Escript.Install do
8787
end
8888

8989
defp should_install?(src, true) do
90-
Mix.shell.yes?("Found existing escript: #{basename(src)}.\n" <>
90+
Mix.shell.yes?("Found existing escript: #{Mix.Local.Utils.basename(src)}.\n" <>
9191
"Are you sure you want to replace it?")
9292
end
9393

94-
defp basename(path) do
95-
%URI{path: path} = URI.parse(path)
96-
Path.basename(path)
97-
end
98-
9994
defp check_discoverability(path) do
10095
executable = Path.basename(path)
10196
sys_path = System.find_executable(executable)

lib/mix/lib/mix/tasks/escript.uninstall.ex

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,8 @@ defmodule Mix.Tasks.Escript.Uninstall do
1111
"""
1212
@spec run(OptionParser.argv) :: :ok
1313
def run(argv) do
14-
{_, argv, _} = OptionParser.parse(argv)
15-
16-
if name = List.first(argv) do
17-
path = Path.join(Mix.Local.escripts_path, name)
18-
if File.regular?(path) do
19-
File.rm!(path)
20-
else
21-
Mix.shell.error "Could not find a local escript named #{inspect name}. "<>
22-
"Existing escripts are:"
23-
Mix.Task.run "escript"
24-
end
25-
else
26-
Mix.raise "No escript was given to escript.uninstall"
27-
end
14+
Mix.Local.Utils.uninstall(argv, Mix.Local.escripts_path,
15+
item_name: "escript",
16+
item_plural: "escripts")
2817
end
2918
end

0 commit comments

Comments
 (0)