Created
October 12, 2017 06:45
-
-
Save nimatrueway/aff9336eff532c64ea50c46b870b2bb0 to your computer and use it in GitHub Desktop.
An implementation of ls -l in Scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.File | |
import java.nio.file.attribute.{PosixFilePermission, PosixFileAttributes} | |
import java.nio.file.{Files, Path} | |
import java.time.format.DateTimeFormatter | |
import java.time.{LocalDateTime, ZoneId} | |
/* | |
A solution for assignment #1 | |
Nima Taheri ([email protected]) | |
*/ | |
class RichFile(file: Path) { | |
def getPermissions = { | |
val filePermissions = Files.getPosixFilePermissions(file) | |
val permissionToString = Seq( | |
(PosixFilePermission.OWNER_READ, "r"), | |
(PosixFilePermission.OWNER_WRITE, "w"), | |
(PosixFilePermission.OWNER_EXECUTE, "x"), | |
(PosixFilePermission.GROUP_READ, "r"), | |
(PosixFilePermission.GROUP_WRITE, "w"), | |
(PosixFilePermission.GROUP_EXECUTE, "x"), | |
(PosixFilePermission.OTHERS_READ, "r"), | |
(PosixFilePermission.OTHERS_WRITE, "w"), | |
(PosixFilePermission.OTHERS_EXECUTE, "x") | |
) | |
val permissions = permissionToString.map({ | |
case (permission, representation) if filePermissions.contains(permission) => representation | |
case _ => "-" | |
}).mkString | |
val directory = if (file.toFile.isDirectory) "d" else "-" | |
s"$directory$permissions" | |
} | |
def getOwner = { | |
Files.readAttributes(file, classOf[PosixFileAttributes]).owner().getName | |
} | |
def getGroup = { | |
Files.readAttributes(file, classOf[PosixFileAttributes]).group().getName | |
} | |
def getSize = { | |
file.toFile.length.toString | |
} | |
def getLastModificationDate = { | |
val now = LocalDateTime.now() | |
val lastModificationDate = LocalDateTime.ofInstant(Files.getLastModifiedTime(file).toInstant, ZoneId.systemDefault()) | |
val datePattern = | |
if (lastModificationDate.getYear == now.getYear) | |
DateTimeFormatter.ofPattern("MMM dd HH:mm") | |
else | |
DateTimeFormatter.ofPattern("MMM dd YYYY") | |
lastModificationDate.format(datePattern) | |
} | |
def getName = { | |
file.getFileName.toString | |
} | |
} | |
object LsSimulator { | |
def listFiles(path: String): Seq[String] = { | |
def addPadding(table: Seq[Seq[String]], widths: Seq[Int]) = { | |
table.map(_.zip(widths).map({ | |
case (column, 0) => column | |
case (column, width) => s"%${width}s".format(column) | |
})) | |
} | |
def findMaximumColumnLength(table: Seq[Seq[String]]) = { | |
if (table.nonEmpty) table.head.indices.map(col => table.map(_.apply(col).length).max) else Nil | |
} | |
val filesData = new File(path).listFiles().toSeq | |
.map(f => new RichFile(f.toPath)) | |
.map(rf => Seq(rf.getPermissions, rf.getOwner, rf.getGroup, rf.getSize, rf.getLastModificationDate, rf.getName)) | |
val columnLengths = findMaximumColumnLength(filesData).dropRight(1) :+ 0 // replace columnLength of lastItem with zero to skip right-padding on it | |
addPadding(filesData, columnLengths).map(_.mkString(" ")) | |
} | |
def main(args: Array[String]) = { | |
val path = args.headOption.getOrElse(System.getenv("HOME")) | |
println(listFiles(path).mkString("\n")) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment