AI git commit test from Clojure
This commit is contained in:
+109
-1
@@ -1,4 +1,4 @@
|
|||||||
import strutils, sequtils, hashes, algorithm
|
import strutils, sequtils, hashes, algorithm, os, osproc
|
||||||
|
|
||||||
type
|
type
|
||||||
CljKind* = enum
|
CljKind* = enum
|
||||||
@@ -1070,3 +1070,111 @@ proc cljRange*(start, finish: CljVal): CljVal =
|
|||||||
for i in start.intVal..<finish.intVal:
|
for i in start.intVal..<finish.intVal:
|
||||||
items.add(cljInt(i))
|
items.add(cljInt(i))
|
||||||
cljList(items)
|
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)
|
||||||
|
|||||||
@@ -96,6 +96,18 @@ proc runtimeName(op: string): string =
|
|||||||
of "deref": "cljDeref"
|
of "deref": "cljDeref"
|
||||||
of "reset!": "cljReset"
|
of "reset!": "cljReset"
|
||||||
of "swap!": "cljSwap"
|
of "swap!": "cljSwap"
|
||||||
|
# ---- File operations ----
|
||||||
|
of "file/read": "cljFileRead"
|
||||||
|
of "file/write": "cljFileWrite"
|
||||||
|
of "file/append": "cljFileAppend"
|
||||||
|
of "file/ls": "cljFileLs"
|
||||||
|
of "file/exists?": "cljFileExists"
|
||||||
|
# ---- Git operations ----
|
||||||
|
of "git/status": "cljGitStatus"
|
||||||
|
of "git/commit": "cljGitCommit"
|
||||||
|
of "git/push": "cljGitPush"
|
||||||
|
of "git/diff": "cljGitDiff"
|
||||||
|
of "git/log": "cljGitLog"
|
||||||
else: ""
|
else: ""
|
||||||
|
|
||||||
proc emitArgs(args: seq[CljVal]): string =
|
proc emitArgs(args: seq[CljVal]): string =
|
||||||
|
|||||||
Reference in New Issue
Block a user