Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix fetching permissions through getPosixFileAttributes and add equality #3345

Merged
merged 4 commits into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,13 @@ ThisBuild / mimaBinaryIssueFilters ++= Seq(
// sealed trait: #3349
ProblemFilters.exclude[ReversedMissingMethodProblem](
"fs2.io.net.tls.TLSParameters.withClientAuthType"
),
// equals/hashCode/toString on file attributes: #3345
ProblemFilters.exclude[ReversedMissingMethodProblem](
"fs2.io.file.PosixFileAttributes.fs2$io$file$PosixFileAttributes$$super=uals"
),
ProblemFilters.exclude[ReversedMissingMethodProblem](
"fs2.io.file.PosixFileAttributes.fs2$io$file$PosixFileAttributes$$super#Code"
)
)

Expand Down
3 changes: 2 additions & 1 deletion io/jvm-native/src/main/scala/fs2/io/file/FilesPlatform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ private[file] trait FilesCompanionPlatform {
with PosixFileAttributes.UnsealedPosixFileAttributes {
def owner: Principal = attr.owner
def group: Principal = attr.group
def permissions: PosixPermissions = PosixPermissions.fromString(attr.permissions.toString).get
def permissions: PosixPermissions =
PosixPermissions.fromString(PosixFilePermissions.toString(attr.permissions)).get
}
}
48 changes: 48 additions & 0 deletions io/shared/src/main/scala/fs2/io/file/FileAttributes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,38 @@ sealed trait BasicFileAttributes {
def lastAccessTime: FiniteDuration
def lastModifiedTime: FiniteDuration
def size: Long

override def equals(that: Any): Boolean = that match {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Override hashCode and toString here too?

case other: BasicFileAttributes =>
creationTime == other.creationTime &&
fileKey == other.fileKey &&
isDirectory == other.isDirectory &&
isOther == other.isOther &&
isRegularFile == other.isRegularFile &&
isSymbolicLink == other.isSymbolicLink &&
lastAccessTime == other.lastAccessTime &&
lastModifiedTime == other.lastModifiedTime &&
size == other.size
case _ => false
}

override def hashCode: Int = {
import util.hashing.MurmurHash3.{stringHash, mix, finalizeHash}
val h = stringHash("FileAttributes")
mix(h, creationTime.##)
mix(h, fileKey.##)
mix(h, isDirectory.##)
mix(h, isOther.##)
mix(h, isRegularFile.##)
mix(h, isSymbolicLink.##)
mix(h, lastAccessTime.##)
mix(h, lastModifiedTime.##)
mix(h, size.##)
finalizeHash(h, 9)
}

override def toString: String =
s"BasicFileAttributes($creationTime, $fileKey, $isDirectory, $isOther, $isRegularFile, $isSymbolicLink, $lastAccessTime, $lastModifiedTime, $size)"
}

object BasicFileAttributes {
Expand All @@ -54,6 +86,22 @@ object BasicFileAttributes {
// the owner/group operations JVM only.
sealed trait PosixFileAttributes extends BasicFileAttributes {
def permissions: PosixPermissions

final override def equals(that: Any): Boolean = that match {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hashCode and toString as well?

case other: PosixFileAttributes => super.equals(other) && permissions == other.permissions
case _ => false
}

final override def hashCode: Int = {
import util.hashing.MurmurHash3.{stringHash, mix, finalizeHash}
val h = stringHash("PosixFileAttributes")
mix(h, super.hashCode)
mix(h, permissions.##)
finalizeHash(h, 2)
}

final override def toString: String =
s"PosixFileAttributes($creationTime, $fileKey, $isDirectory, $isOther, $isRegularFile, $isSymbolicLink, $lastAccessTime, $lastModifiedTime, $size, $permissions)"
}

object PosixFileAttributes {
Expand Down
17 changes: 17 additions & 0 deletions io/shared/src/test/scala/fs2/io/file/FilesSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -856,4 +856,21 @@ class FilesSuite extends Fs2IoSuite with BaseFileSuite {
}
}

group("attributes") {

test("basic attributes are consistent for the same file") {
tempFile.use { p =>
val attr = Files[IO].getBasicFileAttributes(p)
(attr, attr).mapN(assertEquals(_, _))
}
}

test("posix attributes are consistent for the same file") {
tempFile.use { p =>
val attr = Files[IO].getPosixFileAttributes(p)
(attr, attr).mapN(assertEquals(_, _))
}
}
}

}