AI git commit test from Clojure

This commit is contained in:
2026-05-08 17:11:12 +03:00
parent 301231787c
commit b239dd959b
2 changed files with 121 additions and 1 deletions
+109 -1
View File
@@ -1,4 +1,4 @@
import strutils, sequtils, hashes, algorithm
import strutils, sequtils, hashes, algorithm, os, osproc
type
CljKind* = enum
@@ -1070,3 +1070,111 @@ proc cljRange*(start, finish: CljVal): CljVal =
for i in start.intVal..<finish.intVal:
items.add(cljInt(i))
cljList(items)
# ---- File Operations ----
proc cljFileRead*(path: CljVal): CljVal =
if path.kind != ckString:
return cljMapFromPairs(@[(cljKeyword("error"), cljString("file/read requires a string path"))])
try:
let content = readFile(path.strVal)
cljString(content)
except CatchableError as e:
cljMapFromPairs(@[(cljKeyword("error"), cljString(e.msg))])
proc cljFileWrite*(path, content: CljVal): CljVal =
if path.kind != ckString or content.kind != ckString:
return cljMapFromPairs(@[(cljKeyword("error"), cljString("file/write requires two strings"))])
try:
writeFile(path.strVal, content.strVal)
cljBool(true)
except CatchableError as e:
cljMapFromPairs(@[(cljKeyword("error"), cljString(e.msg))])
proc cljFileAppend*(path, content: CljVal): CljVal =
if path.kind != ckString or content.kind != ckString:
return cljMapFromPairs(@[(cljKeyword("error"), cljString("file/append requires two strings"))])
try:
let f = open(path.strVal, fmAppend)
f.write(content.strVal)
f.close()
cljBool(true)
except CatchableError as e:
cljMapFromPairs(@[(cljKeyword("error"), cljString(e.msg))])
proc cljFileLs*(dir: CljVal): CljVal =
let path = if dir.kind == ckString: dir.strVal else: "."
var items: seq[CljVal] = @[]
try:
for kind, name in walkDir(path):
items.add(cljString(name))
cljVector(items)
except CatchableError as e:
cljVector(@[cljString("error: " & e.msg)])
proc cljFileExists*(path: CljVal): CljVal =
if path.kind != ckString:
return cljBool(false)
cljBool(fileExists(path.strVal))
# ---- Git Operations ----
proc cljGitStatus*(): CljVal =
let (branchOut, _) = execCmdEx("git rev-parse --abbrev-ref HEAD")
let branch = branchOut.strip()
let (statusOut, _) = execCmdEx("git status --porcelain")
var modified: seq[CljVal] = @[]
var untracked: seq[CljVal] = @[]
var staged: seq[CljVal] = @[]
for line in statusOut.splitLines():
if line.len < 3: continue
let status = line[0..1]
let file = line[3..^1]
if status[0] != ' ' and status[0] != '?':
staged.add(cljString(file))
if status[1] != ' ':
modified.add(cljString(file))
if status == "??":
untracked.add(cljString(file))
let clean = modified.len == 0 and untracked.len == 0 and staged.len == 0
cljMapFromPairs(@[
(cljKeyword("branch"), cljString(branch)),
(cljKeyword("modified"), cljVector(modified)),
(cljKeyword("untracked"), cljVector(untracked)),
(cljKeyword("staged"), cljVector(staged)),
(cljKeyword("clean"), cljBool(clean))
])
proc cljGitCommit*(msg: CljVal): CljVal =
if msg.kind != ckString:
return cljMapFromPairs(@[(cljKeyword("error"), cljString("git/commit requires a string message"))])
let (gitOut, exit) = execCmdEx("git add -A && git commit -m " & quoteShell(msg.strVal))
if exit != 0:
return cljMapFromPairs(@[(cljKeyword("error"), cljString(gitOut)), (cljKeyword("success"), cljBool(false))])
var sha = ""
let (shaOut, _) = execCmdEx("git rev-parse --short HEAD")
sha = shaOut.strip()
cljMapFromPairs(@[
(cljKeyword("sha"), cljString(sha)),
(cljKeyword("success"), cljBool(true))
])
proc cljGitPush*(): CljVal =
let (gitOut, exit) = execCmdEx("git push")
cljMapFromPairs(@[
(cljKeyword("success"), cljBool(exit == 0)),
(cljKeyword("output"), cljString(gitOut.strip()))
])
proc cljGitDiff*(): CljVal =
let (gitOut, _) = execCmdEx("git diff")
cljString(gitOut)
proc cljGitLog*(n: CljVal = cljInt(5)): CljVal =
let count = if n.kind == ckInt: n.intVal else: 5
let (gitOut, _) = execCmdEx("git log --oneline -" & $count)
var items: seq[CljVal] = @[]
for line in gitOut.splitLines():
if line.len > 0:
items.add(cljString(line))
cljVector(items)