CLI implementation & linting (#2)
All checks were successful
Test Workflow / Lint and test library (push) Successful in 17m11s
Publish Workflow / Publish library (push) Successful in 8m49s

Implement a basic CLI interface & add linting to the project.

Reviewed-on: #2
This commit is contained in:
2023-12-30 06:36:49 +00:00
parent 36728fa1e9
commit 694b8d4d28
16 changed files with 563 additions and 229 deletions

80
src/main/kotlin/Main.kt Normal file
View File

@@ -0,0 +1,80 @@
import aws.sdk.kotlin.services.s3.S3Client
import backup.BackupClient
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.subcommands
import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.arguments.help
import com.github.ajalt.clikt.parameters.types.file
import kotlinx.coroutines.runBlocking
import kotlin.system.exitProcess
fun main(args: Array<String>) =
runBlocking {
S3Client.fromEnvironment().use { s3 ->
S3BackupTool()
.subcommands(
Create(s3),
Restore(s3),
RestoreFile(s3),
)
.main(args)
}
}
class S3BackupTool : CliktCommand(
help = "A simple AWS S3 backup tool. This tool assumes credentials are properly configured using aws-cli.",
) {
override fun run() {
shortHelp(currentContext)
}
}
class Create(val s3: S3Client) : CliktCommand(
help = "Create a backup of a file or directory.",
) {
val source by argument().file(mustExist = true).help("File or directory to backup")
val bucket by argument().help("Name of S3 bucket to backup to")
override fun run() =
runBlocking {
val backupKey = BackupClient(s3, bucket).upload(source)
echo("Successfully created backup with key '$backupKey'")
}
}
class Restore(val s3: S3Client) : CliktCommand(
help = "Restore a backup from AWS S3.",
) {
val bucket by argument().help("Name of S3 bucket to restore the backup from")
val backupKey by argument().help("The S3 key of the backup to restore")
val destination by argument().file(mustExist = true).help("Directory to restore to")
override fun run() =
runBlocking {
if (!destination.isDirectory) {
echo("Destination must be an existing directory", err = true)
exitProcess(1)
}
BackupClient(s3, bucket).restore(destination.toPath(), backupKey)
echo("Successfully restored backup '$backupKey' to '$destination'")
}
}
class RestoreFile(val s3: S3Client) : CliktCommand(
help = "Restore a single file from a backup from AWS S3.",
) {
val bucket by argument().help("Name of S3 bucket to restore the backup from")
val backupKey by argument().help("The S3 key of the backup to restore")
val filePath by argument().help("File path within the backup")
val destination by argument().file(mustExist = true).help("Directory to restore to")
override fun run() =
runBlocking {
if (!destination.isDirectory) {
echo("Destination must be an existing directory", err = true)
exitProcess(1)
}
BackupClient(s3, bucket).restoreFile(destination.toPath(), backupKey, filePath)
echo("Successfully restored '$filePath' from backup '$backupKey' to '$destination'")
}
}