Skip to content

Commit

Permalink
rework boatConfig to support configs of type Config/JsonNode
Browse files Browse the repository at this point in the history
  • Loading branch information
noahehall committed Mar 16, 2023
1 parent 274b555 commit 7ec90b0
Show file tree
Hide file tree
Showing 15 changed files with 144 additions and 80 deletions.
18 changes: 14 additions & 4 deletions bdd.nim
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ proc itShouldNot*(
type What* = enum
## expected result of some condition
should, ## be true
shouldError, ## when called
shouldRaise, ## error when called
shouldNot, ## be true
shouldNotError, ## when called
shouldNotRaise, ## error when called

proc bdd*(caseName: string): (What, string, () -> bool) -> void =
## simple assertions for use with testament
Expand All @@ -50,11 +50,21 @@ proc bdd*(caseName: string): (What, string, () -> bool) -> void =
case what
of should: itShould msg, caseName, condition()
of shouldNot: itShouldNot msg, caseName, condition()
of shouldError, shouldNotError:
of shouldRaise, shouldNotRaise:
var didError = false
try: discard condition()
except CatchableError, OSError: didError = true
finally:
if what.ord == shouldError.ord: itShould msg, caseName, didError
if what.ord == shouldRaise.ord: itShould msg, caseName, didError
else: itShouldNot msg, caseName, didError
)


when isMainModule:
proc catchme: bool = raise newException(CatchableError, "if you can")
let it = bdd "bdd tests"

it should, "be true", () => true
it shouldNot, "be true", () => false
it shouldRaise, "error", () => catchme()
it shouldNotRaise, "error", () => true
8 changes: 4 additions & 4 deletions src/boat.nim
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
## .. include:: ./readme.rst

import boat/private/[
BoatConfig,
BoatConstants,
BoatErrors,
]
boatConfig,
boatConstants,
boatErrors,
]

proc boat*: void = echo "All HANDS! cat o'nine tails! blue peter! OMG... landlubber"

Expand Down
23 changes: 0 additions & 23 deletions src/boat/private/BoatConfigType.nim

This file was deleted.

46 changes: 28 additions & 18 deletions src/boat/private/BoatConfig.nim → src/boat/private/boatConfig.nim
Original file line number Diff line number Diff line change
Expand Up @@ -19,61 +19,63 @@ import std/[
json,
os,
strutils,
]
]

import
BoatConstants,
BoatErrors,
BoatConfigType,
FileManager
boatConstants,
boatErrors,
boatConfigType,
fileManager

# consumers can retrieve the parsed Config and path on disk
# but only internal functions should be able to set it
export BoatConfigType.BoatConfig, parsed, parsedPath

var captainsLog* {.global.} = %* {} ## \
## captains log is the world

proc parseLocalManifest*(self: BoatConfig, path = self.use): bool =
proc parseLocalManifest*(self: BoatConfig, path: string = ""): bool =
## parse self.use to self.parsed
## prefer calling self.load or self.reload for validation
self.parsed = loadConfig path
let usePath = self.usePath path

# self.parsed = self.parsed.retrieve usePath
result = true

proc localManifestIsValid*(self: BoatConfig, path: string = self.use): bool =
proc localManifestIsValid*(self: BoatConfig, path: string = ""): bool =
## throws if manifest not found, cant be read, or errors during parsing
let pathInfo = path.getFileInfo
let usePath = self.usePath path
let pathInfo = usePath.getFileInfo

result = case pathInfo.kind
of pcFile, pcLinkToFile:
if fpUserRead notin pathInfo.permissions: raise filePermissionError
elif not path.endsWith manifestName: raise manifestNameError
elif not self.parseLocalManifest path: raise configParseError
elif not usePath.endsWith manifestName: raise manifestNameError
elif not self.parseLocalManifest usePath: raise configParseError
else: true
of pcDir, pcLinkToDir:
# force directories to use their manifest
self.use = self.use / manifestName
self.localManifestIsValid()

proc save*(self: BoatConfig, path = self.use): bool =
proc save*(self: BoatConfig, path: string = ""): bool =
## serialize Self.parsed to disk @ boatConstants.cacheDir / <SELF.ID>.{manifestName}
## updates captains manifest with stuffWeCached.self.use -> cache location
# should call fileManager.toDisk
result = true

proc init*(self: BoatConfig, path = self.use): bool =
proc init*(self: BoatConfig, path: string = ""): bool =
let usePath = self.usePath path
# starts with https?
# ends with manifestName?
# save to boatConstants.tempDir / self.use
# recurse self.reload path = temp location
# throw: urls must point to a manifest.nim.ini
case path.startsWith "https"
case usePath.startsWith "https"
of true: raise tddError
else:
try: doAssert self.localManifestIsValid(path) == true
except CatchableError:
debugEcho repr getCurrentException()
raise fileLoadError
if not self.save path : raise fileSaveDefect
if not self.save usePath: raise fileSaveDefect
else: result = true

proc reload*(self: BoatConfig): bool =
Expand All @@ -97,3 +99,11 @@ proc loadCaptainsLog(): void =

# always load the captainsLog into ram
if not captainsLogLoaded: loadCaptainsLog()


# consumers can retrieve the parsed Config and path on disk
# but only internal functions should be able to set it
export
boatConfigType.BoatConfig,
parsed,
parsedPath
26 changes: 26 additions & 0 deletions src/boat/private/boatConfigType.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import std/[parsecfg, json]

import fileManager, boatConstants

type BoatConfig*[T: BoatConfigKind = Config] = ref object of RootObj
## base type for all boat configs
use*: string ## \
## filepath, dir containing a file or remote uri

parsed: T ## \
## the parsed config after loading
parsedPath: string ## \
## path on disk the parsed config was saved to

proc `parsed=`*(self: BoatConfig, path: string): void =
self.parsed = self.parsed.retrieve path

proc `parsed`*(self: BoatConfig): BoatConfigKind = self.parsed

proc `parsedPath=`*(self: BoatConfig, path: string): void =
self.parsedPath = path

proc `parsedPath`*(self: BoatConfig): string = self.parsedPath

proc usePath*(self: BoatConfig, path: string): string =
if path.len is Positive: path else: self.use
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@

import std/os

import BoatErrors
from json import JsonNode
from parsecfg import Config

import boatErrors

type BoatConfigKind* = Config | JsonNode

var captainsLogLoaded* {.global.} = false ## \
## true if we've loaded the captains log from disk into ram
Expand All @@ -29,3 +34,5 @@ for dir in @[cacheDir, tempDir]:
except CatchableError:
debugEcho repr getCurrentException()
raise dirCreateDefect

export json.JsonNode, parsecfg.Config
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,21 @@
## ==========
## standard errors and defects

type BoatError* = ref object of CatchableError
import std/strformat

type BoatError* = ref object of CatchableError ## \
## standard catchable boat error

var configParseError* = BoatError(msg: "Cant Parse Config")
var fileLoadError* = BoatError(msg: "Cant Load File")
var filePermissionError* = BoatError(msg: "Invalid File Permissions")
var fileSaveError* = BoatError(msg: "Cant Save File")
var manifestNameError* = BoatError(msg: "Invalid Manifest Name")

type BoatDefect = ref object of Defect
type BoatDefect = ref object of Defect ## \
# standard boat defect

var dirCreateDefect* = BoatDefect(msg: "Dir Create Failed")
var fileLoadDefect* = BoatDefect(msg: "Cant Load File")
var fileSaveDefect* = BoatDefect(msg: "Cant Save File")
var boatConfigKindError* = BoatDefect(msg: fmt"Expected BoatConfigKind")
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@
from ../../../bdd import tddError

import std/[
asyncdispatch,
json,
locks,
parsecfg,
threadpool,
]
]

import BoatConstants, BoatErrors

export asyncdispatch
import
boatConstants,
boatErrors,
fileManagerUtils

type SaveType* = enum
parsedConfig,
Expand All @@ -39,15 +37,6 @@ proc encode*[T: JsonNode | string](self: T): string =
# of JsonNode -> parse to string -> base64
# of string -> base64

proc persist*[T: string | Config](self: T, path: string): Future[void] {.async.} =
## writes strings to path
## calls parsecfg.writeConfig for configs
raise tddError
# lock
# of string -> data.write path
# of Config -> parsecfg.writeConfig path
# unlock
# throw if any errors occur

proc toDisk*[T: JsonNode | string | Config](
self: SaveType,
Expand Down Expand Up @@ -86,3 +75,6 @@ proc fromDisk*[T](
# if file not found / cant be read then throw if errorNotFound is true
if errorNotFound and "cant load file" is string: raise fileLoadError
else: result = ("", new(to))


export fileManagerUtils
33 changes: 33 additions & 0 deletions src/boat/private/fileManagerUtils.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from ../../../bdd import tddError

import std/[
asyncdispatch,
json,
parsecfg,
]

import boatErrors, boatConstants


proc persist*[T: string | Config](self: T, path: string): Future[void] {.async.} =
## writes strings to path
## calls parsecfg.writeConfig for configs
raise tddError
# lock
# of string -> data.write path
# of Config -> parsecfg.writeConfig path
# unlock
# throw if any errors occur

proc retrieve*[T: BoatConfigKind](self: T, path: string): T =
# retrieves a Config or Json from a path
try:
if self is Config: result = loadConfig path
elif self is JsonNode: raise tddError # should load json from path
else: raise boatConfigKindError
except CatchableError:
debugEcho repr getCurrentException()
raise fileLoadDefect


export asyncdispatch, json, parsecfg
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions testresults.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions tests/config/tconfig.nim
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ block todoCases:
it should, "save config", () => newConf().save()

for conf in @[
newConf("192.168.1.1"),
newConf("http://www.not.https")
]: it shouldError, "invalid protocol", () => conf.load()
newConf(use = "192.168.1.1"),
newConf(use = "http://www.not.https")
]: it shouldRaise, "invalid protocol", () => conf.load()
17 changes: 10 additions & 7 deletions tests/helpers.nim
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import std/[os]
import std/[os, parsecfg]

import ../src/boat/private/BoatConfig

export BoatConfig
export os
import ../src/boat/private/[boatConfig, boatConstants]

let defaultManifest = getCurrentDir() / "src/boat/private/captain/manifest.nim.ini"

proc newConf*(use: string = defaultManifest): BoatConfig = BoatConfig(use: use)
proc newConfD*(use: string = defaultManifest): BoatConfig = BoatConfig(use: use.splitPath.head)
proc newConf*[T: BoatConfigKind](self: T = newConfig(), use: string = defaultManifest): BoatConfig[T] =
BoatConfig[T](use: use)

proc newConfD*[T: BoatConfigKind](self: T = newConfig(), use: string = defaultManifest): BoatConfig[T] =
BoatConfig[T](use: use.splitPath.head)


export boatConfig, os

when isMainModule:
debugEcho repr newConf()
Expand Down

0 comments on commit 7ec90b0

Please sign in to comment.