From 5ae296afa27c5623dd5731014c96f2b219ceca2b Mon Sep 17 00:00:00 2001 From: aethrvmn Date: Wed, 8 Oct 2025 02:48:09 +0300 Subject: added core functionality bar the parser for dependencies --- src/core/locker.nim | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/core/manager.nim | 84 ++++++++++++++++++++++++++++++++++++++++++ src/core/parser.nim | 1 + 3 files changed, 187 insertions(+) create mode 100644 src/core/locker.nim create mode 100644 src/core/manager.nim create mode 100644 src/core/parser.nim (limited to 'src/core') diff --git a/src/core/locker.nim b/src/core/locker.nim new file mode 100644 index 0000000..d52b55d --- /dev/null +++ b/src/core/locker.nim @@ -0,0 +1,102 @@ +import std / [ + os, + json, + hashes, + strformat +] + +import ./manager + +proc lockPath*(): string = + let + homeDir: string = getHomeDir() + lockDir: string = homeDir / ".local" / "tesserae" + ensureDir(lockDir) + result = lockDir / "tesserae.lock" + +proc loadLock*(): JsonNode = + let lockFile: string = lockPath() + result = %*{} + if fileExists(lockFile): + try: + result = parseFile(lockFile) + except JsonParsingError: + echo "JsonParsingError. Treating the lockfile as non existant" + result = %*{} + +proc writeLock*(jsonObject: JsonNode) = + let lockFile: string = lockPath() + writeFile(lockFile, jsonObject.pretty()) + +proc updateLock*( + packageName: string, + sourceURL: string, + chosenTag: string, + configPath: string +) = + ## Updates the lockfile + var lock: JsonNode = loadLock() + let + config: string = readConfigFile(configPath) + jsonObject: JsonNode = %*{ + "source": { "url": sourceURL }, + "tag": chosenTag, + "config": config + # I should probably add a sha256 thingy + } + lock[packageName] = jsonObject + writeLock(lock) + echo "Updated {packageName}".fmt + + +proc needRebuildLock*( + packageName: string, + sourceURL: string, + chosenTag: string, + configPath: string +): bool = + ## Checks whether the following have changed:\n + ## - source (repo url) + ## - tag (new release, manually updated, etc) + result = false + let lockFile = loadLock() + if not lockFile.hasKey(packageName): + echo "{packageName} added to queue" + result = true + else: + let package = lockFile[packageName] + if not package.hasKey("source"): + echo "Could not find source for package {packageName}".fmt + echo "{packageName} added to queue" + result = true + + if package.hasKey("source") and package["source"].hasKey("url"): + let packageSource: string = package["source"]["url"].getStr + if packageSource != sourceURL: + echo "Source URL for package {packageName} has changed".fmt + echo "{packageName} added to queue" + result = true + + if not package.hasKey("tag"): + result = true + else: + if package["tag"].getStr != chosenTag: + echo "Release tag has changed from {package["tag"]} -> {chosenTag}".fmt + echo "{packageName} added to queue" + result = true + if not package.hasKey("config"): + echo "Configuration file not found for package {packageName}".fmt + echo "{packageName} added to queue" + result = true + else: + let config: string = readConfigFile(configPath) + if package["config"].getStr != config: + echo "Configuration file changed for package {packageName}".fmt + echo "{packageName} added to queue" + result = true + + + + + + diff --git a/src/core/manager.nim b/src/core/manager.nim new file mode 100644 index 0000000..0453fa6 --- /dev/null +++ b/src/core/manager.nim @@ -0,0 +1,84 @@ +import std / [ os, strformat, osproc ] + +proc runCommand*( + command: string, + workingDir: string = "" +): (string, int) = + echo "-> {command} (workingDir: {workingDir})".fmt + let (output, code) = execCmdEx( + command=command, + workingDir=workingDir + ) + result = (output, code) + +proc ensureDir*(path: string) = + if not dirExists(path): + createDir(path) + +proc readConfigFile*(configPath: string): string = + if fileExists(configPath): + result = readFile(configPath) + else: + result = "" + +proc cloneSource*( + repoURL: string, + destinationDir: string +) = + if dirExists(destinationDir): + echo "Repository already exists at {destinationDir}".fmt + echo "Pulling..." + let (output, code) = runCommand( + command="git pull", + workingDir=destinationDir + ) + echo output + else: + echo "Cloning from {repoURL}...".fmt + let (output, code) = runCommand( + command="git clone {repoURL} {destinationDir}".fmt + ) + echo output + +proc fetchTags*( + destinationDir: string +) = + let (output, code) = runCommand( + command="git fetch --tags --force", + workingDir=destinationDir + ) + echo output + + +proc resolveTag*( + destinationDir: string, + pinnedTag: string = "" +): string = + ## if pinnedTag is defined, we use that; + ## otherwise we fall back to newest tag + if pinnedTag.len > 0: + result = pinnedTag + let (output, code) = runCommand( + command="git rev-parse --verify {pinnedTag}".fmt, + workingDir=destinationDir + ) + echo output + if code != 0: + # if it fails, we try to fetch the tag + # just in case + fetchTags(destinationDir) + let (newOutput, newCode) = runCommand( + "git rev-parse --verify {pinnedTag}".fmt, + workingDir=destinationdir + ) + echo newOutput + if newCode != 0: + quit("Pinned tag {pinnedTag} not found in repo at {destDir}.") + else: + let (output, code) = runCommand( + command="git describe --tags --abbrev=0", + workingDir=destinationDir + ) + result = output + if code != 0: + quit("There seem to be no releases available from this software") diff --git a/src/core/parser.nim b/src/core/parser.nim new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/core/parser.nim @@ -0,0 +1 @@ + -- cgit v1.2.3