Skip to content

Instantly share code, notes, and snippets.

@Groostav
Created September 10, 2016 00:10
Show Gist options
  • Save Groostav/992f95ca44408912128651bfb55ed359 to your computer and use it in GitHub Desktop.
Save Groostav/992f95ca44408912128651bfb55ed359 to your computer and use it in GitHub Desktop.
methods to coerce one file system directory "into" another
/**
* make `targetToModify` identical to `source` in as few changes as possible.
*/
@JvmStatic fun coerceTo(source: Path, targetToModify: Path){
NIOFiles.walkFileTree(targetToModify, PruneByComparisonFileVisitor(source, targetToModify))
NIOFiles.walkFileTree(source, AddByComparisonFileVisitor(source, targetToModify))
}
infix fun Int.pow(power: Int) = Math.pow(this.toDouble(), power.toDouble()).toInt()
class PruneByComparisonFileVisitor(val reference: Path, val targetToModify: Path) : FileVisitor<Path> {
override fun preVisitDirectory(dir: Path, attrs: BasicFileAttributes): FileVisitResult {
val relativePath = dir relativeTo targetToModify
if(relativePath.isEmpty){ return CONTINUE }
if((reference / relativePath).nodeEquals(dir)){ return CONTINUE }
FileUtils.deleteDirectory(dir.toFile())
return FileVisitResult.SKIP_SUBTREE
}
override fun postVisitDirectory(dir: Path, exc: IOException?) = CONTINUE
override fun visitFile(file: Path, attrs: BasicFileAttributes?): FileVisitResult {
val relativePath = file relativeTo targetToModify
//remember, the copy structure will replace older files with newer ones,
//we're only interested in deleting files.
if((reference / relativePath).nodeEquals(file)) { return CONTINUE }
NIOFiles.delete(file);
return CONTINUE
}
override fun visitFileFailed(file: Path, exc: IOException?) = CONTINUE
}
class AddByComparisonFileVisitor(val reference: Path, val targetToModify: Path) : FileVisitor<Path> {
override fun preVisitDirectory(dir: Path, attrs: BasicFileAttributes): FileVisitResult {
val relativePath = dir relativeTo reference
if(relativePath.isEmpty){ return CONTINUE }
val pathOnTarget = targetToModify / relativePath
if( ! pathOnTarget.nodeEquals(dir)){
NIOFiles.createDirectory(pathOnTarget)
}
return CONTINUE
}
override fun visitFileFailed(file: Path, exc: IOException?): FileVisitResult {
return CONTINUE;
}
override fun postVisitDirectory(dir: Path, exc: IOException?): FileVisitResult {
return CONTINUE;
}
override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult {
val target = targetToModify / (file relativeTo reference)
//TODO cache this? this is going to copy a lot of files over top of exact copies of those files.
FileUtils.copyFile(file.toFile(), target.toFile())
return CONTINUE;
}
}
fun Path.nodeEquals(other: Path): Boolean {
return (NIOFiles.exists(this) == NIOFiles.exists(other))
&& (this.fileName == other.fileName)
&& (NIOFiles.isDirectory(this) == NIOFiles.isDirectory(other))
&& (NIOFiles.isRegularFile(this) == NIOFiles.isRegularFile(other))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment