This commit is contained in:
chaos 2024-11-07 21:45:22 +00:00
parent 87e114d76d
commit d2da9e1af4
14 changed files with 123 additions and 62 deletions

3
.gitignore vendored
View file

@ -1 +1,2 @@
export.json
export.json
.dev.env

15
run.sh
View file

@ -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 -- "$@"

View file

@ -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"
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

View file

View file

View file

@ -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):

View file

@ -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: []

View file

@ -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"));

View file

@ -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)

View file

@ -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);

View file

@ -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 |

View file

@ -1,3 +1,5 @@
include "dropins";
def debugLog($target; $value):
if
($ENV["JQ_DEBUG"] == $target)