diff --git a/run.sh b/run.sh index 60a4efc..ad3cdce 100755 --- a/run.sh +++ b/run.sh @@ -7,11 +7,11 @@ TOOL_DIR="$(cd -- "$(dirname -- "$0")" && pwd)/tool" cd "${WORKING_DIRECTORY}" JQ=${JQ:-jq} -export JQ_FLAVOR=${JQ_FLAVOR:-"$(basename "${JQ}")"} +export JQ_FLAVOUR=${JQ_FLAVOUR:-"$(basename "${JQ}")"} run() { - if [ -d "${TOOL_DIR}/lib/stubs/${JQ_FLAVOR}" ]; then - STUBS_DIR="${TOOL_DIR}/lib/stubs/${JQ_FLAVOR}" + if [ -d "${TOOL_DIR}/lib/stubs/${JQ_FLAVOUR}" ]; then + STUBS_DIR="${TOOL_DIR}/lib/stubs/${JQ_FLAVOUR}" else STUBS_DIR="${TOOL_DIR}/lib/stubs/jq" fi @@ -19,7 +19,7 @@ run() { FILES_ARGS=() if [ "${EXPORT_FILE:-}" != "" ] && [ -f "${EXPORT_FILE}" ]; then FILES_ARGS+=(--arg exportFileName "${EXPORT_FILE:-}") - if [ "${JQ_FLAVOR}" != "gojq-extended" ]; then + if [ "${JQ_FLAVOUR}" != "gojq-extended" ]; then FILES_ARGS+=(--slurpfile exportFile "${EXPORT_FILE}") fi else diff --git a/runTests.sh b/runTests.sh index b0eb273..4a69a10 100755 --- a/runTests.sh +++ b/runTests.sh @@ -4,18 +4,18 @@ SCRIPT_DIR="$(cd -- "$(dirname -- "$0")" && pwd)" cd "${SCRIPT_DIR}/tool" || return JQ=${JQ:-jq} -export JQ_FLAVOR=${JQ_FLAVOR:-"$(basename "${JQ}")"} +export JQ_FLAVOUR=${JQ_FLAVOUR:-"$(basename "${JQ}")"} export JQ_TYPECHECKING=1 -if [ ! -d "./lib/stubs/${JQ_FLAVOR}" ]; then - STUBS_DIR="./lib/stubs/${JQ_FLAVOR}" +if [ ! -d "./lib/stubs/${JQ_FLAVOUR}" ]; then + STUBS_DIR="./lib/stubs/${JQ_FLAVOUR}" else STUBS_DIR="./lib/stubs/jq" fi runTests() { echo "Running Tests with JQ=${JQ}" - export JQ_FLAVOR=${JQ_FLAVOR:-"$(basename "${JQ}")"} + export JQ_FLAVOUR=${JQ_FLAVOUR:-"$(basename "${JQ}")"} ${JQ} -nr \ -L "$(realpath .)" -L "$(realpath ./lib)" -L "$(realpath "${STUBS_DIR}")" \ "include \"tests\"; testsMain" @@ -24,5 +24,5 @@ runTests() { runTests if command -v gojq 2>/dev/null >/dev/null; then - JQ=gojq JQ_FLAVOR=gojq runTests + JQ=gojq JQ_FLAVOUR=gojq runTests fi \ No newline at end of file diff --git a/tool/lib/JSONLib.jq b/tool/lib/JSONLib.jq new file mode 100644 index 0000000..318d057 --- /dev/null +++ b/tool/lib/JSONLib.jq @@ -0,0 +1,110 @@ +import "ansiLib" as ansiLib; + +def colorEscapes: + def parseJQColours: + (. | split(":")) | + { + "null": .[0], + "false": .[1], + "true": .[2], + "number": .[3], + "string": .[4], + "array": .[5], + "object": .[6], + "objectKey": .[7], + }; + + def parseGOJQColours: + (. | split(":")) | + { + "null": .[0], + "false": .[1], + "true": .[2], + "number": .[3], + "string": .[4], + "objectKey": .[5], + "array": .[6], + "object": .[7], + }; + def defaultColours: + if ($ENV["JQ_FLAVOUR"] | tostring | startswith("gojq")) then + "90:33:33:36:32:34;1" | parseGOJQColours + else + "0;90:0;39:0;39:0;39:0;32:1;39:1;39:1;34" | parseJQColours + end; + + try ( + if $ENV["JQ_COLORS"] != null then + $ENV["JQ_COLORS"] | parseJQColours + elif $ENV["GOJQ_COLORS"] != null then + $ENV["GOJQ_COLORS"] | parseGOJQColours + else + defaultColours + end + ) catch ( + defaultColours + ); + +def encodeJSONValue($withColour; $escapes; $indent; $currentDepth): + def colourText($kind; $escapes): + . as $text | + ansiLib::CSR + $escapes[$kind] + "m" + $text + ansiLib::CSR + "0m"; + + def maybeColourText($withColour; $kind; $escapes): if $withColour then colourText($kind; $escapes) end; + + def maybeIndent($indent; $currentDepth): + if $indent > 0 then [range($indent * $currentDepth) | " "] | join("") else "" end; + def maybeNewline($indent): + if $indent > 0 then "\n" else "" end; + def maybeSpace($indent): + if $indent > 0 then " " else "" end; + + . as $value | + (. | type) as $valueType | + if $valueType == "null" then + "null" | maybeColourText($withColour; "null"; $escapes) + elif $valueType == "boolean" then + if $value then + "true" | maybeColourText($withColour; "true"; $escapes) + else + "false" | maybeColourText($withColour; "false"; $escapes) + end + elif $valueType == "number" then + $value | tostring | maybeColourText($withColour; "number"; $escapes) + elif $valueType == "string" then + $value | tojson | maybeColourText($withColour; "string"; $escapes) + elif $valueType == "array" then + ($value | length) as $numValues | + ("[" | maybeColourText($withColour; "array"; $escapes)) + + if $numValues > 0 then maybeNewline($indent) else "" end + + ([ + $value[] | + maybeIndent($indent; $currentDepth) + + encodeJSONValue($withColour; $escapes; $indent; $currentDepth + 1) + ] | join("," + maybeNewline($indent))) + + if $numValues > 0 then maybeNewline($indent) else "" end + + if $numValues > 0 then maybeIndent($indent; $currentDepth-1) else "" end + + ("]" | maybeColourText($withColour; "array"; $escapes)) + elif $valueType == "object" then + ($value | keys | length) as $numKeys | + ("{" | maybeColourText($withColour; "object"; $escapes)) + + if $numKeys > 0 then maybeNewline($indent) else "" end + + ([ + $value | keys | sort[] | + . as $objectKey | + $value[$objectKey] as $objectValue | + maybeIndent($indent; $currentDepth) + + ($objectKey | tojson | maybeColourText($withColour; "objectKey"; $escapes)) + + ":" + maybeSpace($indent) + + ($objectValue | encodeJSONValue($withColour; $escapes; $indent; $currentDepth + 1)) + ] | join("," + maybeNewline($indent))) + + if $numKeys > 0 then maybeNewline($indent) else "" end + + if $numKeys > 0 then maybeIndent($indent; $currentDepth-1) else "" end + + ("}" | maybeColourText($withColour; "object"; $escapes)) + end; + +def encodeJSON($withColour; $indent): + . | encodeJSONValue($withColour; colorEscapes; $indent // 0; 1); + + + \ No newline at end of file diff --git a/tool/lib/ansiLib.jq b/tool/lib/ansiLib.jq new file mode 100644 index 0000000..49917df --- /dev/null +++ b/tool/lib/ansiLib.jq @@ -0,0 +1,24 @@ +def supportsColour: + $ENV["JQ_SUPPORTS_COLOR"] == "1" or $ENV["JQ_SUPPORTS_COLOUR"] == "1" ; + +def CSR: + "\u001b["; + +def resetColours: + CSR + "0m"; + +def colourText($colourCode): + . as $text | + if supportsColour | not then + $text + else + CSR + ($colourCode | tostring) + "m" + $text + resetColours + end; + +def colourText($colourCode; $mode): + . as $text | + if supportsColour | not then + $text + else + CSR + ($mode | tostring) + ";" + ($colourCode | tostring) + "m" + $text + resetColours + end; \ No newline at end of file diff --git a/tool/lib/gojqExtendedLib.jq b/tool/lib/gojqExtendedLib.jq index 2b43f3f..470d546 100644 --- a/tool/lib/gojqExtendedLib.jq +++ b/tool/lib/gojqExtendedLib.jq @@ -1,7 +1,7 @@ include "stubs"; def checkSupported: - $ENV.JQ_FLAVOR == "gojq-extended"; + $ENV.JQ_FLAVOUR == "gojq-extended"; def readFile($filename): _readFile($filename); def writeFileString($filename): _writeFileString($filename); \ No newline at end of file diff --git a/tool/lib/journalTypes.jq b/tool/lib/journalTypes.jq index 6d877a6..5f3ebd2 100644 --- a/tool/lib/journalTypes.jq +++ b/tool/lib/journalTypes.jq @@ -3,7 +3,7 @@ import "typeLib" as typeLib; def ensureAdministrationRoute: . as $administrationRoute | if typeLib::typecheckingEnabled then - [ + if [ "ORAL", "SUBLINGUAL", "BUCCAL", @@ -15,7 +15,9 @@ def ensureAdministrationRoute: "INTRAVENOUS", "SMOKED", "INHALED" - ] | any(index($administrationRoute)) + ] | any(index($administrationRoute)) | not then + typeLib::typeErrorText("administrationRoute") + end end; def ensureIngestion: diff --git a/tool/lib/logLib.jq b/tool/lib/logLib.jq new file mode 100644 index 0000000..010de77 --- /dev/null +++ b/tool/lib/logLib.jq @@ -0,0 +1,99 @@ +import "typeLib" as typeLib; +import "ansiLib" as ansiLib; +import "JSONLib" as JSONLib; + +def logLevels: + [ + "trace", + "debug", + "info", + "warn", + "error", + "fatal" + ]; + +def isValidLogLevel($logLevel): + logLevels | any(index($logLevel)); + +def ensureLogLevel: + . as $logLevel | + if typeLib::typecheckingEnabled then + if isValidLogLevel($logLevel) | not then typeLib::typeErrorText("logLevel") end + end; + +def maxLogLevel: + ($ENV["JQ_LOGLEVEL"] // "info") as $maxLogLevel | + if isValidLogLevel($maxLogLevel) | not then + "info" + else $maxLogLevel end; + +def shouldLog($logLevel): + maxLogLevel as $maxLogLevel | + logLevels as $logLevels | + reduce range($logLevels | length) as $logLevelIndex ({}; + .[$logLevels[$logLevelIndex]] = $logLevelIndex + ) as $logLevelIndexes | + $logLevelIndexes[$maxLogLevel] <= $logLevelIndexes[$logLevel]; + +def ansiColourByName: + . as $name | + { + "red": "31", + "yellow": "33", + "blue": "36", + "gray": "37" + }[$name]; + +def levelColour: + . as $logLevel | + { + "trace": "yellow", + "debug": "gray", + "info": "blue", + "warn": "yellow", + "error": "red", + "fatal": "red" + }[$logLevel] | ansiColourByName; + +def log($logLevel; $msg; $data): + . as $input | + ($logLevel | ensureLogLevel) | + ($msg | typeLib::ensureNullOr(typeLib::ensureString)) | + + if shouldLog($logLevel) then + ($logLevel | levelColour) as $logLevelColour | + ($logLevel | ascii_upcase | ansiLib::colourText($logLevelColour)) as $logLevelText | + ($msg | ansiLib::colourText("gray" | ansiColourByName)) as $msgText | + + if $data != null then + $data | JSONLib::encodeJSON(true; 2) + else "" end | . as $dataText | + + "\($logLevelText) \($msgText) \($dataText)\n" | + if $logLevel == "fatal" then halt_error(1) else stderr end + end | + + $input; + +def trace($msg; $data): log("trace"; $msg; $data); +def debug($msg; $data): log("debug"; $msg; $data); +def info($msg; $data): log("info"; $msg; $data); +def warn($msg; $data): log("warn"; $msg; $data); +def error($msg; $data): log("error"; $msg; $data); +def fatal($msg; $data): log("fatal"; $msg; $data); + +def trace($msg): trace($msg; null); +def debug($msg): debug($msg; null); +def info($msg): info($msg; null); +def warn($msg): warn($msg; null); +def error($msg): error($msg; null); +def fatal($msg): fatal($msg; null); + +def logTest: + ([ + "trace", + "debug", + "info", + "warn", + "error" + ][] | log(.; "example text \(.)"; {})) | empty; \ No newline at end of file diff --git a/tool/lib/typeLib.jq b/tool/lib/typeLib.jq index 4776d01..5d7d62a 100644 --- a/tool/lib/typeLib.jq +++ b/tool/lib/typeLib.jq @@ -1,8 +1,8 @@ import "testLib" as testLib; def typecheckingEnabled: - if $ENV["JQ_TYPECHECKING"] != null and (["true", "1", "debug"] | any(index($ENV["JQ_TYPECHECKING"]))) then - true + if $ENV["JQ_TYPECHECKING"] != null then + ["true", "1", "debug"] | any(index($ENV["JQ_TYPECHECKING"])) else false end; def typecheckingDebug: @@ -31,6 +31,7 @@ def dumpType: def typeErrorText: . as $type | "Type Error Checking '\($type)'"; + def typeErrorText($type): $type | typeErrorText; def typeError($type):