Skip to content

Commit

Permalink
Drop exceptions in deleteIfExists
Browse files Browse the repository at this point in the history
The legacy behavior of IO.delete is that it leaves behind any files in
the tree that it is unable to delete. This is because File.delete only
throws if an AccessDeniedException occurs. On windows, it is not unusual
for deletions to fail because a jar or class file is in use somewhere.
As a result, we leak temporary directories all over the place. These
silent failures also impacts the DefaultBackgroundJobService which does
not actually correctly clean up jar files when sbt exits.

At any rate, much of sbt relies on the legacy behavior so I had to add
logic to swallow exceptions. I didn't switch back to File.delete to make
it clear that this method is broken semantically.
  • Loading branch information
eatkins committed May 2, 2019
1 parent 620cb0b commit fa0d0ee
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions io/src/main/scala/sbt/io/IO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -551,17 +551,23 @@ object IO {
deleteEmpty(parents(files.toSet))
}

/** Deletes `file`, recursively if it is a directory. */
/**
* Deletes `file`, recursively if it is a directory. Note that this method may silently fail to
* delete the file (or directory) if any errors occur.
*/
def delete(file: File): Unit = Retry {
try {
FileTreeView.default.list(file.toPath).foreach {
case (dir, attrs) if attrs.isDirectory => delete(dir.toFile)
case (f, _) => Files.deleteIfExists(f)
case (f, _) =>
try Files.deleteIfExists(f)
catch { case _: IOException => }
}
} catch {
case _: NotDirectoryException =>
}
Files.deleteIfExists(file.toPath)
try Files.deleteIfExists(file.toPath)
catch { case _: IOException => }
()
}

Expand Down

0 comments on commit fa0d0ee

Please sign in to comment.