feat(colors): colored output; removed colorutils
This commit is contained in:
@@ -10,7 +10,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = "org.notevc"
|
||||
version = "1.0.7"
|
||||
version = "1.0.8"
|
||||
|
||||
buildConfig {
|
||||
buildConfigField("String", "VERSION", "\"${project.version}\"")
|
||||
@@ -26,7 +26,7 @@ dependencies {
|
||||
val junitVersion = "5.10.0"
|
||||
implementation(kotlin("stdlib"))
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
|
||||
implementation("org.kargs:kargs:1.0.4")
|
||||
implementation("org.kargs:kargs:1.0.8")
|
||||
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion")
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitVersion")
|
||||
|
||||
@@ -2,12 +2,17 @@ package org.notevc
|
||||
|
||||
import org.notevc.core.Repository
|
||||
import org.notevc.commands.*
|
||||
import org.notevc.utils.ColorUtils
|
||||
import org.kargs.*
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val argsList = args.toMutableList()
|
||||
|
||||
// Create argument parser
|
||||
val parser = Parser("notevc", ParserConfig(programVersion = Repository.VERSION))
|
||||
val parser = Parser("notevc", ParserConfig(programVersion = Repository.VERSION, colorsEnabled = true))
|
||||
|
||||
if (argsList.remove("--no-color")) {
|
||||
Colors.setGlobalColorsEnabled(false)
|
||||
} else Colors.setGlobalColorsEnabled(true)
|
||||
|
||||
// Register subcommands
|
||||
parser.subcommands(
|
||||
@@ -22,7 +27,7 @@ fun main(args: Array<String>) {
|
||||
|
||||
// Parse arguments
|
||||
try {
|
||||
parser.parse(args)
|
||||
parser.parse(argsList.toTypedArray())
|
||||
} catch (e: Exception) {
|
||||
kotlin.system.exitProcess(1)
|
||||
}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
package org.notevc.cli
|
||||
@@ -7,12 +7,8 @@ import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import java.nio.file.Files
|
||||
import java.time.Instant
|
||||
import org.notevc.utils.ColorUtils
|
||||
import kotlin.io.path.*
|
||||
import org.kargs.Subcommand
|
||||
import org.kargs.ArgType
|
||||
import org.kargs.Option
|
||||
import org.kargs.Argument
|
||||
import org.kargs.*
|
||||
|
||||
class CommitCommand : Subcommand("commit", description = "Create a commit of changed files") {
|
||||
val targetFile by Option(ArgType.readableFile(), longName = "file", shortName = "f", description = "Commit only a specific file")
|
||||
@@ -30,7 +26,7 @@ class CommitCommand : Subcommand("commit", description = "Create a commit of cha
|
||||
}
|
||||
|
||||
result.onSuccess { message -> println(message) }
|
||||
result.onFailure { error -> println("${ColorUtils.error("Error:")} ${error.message}") }
|
||||
result.onFailure { error -> println("${Colors.error("Error:")} ${error.message}") }
|
||||
}
|
||||
|
||||
private fun createSingleFileCommit(repo: Repository, targetFile: String, message: String): String {
|
||||
@@ -77,9 +73,9 @@ class CommitCommand : Subcommand("commit", description = "Create a commit of cha
|
||||
updateRepositoryHead(repo, commitHash, timestamp, message)
|
||||
|
||||
return buildString {
|
||||
appendLine("${ColorUtils.success("Created commit")} ${ColorUtils.hash(commitHash)}")
|
||||
appendLine("${ColorUtils.bold("Message:")} $message")
|
||||
appendLine("${ColorUtils.bold("File:")} ${ColorUtils.filename(relativePath)} ${ColorUtils.dim("(${snapshot.blocks.size} blocks)")}")
|
||||
appendLine("${Colors.success("Created commit")} ${Colors.yellow(commitHash)}")
|
||||
appendLine("${Colors.bold("Message:")} $message")
|
||||
appendLine("${Colors.bold("File:")} ${Colors.filename(relativePath)} ${Colors.dim("(${snapshot.blocks.size} blocks)")}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,16 +136,16 @@ class CommitCommand : Subcommand("commit", description = "Create a commit of cha
|
||||
updateRepositoryHead(repo, commitHash, timestamp, message)
|
||||
|
||||
return buildString {
|
||||
appendLine("${ColorUtils.success("Created commit")} ${ColorUtils.hash(commitHash)}")
|
||||
appendLine("${ColorUtils.bold("Message:")} $message")
|
||||
appendLine("${ColorUtils.bold("Files committed:")} ${changedFiles.size}")
|
||||
appendLine("${ColorUtils.bold("Total blocks:")} $totalBlocksStored")
|
||||
appendLine("${Colors.success("Created commit")} ${Colors.yellow(commitHash)}")
|
||||
appendLine("${Colors.bold("Message:")} $message")
|
||||
appendLine("${Colors.bold("Files committed:")} ${changedFiles.size}")
|
||||
appendLine("${Colors.bold("Total blocks:")} $totalBlocksStored")
|
||||
appendLine()
|
||||
changedFiles.forEach { fileInfo ->
|
||||
val parts = fileInfo.split(" (")
|
||||
val filename = parts[0]
|
||||
val blockInfo = if (parts.size > 1) " (${parts[1]}" else ""
|
||||
appendLine(" ${ColorUtils.filename(filename)}${ColorUtils.dim(blockInfo)}")
|
||||
appendLine(" ${Colors.filename(filename)}${Colors.dim(blockInfo)}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.notevc.commands
|
||||
|
||||
import org.notevc.core.*
|
||||
import org.notevc.utils.ColorUtils
|
||||
import kotlinx.serialization.json.Json
|
||||
import java.nio.file.Files
|
||||
import java.time.Instant
|
||||
@@ -53,7 +52,7 @@ class DiffCommand : Subcommand("diff", description = "Show differences between c
|
||||
}
|
||||
|
||||
result.onSuccess { message -> println(message) }
|
||||
result.onFailure { error -> println("${ColorUtils.error("Error:")} ${error.message}") }
|
||||
result.onFailure { error -> println("${Colors.error("Error:")} ${error.message}") }
|
||||
}
|
||||
|
||||
private fun compareSpecificBlock(repo: Repository, commitHash: String?, blockHash: String, targetFile: String?): String {
|
||||
@@ -66,13 +65,13 @@ class DiffCommand : Subcommand("diff", description = "Show differences between c
|
||||
}
|
||||
|
||||
val result = StringBuilder()
|
||||
result.appendLine("${ColorUtils.bold("Block comparison:")} ${ColorUtils.hash(blockHash.take(8))}")
|
||||
result.appendLine("${Colors.bold("Block comparison:")} ${Colors.yellow(blockHash.take(8))}")
|
||||
result.appendLine()
|
||||
|
||||
// Get the commit snapshot if provided, otherwise use latest
|
||||
val commitSnapshot = if (commitHash != null) {
|
||||
val commit = findCommit(repo, commitHash)
|
||||
?: throw Exception("Commit ${ColorUtils.hash(commitHash)} not found")
|
||||
?: throw Exception("Commit ${Colors.yellow(commitHash)} not found")
|
||||
val commitTime = Instant.parse(commit.timestamp)
|
||||
blockStore.getLatestBlockSnapshotBefore(targetFile, commitTime)
|
||||
} else {
|
||||
@@ -94,41 +93,41 @@ class DiffCommand : Subcommand("diff", description = "Show differences between c
|
||||
val newBlock = currentSnapshot.blocks.find { it.id.startsWith(blockHash) }
|
||||
|
||||
if (oldBlock == null && newBlock == null) {
|
||||
throw Exception("Block ${ColorUtils.hash(blockHash)} not found")
|
||||
throw Exception("Block ${Colors.yellow(blockHash)} not found")
|
||||
}
|
||||
|
||||
val headingText = (newBlock?.heading ?: oldBlock?.heading ?: "").replace(Regex("^#+\\s*"), "").trim()
|
||||
|
||||
result.appendLine("${ColorUtils.heading(headingText)} ${ColorUtils.dim("[${blockHash.take(8)}]")}")
|
||||
result.appendLine("${ColorUtils.dim("─".repeat(70))}")
|
||||
result.appendLine("${Colors.heading(headingText)} ${Colors.dim("[${blockHash.take(8)}]")}")
|
||||
result.appendLine(Colors.dim("─".repeat(70)))
|
||||
result.appendLine()
|
||||
|
||||
when {
|
||||
oldBlock == null && newBlock != null -> {
|
||||
result.appendLine("${ColorUtils.success("This block was ADDED")}")
|
||||
result.appendLine(Colors.green("This block was ADDED"))
|
||||
result.appendLine()
|
||||
val newContent = objectStore.getContent(newBlock.contentHash)
|
||||
if (newContent != null) {
|
||||
newContent.lines().forEach { line ->
|
||||
result.appendLine("${ColorUtils.success("+ ")} $line")
|
||||
result.appendLine("${Colors.green("+ ")} $line")
|
||||
}
|
||||
}
|
||||
}
|
||||
oldBlock != null && newBlock == null -> {
|
||||
result.appendLine("${ColorUtils.error("This block was DELETED")}")
|
||||
result.appendLine(Colors.error("This block was DELETED"))
|
||||
result.appendLine()
|
||||
val oldContent = objectStore.getContent(oldBlock.contentHash)
|
||||
if (oldContent != null) {
|
||||
oldContent.lines().forEach { line ->
|
||||
result.appendLine("${ColorUtils.error("- ")} $line")
|
||||
result.appendLine("${Colors.error("- ")} $line")
|
||||
}
|
||||
}
|
||||
}
|
||||
oldBlock != null && newBlock != null -> {
|
||||
if (oldBlock.contentHash == newBlock.contentHash) {
|
||||
result.appendLine("${ColorUtils.dim("No changes")}")
|
||||
result.appendLine(Colors.dim("No changes"))
|
||||
} else {
|
||||
result.appendLine("${ColorUtils.warning("Block was MODIFIED")}")
|
||||
result.appendLine(Colors.warn("Block was MODIFIED"))
|
||||
result.appendLine()
|
||||
val oldContent = objectStore.getContent(oldBlock.contentHash)
|
||||
val newContent = objectStore.getContent(newBlock.contentHash)
|
||||
@@ -152,9 +151,9 @@ class DiffCommand : Subcommand("diff", description = "Show differences between c
|
||||
|
||||
// Find commits
|
||||
val commit1 = findCommit(repo, hash1)
|
||||
?: throw Exception("Commit ${ColorUtils.hash(hash1)} not found")
|
||||
?: throw Exception("Commit ${Colors.yellow(hash1)} not found")
|
||||
val commit2 = findCommit(repo, hash2)
|
||||
?: throw Exception("Commit ${ColorUtils.hash(hash2)} not found")
|
||||
?: throw Exception("Commit ${Colors.yellow(hash2)} not found")
|
||||
|
||||
val time1 = Instant.parse(commit1.timestamp)
|
||||
val time2 = Instant.parse(commit2.timestamp)
|
||||
@@ -170,9 +169,9 @@ class DiffCommand : Subcommand("diff", description = "Show differences between c
|
||||
}
|
||||
|
||||
val result = StringBuilder()
|
||||
result.appendLine("${ColorUtils.bold("Comparing commits:")}")
|
||||
result.appendLine(" ${ColorUtils.hash(hash1.take(8))} ${ColorUtils.dim(commit1.message)}")
|
||||
result.appendLine(" ${ColorUtils.hash(hash2.take(8))} ${ColorUtils.dim(commit2.message)}")
|
||||
result.appendLine(Colors.bold("Comparing commits:"))
|
||||
result.appendLine(" ${Colors.yellow(hash1.take(8))} ${Colors.dim(commit1.message)}")
|
||||
result.appendLine(" ${Colors.yellow(hash2.take(8))} ${Colors.dim(commit2.message)}")
|
||||
result.appendLine()
|
||||
|
||||
var totalChanges = 0
|
||||
@@ -184,7 +183,7 @@ class DiffCommand : Subcommand("diff", description = "Show differences between c
|
||||
if (snapshot1 != null || snapshot2 != null) {
|
||||
val changes = blockStore.compareBlocks(snapshot1, snapshot2)
|
||||
if (changes.isNotEmpty()) {
|
||||
result.appendLine("${ColorUtils.filename(filePath)}:")
|
||||
result.appendLine("${Colors.filename(filePath)}:")
|
||||
result.append(formatBlockChanges(changes, objectStore))
|
||||
result.appendLine()
|
||||
totalChanges += changes.size
|
||||
@@ -193,9 +192,9 @@ class DiffCommand : Subcommand("diff", description = "Show differences between c
|
||||
}
|
||||
|
||||
if (totalChanges == 0) {
|
||||
result.appendLine("${ColorUtils.dim("No differences found")}")
|
||||
result.appendLine(Colors.dim("No differences found"))
|
||||
} else {
|
||||
result.appendLine("${ColorUtils.bold("Total changes:")} $totalChanges")
|
||||
result.appendLine("${Colors.bold("Total changes:")} $totalChanges")
|
||||
}
|
||||
|
||||
return result.toString()
|
||||
@@ -208,7 +207,7 @@ class DiffCommand : Subcommand("diff", description = "Show differences between c
|
||||
|
||||
// Find commit
|
||||
val commit = findCommit(repo, hash)
|
||||
?: throw Exception("Commit ${ColorUtils.hash(hash)} not found")
|
||||
?: throw Exception("Commit ${Colors.yellow(hash)} not found")
|
||||
|
||||
val commitTime = Instant.parse(commit.timestamp)
|
||||
|
||||
@@ -225,8 +224,8 @@ class DiffCommand : Subcommand("diff", description = "Show differences between c
|
||||
}
|
||||
|
||||
val result = StringBuilder()
|
||||
result.appendLine("${ColorUtils.bold("Comparing working directory to commit:")}")
|
||||
result.appendLine(" ${ColorUtils.hash(hash.take(8))} ${ColorUtils.dim(commit.message)}")
|
||||
result.appendLine(Colors.bold("Comparing working directory to commit:"))
|
||||
result.appendLine(" ${Colors.yellow(hash.take(8))} ${Colors.lightGray(commit.message)}")
|
||||
result.appendLine()
|
||||
|
||||
var totalChanges = 0
|
||||
@@ -247,7 +246,7 @@ class DiffCommand : Subcommand("diff", description = "Show differences between c
|
||||
|
||||
val changes = blockStore.compareBlocks(commitSnapshot, currentSnapshot)
|
||||
if (changes.isNotEmpty()) {
|
||||
result.appendLine("${ColorUtils.filename(filePath)}:")
|
||||
result.appendLine("${Colors.filename(filePath)}:")
|
||||
result.append(formatBlockChanges(changes, objectStore))
|
||||
result.appendLine()
|
||||
totalChanges += changes.size
|
||||
@@ -256,9 +255,9 @@ class DiffCommand : Subcommand("diff", description = "Show differences between c
|
||||
}
|
||||
|
||||
if (totalChanges == 0) {
|
||||
result.appendLine("${ColorUtils.dim("No differences found")}")
|
||||
result.appendLine(Colors.dim("No differences found"))
|
||||
} else {
|
||||
result.appendLine("${ColorUtils.bold("Total changes:")} $totalChanges")
|
||||
result.appendLine("${Colors.bold("Total changes:")} $totalChanges")
|
||||
}
|
||||
|
||||
return result.toString()
|
||||
@@ -282,7 +281,7 @@ class DiffCommand : Subcommand("diff", description = "Show differences between c
|
||||
}
|
||||
|
||||
val result = StringBuilder()
|
||||
result.appendLine("${ColorUtils.bold("Changes in working directory:")}")
|
||||
result.appendLine(Colors.bold("Changes in working directory:"))
|
||||
result.appendLine()
|
||||
|
||||
var totalChanges = 0
|
||||
@@ -294,16 +293,14 @@ class DiffCommand : Subcommand("diff", description = "Show differences between c
|
||||
val parsedFile = blockParser.parseFile(content, filePath)
|
||||
|
||||
// Skip disabled files
|
||||
if (parsedFile.frontMatter?.isEnabled == false) {
|
||||
return@forEach
|
||||
}
|
||||
if (parsedFile.frontMatter?.isEnabled == false) return@forEach
|
||||
|
||||
val latestSnapshot = blockStore.getLatestBlockSnapshot(filePath)
|
||||
val currentSnapshot = createCurrentSnapshot(parsedFile, objectStore)
|
||||
|
||||
val changes = blockStore.compareBlocks(latestSnapshot, currentSnapshot)
|
||||
if (changes.isNotEmpty()) {
|
||||
result.appendLine("${ColorUtils.filename(filePath)}:")
|
||||
result.appendLine("${Colors.filename(filePath)}:")
|
||||
result.append(formatBlockChanges(changes, objectStore))
|
||||
result.appendLine()
|
||||
totalChanges += changes.size
|
||||
@@ -312,9 +309,9 @@ class DiffCommand : Subcommand("diff", description = "Show differences between c
|
||||
}
|
||||
|
||||
if (totalChanges == 0) {
|
||||
result.appendLine("${ColorUtils.dim("No changes detected - working directory clean")}")
|
||||
result.appendLine(Colors.lightGray("No changes detected - working directory clean"))
|
||||
} else {
|
||||
result.appendLine("${ColorUtils.bold("Total changes:")} $totalChanges")
|
||||
result.appendLine("${Colors.bold("Total changes:")} $totalChanges")
|
||||
}
|
||||
|
||||
return result.toString()
|
||||
@@ -330,42 +327,42 @@ class DiffCommand : Subcommand("diff", description = "Show differences between c
|
||||
when (change.type) {
|
||||
BlockChangeType.ADDED -> {
|
||||
result.appendLine()
|
||||
result.appendLine(" ${ColorUtils.success("+++")} ${ColorUtils.bold("ADDED")} ${ColorUtils.success("+++")} ${ColorUtils.heading(headingText)} ${ColorUtils.dim("[$blockId]")}")
|
||||
result.appendLine(" ${ColorUtils.dim("─".repeat(60))}")
|
||||
result.appendLine(" ${Colors.green("+++")} ${Colors.bold("ADDED")} ${Colors.green("+++")} ${Colors.heading(headingText)} ${Colors.dim("[$blockId]")}")
|
||||
result.appendLine(" ${Colors.dim("─".repeat(60))}")
|
||||
|
||||
if (change.newHash != null) {
|
||||
val content = objectStore.getContent(change.newHash)
|
||||
if (content != null) {
|
||||
content.lines().take(5).forEach { line ->
|
||||
result.appendLine(" ${ColorUtils.success("+")} $line")
|
||||
result.appendLine(" ${Colors.green("+")} $line")
|
||||
}
|
||||
if (content.lines().size > 5) {
|
||||
result.appendLine(" ${ColorUtils.dim(" ... ${content.lines().size - 5} more lines")}")
|
||||
result.appendLine(" ${Colors.dim(" ... ${content.lines().size - 5} more lines")}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BlockChangeType.DELETED -> {
|
||||
result.appendLine()
|
||||
result.appendLine(" ${ColorUtils.error("---")} ${ColorUtils.bold("DELETED")} ${ColorUtils.error("---")} ${ColorUtils.heading(headingText)} ${ColorUtils.dim("[$blockId]")}")
|
||||
result.appendLine(" ${ColorUtils.dim("─".repeat(60))}")
|
||||
result.appendLine(" ${Colors.error("---")} ${Colors.bold("DELETED")} ${Colors.error("---")} ${Colors.heading(headingText)} ${Colors.dim("[$blockId]")}")
|
||||
result.appendLine(" ${Colors.dim("─".repeat(60))}")
|
||||
|
||||
if (change.oldHash != null) {
|
||||
val content = objectStore.getContent(change.oldHash)
|
||||
if (content != null) {
|
||||
content.lines().take(5).forEach { line ->
|
||||
result.appendLine(" ${ColorUtils.error("-")} $line")
|
||||
result.appendLine(" ${Colors.error("-")} $line")
|
||||
}
|
||||
if (content.lines().size > 5) {
|
||||
result.appendLine(" ${ColorUtils.dim(" ... ${content.lines().size - 5} more lines")}")
|
||||
result.appendLine(" ${Colors.dim(" ... ${content.lines().size - 5} more lines")}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BlockChangeType.MODIFIED -> {
|
||||
result.appendLine()
|
||||
result.appendLine(" ${ColorUtils.warning("~~~")} ${ColorUtils.bold("MODIFIED")} ${ColorUtils.warning("~~~")} ${ColorUtils.heading(headingText)} ${ColorUtils.dim("[$blockId]")}")
|
||||
result.appendLine(" ${ColorUtils.dim("─".repeat(60))}")
|
||||
result.appendLine(" ${Colors.warn("~~~")} ${Colors.bold("MODIFIED")} ${Colors.warn("~~~")} ${Colors.heading(headingText)} ${Colors.dim("[$blockId]")}")
|
||||
result.appendLine(" ${Colors.dim("─".repeat(60))}")
|
||||
|
||||
// Show detailed diff
|
||||
if (change.oldHash != null && change.newHash != null) {
|
||||
@@ -405,27 +402,27 @@ class DiffCommand : Subcommand("diff", description = "Show differences between c
|
||||
when {
|
||||
oldLine == null && newLine != null -> {
|
||||
// Addition
|
||||
diff.add("${ColorUtils.success("+ ")} $newLine")
|
||||
diff.add("${Colors.green("+ ")} $newLine")
|
||||
newIndex++
|
||||
displayedLines++
|
||||
}
|
||||
oldLine != null && newLine == null -> {
|
||||
// Deletion
|
||||
diff.add("${ColorUtils.error("- ")} $oldLine")
|
||||
diff.add("${Colors.boldRed("- ")} $oldLine")
|
||||
oldIndex++
|
||||
displayedLines++
|
||||
}
|
||||
oldLine == newLine -> {
|
||||
// Unchanged line (context)
|
||||
diff.add("${ColorUtils.dim(" ")} ${ColorUtils.dim(oldLine ?: "")}")
|
||||
diff.add("${Colors.dim(" ")} ${Colors.dimWhite(oldLine ?: "")}")
|
||||
oldIndex++
|
||||
newIndex++
|
||||
displayedLines++
|
||||
}
|
||||
else -> {
|
||||
// Modified line
|
||||
diff.add("${ColorUtils.error("- ")} $oldLine")
|
||||
diff.add("${ColorUtils.success("+ ")} $newLine")
|
||||
diff.add("${Colors.boldRed("- ")} $oldLine")
|
||||
diff.add("${Colors.green("+ ")} $newLine")
|
||||
oldIndex++
|
||||
newIndex++
|
||||
displayedLines += 2
|
||||
@@ -435,7 +432,7 @@ class DiffCommand : Subcommand("diff", description = "Show differences between c
|
||||
|
||||
val remainingLines = (oldLines.size - oldIndex) + (newLines.size - newIndex)
|
||||
if (remainingLines > 0) {
|
||||
diff.add("${ColorUtils.dim(" ... $remainingLines more lines")}")
|
||||
diff.add(Colors.dim(" ... $remainingLines more lines"))
|
||||
}
|
||||
|
||||
return diff
|
||||
|
||||
@@ -2,10 +2,7 @@ package org.notevc.commands
|
||||
|
||||
import org.notevc.core.Repository
|
||||
import java.nio.file.Path
|
||||
import org.notevc.utils.ColorUtils
|
||||
import org.kargs.Subcommand
|
||||
import org.kargs.Argument
|
||||
import org.kargs.ArgType
|
||||
import org.kargs.*
|
||||
|
||||
class InitCommand : Subcommand("init", description = "Initialize a repository", aliases = listOf("i")) {
|
||||
val path by Argument(ArgType.existingDirectory(), "path", description = "Initialize in a specified directory", required = false)
|
||||
@@ -19,13 +16,13 @@ class InitCommand : Subcommand("init", description = "Initialize a repository",
|
||||
repo.init().fold(
|
||||
onSuccess = {
|
||||
val absolutePath = repo.path.toAbsolutePath().toString()
|
||||
"Initialized notevc repository in ${ColorUtils.filename(absolutePath)}"
|
||||
"Initialized notevc repository in ${Colors.filename(absolutePath)}"
|
||||
},
|
||||
onFailure = { error -> throw Exception(error) }
|
||||
)
|
||||
}
|
||||
|
||||
result.onSuccess { message -> println(message) }
|
||||
result.onFailure { error -> println("${ColorUtils.error("Error:")} ${error.message}") }
|
||||
result.onFailure { error -> println("${Colors.error("Error:")} ${error.message}") }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import org.notevc.core.*
|
||||
import kotlinx.serialization.json.Json
|
||||
import java.nio.file.Files
|
||||
import java.time.Instant
|
||||
import org.notevc.utils.ColorUtils
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
import kotlin.io.path.*
|
||||
@@ -27,7 +26,7 @@ class LogCommand : Subcommand("log", description = "Show commit history with det
|
||||
}
|
||||
|
||||
result.onSuccess { message -> println(message) }
|
||||
result.onFailure { error -> println("${ColorUtils.error("Error:")} ${error.message}") }
|
||||
result.onFailure { error -> println("${Colors.error("Error:")} ${error.message}") }
|
||||
}
|
||||
|
||||
private fun generateLog(repo: Repository, options: LogOptions): String {
|
||||
@@ -111,10 +110,10 @@ class LogCommand : Subcommand("log", description = "Show commit history with det
|
||||
return commits.joinToString("\n") { commit ->
|
||||
val fileInfo = if (options.showFiles) {
|
||||
val stats = getCommitStats(repo, commit, options.targetFile)
|
||||
ColorUtils.dim(" (${stats.filesChanged} files, ${stats.totalBlocks} blocks)")
|
||||
Colors.dim(" (${stats.filesChanged} files, ${stats.totalBlocks} blocks)")
|
||||
} else ""
|
||||
|
||||
"${ColorUtils.hash(commit.hash)} ${commit.message}$fileInfo"
|
||||
"${Colors.yellow(commit.hash)} ${commit.message}$fileInfo"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,22 +126,23 @@ class LogCommand : Subcommand("log", description = "Show commit history with det
|
||||
val formattedDate = formatter.format(timestamp)
|
||||
|
||||
buildString {
|
||||
appendLine("${ColorUtils.bold("commit")} ${ColorUtils.hash(commit.hash)}")
|
||||
appendLine("${ColorUtils.bold("Author:")} ${ColorUtils.author(commit.author)}")
|
||||
appendLine("${ColorUtils.bold("Date:")} ${ColorUtils.date(formattedDate)}")
|
||||
appendLine("${Colors.bold("commit")} ${Colors.yellow(commit.hash)}")
|
||||
appendLine("${Colors.bold("Author:")} ${Colors.green(commit.author)}")
|
||||
appendLine("${Colors.bold("Date:")} ${Colors.dim(formattedDate)}")
|
||||
|
||||
if (options.showFiles) {
|
||||
val stats = getCommitStats(repo, commit, options.targetFile)
|
||||
appendLine("${ColorUtils.info("Files changed:")} ${stats.filesChanged}, ${ColorUtils.info("Total blocks:")} ${stats.totalBlocks}")
|
||||
appendLine("${Colors.info("Files changed:")} ${stats.filesChanged}, ${Colors.info("Total blocks:")} ${stats.totalBlocks}")
|
||||
|
||||
if (stats.fileDetails.isNotEmpty()) {
|
||||
appendLine()
|
||||
stats.fileDetails.forEach { (file, blocks) ->
|
||||
appendLine(" ${ColorUtils.filename(file)} ${ColorUtils.dim("(${blocks.size} blocks)")}")
|
||||
appendLine(" ${Colors.filename(file)} ${Colors.dim("(${blocks.size} blocks)")}")
|
||||
blocks.forEach { block ->
|
||||
val heading = block.heading.replace(Regex("^#+\\s*"), "").trim()
|
||||
appendLine(" - ${ColorUtils.hash(block.id.take(8))}: ${ColorUtils.heading(heading)}")
|
||||
appendLine(" - ${Colors.yellow(block.id.take(8))}: ${Colors.magenta(heading)}")
|
||||
}
|
||||
appendLine()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.notevc.commands
|
||||
|
||||
import org.notevc.core.*
|
||||
import org.notevc.utils.ColorUtils
|
||||
import kotlinx.serialization.json.Json
|
||||
import java.nio.file.Files
|
||||
import java.time.Instant
|
||||
@@ -35,7 +34,7 @@ class RestoreCommand : Subcommand("restore", description = "Restore files or blo
|
||||
}
|
||||
|
||||
result.onSuccess { message -> println(message) }
|
||||
result.onFailure { error -> println("${ColorUtils.error("Error:")} ${error.message}") }
|
||||
result.onFailure { error -> println("${Colors.error("Error:")} ${error.message}") }
|
||||
}
|
||||
|
||||
private fun restoreSpecificBlock(repo: Repository, commitHash: String, blockHash: String, targetFile: String): String {
|
||||
@@ -45,21 +44,21 @@ class RestoreCommand : Subcommand("restore", description = "Restore files or blo
|
||||
|
||||
// Find the commit
|
||||
val commit = findCommit(repo, commitHash)
|
||||
?: throw Exception("Commit ${ColorUtils.hash(commitHash)} not found")
|
||||
?: throw Exception("Commit ${Colors.yellow(commitHash)} not found")
|
||||
|
||||
// Find the block snapshot for this file at the commit time
|
||||
val commitTime = Instant.parse(commit.timestamp)
|
||||
val snapshot = blockStore.getBlocksAtTime(targetFile, commitTime)
|
||||
?: throw Exception("No snapshot found for ${ColorUtils.filename(targetFile)} at commit ${ColorUtils.hash(commitHash)}")
|
||||
?: throw Exception("No snapshot found for ${Colors.filename(targetFile)} at commit ${Colors.yellow(commitHash)}")
|
||||
|
||||
// Find the specific block
|
||||
val targetBlock = snapshot.find { it.id.startsWith(blockHash) }
|
||||
?: throw Exception("Block ${ColorUtils.hash(blockHash)} not found in ${ColorUtils.filename(targetFile)} at commit ${ColorUtils.hash(commitHash)}")
|
||||
?: throw Exception("Block ${Colors.yellow(blockHash)} not found in ${Colors.filename(targetFile)} at commit ${Colors.yellow(commitHash)}")
|
||||
|
||||
// Read current file
|
||||
val filePath = repo.path.resolve(targetFile)
|
||||
if (!filePath.exists()) {
|
||||
throw Exception("File ${ColorUtils.filename(targetFile)} does not exist")
|
||||
throw Exception("File ${Colors.filename(targetFile)} does not exist")
|
||||
}
|
||||
|
||||
val currentContent = Files.readString(filePath)
|
||||
@@ -68,7 +67,7 @@ class RestoreCommand : Subcommand("restore", description = "Restore files or blo
|
||||
// Find the block to replace in current file
|
||||
val currentBlockIndex = currentParsedFile.blocks.indexOfFirst { it.id.startsWith(blockHash) }
|
||||
if (currentBlockIndex == -1) {
|
||||
throw Exception("Block ${ColorUtils.hash(blockHash)} not found in current ${ColorUtils.filename(targetFile)}")
|
||||
throw Exception("Block ${Colors.yellow(blockHash)} not found in current ${Colors.filename(targetFile)}")
|
||||
}
|
||||
|
||||
// Replace the block
|
||||
@@ -82,7 +81,7 @@ class RestoreCommand : Subcommand("restore", description = "Restore files or blo
|
||||
Files.writeString(filePath, restoredContent)
|
||||
|
||||
val blockHeading = targetBlock.heading.replace(Regex("^#+\\s*"), "").trim()
|
||||
return "${ColorUtils.success("Restored block")} ${ColorUtils.hash(blockHash.take(8))} ${ColorUtils.heading("\"$blockHeading\"")} in ${ColorUtils.filename(targetFile)} from commit ${ColorUtils.hash(commitHash)}"
|
||||
return "${Colors.success("Restored block")} ${Colors.yellow(blockHash.take(8))} ${Colors.heading("\"$blockHeading\"")} in ${Colors.filename(targetFile)} from commit ${Colors.yellow(commitHash)}"
|
||||
}
|
||||
|
||||
private fun restoreSpecificFile(repo: Repository, commitHash: String, targetFile: String): String {
|
||||
@@ -92,15 +91,15 @@ class RestoreCommand : Subcommand("restore", description = "Restore files or blo
|
||||
|
||||
// Find the commit
|
||||
val commit = findCommit(repo, commitHash)
|
||||
?: throw Exception("Commit ${ColorUtils.hash(commitHash)} not found")
|
||||
?: throw Exception("Commit ${Colors.yellow(commitHash)} not found")
|
||||
|
||||
// Find the block snapshot for this file at the commit time
|
||||
val commitTime = Instant.parse(commit.timestamp)
|
||||
val snapshot = blockStore.getLatestBlockSnapshotBefore(targetFile, commitTime)
|
||||
?: throw Exception("No snapshot found for ${ColorUtils.filename(targetFile)} at commit ${ColorUtils.hash(commitHash)}")
|
||||
?: throw Exception("No snapshot found for ${Colors.filename(targetFile)} at commit ${Colors.yellow(commitHash)}")
|
||||
|
||||
val blocks = blockStore.getBlocksAtTime(targetFile, commitTime)
|
||||
?: throw Exception("No blocks found for ${ColorUtils.filename(targetFile)} at commit ${ColorUtils.hash(commitHash)}")
|
||||
?: throw Exception("No blocks found for ${Colors.filename(targetFile)} at commit ${Colors.yellow(commitHash)}")
|
||||
|
||||
// Reconstruct the file from blocks with frontmatter from snapshot
|
||||
val parsedFile = ParsedFile(
|
||||
@@ -116,7 +115,7 @@ class RestoreCommand : Subcommand("restore", description = "Restore files or blo
|
||||
Files.createDirectories(filePath.parent)
|
||||
Files.writeString(filePath, restoredContent)
|
||||
|
||||
return "${ColorUtils.success("Restored file")} ${ColorUtils.filename(targetFile)} ${ColorUtils.dim("(${blocks.size} blocks)")} from commit ${ColorUtils.hash(commitHash)}"
|
||||
return "${Colors.success("Restored file")} ${Colors.filename(targetFile)} ${Colors.dim("(${blocks.size} blocks)")} from commit ${Colors.yellow(commitHash)}"
|
||||
}
|
||||
|
||||
private fun restoreEntireRepository(repo: Repository, commitHash: String): String {
|
||||
@@ -126,7 +125,7 @@ class RestoreCommand : Subcommand("restore", description = "Restore files or blo
|
||||
|
||||
// Find the commit
|
||||
val commit = findCommit(repo, commitHash)
|
||||
?: throw Exception("Commit ${ColorUtils.hash(commitHash)} not found")
|
||||
?: throw Exception("Commit ${Colors.yellow(commitHash)} not found")
|
||||
|
||||
val commitTime = Instant.parse(commit.timestamp)
|
||||
|
||||
@@ -134,7 +133,7 @@ class RestoreCommand : Subcommand("restore", description = "Restore files or blo
|
||||
val trackedFiles = getTrackedFilesAtCommit(repo, commitTime)
|
||||
|
||||
if (trackedFiles.isEmpty()) {
|
||||
throw Exception("No files found at commit ${ColorUtils.hash(commitHash)}")
|
||||
throw Exception("No files found at commit ${Colors.yellow(commitHash)}")
|
||||
}
|
||||
|
||||
var restoredFiles = 0
|
||||
@@ -162,10 +161,10 @@ class RestoreCommand : Subcommand("restore", description = "Restore files or blo
|
||||
}
|
||||
|
||||
return buildString {
|
||||
appendLine("${ColorUtils.success("Restored repository")} to commit ${ColorUtils.hash(commitHash)}")
|
||||
appendLine("${ColorUtils.bold("Files restored:")} $restoredFiles")
|
||||
appendLine("${ColorUtils.bold("Total blocks:")} $totalBlocks")
|
||||
appendLine("${ColorUtils.bold("Commit message:")} ${commit.message}")
|
||||
appendLine("${Colors.success("Restored repository")} to commit ${Colors.yellow(commitHash)}")
|
||||
appendLine("${Colors.bold("Files restored:")} $restoredFiles")
|
||||
appendLine("${Colors.bold("Total blocks:")} $totalBlocks")
|
||||
appendLine("${Colors.bold("Commit message:")} ${commit.message}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.notevc.commands
|
||||
|
||||
import org.notevc.core.*
|
||||
import org.notevc.utils.ColorUtils
|
||||
import kotlinx.serialization.json.Json
|
||||
import java.nio.file.Files
|
||||
import java.time.Instant
|
||||
@@ -30,7 +29,7 @@ class ShowCommand : Subcommand("show", description = "Show detailed information
|
||||
}
|
||||
|
||||
result.onSuccess { message -> println(message) }
|
||||
result.onFailure { error -> println("${ColorUtils.error("Error:")} ${error.message}") }
|
||||
result.onFailure { error -> println("${Colors.error("Error:")} ${error.message}") }
|
||||
}
|
||||
|
||||
private fun showCommit(repo: Repository, commitHash: String, targetFile: String?): String {
|
||||
@@ -39,7 +38,7 @@ class ShowCommand : Subcommand("show", description = "Show detailed information
|
||||
|
||||
// Find the commit
|
||||
val commit = findCommit(repo, commitHash)
|
||||
?: throw Exception("Commit ${ColorUtils.hash(commitHash)} not found")
|
||||
?: throw Exception("Commit ${Colors.yellow(commitHash)} not found")
|
||||
|
||||
val commitTime = Instant.parse(commit.timestamp)
|
||||
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
|
||||
@@ -48,11 +47,11 @@ class ShowCommand : Subcommand("show", description = "Show detailed information
|
||||
val result = StringBuilder()
|
||||
|
||||
// Show commit header
|
||||
result.appendLine("${ColorUtils.bold("Commit:")} ${ColorUtils.hash(commit.hash)}")
|
||||
result.appendLine("${ColorUtils.bold("Author:")} ${commit.author}")
|
||||
result.appendLine("${ColorUtils.bold("Date:")} ${formatter.format(commitTime)}")
|
||||
result.appendLine("${Colors.bold("Commit:")} ${Colors.yellow(commit.hash)}")
|
||||
result.appendLine("${Colors.bold("Author:")} ${commit.author}")
|
||||
result.appendLine("${Colors.bold("Date:")} ${formatter.format(commitTime)}")
|
||||
if (commit.parent != null) {
|
||||
result.appendLine("${ColorUtils.bold("Parent:")} ${ColorUtils.hash(commit.parent)}")
|
||||
result.appendLine("${Colors.bold("Parent:")} ${Colors.yellow(commit.parent)}")
|
||||
}
|
||||
result.appendLine()
|
||||
result.appendLine(" ${commit.message}")
|
||||
@@ -66,12 +65,12 @@ class ShowCommand : Subcommand("show", description = "Show detailed information
|
||||
}
|
||||
|
||||
if (filesToShow.isEmpty()) {
|
||||
result.appendLine("${ColorUtils.dim("No files found at this commit")}")
|
||||
result.appendLine("${Colors.dim("No files found at this commit")}")
|
||||
return result.toString()
|
||||
}
|
||||
|
||||
// Show changes for each file
|
||||
result.appendLine("${ColorUtils.bold("Changes:")}")
|
||||
result.appendLine("${Colors.bold("Changes:")}")
|
||||
result.appendLine()
|
||||
|
||||
var totalAdded = 0
|
||||
@@ -94,7 +93,7 @@ class ShowCommand : Subcommand("show", description = "Show detailed information
|
||||
val changes = blockStore.compareBlocks(parentSnapshot, currentSnapshot)
|
||||
|
||||
if (changes.isNotEmpty()) {
|
||||
result.appendLine("${ColorUtils.filename(filePath)}:")
|
||||
result.appendLine("${Colors.filename(filePath)}:")
|
||||
|
||||
val added = changes.count { it.type == BlockChangeType.ADDED }
|
||||
val modified = changes.count { it.type == BlockChangeType.MODIFIED }
|
||||
@@ -104,9 +103,9 @@ class ShowCommand : Subcommand("show", description = "Show detailed information
|
||||
totalModified += modified
|
||||
totalDeleted += deleted
|
||||
|
||||
if (added > 0) result.appendLine(" ${ColorUtils.success("+")} $added ${if (added == 1) "block" else "blocks"} added")
|
||||
if (modified > 0) result.appendLine(" ${ColorUtils.warning("~")} $modified ${if (modified == 1) "block" else "blocks"} modified")
|
||||
if (deleted > 0) result.appendLine(" ${ColorUtils.error("-")} $deleted ${if (deleted == 1) "block" else "blocks"} deleted")
|
||||
if (added > 0) result.appendLine(" ${Colors.boldGreen("+")} $added ${if (added == 1) "block" else "blocks"} added")
|
||||
if (modified > 0) result.appendLine(" ${Colors.warn("~")} $modified ${if (modified == 1) "block" else "blocks"} modified")
|
||||
if (deleted > 0) result.appendLine(" ${Colors.error("-")} $deleted ${if (deleted == 1) "block" else "blocks"} deleted")
|
||||
|
||||
result.appendLine()
|
||||
|
||||
@@ -117,13 +116,13 @@ class ShowCommand : Subcommand("show", description = "Show detailed information
|
||||
|
||||
when (change.type) {
|
||||
BlockChangeType.ADDED -> {
|
||||
result.appendLine(" ${ColorUtils.success("+")} ${ColorUtils.heading(headingText)} ${ColorUtils.dim("[$blockId]")}")
|
||||
result.appendLine(" ${Colors.boldGreen("+")} ${Colors.heading(headingText)} ${Colors.dim("[$blockId]")}")
|
||||
}
|
||||
BlockChangeType.DELETED -> {
|
||||
result.appendLine(" ${ColorUtils.error("-")} ${ColorUtils.heading(headingText)} ${ColorUtils.dim("[$blockId]")}")
|
||||
result.appendLine(" ${Colors.error("-")} ${Colors.heading(headingText)} ${Colors.dim("[$blockId]")}")
|
||||
}
|
||||
BlockChangeType.MODIFIED -> {
|
||||
result.appendLine(" ${ColorUtils.warning("~")} ${ColorUtils.heading(headingText)} ${ColorUtils.dim("[$blockId]")}")
|
||||
result.appendLine(" ${Colors.warn("~")} ${Colors.heading(headingText)} ${Colors.dim("[$blockId]")}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,8 +133,8 @@ class ShowCommand : Subcommand("show", description = "Show detailed information
|
||||
|
||||
// Summary
|
||||
if (totalAdded + totalModified + totalDeleted > 0) {
|
||||
result.appendLine("${ColorUtils.bold("Summary:")}")
|
||||
result.appendLine(" ${ColorUtils.success("+")} $totalAdded added, ${ColorUtils.warning("~")} $totalModified modified, ${ColorUtils.error("-")} $totalDeleted deleted")
|
||||
result.appendLine("${Colors.bold("Summary:")}")
|
||||
result.appendLine(" ${Colors.boldGreen("+")} $totalAdded added, ${Colors.warn("~")} $totalModified modified, ${Colors.error("-")} $totalDeleted deleted")
|
||||
}
|
||||
|
||||
return result.toString()
|
||||
@@ -190,7 +189,7 @@ class ShowCommand : Subcommand("show", description = "Show detailed information
|
||||
val blockStore = BlockStore(objectStore, repo.path.resolve("${Repository.NOTEVC_DIR}/blocks"))
|
||||
|
||||
val commit = findCommit(repo, options.commitHash)
|
||||
?: throw Exception("Commit ${ColorUtils.hash(options.commitHash)} not found")
|
||||
?: throw Exception("Commit ${Colors.yellow(options.commitHash)} not found")
|
||||
|
||||
val commitTime = Instant.parse(commit.timestamp)
|
||||
|
||||
@@ -202,7 +201,7 @@ class ShowCommand : Subcommand("show", description = "Show detailed information
|
||||
?: throw Exception("No snapshot found for ${options.targetFile} at commit ${options.commitHash}")
|
||||
|
||||
val block = snapshot.blocks.find { it.id.startsWith(options.blockHash!!) }
|
||||
?: throw Exception("Block ${ColorUtils.hash(options.blockHash!!)} not found")
|
||||
?: throw Exception("Block ${Colors.yellow(options.blockHash!!)} not found")
|
||||
|
||||
val content = objectStore.getContent(block.contentHash)
|
||||
?: throw Exception("Content not found for block")
|
||||
@@ -210,12 +209,12 @@ class ShowCommand : Subcommand("show", description = "Show detailed information
|
||||
val headingText = block.heading.replace(Regex("^#+\\s*"), "").trim()
|
||||
val result = StringBuilder()
|
||||
|
||||
result.appendLine("${ColorUtils.bold("Block:")} ${ColorUtils.hash(block.id.take(8))}")
|
||||
result.appendLine("${ColorUtils.bold("Heading:")} ${ColorUtils.heading(headingText)}")
|
||||
result.appendLine("${ColorUtils.bold("File:")} ${ColorUtils.filename(options.targetFile)}")
|
||||
result.appendLine("${ColorUtils.bold("Commit:")} ${ColorUtils.hash(commit.hash)}")
|
||||
result.appendLine("${Colors.bold("Block:")} ${Colors.yellow(block.id.take(8))}")
|
||||
result.appendLine("${Colors.bold("Heading:")} ${Colors.heading(headingText)}")
|
||||
result.appendLine("${Colors.bold("File:")} ${Colors.filename(options.targetFile)}")
|
||||
result.appendLine("${Colors.bold("Commit:")} ${Colors.yellow(commit.hash)}")
|
||||
result.appendLine()
|
||||
result.appendLine("${ColorUtils.dim("─".repeat(70))}")
|
||||
result.appendLine("${Colors.dim("─".repeat(70))}")
|
||||
result.appendLine()
|
||||
result.append(content)
|
||||
|
||||
@@ -228,7 +227,7 @@ class ShowCommand : Subcommand("show", description = "Show detailed information
|
||||
val blockParser = BlockParser()
|
||||
|
||||
val commit = findCommit(repo, options.commitHash)
|
||||
?: throw Exception("Commit ${ColorUtils.hash(options.commitHash)} not found")
|
||||
?: throw Exception("Commit ${Colors.yellow(options.commitHash)} not found")
|
||||
|
||||
val commitTime = Instant.parse(commit.timestamp)
|
||||
|
||||
@@ -261,11 +260,11 @@ class ShowCommand : Subcommand("show", description = "Show detailed information
|
||||
val reconstructedContent = blockParser.reconstructFile(parsedFile)
|
||||
|
||||
val result = StringBuilder()
|
||||
result.appendLine("${ColorUtils.bold("File:")} ${ColorUtils.filename(options.targetFile)}")
|
||||
result.appendLine("${ColorUtils.bold("Commit:")} ${ColorUtils.hash(commit.hash)}")
|
||||
result.appendLine("${ColorUtils.bold("Blocks:")} ${blocks.size}")
|
||||
result.appendLine("${Colors.bold("File:")} ${Colors.filename(options.targetFile)}")
|
||||
result.appendLine("${Colors.bold("Commit:")} ${Colors.yellow(commit.hash)}")
|
||||
result.appendLine("${Colors.bold("Blocks:")} ${blocks.size}")
|
||||
result.appendLine()
|
||||
result.appendLine("${ColorUtils.dim("─".repeat(70))}")
|
||||
result.appendLine("${Colors.dim("─".repeat(70))}")
|
||||
result.appendLine()
|
||||
result.append(reconstructedContent)
|
||||
|
||||
|
||||
@@ -2,10 +2,9 @@ package org.notevc.commands
|
||||
|
||||
import org.notevc.core.*
|
||||
import org.notevc.utils.FileUtils
|
||||
import org.notevc.utils.ColorUtils
|
||||
import org.notevc.core.Repository.Companion.NOTEVC_DIR
|
||||
import java.time.Instant
|
||||
import org.kargs.Subcommand
|
||||
import org.kargs.*
|
||||
|
||||
class StatusCommand : Subcommand("status", description = "Show status of tracked files", aliases = listOf("st")) {
|
||||
override fun execute() {
|
||||
@@ -21,7 +20,7 @@ class StatusCommand : Subcommand("status", description = "Show status of tracked
|
||||
}
|
||||
|
||||
result.onSuccess { output -> println(output) }
|
||||
result.onFailure { error -> println("${ColorUtils.error("Error:")} ${error.message}") }
|
||||
result.onFailure { error -> println("${Colors.error("Error:")} ${error.message}") }
|
||||
}
|
||||
|
||||
private fun getRepositoryStatus(repo: Repository): RepositoryStatus {
|
||||
@@ -111,35 +110,35 @@ class StatusCommand : Subcommand("status", description = "Show status of tracked
|
||||
|
||||
// Modified files
|
||||
grouped[FileStatusType.MODIFIED]?.let { modifiedFiles ->
|
||||
output.appendLine(ColorUtils.bold("Modified files:"))
|
||||
output.appendLine(Colors.bold("Modified files:"))
|
||||
modifiedFiles.forEach { fileStatus ->
|
||||
output.appendLine(" ${ColorUtils.filename(fileStatus.path)}")
|
||||
output.appendLine(" ${Colors.filename(fileStatus.path)}")
|
||||
fileStatus.blockChanges?.forEach { change ->
|
||||
val symbol = when (change.type) {
|
||||
BlockChangeType.MODIFIED -> ColorUtils.modified("~")
|
||||
BlockChangeType.ADDED -> ColorUtils.added("+")
|
||||
BlockChangeType.DELETED -> ColorUtils.deleted("-")
|
||||
BlockChangeType.MODIFIED -> Colors.boldYellow("~")
|
||||
BlockChangeType.ADDED -> Colors.boldGreen("+")
|
||||
BlockChangeType.DELETED -> Colors.boldRed("-")
|
||||
}
|
||||
val heading = change.heading.replace(Regex("^#+\\s*"), "").trim()
|
||||
output.appendLine(" $symbol ${ColorUtils.heading(heading)}")
|
||||
output.appendLine(" $symbol ${Colors.heading(heading)}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Untracked files
|
||||
grouped[FileStatusType.UNTRACKED]?.let { untrackedFiles ->
|
||||
output.appendLine(ColorUtils.bold("Untracked files:"))
|
||||
output.appendLine(Colors.bold("Untracked files:"))
|
||||
untrackedFiles.forEach { fileStatus ->
|
||||
output.appendLine(" ${ColorUtils.untracked(fileStatus.path)} ${ColorUtils.dim("(${fileStatus.blockCount} blocks)")}")
|
||||
output.appendLine(" ${Colors.dimWhite(fileStatus.path)} ${Colors.dim("(${fileStatus.blockCount} blocks)")}")
|
||||
}
|
||||
output.appendLine()
|
||||
}
|
||||
|
||||
// Deleted files
|
||||
grouped[FileStatusType.DELETED]?.let { deletedFiles ->
|
||||
output.appendLine(ColorUtils.bold("Deleted files:"))
|
||||
output.appendLine(Colors.bold("Deleted files:"))
|
||||
deletedFiles.forEach { fileStatus ->
|
||||
output.appendLine(" ${ColorUtils.deleted(fileStatus.path)}")
|
||||
output.appendLine(" ${Colors.boldRed(fileStatus.path)}")
|
||||
}
|
||||
output.appendLine()
|
||||
}
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
package org.notevc.utils
|
||||
|
||||
object ColorUtils {
|
||||
// ANSI color codes
|
||||
private const val RESET = "\u001B[0m"
|
||||
private const val BOLD = "\u001B[1m"
|
||||
private const val DIM = "\u001B[2m"
|
||||
|
||||
// Colors
|
||||
private const val BLACK = "\u001B[30m"
|
||||
private const val RED = "\u001B[31m"
|
||||
private const val GREEN = "\u001B[32m"
|
||||
private const val YELLOW = "\u001B[33m"
|
||||
private const val BLUE = "\u001B[34m"
|
||||
private const val MAGENTA = "\u001B[35m"
|
||||
private const val CYAN = "\u001B[36m"
|
||||
private const val WHITE = "\u001B[37m"
|
||||
|
||||
// Bright colors
|
||||
private const val BRIGHT_RED = "\u001B[91m"
|
||||
private const val BRIGHT_GREEN = "\u001B[92m"
|
||||
private const val BRIGHT_YELLOW = "\u001B[93m"
|
||||
private const val BRIGHT_BLUE = "\u001B[94m"
|
||||
private const val BRIGHT_MAGENTA = "\u001B[95m"
|
||||
private const val BRIGHT_CYAN = "\u001B[96m"
|
||||
|
||||
// Flag to force disable colors via --no-color flag
|
||||
var forceDisableColors = false
|
||||
|
||||
// Check if colors should be enabled (disable in CI/pipes or via flag)
|
||||
private val colorsEnabled: Boolean
|
||||
get() = !forceDisableColors &&
|
||||
System.getenv("NO_COLOR") == null &&
|
||||
System.getenv("CI") == null &&
|
||||
System.console() != null
|
||||
|
||||
// Function to disable colors programmatically
|
||||
fun disableColors() {
|
||||
forceDisableColors = true
|
||||
}
|
||||
|
||||
// Public color functions
|
||||
fun red(text: String): String = if (colorsEnabled) "$RED$text$RESET" else text
|
||||
fun green(text: String): String = if (colorsEnabled) "$GREEN$text$RESET" else text
|
||||
fun yellow(text: String): String = if (colorsEnabled) "$YELLOW$text$RESET" else text
|
||||
fun blue(text: String): String = if (colorsEnabled) "$BLUE$text$RESET" else text
|
||||
fun magenta(text: String): String = if (colorsEnabled) "$MAGENTA$text$RESET" else text
|
||||
fun cyan(text: String): String = if (colorsEnabled) "$CYAN$text$RESET" else text
|
||||
|
||||
fun brightRed(text: String): String = if (colorsEnabled) "$BRIGHT_RED$text$RESET" else text
|
||||
fun brightGreen(text: String): String = if (colorsEnabled) "$BRIGHT_GREEN$text$RESET" else text
|
||||
fun brightYellow(text: String): String = if (colorsEnabled) "$BRIGHT_YELLOW$text$RESET" else text
|
||||
fun brightBlue(text: String): String = if (colorsEnabled) "$BRIGHT_BLUE$text$RESET" else text
|
||||
fun brightMagenta(text: String): String = if (colorsEnabled) "$BRIGHT_MAGENTA$text$RESET" else text
|
||||
fun brightCyan(text: String): String = if (colorsEnabled) "$BRIGHT_CYAN$text$RESET" else text
|
||||
|
||||
fun bold(text: String): String = if (colorsEnabled) "$BOLD$text$RESET" else text
|
||||
fun dim(text: String): String = if (colorsEnabled) "$DIM$text$RESET" else text
|
||||
|
||||
// Semantic colors for version control
|
||||
fun success(text: String): String = brightGreen(text)
|
||||
fun error(text: String): String = brightRed(text)
|
||||
fun warning(text: String): String = brightYellow(text)
|
||||
fun info(text: String): String = brightBlue(text)
|
||||
fun hash(text: String): String = yellow(text)
|
||||
fun filename(text: String): String = cyan(text)
|
||||
fun heading(text: String): String = brightMagenta(text)
|
||||
fun author(text: String): String = green(text)
|
||||
fun date(text: String): String = dim(text)
|
||||
|
||||
// Status-specific colors
|
||||
fun added(text: String): String = brightGreen(text)
|
||||
fun modified(text: String): String = brightYellow(text)
|
||||
fun deleted(text: String): String = brightRed(text)
|
||||
fun untracked(text: String): String = red(text)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user