@@ -1619,6 +1619,13 @@ defmodule File do
16191619 directories removed in no specific order, `{:error, reason, file}`
16201620 otherwise.
16211621
1622+ ## Options
1623+
1624+ * `:each_directory` - (since v1.20.0) a callback invoked for each
1625+ directory before its contents are deleted. The callback receives the
1626+ directory path as a binary. It is useful, for example, to grant write
1627+ permission to a directory before attempting to delete it.
1628+
16221629 ## Examples
16231630
16241631 File.rm_rf("samples")
@@ -1630,24 +1637,28 @@ defmodule File do
16301637 File.rm_rf("/tmp")
16311638 #=> {:error, :eperm, "/tmp"}
16321639 """
1633- @ spec rm_rf ( Path . t ( ) ) :: { :ok , [ binary ] } | { :error , posix | :badarg , binary }
1634- def rm_rf ( path ) do
1640+ @ spec rm_rf ( Path . t ( ) , each_directory: ( Path . t ( ) -> term ) ) ::
1641+ { :ok , [ binary ] } | { :error , posix | :badarg , binary }
1642+ def rm_rf ( path , options \\ [ ] ) do
16351643 { major , _ } = :os . type ( )
1644+ each_directory = Keyword . get ( options , :each_directory , fn _ -> :ok end )
16361645
16371646 path
16381647 |> IO . chardata_to_string ( )
16391648 |> assert_no_null_byte! ( "File.rm_rf/1" )
1640- |> do_rm_rf ( [ ] , major )
1649+ |> do_rm_rf ( [ ] , major , each_directory )
16411650 end
16421651
1643- defp do_rm_rf ( path , acc , major ) do
1652+ defp do_rm_rf ( path , acc , major , each_directory ) do
16441653 case safe_list_dir ( path , major ) do
16451654 { :ok , files } when is_list ( files ) ->
1655+ each_directory . ( path )
1656+
16461657 acc =
16471658 Enum . reduce ( files , acc , fn file , acc ->
16481659 # In case we can't delete, continue anyway, we might succeed
16491660 # to delete it on Windows due to how they handle symlinks.
1650- case do_rm_rf ( Path . join ( path , file ) , acc , major ) do
1661+ case do_rm_rf ( Path . join ( path , file ) , acc , major , each_directory ) do
16511662 { :ok , acc } -> acc
16521663 { :error , _ , _ } -> acc
16531664 end
@@ -1723,7 +1734,7 @@ defmodule File do
17231734 end
17241735
17251736 @ doc """
1726- Same as `rm_rf/1 ` but raises a `File.Error` exception in case of failures,
1737+ Same as `rm_rf/2 ` but raises a `File.Error` exception in case of failures,
17271738 otherwise returns the list of files or directories removed.
17281739
17291740 ## Examples
@@ -1737,9 +1748,9 @@ defmodule File do
17371748 File.rm_rf!("/tmp")
17381749 ** (File.Error) could not remove files and directories recursively from "/tmp": not owner
17391750 """
1740- @ spec rm_rf! ( Path . t ( ) ) :: [ binary ]
1741- def rm_rf! ( path ) do
1742- case rm_rf ( path ) do
1751+ @ spec rm_rf! ( Path . t ( ) , each_directory: ( Path . t ( ) -> term ) ) :: [ binary ]
1752+ def rm_rf! ( path , options \\ [ ] ) do
1753+ case rm_rf ( path , options ) do
17431754 { :ok , files } ->
17441755 files
17451756
0 commit comments