feat(repo): added minimal repo class
This commit is contained in:
@@ -2,12 +2,12 @@
|
||||
|
||||
- [x] Initialize Project
|
||||
- [x] Configure `build.gradle.kts` with dependencies
|
||||
- [ ] Set up testing framework
|
||||
- [x] Set up testing framework
|
||||
|
||||
# Core
|
||||
|
||||
- [ ] Create `Repository.kt` class
|
||||
- [ ] Implement `.notevc` directory initialization
|
||||
- [x] Create `Repository.kt` class
|
||||
- [x] Implement `.notevc` directory initialization
|
||||
- [ ] Create `ObjectStore.kt` for content storage
|
||||
- [ ] Implement content hashing `HashUtils.kt`
|
||||
- [ ] Create `NoteSnapshot` data class
|
||||
|
||||
@@ -1,25 +1,48 @@
|
||||
import java.time.Instant
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "2.2.21"
|
||||
kotlin("plugin.serialization") version "2.2.21"
|
||||
application
|
||||
id("com.github.gmazzo.buildconfig") version "4.1.2"
|
||||
id("com.gradleup.shadow") version "9.2.2"
|
||||
}
|
||||
|
||||
group = "io.notevc"
|
||||
version = "1.0.0"
|
||||
|
||||
buildConfig {
|
||||
buildConfigField("String", "VERSION", "\"${project.version}\"")
|
||||
buildConfigField("String", "BUILD_TIME", "\"${Instant.now()}\"")
|
||||
packageName("io.notevc")
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
val junitVersion = "5.10.0"
|
||||
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 {
|
||||
mainClass.set("io.notevc.NoteVCKt")
|
||||
}
|
||||
|
||||
tasks.jar {
|
||||
manifest {
|
||||
attributes["Main-Class"] = "io.notevc.NoteVCKt"
|
||||
}
|
||||
tasks.withType<Test> {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
tasks.build {
|
||||
dependsOn(tasks.shadowJar)
|
||||
}
|
||||
|
||||
tasks.jar {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
package io.notevc
|
||||
|
||||
fun main() {
|
||||
println("hello world")
|
||||
import io.notevc.core.Repository
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user