feat(repo): added minimal repo class
This commit is contained in:
@@ -2,12 +2,12 @@
|
|||||||
|
|
||||||
- [x] Initialize Project
|
- [x] Initialize Project
|
||||||
- [x] Configure `build.gradle.kts` with dependencies
|
- [x] Configure `build.gradle.kts` with dependencies
|
||||||
- [ ] Set up testing framework
|
- [x] Set up testing framework
|
||||||
|
|
||||||
# Core
|
# Core
|
||||||
|
|
||||||
- [ ] Create `Repository.kt` class
|
- [x] Create `Repository.kt` class
|
||||||
- [ ] Implement `.notevc` directory initialization
|
- [x] Implement `.notevc` directory initialization
|
||||||
- [ ] Create `ObjectStore.kt` for content storage
|
- [ ] Create `ObjectStore.kt` for content storage
|
||||||
- [ ] Implement content hashing `HashUtils.kt`
|
- [ ] Implement content hashing `HashUtils.kt`
|
||||||
- [ ] Create `NoteSnapshot` data class
|
- [ ] Create `NoteSnapshot` data class
|
||||||
|
|||||||
@@ -1,25 +1,48 @@
|
|||||||
|
import java.time.Instant
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "2.2.21"
|
kotlin("jvm") version "2.2.21"
|
||||||
|
kotlin("plugin.serialization") version "2.2.21"
|
||||||
application
|
application
|
||||||
|
id("com.github.gmazzo.buildconfig") version "4.1.2"
|
||||||
|
id("com.gradleup.shadow") version "9.2.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "io.notevc"
|
group = "io.notevc"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
|
||||||
|
buildConfig {
|
||||||
|
buildConfigField("String", "VERSION", "\"${project.version}\"")
|
||||||
|
buildConfigField("String", "BUILD_TIME", "\"${Instant.now()}\"")
|
||||||
|
packageName("io.notevc")
|
||||||
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
val junitVersion = "5.10.0"
|
||||||
implementation(kotlin("stdlib"))
|
implementation(kotlin("stdlib"))
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
|
||||||
|
|
||||||
|
testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion")
|
||||||
|
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitVersion")
|
||||||
}
|
}
|
||||||
|
|
||||||
application {
|
application {
|
||||||
mainClass.set("io.notevc.NoteVCKt")
|
mainClass.set("io.notevc.NoteVCKt")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.withType<Test> {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.build {
|
||||||
|
dependsOn(tasks.shadowJar)
|
||||||
|
}
|
||||||
|
|
||||||
tasks.jar {
|
tasks.jar {
|
||||||
manifest {
|
enabled = false
|
||||||
attributes["Main-Class"] = "io.notevc.NoteVCKt"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,31 @@
|
|||||||
package io.notevc
|
package io.notevc
|
||||||
|
|
||||||
fun main() {
|
import io.notevc.core.Repository
|
||||||
println("hello world")
|
import io.notevc.commands.*
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
// Args logic
|
||||||
|
when (args.firstOrNull()) {
|
||||||
|
"init" -> {
|
||||||
|
val initCommand = InitCommand()
|
||||||
|
val result = initCommand.execute(args.getOrNull(1))
|
||||||
|
|
||||||
|
result.fold(
|
||||||
|
onSuccess = { message -> println(message) },
|
||||||
|
onFailure = { error -> println("Error: ${error.message}") }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
"commit" -> {
|
||||||
|
println("Not implemented yet")
|
||||||
|
}
|
||||||
|
|
||||||
|
"status" -> {
|
||||||
|
println("Not implemented yet")
|
||||||
|
}
|
||||||
|
|
||||||
|
"version", "--version", "-v" -> {
|
||||||
|
println("notevc version ${Repository.VERSION}")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,26 @@
|
|||||||
package io.notevc.commands
|
package io.notevc.commands
|
||||||
|
|
||||||
|
import io.notevc.core.Repository
|
||||||
|
import java.nio.file.Path
|
||||||
|
|
||||||
|
class InitCommand {
|
||||||
|
fun execute(path: String?): Result<String> {
|
||||||
|
return try {
|
||||||
|
val repo = if (path != null) {
|
||||||
|
Repository.at(path).getOrElse { return Result.failure(it) }
|
||||||
|
} else Repository.current()
|
||||||
|
|
||||||
|
repo.init().fold(
|
||||||
|
onSuccess = {
|
||||||
|
Result.success("Initialized notevc repository in ${repo.path.toAbsolutePath()}")
|
||||||
|
},
|
||||||
|
onFailure = {
|
||||||
|
error -> Result.failure(error)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
catch (e: Exception) {
|
||||||
|
Result.failure(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1 +1,103 @@
|
|||||||
package io.notevc.core
|
package io.notevc.core
|
||||||
|
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.nio.file.Paths
|
||||||
|
import kotlin.io.path.*
|
||||||
|
import io.notevc.BuildConfig
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.encodeToString
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
class Repository private constructor(private val rootPath: Path) {
|
||||||
|
private val notevcDir = rootPath.resolve(NOTEVC_DIR)
|
||||||
|
val path: Path get() = rootPath
|
||||||
|
val isInitialized: Boolean get() = notevcDir.exists()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
// Factory methods - these create Repository instances
|
||||||
|
|
||||||
|
// Create repository at a specified path
|
||||||
|
fun at(path: String): Result<Repository> {
|
||||||
|
return try {
|
||||||
|
val absolutePath = Path.of(path).toAbsolutePath()
|
||||||
|
when {
|
||||||
|
!absolutePath.exists() -> Result.failure(Exception("Directory does not exist: $path"))
|
||||||
|
!absolutePath.isDirectory() -> Result.failure(Exception("Path is not directory: $path"))
|
||||||
|
!absolutePath.isWritable() -> Result.failure(Exception("Directory is not writable: $path"))
|
||||||
|
else -> Result.success(Repository(absolutePath))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (e: Exception) {
|
||||||
|
Result.failure(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create repository at current directory
|
||||||
|
fun current(): Repository = Repository(Path.of(System.getProperty("user.dir")).toAbsolutePath())
|
||||||
|
|
||||||
|
// Find existing repository by walking up
|
||||||
|
fun find(): Repository? {
|
||||||
|
var current = Path.of(System.getProperty("user.dir")).toAbsolutePath()
|
||||||
|
while (current != null) {
|
||||||
|
if (current.resolve(NOTEVC_DIR).exists()) return Repository(current)
|
||||||
|
current = current.parent // Go up one level
|
||||||
|
}
|
||||||
|
return null // No repository found
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
const val NOTEVC_DIR = ".notevc"
|
||||||
|
val VERSION = BuildConfig.VERSION
|
||||||
|
val BUILD_TIME = BuildConfig.BUILD_TIME
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String = "Repository(path=${rootPath.toAbsolutePath()}, initialized=$isInitialized)"
|
||||||
|
|
||||||
|
fun init(): Result<Unit> {
|
||||||
|
return try {
|
||||||
|
// Check if already initialized
|
||||||
|
if (isInitialized) return Result.failure(Exception("Repository already initialized at ${rootPath.toAbsolutePath()}"))
|
||||||
|
|
||||||
|
// Create .notevc directory structure
|
||||||
|
Files.createDirectories(notevcDir)
|
||||||
|
Files.createDirectories(notevcDir.resolve("objects"))
|
||||||
|
|
||||||
|
// Create initial metadata
|
||||||
|
val metadata = RepoMetadata(
|
||||||
|
version = VERSION,
|
||||||
|
created = Instant.now().toString(),
|
||||||
|
head = null
|
||||||
|
)
|
||||||
|
|
||||||
|
// Save metadata to .notevc/metadata.json
|
||||||
|
val metadataFile = notevcDir.resolve("metadata.json")
|
||||||
|
Files.writeString(metadataFile, Json.encodeToString(metadata))
|
||||||
|
|
||||||
|
// Create empty timeline
|
||||||
|
val timelineFile = notevcDir.resolve("timeline.json")
|
||||||
|
Files.writeString(timelineFile, "[]")
|
||||||
|
|
||||||
|
Result.success(Unit)
|
||||||
|
}
|
||||||
|
catch (e: Exception) {
|
||||||
|
Result.failure(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class RepoMetadata(
|
||||||
|
val version: String,
|
||||||
|
val created: String,
|
||||||
|
var head: String?
|
||||||
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class RepoConfig(
|
||||||
|
val autoCommit: Boolean = false,
|
||||||
|
val compressionEnabled: Boolean = false,
|
||||||
|
val maxSnapshots: Int = 100
|
||||||
|
)
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
package io.notevc.utils
|
package io.notevc.utils
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user