Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .agents/codebase-insights.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@
- Interpreter overrides (e.g. `CODETRACER_PYTHON_INTERPRETER`) are now treated as authoritative; if the configured path cannot be resolved we error instead of silently falling back to PATH.
- `ct record` verifies that `codetracer_python_recorder` is importable before launching the db backend and prints actionable guidance if the module is missing or broken.
- Sudoku test-program datasets include intentionally invalid boards (e.g., examples #3 and #6) with duplicate digits inside a sub-grid; solvers should detect and report these gracefully.
- Default config templates live in `src/config/defaults.nim` and are embedded with `staticRead`; installers write from the embedded string rather than copying from `linksPath`.
14 changes: 11 additions & 3 deletions src/common/config.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import std / [ strutils, sequtils, streams, strformat, os ]
import json_serialization/std/tables, yaml
import .. / common / [paths, types]
import .. / config / defaults

type
RRBackendConfig* = object
Expand Down Expand Up @@ -89,6 +90,10 @@ let configDir* = linksPath / "config"
let userConfigDir* = getEnv("XDG_CONFIG_HOME", getHomeDir() / ".config") / "codetracer"
let userLayoutDir* = getEnv("XDG_CONFIG_HOME", getHomeDir() / ".config") / "codetracer"

proc writeDefaultConfigFile(destPath: string) {.raises: [IOError, OSError].} =
## Persist the embedded default configuration to `destPath`.
writeFile(destPath, defaults.defaultConfigContent)

func normalize(shortcut: string): string =
# for now we expect to write editor-style monaco shortcuts
shortcut
Expand Down Expand Up @@ -140,7 +145,7 @@ proc loadConfig*(folder: string, inTest: bool): Config =
if file.len == 0:
file = userConfigDir / configPath
createDir(userConfigDir)
copyFile(configDir / defaultConfigPath, file)
writeDefaultConfigFile(file)
# if inTest:
# file = codetracerTestDir / testConfigPath
var raw = ""
Expand Down Expand Up @@ -170,6 +175,9 @@ proc loadConfig*(folder: string, inTest: bool): Config =
echo fmt" for now we now have directly copied your existing config file to {backupFilePath}"
except Exception as copyError:
echo "ERROR: couldn't backup your existing config file; error: ", copyError.msg
copyFile(configDir / defaultConfigPath, file)
try:
writeDefaultConfigFile(file)
except CatchableError as defaultWriteError:
echo "ERROR: failed to write default config: ", defaultWriteError.msg
quit(1)
echo " REPLACED with new up to date default config file"

10 changes: 10 additions & 0 deletions src/config/defaults.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
## Default configuration payloads embedded at compile time.
##
## Keeping the defaults in a dedicated module allows both CLI and frontend
## components to share the same embedded assets without relying on runtime
## filesystem access.

const
defaultConfigFilename* = "default_config.yaml"
defaultConfigContent* = staticRead(defaultConfigFilename)

5 changes: 3 additions & 2 deletions src/frontend/config.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ import
std / [json, strutils, sequtils, jsffi],
types,
lib/jslib,
.. / common / ct_logging
.. / common / ct_logging,
.. / config / defaults

let
configPath* = ".config.yaml"
testConfigPath* = ".config.yaml"
defaultConfigPath* = "default_config.yaml"
defaultLayoutPath* = "default_layout.json"
defaultConfigContent* = defaults.defaultConfigContent

when not defined(ctRenderer):
import
Expand Down Expand Up @@ -56,4 +58,3 @@ proc initShortcutMap*(map: InputShortcutMap): ShortcutMap =
result.conflictList.add((key, value))
return result


17 changes: 9 additions & 8 deletions src/frontend/index/config.nim
Original file line number Diff line number Diff line change
Expand Up @@ -193,15 +193,16 @@ proc loadConfig*(main: js, startOptions: StartOptions, home: cstring = cstring""
errorPrint "mkdir for config folder error: exiting: ", errMkdir
quit(1)

let errCopy = await fsCopyFileWithErr(
cstring(fmt"{configDir / defaultConfigPath}"),
cstring(fmt"{userConfigDir / configPath}")
# Persist the embedded default config when the user has no local file yet.
let errWrite = await fsWriteFileWithErr(
cstring(fmt"{userConfigDir / configPath}"),
cstring(defaultConfigContent)
)

if not errCopy.isNil:
errorPrint "can't copy .config.yaml to user config dir:"
errorPrint " tried to copy from: ", cstring(fmt"{configDir / defaultConfigPath}")
errorPrint " to: ", fmt"{userConfigDir / configPath}"
if not errWrite.isNil:
errorPrint "can't write default .config.yaml to user config dir:"
errorPrint " target: ", fmt"{userConfigDir / configPath}"
errorPrint " error: ", errWrite
quit(1)

infoPrint "index: load config ", file
Expand Down Expand Up @@ -261,4 +262,4 @@ proc loadValues*(a: js, id: cstring): JsAssoc[cstring, cstring] =
values[field] = cstring"undefined"
else:
values[field] = cstring"nil"
return values
return values
19 changes: 8 additions & 11 deletions src/frontend/index_config.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1219,17 +1219,14 @@ proc loadConfig*(main: js, startOptions: StartOptions, home: cstring = j"", send
if not errMkdir.isNil:
errorPrint "mkdir for config folder error: exiting: ", errMkdir
quit(1)
# thanks to Peter for the good advice to use copyFile instead of `cp`
# works around an issue i had with wrong libc version and nix
# and more clean
let errCopy = await fsCopyFileWithErr(
cstring(fmt"{configDir / defaultConfigPath}"),
cstring(fmt"{userConfigDir / configPath}"));
# cstring(&"cp {configDir}{defaultLayoutPath} {filename}"))
if not errCopy.isNil:
errorPrint "can't copy .config.yaml to user config dir:"
errorPrint " tried to copy from: ", cstring(fmt"{configDir / defaultConfigPath}")
errorPrint " to: ", fmt"{userConfigDir / configPath}"
# Persist the embedded default config when the user has no local file yet.
let errWrite = await fsWriteFileWithErr(
cstring(fmt"{userConfigDir / configPath}"),
cstring(defaultConfigContent))
if not errWrite.isNil:
errorPrint "can't write default .config.yaml to user config dir:"
errorPrint " target: ", fmt"{userConfigDir / configPath}"
errorPrint " error: ", errWrite
quit(1)

# TODO: maybe remove config test logic?
Expand Down
Loading