1
1
defmodule Mix.Tasks.Archive.Install do
2
2
use Mix.Task
3
3
4
- import Mix.Generator , only: [ create_file: 2 ]
5
-
6
4
@ shortdoc "Install an archive locally"
7
5
8
6
@ moduledoc """
@@ -55,10 +53,15 @@ defmodule Mix.Tasks.Archive.Install do
55
53
56
54
if opts [ :force ] || should_install? ( src , previous ) do
57
55
remove_previous_versions ( previous )
56
+
58
57
dest = Mix.Local . archives_path ( )
59
- File . mkdir_p! ( dest )
60
58
archive = Path . join ( dest , basename ( src ) )
61
- create_file archive , Mix.Utils . read_path! ( src , opts )
59
+ check_file_exists ( archive )
60
+
61
+ File . mkdir_p! ( dest )
62
+ File . write! ( archive , Mix.Utils . read_path! ( src , opts ) )
63
+ Mix . shell . info [ :green , "* creating " , :reset , Path . relative_to_cwd ( archive ) ]
64
+
62
65
true = Code . append_path ( Mix.Archive . ebin ( archive ) )
63
66
else
64
67
false
@@ -81,6 +84,18 @@ defmodule Mix.Tasks.Archive.Install do
81
84
"Are you sure you want to replace them?" )
82
85
end
83
86
87
+ defp check_file_exists ( path ) do
88
+ # OTP keeps loaded archives open, this leads to unfortunate behaviour on
89
+ # Windows when trying overwrite loaded archives. remove_previous_versions
90
+ # completes successfully even though the file will be first removed after
91
+ # the BEAM process is dead. Because of this we ask the user rerun the
92
+ # command, which should complete successfully at that time
93
+
94
+ if File . exists? ( path ) and match? ( { :win32 , _ } , :os . type ) do
95
+ Mix . raise "Unable to overwrite open archives on Windows. Run the command again"
96
+ end
97
+ end
98
+
84
99
defp previous_versions ( src ) do
85
100
app = src
86
101
|> Mix.Archive . dir
0 commit comments