feat(cli): add --lib-path flag and unify getLibPath logic

- Add --lib-path <dir> global CLI flag (parsed before subcommand)
- getLibPath() now checks CLI override first, then CLJNIM_LIB_PATH env,
  then current dir lib/, then app dir lib/
- nimCompile always includes compiler runtime lib path so cljnim_runtime
  is found even when --lib-path points to a project-specific directory
- Sync repl.nim getLibPath() to match cljnim.nim (env var + current dir)
This commit is contained in:
2026-05-12 11:28:12 +03:00
parent bc33eab7fc
commit 9a8519df87
2 changed files with 37 additions and 14 deletions
+30 -12
View File
@@ -2,8 +2,13 @@
import os, osproc, strutils, times import os, osproc, strutils, times
import reader, emitter, types, repl, macros, deps, ai_assist, tui import reader, emitter, types, repl, macros, deps, ai_assist, tui
var libPathOverride* = ""
proc getLibPath(): string = proc getLibPath(): string =
# Check environment variable first # CLI --lib-path takes highest precedence
if libPathOverride.len > 0 and dirExists(libPathOverride):
return libPathOverride
# Check environment variable
let envPath = getEnv("CLJNIM_LIB_PATH", "") let envPath = getEnv("CLJNIM_LIB_PATH", "")
if envPath.len > 0 and dirExists(envPath): if envPath.len > 0 and dirExists(envPath):
return envPath return envPath
@@ -131,9 +136,13 @@ proc compileFileLib*(inputPath: string, outputPath: string, extraPaths: seq[stri
proc nimCompile(nimPath: string, binPath: string, release: bool = false): tuple[exitCode: int, output: string] = proc nimCompile(nimPath: string, binPath: string, release: bool = false): tuple[exitCode: int, output: string] =
let libPath = getLibPath() let libPath = getLibPath()
let compilerLib = getAppDir() / "lib"
var cmd = "nim c" var cmd = "nim c"
if release: if release:
cmd.add(" -d:release") cmd.add(" -d:release")
# Always include compiler runtime lib so cljnim_runtime is found
if dirExists(compilerLib) and compilerLib != libPath:
cmd.add(" --path:" & quoteShell(compilerLib))
cmd.add(" --path:" & quoteShell(libPath)) cmd.add(" --path:" & quoteShell(libPath))
cmd.add(" -o:" & quoteShell(binPath) & " " & quoteShell(nimPath)) cmd.add(" -o:" & quoteShell(binPath) & " " & quoteShell(nimPath))
echo "Compiling: ", cmd echo "Compiling: ", cmd
@@ -215,20 +224,29 @@ proc runFile*(inputPath: string) =
proc main() = proc main() =
initBuiltinMacros() initBuiltinMacros()
let args = commandLineParams() var args = commandLineParams()
# Strip leading global flags
if args.len >= 2 and args[0] == "--lib-path":
libPathOverride = args[1]
args = args[2..^1]
if args.len == 0: if args.len == 0:
echo "Bara Lang — AI-First Compiler" echo "Bara Lang — AI-First Compiler"
echo "" echo ""
echo "Usage:" echo "Usage:"
echo " cljnim compile <file.clj> [output.nim] Compile to Nim source" echo " cljnim [--lib-path <dir>] compile <file.clj> [output.nim]"
echo " cljnim run <file.clj> Compile and run binary" echo " cljnim [--lib-path <dir>] run <file.clj>"
echo " cljnim read <file.clj> Parse and print AST" echo " cljnim [--lib-path <dir>] read <file.clj>"
echo " cljnim repl [--json] Start REPL (human or AI mode)" echo " cljnim repl [--json]"
echo " cljnim deps Resolve dependencies from deps.edn" echo " cljnim deps"
echo " cljnim -e '<code>' Evaluate expression" echo " cljnim -e '<code>'"
echo " cljnim ai '<description>' Generate Bara Lang code with AI" echo " cljnim ai '<description>'"
echo " cljnim tui Start interactive TUI" echo " cljnim tui"
echo ""
echo "Global Options:"
echo " --lib-path <dir> Additional Nim library search path"
echo " (also via CLJNIM_LIB_PATH env var)"
echo "" echo ""
echo "REPL Commands:" echo "REPL Commands:"
echo " :quit, :q Exit REPL" echo " :quit, :q Exit REPL"
@@ -241,7 +259,7 @@ proc main() =
echo " Input: {\"op\":\"eval\",\"form\":\"(+ 1 2)\"}" echo " Input: {\"op\":\"eval\",\"form\":\"(+ 1 2)\"}"
echo " Output: {\"status\":\"ok\",\"result\":{...},\"meta\":{...}}" echo " Output: {\"status\":\"ok\",\"result\":{...},\"meta\":{...}}"
quit(0) quit(0)
let cmd = args[0] let cmd = args[0]
# Handle -e flag # Handle -e flag
+7 -2
View File
@@ -16,13 +16,18 @@ type
evalEnv*: Env evalEnv*: Env
proc getLibPath(): string = proc getLibPath(): string =
# Check environment variable first
let envPath = getEnv("CLJNIM_LIB_PATH", "")
if envPath.len > 0 and dirExists(envPath):
return envPath
# Check current directory's lib first (project-local libs)
let candidate0 = getCurrentDir() / "lib"
if dirExists(candidate0): return candidate0
let appDir = getAppDir() let appDir = getAppDir()
let candidate1 = appDir / "lib" let candidate1 = appDir / "lib"
let candidate2 = appDir.parentDir / "lib" let candidate2 = appDir.parentDir / "lib"
let candidate3 = getCurrentDir() / "lib"
if dirExists(candidate1): return candidate1 if dirExists(candidate1): return candidate1
if dirExists(candidate2): return candidate2 if dirExists(candidate2): return candidate2
if dirExists(candidate3): return candidate3
return "lib" return "lib"
proc initReplState*(mode: ReplMode): ReplState = proc initReplState*(mode: ReplMode): ReplState =