From f07851b9541070da761158de0da44d58cb7dcec0 Mon Sep 17 00:00:00 2001 From: HiFlii Date: Tue, 1 Apr 2025 18:09:30 -0400 Subject: [PATCH 1/2] feat: add pull & clone support w/ ssh keys --- .../kotlin/com/mineinabyss/keepup/cli/Main.kt | 3 +- .../com/mineinabyss/keepup/cli/PullCommand.kt | 69 +++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 keepup-cli/src/main/kotlin/com/mineinabyss/keepup/cli/PullCommand.kt diff --git a/keepup-cli/src/main/kotlin/com/mineinabyss/keepup/cli/Main.kt b/keepup-cli/src/main/kotlin/com/mineinabyss/keepup/cli/Main.kt index d1d1fe0..3e69c8e 100644 --- a/keepup-cli/src/main/kotlin/com/mineinabyss/keepup/cli/Main.kt +++ b/keepup-cli/src/main/kotlin/com/mineinabyss/keepup/cli/Main.kt @@ -16,5 +16,6 @@ class KeepupCommand : CliktCommand() { fun main(args: Array) = KeepupCommand().subcommands( PluginsCommand(), ConfigCommand(), - TemplateCommand() + TemplateCommand(), + PullCommand() ).main(args) diff --git a/keepup-cli/src/main/kotlin/com/mineinabyss/keepup/cli/PullCommand.kt b/keepup-cli/src/main/kotlin/com/mineinabyss/keepup/cli/PullCommand.kt new file mode 100644 index 0000000..c21fe25 --- /dev/null +++ b/keepup-cli/src/main/kotlin/com/mineinabyss/keepup/cli/PullCommand.kt @@ -0,0 +1,69 @@ +package com.mineinabyss.keepup.cli +import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.core.Context +import com.github.ajalt.clikt.parameters.arguments.argument +import com.github.ajalt.clikt.parameters.arguments.optional +import com.github.ajalt.clikt.parameters.options.option +import com.github.ajalt.clikt.parameters.options.required +import com.github.ajalt.clikt.parameters.types.path +import com.mineinabyss.keepup.t +import kotlin.io.path.* + +class PullCommand : CliktCommand(name = "pull"){ + override fun help(context: Context): String = "Pulls a github repository or clones it if it has not been previously pulled." + + val repo by argument(help = "Github repository to pull, specified as 'owner/repo_name'") + + val branch by argument(help = "Branch to pull").optional() + + val destRoot by option("-d", "--dest", help = "Will place repo as a directory inside this directory.") + .path(mustExist = false, canBeFile = false, mustBeWritable = false) + .required() + + val keyPath by option("-k", "--key-path", help = "Path to SSH key used to access private repos or get a higher rate limit") + .path(mustExist = true, canBeDir = false, mustBeReadable = true) + + fun runProcess(vararg command: String) { + ProcessBuilder() + .command(*command) + .redirectError(ProcessBuilder.Redirect.INHERIT) + .redirectOutput(ProcessBuilder.Redirect.INHERIT) + .start() + .waitFor() + } + + override fun run() { + val repoDir = destRoot.resolve(repo.split("/")[1]) + t.println("Pulling files from repo: $repo, branch: ${branch?: "default"}, to directory: $repoDir.") + + var sshString: String + if (keyPath != null) { + sshString = "core.sshCommand=ssh -i ${keyPath!!.toAbsolutePath()}" + } else { + sshString = "" + } + + var checkoutCommand: Array + if (branch != null) { + checkoutCommand = arrayOf("git", "-C", repoDir.toAbsolutePath().toString(), "checkout", branch!!) + } else { + checkoutCommand = emptyArray() + } + + var command: List + if (!repoDir.exists()) { + // Must clone if directory doesn't exist + t.println("Repository doesn't exist, cloning into $repoDir instead.") + repoDir.createDirectories() + runProcess("git", "clone", "-c", sshString, "git@github.com:${repo}.git", repoDir.toAbsolutePath().toString()) + if (branch != null) { // Checkout desired branch + runProcess(*checkoutCommand) + runProcess("git", "-C", repoDir.toAbsolutePath().toString(), "pull") // Pull branch, checkout only makes local copy + } + } else { + runProcess("git", "-C", repoDir.toAbsolutePath().toString(), "stash") // Stash first to discard local changes + runProcess(*checkoutCommand) + runProcess("git", "-C", repoDir.toAbsolutePath().toString(), "pull") + } + } +} \ No newline at end of file From 75831df35a2e69c5d5cc09e0d604ae6eaacfbc5b Mon Sep 17 00:00:00 2001 From: HiFlii Date: Tue, 1 Apr 2025 18:29:49 -0400 Subject: [PATCH 2/2] feat: add toggle for stashing --- .../com/mineinabyss/keepup/cli/PullCommand.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/keepup-cli/src/main/kotlin/com/mineinabyss/keepup/cli/PullCommand.kt b/keepup-cli/src/main/kotlin/com/mineinabyss/keepup/cli/PullCommand.kt index c21fe25..d398ef6 100644 --- a/keepup-cli/src/main/kotlin/com/mineinabyss/keepup/cli/PullCommand.kt +++ b/keepup-cli/src/main/kotlin/com/mineinabyss/keepup/cli/PullCommand.kt @@ -3,6 +3,7 @@ import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.core.Context import com.github.ajalt.clikt.parameters.arguments.argument import com.github.ajalt.clikt.parameters.arguments.optional +import com.github.ajalt.clikt.parameters.options.flag import com.github.ajalt.clikt.parameters.options.option import com.github.ajalt.clikt.parameters.options.required import com.github.ajalt.clikt.parameters.types.path @@ -23,6 +24,9 @@ class PullCommand : CliktCommand(name = "pull"){ val keyPath by option("-k", "--key-path", help = "Path to SSH key used to access private repos or get a higher rate limit") .path(mustExist = true, canBeDir = false, mustBeReadable = true) + val dontStashChanges by option("-n", "--no-stash", help = "Don't stash changes before pulling. If enabled, may fail pull if unable to merge.") + .flag(default = false) + fun runProcess(vararg command: String) { ProcessBuilder() .command(*command) @@ -50,7 +54,6 @@ class PullCommand : CliktCommand(name = "pull"){ checkoutCommand = emptyArray() } - var command: List if (!repoDir.exists()) { // Must clone if directory doesn't exist t.println("Repository doesn't exist, cloning into $repoDir instead.") @@ -61,7 +64,14 @@ class PullCommand : CliktCommand(name = "pull"){ runProcess("git", "-C", repoDir.toAbsolutePath().toString(), "pull") // Pull branch, checkout only makes local copy } } else { - runProcess("git", "-C", repoDir.toAbsolutePath().toString(), "stash") // Stash first to discard local changes + if (!dontStashChanges) { + runProcess( + "git", + "-C", + repoDir.toAbsolutePath().toString(), + "stash" + ) // Stash first to discard local changes + } runProcess(*checkoutCommand) runProcess("git", "-C", repoDir.toAbsolutePath().toString(), "pull") }