From d2da9e1af4404f93396800733ed708b0b5270abe Mon Sep 17 00:00:00 2001 From: chaos Date: Thu, 7 Nov 2024 21:45:22 +0000 Subject: [PATCH] update --- .gitignore | 3 +- run.sh | 15 ++++- runTests.sh | 20 ++++-- tool/dropins/gojq/dropins.jq | 0 tool/dropins/jq/dropins.jq | 0 tool/journalUtils.jq | 10 +-- tool/{ => lib}/argsLib.jq | 5 +- tool/{ => lib}/testLib.jq | 0 tool/{ => lib}/typeLib.jq | 19 ++++-- tool/main.jq | 21 +++--- {testdata => tool/testdata}/tests_export.json | 0 tool/tests.jq | 23 ++++--- tool/types.jq | 67 +++++++++++++------ tool/utils.jq | 2 + 14 files changed, 123 insertions(+), 62 deletions(-) create mode 100644 tool/dropins/gojq/dropins.jq create mode 100644 tool/dropins/jq/dropins.jq rename tool/{ => lib}/argsLib.jq (86%) rename tool/{ => lib}/testLib.jq (100%) rename tool/{ => lib}/typeLib.jq (82%) rename {testdata => tool/testdata}/tests_export.json (100%) diff --git a/.gitignore b/.gitignore index b469f3b..25f93ed 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -export.json \ No newline at end of file +export.json +.dev.env diff --git a/run.sh b/run.sh index f50f4c6..84ff932 100755 --- a/run.sh +++ b/run.sh @@ -3,6 +3,17 @@ set -eu SCRIPT_DIR="$(cd -- "$(dirname -- "$0")" && pwd)" -cd "$SCRIPT_DIR" +cd "$SCRIPT_DIR/tool" + +JQ=${JQ:-jq} +export JQ_FLAVOR=${JQ_FLAVOR:-${JQ}} + +run() { + ${JQ} -rn -L "$(realpath .)" -L "$(realpath lib)" -L "$(realpath dropins)/${JQ_FLAVOR}" \ + --slurpfile exportFile "${EXPORT_FILE:-export.json}" \ + 'include "main"; main' \ + --args -- "$@" +} + +run "$@" -${JQ:-jq} ${JQ_ARGS:-} -L "tool" -f tool/main.jq -Cr "${EXPORT_FILE:-export.json}" --args -- "$@" \ No newline at end of file diff --git a/runTests.sh b/runTests.sh index c0fc3ee..83a7068 100755 --- a/runTests.sh +++ b/runTests.sh @@ -1,11 +1,19 @@ #!/usr/bin/env bash -set -eu - SCRIPT_DIR="$(cd -- "$(dirname -- "$0")" && pwd)" -cd "$SCRIPT_DIR" +cd "${SCRIPT_DIR}/tool" || return -export TYPECHECKING=1 +export JQ_TYPECHECKING=1 -${JQ:-jq} -n -r -L tool -L . "include \"testLib\"; testLibMain" -${JQ:-jq} -n -r -L tool -L . "include \"tests\"; testsMain" \ No newline at end of file +runTests() { + JQ=${JQ:-jq} + export JQ_FLAVOR=${JQ_FLAVOR:-jq} + echo "Running Tests with JQ=${JQ}" + ${JQ} -n -r -L . -L "dropins/${JQ_FLAVOR}" "include \"tests\"; testsMain" +} + +runTests + +if command -v gojq 2>/dev/null >/dev/null; then + JQ=gojq JQ_FLAVOR=gojq runTests +fi \ No newline at end of file diff --git a/tool/dropins/gojq/dropins.jq b/tool/dropins/gojq/dropins.jq new file mode 100644 index 0000000..e69de29 diff --git a/tool/dropins/jq/dropins.jq b/tool/dropins/jq/dropins.jq new file mode 100644 index 0000000..e69de29 diff --git a/tool/journalUtils.jq b/tool/journalUtils.jq index 79f44bc..6418202 100644 --- a/tool/journalUtils.jq +++ b/tool/journalUtils.jq @@ -1,3 +1,4 @@ +include "dropins"; include "utils"; def formatExperienceTitle: @@ -47,7 +48,7 @@ def formatIngestionROA($customUnits; $substitutions): (if $substitutions | has($roa) then - $substitutions.[$roa] + $substitutions | .[$roa] else $roa | titleCase end) as $roaText | @@ -104,8 +105,7 @@ def experienceStats($customUnits): . | ingestionUnit($customUnits) as $unit | (.consumerName // "default") as $consumerName | - $stats | - .[$consumerName].[$name].[$administrationRoute]|= + $stats | .[$consumerName].[$name].[$administrationRoute] |= ($stats.[$consumerName].[$name].[$administrationRoute] // { unit: "", # null because null+null = null for ingestions with unknown dose which .dose is null @@ -117,8 +117,8 @@ def experienceStats($customUnits): def calculateCombinedDose($substanceName; $consumerName): . as $stats | - ($stats.[$consumerName].[$substanceName] | [to_entries[] | .value.dose] | add)| . as $combinedDose | - ($stats.[$consumerName].[$substanceName] | to_entries[0] | .value.unit) as $combinedDoseUnit | + (.[$consumerName].[$substanceName] | [to_entries[] | .value.dose] | add) as $combinedDose | + (.[$consumerName].[$substanceName] | to_entries[0] | .value.unit) as $combinedDoseUnit | {dose: $combinedDose, unit: $combinedDoseUnit}; def experienceByTitle($name): diff --git a/tool/argsLib.jq b/tool/lib/argsLib.jq similarity index 86% rename from tool/argsLib.jq rename to tool/lib/argsLib.jq index ee43e6f..037b986 100644 --- a/tool/argsLib.jq +++ b/tool/lib/argsLib.jq @@ -16,8 +16,11 @@ def parseArgBool: def parseArgs: . as $args | + if + ($args.named | has("argsJson")) + then $args.named.argsJson[0] else $args.positional end | . as $args | - reduce $args.positional[] as $arg ({ + reduce $args[] as $arg ({ shortArgs: [], longArgs: {}, nonArgs: [] diff --git a/tool/testLib.jq b/tool/lib/testLib.jq similarity index 100% rename from tool/testLib.jq rename to tool/lib/testLib.jq diff --git a/tool/typeLib.jq b/tool/lib/typeLib.jq similarity index 82% rename from tool/typeLib.jq rename to tool/lib/typeLib.jq index ad4163d..9fa3741 100644 --- a/tool/typeLib.jq +++ b/tool/lib/typeLib.jq @@ -1,12 +1,12 @@ -include "testLib"; +import "testLib" as testLib; def typecheckingEnabled: - if $ENV["TYPECHECKING"] != null and (["1", "true", "on"] | any(index($ENV["TYPECHECKING"]))) then + if $ENV["JQ_TYPECHECKING"] != null and (["true", "1", "debug"] | any(index($ENV["JQ_TYPECHECKING"]))) then true else false end; def typecheckingDebug: - if $ENV["TYPECHECKING_DEBUG"] != "" and $ENV["TYPECHECKING_DEBUG"] != null then + if $ENV["JQ_TYPECHECKING"] == "debug" then true else false end; @@ -59,21 +59,26 @@ def ensureKey($value; $type; $key): $value | ensureKey($type; $key); def ensureWrapError($newType; ensureType): . as $value | - try (. | ensureType) catch (error(typeErrorText($newType))); + try (. | ensureType) + catch ( + . as $prevError | + if typecheckingDebug then debug({$newType, $prevError}) end | + error(typeErrorText($newType)) + ); def ensureWrapError($value; $newType; ensureType): $value | ensureWrapError($newType; ensureType); -# TYPECHECKING=1 required for tests +# JQ_TYPECHECKING=true required for tests def typeLibTests: - expectPassed(runTest( + testLib::expectPassed(testLib::runTest( "null is null"; (null | ensureNull); true; false )) | - expectPassed(runTest( + testLib::expectPassed(testLib::runTest( "boolean is not null"; (true | ensureNull); (. == typeErrorText("null")); diff --git a/tool/main.jq b/tool/main.jq index 9d311b1..c3726b8 100644 --- a/tool/main.jq +++ b/tool/main.jq @@ -1,10 +1,11 @@ -# run as: jq export.json -f tool.jq -Cr --args -- +include "dropins"; + +import "lib/typeLib" as typeLib; +import "lib/argsLib" as argsLib; include "utils"; -include "argsLib"; include "journalUtils"; import "types" as types; -import "typeLib" as typeLib; def printExperienceStats($stats; $substanceFilter; $consumerFilter; $withTitle): . as $experience | @@ -244,17 +245,17 @@ def printExperiencesAdvanced($customUnits; $substanceFilter; $consumerFilter; $s )) + "\n"; -def main($ARGS): +def main: def usage: [ "psychonaut_journal_stats {printExperience,printExperiencesAdvanced}", "" ] | join("\n") | halt_error(1); - . as $exportData | + $ARGS.named["exportFile"][0] as $exportData | $exportData | types::ensureExportData | - ($ARGS | parseArgs) as $parsedArgs | + ($ARGS | argsLib::parseArgs) as $parsedArgs | $parsedArgs.nonArgs[0] as $program | ($parsedArgs | .nonArgs |= $parsedArgs.nonArgs[1:]) as $parsedArgs | @@ -292,13 +293,13 @@ def main($ARGS): $longArg.value as $value | if $arg == "pretty" then - .pretty |= (ifNullDefault($value; $defaultOptions.pretty) | parseArgBool) + .pretty |= (ifNullDefault($value; $defaultOptions.pretty) | argsLib::parseArgBool) end | if $arg == "title" then - .withTitle |= (ifNullDefault($value; $defaultOptions.withTitle) | parseArgBool) + .withTitle |= (ifNullDefault($value; $defaultOptions.withTitle) | argsLib::parseArgBool) end | if $arg == "stats" then - .withStats |= (ifNullDefault($value; $defaultOptions.withStats) | parseArgBool) + .withStats |= (ifNullDefault($value; $defaultOptions.withStats) | argsLib::parseArgBool) end | if $arg == "substance-filter" then .substanceFilter |= ($parsedArgs.longArgs.["substance-filter"] | split(",")) @@ -390,5 +391,3 @@ def main($ARGS): else usage end; - -main($ARGS) \ No newline at end of file diff --git a/testdata/tests_export.json b/tool/testdata/tests_export.json similarity index 100% rename from testdata/tests_export.json rename to tool/testdata/tests_export.json diff --git a/tool/tests.jq b/tool/tests.jq index e073081..4e5241a 100644 --- a/tool/tests.jq +++ b/tool/tests.jq @@ -1,27 +1,32 @@ -import "./testdata/tests_export" as $exportDataArray; -include "journalUtils"; -include "testLib"; -import "typeLib" as typeLib; +include "dropins"; + +import "lib/testLib" as testLib; +import "lib/typeLib" as typeLib; + +import "journalUtils" as journalUtils; + +import "testdata/tests_export" as $exportDataArray; def journalUtilsTests: - expectPassed(runTest( + testLib::expectPassed(testLib::runTest( "invalid input to experienceByTitle"; ( - null | experienceByTitle("Test") + null | journalUtils::experienceByTitle("Test") ); . == "experienceByTitle takes a array of experiences as input"; true )) | - expectPassed(runTest( + testLib::expectPassed(testLib::runTest( "experience not found"; ( - $exportDataArray[0].experiences | experienceByTitle("Test") + $exportDataArray[0].experiences | journalUtils::experienceByTitle("Test") ); . == null; false )); def testsMain: - journalUtilsTests | + testLib::testTests | typeLib::typeLibTests | + journalUtilsTests | "Tests Passed\n" | halt_error(0); diff --git a/tool/types.jq b/tool/types.jq index 680f223..e2e7ffb 100644 --- a/tool/types.jq +++ b/tool/types.jq @@ -1,34 +1,61 @@ -import "typeLib" as typeLib; +include "dropins"; + +import "lib/typeLib" as typeLib; #["DEBUG:",{"creationDate":"number","ingestions":[{"administrationRoute":"string","consumerName":"null","creationDate":"number","customUnitId":"null","dose":"number","estimatedDoseStandardDeviation":"null","isDoseAnEstimate":"boolean","notes":"string","stomachFullness":"null","substanceName":"string","time":"number","units":"string"}],"isFavorite":"boolean","location":"null","ratings":"array:empty/unknown","sortDate":"number","text":"string","timedNotes":"array:empty/unknown","title":"string"}] -def ensureExperience: - . as $experience | +def ensureIngestion: + . as $ingestion | typeLib::ensureObject | - debug(. | typeLib::dumpType) | + $ingestion | typeLib::ensureKey("ingestion"; "substanceName") | + .substanceName | typeLib::ensureWrapError("experience:substanceName"; typeLib::ensureString); - $experience | - typeLib::ensureKey("experience"; "title") | - .title | typeLib::ensureWrapError("experience:title"; typeLib::ensureString) | +def ensureTimedNote: + . as $timedNote | + if typeLib::typecheckingEnabled then + $timedNote | typeLib::ensureObject | + $timedNote | typeLib::ensureKey("timedNote"; "color") | + $timedNote.color | typeLib::ensureWrapError("timedNote:color"; typeLib::ensureString) | + $timedNote | typeLib::ensureKey("timedNote"; "creationDate") | + $timedNote.creationDate | typeLib::ensureWrapError("timedNote:creationDate"; typeLib::ensureNumber) | + $timedNote | typeLib::ensureKey("timedNote"; "isPartOfTimeline") | + $timedNote.isPartOfTimeline | typeLib::ensureWrapError("timedNote:isPartOfTimeline"; typeLib::ensureBool) | + $timedNote | typeLib::ensureKey("timedNote"; "note") | + $timedNote.note | typeLib::ensureWrapError("timedNote:note"; typeLib::ensureString) | + $timedNote | typeLib::ensureKey("timedNote"; "time") | + $timedNote.time | typeLib::ensureWrapError("timedNote:time"; typeLib::ensureNumber) + end; - $experience | - typeLib::ensureKey("experience"; "text") | - .text | typeLib::ensureWrapError("experience:text"; typeLib::ensureString) | +def ensureExperience: + . as $experience | + if typeLib::typecheckingEnabled then + $experience | typeLib::ensureObject | - $experience | - typeLib::ensureKey("experience"; "creationDate") | - .creationDate | typeLib::ensureWrapError("experience:creationDate"; typeLib::ensureNumber) | + $experience | typeLib::ensureKey("experience"; "title") | + $experience.title | typeLib::ensureWrapError("experience:title"; typeLib::ensureString) | - $experience | - typeLib::ensureKey("experience"; "sortDate") | - .sortDate | typeLib::ensureWrapError("experience:sortDate"; typeLib::ensureNumber) | + $experience | typeLib::ensureKey("experience"; "text") | + $experience.text | typeLib::ensureWrapError("experience:text"; typeLib::ensureString) | - $experience | - typeLib::ensureKey("experience"; "isFavorite") | - .isFavorite | typeLib::ensureWrapError("experience:isFavorite"; typeLib::ensureBool) + $experience | typeLib::ensureKey("experience"; "creationDate") | + $experience.creationDate | typeLib::ensureWrapError("experience:creationDate"; typeLib::ensureNumber) | - ; + $experience | typeLib::ensureKey("experience"; "sortDate") | + $experience.sortDate | typeLib::ensureWrapError("experience:sortDate"; typeLib::ensureNumber) | + + $experience | typeLib::ensureKey("experience"; "isFavorite") | + $experience.isFavorite | typeLib::ensureWrapError("experience:isFavorite"; typeLib::ensureBool) | + + $experience | typeLib::ensureKey("experience"; "timedNotes") | + $experience.timedNotes | typeLib::ensureWrapError("experience:timedNotes"; typeLib::ensureArray) | + (reduce $experience.timedNotes[] as $timedNote (null; $timedNote | ensureTimedNote)) | + + $experience | typeLib::ensureKey("experience"; "ingestions") | + $experience.ingestions | typeLib::ensureWrapError("experience:ingestions"; typeLib::ensureArray) | + (reduce $experience.ingestions[] as $ingestion (null; $ingestion | ensureIngestion)) + + end; def ensureExportData: . as $exportData | diff --git a/tool/utils.jq b/tool/utils.jq index 2791dfe..9f81038 100644 --- a/tool/utils.jq +++ b/tool/utils.jq @@ -1,3 +1,5 @@ +include "dropins"; + def debugLog($target; $value): if ($ENV["JQ_DEBUG"] == $target)