Skip to content

Instantly share code, notes, and snippets.

@nimatrueway
Created October 12, 2017 06:45
Show Gist options
  • Save nimatrueway/aff9336eff532c64ea50c46b870b2bb0 to your computer and use it in GitHub Desktop.
Save nimatrueway/aff9336eff532c64ea50c46b870b2bb0 to your computer and use it in GitHub Desktop.
An implementation of ls -l in Scala
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