diff --git a/src/main/scala/net/kemitix/s3thorp/Action.scala b/src/main/scala/net/kemitix/s3thorp/Action.scala index f261ec5..6e6bc75 100644 --- a/src/main/scala/net/kemitix/s3thorp/Action.scala +++ b/src/main/scala/net/kemitix/s3thorp/Action.scala @@ -1,9 +1,10 @@ package net.kemitix.s3thorp sealed trait Action -case class DoNothing(remoteKey: RemoteKey) extends Action -case class ToUpload(localFile: LocalFile) extends Action -case class ToCopy(sourceKey: RemoteKey, - hash: MD5Hash, - targetKey: RemoteKey) extends Action -case class ToDelete(remoteKey: RemoteKey) extends Action +final case class DoNothing(remoteKey: RemoteKey) extends Action +final case class ToUpload(localFile: LocalFile) extends Action +final case class ToCopy( + sourceKey: RemoteKey, + hash: MD5Hash, + targetKey: RemoteKey) extends Action +final case class ToDelete(remoteKey: RemoteKey) extends Action diff --git a/src/main/scala/net/kemitix/s3thorp/Config.scala b/src/main/scala/net/kemitix/s3thorp/Config.scala index b86a096..84c3a3b 100644 --- a/src/main/scala/net/kemitix/s3thorp/Config.scala +++ b/src/main/scala/net/kemitix/s3thorp/Config.scala @@ -2,15 +2,16 @@ package net.kemitix.s3thorp import java.io.File -case class Config(bucket: Bucket = Bucket(""), - prefix: RemoteKey = RemoteKey(""), - verbose: Int = 1, - filters: Seq[Filter] = List(), - excludes: Seq[Exclude] = List(), - multiPartThreshold: Long = 1024 * 1024 * 5, - maxRetries: Int = 3, - source: File - ) { +final case class Config( + bucket: Bucket = Bucket(""), + prefix: RemoteKey = RemoteKey(""), + verbose: Int = 1, + filters: Seq[Filter] = List(), + excludes: Seq[Exclude] = List(), + multiPartThreshold: Long = 1024 * 1024 * 5, + maxRetries: Int = 3, + source: File +) { require(source.isDirectory, s"Source must be a directory: $source") require(multiPartThreshold >= 1024 * 1024 * 5, s"Threshold for multi-part upload is 5Mb: '$multiPartThreshold'") } diff --git a/src/main/scala/net/kemitix/s3thorp/Counters.scala b/src/main/scala/net/kemitix/s3thorp/Counters.scala new file mode 100644 index 0000000..ee9dd1b --- /dev/null +++ b/src/main/scala/net/kemitix/s3thorp/Counters.scala @@ -0,0 +1,6 @@ +package net.kemitix.s3thorp + + +final case class Counters(uploaded: Int = 0, + deleted: Int = 0, + copied: Int = 0) diff --git a/src/main/scala/net/kemitix/s3thorp/Exclude.scala b/src/main/scala/net/kemitix/s3thorp/Exclude.scala index 818dc62..9fa8fc7 100644 --- a/src/main/scala/net/kemitix/s3thorp/Exclude.scala +++ b/src/main/scala/net/kemitix/s3thorp/Exclude.scala @@ -4,7 +4,7 @@ import java.nio.file.Path import java.util.function.Predicate import java.util.regex.Pattern -case class Exclude(exclude: String = "!.*") { +final case class Exclude(exclude: String = "!.*") { lazy val predicate: Predicate[String] = Pattern.compile(exclude).asPredicate() diff --git a/src/main/scala/net/kemitix/s3thorp/Filter.scala b/src/main/scala/net/kemitix/s3thorp/Filter.scala index 17ea823..f27ecab 100644 --- a/src/main/scala/net/kemitix/s3thorp/Filter.scala +++ b/src/main/scala/net/kemitix/s3thorp/Filter.scala @@ -4,7 +4,7 @@ import java.nio.file.Path import java.util.function.Predicate import java.util.regex.Pattern -case class Filter(filter: String = ".*") { +final case class Filter(filter: String = ".*") { lazy val predicate: Predicate[String] = Pattern.compile(filter).asPredicate.negate diff --git a/src/main/scala/net/kemitix/s3thorp/LocalFile.scala b/src/main/scala/net/kemitix/s3thorp/LocalFile.scala index 8c8dd1a..b3a112d 100644 --- a/src/main/scala/net/kemitix/s3thorp/LocalFile.scala +++ b/src/main/scala/net/kemitix/s3thorp/LocalFile.scala @@ -3,15 +3,17 @@ package net.kemitix.s3thorp import java.io.File import java.nio.file.Path -case class LocalFile(file: File, - source: File, - keyGenerator: File => RemoteKey) - (implicit c: Config) +final case class LocalFile( + file: File, + source: File, + keyGenerator: File => RemoteKey, + suppliedHash: Option[MD5Hash] = None) + (implicit c: Config) extends MD5HashGenerator { require(!file.isDirectory, s"LocalFile must not be a directory: $file") - private lazy val myhash = md5File(file) + private lazy val myhash = suppliedHash.getOrElse(md5File(file)) def hash: MD5Hash = myhash diff --git a/src/main/scala/net/kemitix/s3thorp/S3Action.scala b/src/main/scala/net/kemitix/s3thorp/S3Action.scala index 114e5d8..28d42ca 100644 --- a/src/main/scala/net/kemitix/s3thorp/S3Action.scala +++ b/src/main/scala/net/kemitix/s3thorp/S3Action.scala @@ -9,22 +9,25 @@ sealed trait S3Action { } -case class DoNothingS3Action(remoteKey: RemoteKey) extends S3Action { +final case class DoNothingS3Action(remoteKey: RemoteKey) extends S3Action { override val order: Int = 0 } -case class CopyS3Action(remoteKey: RemoteKey) extends S3Action { +final case class CopyS3Action(remoteKey: RemoteKey) extends S3Action { override val order: Int = 1 } -case class UploadS3Action(remoteKey: RemoteKey, - md5Hash: MD5Hash) extends S3Action { + +final case class UploadS3Action( + remoteKey: RemoteKey, + md5Hash: MD5Hash) extends S3Action { override val order: Int = 2 } -case class DeleteS3Action(remoteKey: RemoteKey) extends S3Action { + +final case class DeleteS3Action(remoteKey: RemoteKey) extends S3Action { override val order: Int = 3 } -case class ErroredS3Action(remoteKey: RemoteKey, e: Throwable) extends S3Action { +final case class ErroredS3Action(remoteKey: RemoteKey, e: Throwable) extends S3Action { override val order: Int = 10 } diff --git a/src/main/scala/net/kemitix/s3thorp/S3MetaData.scala b/src/main/scala/net/kemitix/s3thorp/S3MetaData.scala index aafd3ef..936988a 100644 --- a/src/main/scala/net/kemitix/s3thorp/S3MetaData.scala +++ b/src/main/scala/net/kemitix/s3thorp/S3MetaData.scala @@ -1,6 +1,7 @@ package net.kemitix.s3thorp // For the LocalFile, the set of matching S3 objects with the same MD5Hash, and any S3 object with the same remote key -case class S3MetaData(localFile: LocalFile, - matchByHash: Set[RemoteMetaData], - matchByKey: Option[RemoteMetaData]) \ No newline at end of file +final case class S3MetaData( + localFile: LocalFile, + matchByHash: Set[RemoteMetaData], + matchByKey: Option[RemoteMetaData]) diff --git a/src/main/scala/net/kemitix/s3thorp/SyncLogging.scala b/src/main/scala/net/kemitix/s3thorp/SyncLogging.scala index 2f4bc85..459fe1a 100644 --- a/src/main/scala/net/kemitix/s3thorp/SyncLogging.scala +++ b/src/main/scala/net/kemitix/s3thorp/SyncLogging.scala @@ -35,8 +35,4 @@ trait SyncLogging extends Logging { } } - case class Counters(uploaded: Int = 0, - deleted: Int = 0, - copied: Int = 0) - } diff --git a/src/main/scala/net/kemitix/s3thorp/awssdk/CancellableMultiPartUpload.scala b/src/main/scala/net/kemitix/s3thorp/awssdk/CancellableMultiPartUpload.scala index 60eb2bd..b2c9054 100644 --- a/src/main/scala/net/kemitix/s3thorp/awssdk/CancellableMultiPartUpload.scala +++ b/src/main/scala/net/kemitix/s3thorp/awssdk/CancellableMultiPartUpload.scala @@ -1,4 +1,5 @@ package net.kemitix.s3thorp.awssdk -case class CancellableMultiPartUpload(e: Throwable, - uploadId: String) extends Exception(e) +final case class CancellableMultiPartUpload( + e: Throwable, + uploadId: String) extends Exception(e) diff --git a/src/main/scala/net/kemitix/s3thorp/awssdk/S3ObjectsData.scala b/src/main/scala/net/kemitix/s3thorp/awssdk/S3ObjectsData.scala index ad5790a..01c6caf 100644 --- a/src/main/scala/net/kemitix/s3thorp/awssdk/S3ObjectsData.scala +++ b/src/main/scala/net/kemitix/s3thorp/awssdk/S3ObjectsData.scala @@ -5,7 +5,8 @@ import net.kemitix.s3thorp.{HashModified, KeyModified, MD5Hash, RemoteKey} /** * A list of objects and their MD5 hash values. */ -case class S3ObjectsData(byHash: Map[MD5Hash, Set[KeyModified]], - byKey: Map[RemoteKey, HashModified]) { +final case class S3ObjectsData( + byHash: Map[MD5Hash, Set[KeyModified]], + byKey: Map[RemoteKey, HashModified]) { } diff --git a/src/test/scala/net/kemitix/s3thorp/UnitTest.scala b/src/test/scala/net/kemitix/s3thorp/UnitTest.scala index c3a8163..b5caacc 100644 --- a/src/test/scala/net/kemitix/s3thorp/UnitTest.scala +++ b/src/test/scala/net/kemitix/s3thorp/UnitTest.scala @@ -8,9 +8,11 @@ abstract class UnitTest extends FunSpec { def aLocalFile(path: String, myHash: MD5Hash, source: File, fileToKey: File => RemoteKey) (implicit c: Config): LocalFile = - new LocalFile(source.toPath.resolve(path).toFile, source, fileToKey) { - override def hash: MD5Hash = myHash - } + LocalFile( + file = source.toPath.resolve(path).toFile, + source = source, + keyGenerator = fileToKey, + suppliedHash = Some(myHash)) def aRemoteKey(prefix: RemoteKey, path: String): RemoteKey = RemoteKey(prefix.key + "/" + path)