11defmodule Mix.Tasks.Archive.Install do
22 use Mix.Task
33
4- import Mix.Generator , only: [ create_file: 2 ]
5-
64 @ shortdoc "Install an archive locally"
75
86 @ moduledoc """
@@ -55,10 +53,15 @@ defmodule Mix.Tasks.Archive.Install do
5553
5654 if opts [ :force ] || should_install? ( src , previous ) do
5755 remove_previous_versions ( previous )
56+
5857 dest = Mix.Local . archives_path ( )
59- File . mkdir_p! ( dest )
6058 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+
6265 true = Code . append_path ( Mix.Archive . ebin ( archive ) )
6366 else
6467 false
@@ -81,6 +84,18 @@ defmodule Mix.Tasks.Archive.Install do
8184 "Are you sure you want to replace them?" )
8285 end
8386
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+
8499 defp previous_versions ( src ) do
85100 app = src
86101 |> Mix.Archive . dir
0 commit comments