update
This commit is contained in:
parent
87e114d76d
commit
d2da9e1af4
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
export.json
|
export.json
|
||||||
|
.dev.env
|
||||||
|
|
15
run.sh
15
run.sh
|
@ -3,6 +3,17 @@
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd -- "$(dirname -- "$0")" && pwd)"
|
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 -- "$@"
|
|
20
runTests.sh
20
runTests.sh
|
@ -1,11 +1,19 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd -- "$(dirname -- "$0")" && pwd)"
|
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"
|
runTests() {
|
||||||
${JQ:-jq} -n -r -L tool -L . "include \"tests\"; testsMain"
|
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
|
0
tool/dropins/gojq/dropins.jq
Normal file
0
tool/dropins/gojq/dropins.jq
Normal file
0
tool/dropins/jq/dropins.jq
Normal file
0
tool/dropins/jq/dropins.jq
Normal file
|
@ -1,3 +1,4 @@
|
||||||
|
include "dropins";
|
||||||
include "utils";
|
include "utils";
|
||||||
|
|
||||||
def formatExperienceTitle:
|
def formatExperienceTitle:
|
||||||
|
@ -47,7 +48,7 @@ def formatIngestionROA($customUnits; $substitutions):
|
||||||
(if
|
(if
|
||||||
$substitutions | has($roa)
|
$substitutions | has($roa)
|
||||||
then
|
then
|
||||||
$substitutions.[$roa]
|
$substitutions | .[$roa]
|
||||||
else
|
else
|
||||||
$roa | titleCase
|
$roa | titleCase
|
||||||
end) as $roaText |
|
end) as $roaText |
|
||||||
|
@ -104,8 +105,7 @@ def experienceStats($customUnits):
|
||||||
. | ingestionUnit($customUnits) as $unit |
|
. | ingestionUnit($customUnits) as $unit |
|
||||||
(.consumerName // "default") as $consumerName |
|
(.consumerName // "default") as $consumerName |
|
||||||
|
|
||||||
$stats |
|
$stats | .[$consumerName].[$name].[$administrationRoute] |=
|
||||||
.[$consumerName].[$name].[$administrationRoute]|=
|
|
||||||
($stats.[$consumerName].[$name].[$administrationRoute] // {
|
($stats.[$consumerName].[$name].[$administrationRoute] // {
|
||||||
unit: "",
|
unit: "",
|
||||||
# null because null+null = null for ingestions with unknown dose which .dose is null
|
# 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):
|
def calculateCombinedDose($substanceName; $consumerName):
|
||||||
. as $stats |
|
. as $stats |
|
||||||
($stats.[$consumerName].[$substanceName] | [to_entries[] | .value.dose] | add)| . as $combinedDose |
|
(.[$consumerName].[$substanceName] | [to_entries[] | .value.dose] | add) as $combinedDose |
|
||||||
($stats.[$consumerName].[$substanceName] | to_entries[0] | .value.unit) as $combinedDoseUnit |
|
(.[$consumerName].[$substanceName] | to_entries[0] | .value.unit) as $combinedDoseUnit |
|
||||||
{dose: $combinedDose, unit: $combinedDoseUnit};
|
{dose: $combinedDose, unit: $combinedDoseUnit};
|
||||||
|
|
||||||
def experienceByTitle($name):
|
def experienceByTitle($name):
|
||||||
|
|
|
@ -16,8 +16,11 @@ def parseArgBool:
|
||||||
|
|
||||||
def parseArgs:
|
def parseArgs:
|
||||||
. as $args |
|
. 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: [],
|
shortArgs: [],
|
||||||
longArgs: {},
|
longArgs: {},
|
||||||
nonArgs: []
|
nonArgs: []
|
|
@ -1,12 +1,12 @@
|
||||||
include "testLib";
|
import "testLib" as testLib;
|
||||||
|
|
||||||
def typecheckingEnabled:
|
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
|
true
|
||||||
else false end;
|
else false end;
|
||||||
|
|
||||||
def typecheckingDebug:
|
def typecheckingDebug:
|
||||||
if $ENV["TYPECHECKING_DEBUG"] != "" and $ENV["TYPECHECKING_DEBUG"] != null then
|
if $ENV["JQ_TYPECHECKING"] == "debug" then
|
||||||
true
|
true
|
||||||
else false end;
|
else false end;
|
||||||
|
|
||||||
|
@ -59,21 +59,26 @@ def ensureKey($value; $type; $key): $value | ensureKey($type; $key);
|
||||||
|
|
||||||
def ensureWrapError($newType; ensureType):
|
def ensureWrapError($newType; ensureType):
|
||||||
. as $value |
|
. 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):
|
def ensureWrapError($value; $newType; ensureType):
|
||||||
$value | ensureWrapError($newType; ensureType);
|
$value | ensureWrapError($newType; ensureType);
|
||||||
|
|
||||||
|
|
||||||
# TYPECHECKING=1 required for tests
|
# JQ_TYPECHECKING=true required for tests
|
||||||
def typeLibTests:
|
def typeLibTests:
|
||||||
expectPassed(runTest(
|
testLib::expectPassed(testLib::runTest(
|
||||||
"null is null";
|
"null is null";
|
||||||
(null | ensureNull);
|
(null | ensureNull);
|
||||||
true;
|
true;
|
||||||
false
|
false
|
||||||
)) |
|
)) |
|
||||||
expectPassed(runTest(
|
testLib::expectPassed(testLib::runTest(
|
||||||
"boolean is not null";
|
"boolean is not null";
|
||||||
(true | ensureNull);
|
(true | ensureNull);
|
||||||
(. == typeErrorText("null"));
|
(. == typeErrorText("null"));
|
21
tool/main.jq
21
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 "utils";
|
||||||
include "argsLib";
|
|
||||||
include "journalUtils";
|
include "journalUtils";
|
||||||
import "types" as types;
|
import "types" as types;
|
||||||
import "typeLib" as typeLib;
|
|
||||||
|
|
||||||
def printExperienceStats($stats; $substanceFilter; $consumerFilter; $withTitle):
|
def printExperienceStats($stats; $substanceFilter; $consumerFilter; $withTitle):
|
||||||
. as $experience |
|
. as $experience |
|
||||||
|
@ -244,17 +245,17 @@ def printExperiencesAdvanced($customUnits; $substanceFilter; $consumerFilter; $s
|
||||||
)) + "\n";
|
)) + "\n";
|
||||||
|
|
||||||
|
|
||||||
def main($ARGS):
|
def main:
|
||||||
def usage:
|
def usage:
|
||||||
[
|
[
|
||||||
"psychonaut_journal_stats {printExperience,printExperiencesAdvanced}",
|
"psychonaut_journal_stats {printExperience,printExperiencesAdvanced}",
|
||||||
""
|
""
|
||||||
] | join("\n") | halt_error(1);
|
] | join("\n") | halt_error(1);
|
||||||
|
|
||||||
. as $exportData |
|
$ARGS.named["exportFile"][0] as $exportData |
|
||||||
$exportData | types::ensureExportData |
|
$exportData | types::ensureExportData |
|
||||||
|
|
||||||
($ARGS | parseArgs) as $parsedArgs |
|
($ARGS | argsLib::parseArgs) as $parsedArgs |
|
||||||
|
|
||||||
$parsedArgs.nonArgs[0] as $program |
|
$parsedArgs.nonArgs[0] as $program |
|
||||||
($parsedArgs | .nonArgs |= $parsedArgs.nonArgs[1:]) as $parsedArgs |
|
($parsedArgs | .nonArgs |= $parsedArgs.nonArgs[1:]) as $parsedArgs |
|
||||||
|
@ -292,13 +293,13 @@ def main($ARGS):
|
||||||
$longArg.value as $value |
|
$longArg.value as $value |
|
||||||
|
|
||||||
if $arg == "pretty" then
|
if $arg == "pretty" then
|
||||||
.pretty |= (ifNullDefault($value; $defaultOptions.pretty) | parseArgBool)
|
.pretty |= (ifNullDefault($value; $defaultOptions.pretty) | argsLib::parseArgBool)
|
||||||
end |
|
end |
|
||||||
if $arg == "title" then
|
if $arg == "title" then
|
||||||
.withTitle |= (ifNullDefault($value; $defaultOptions.withTitle) | parseArgBool)
|
.withTitle |= (ifNullDefault($value; $defaultOptions.withTitle) | argsLib::parseArgBool)
|
||||||
end |
|
end |
|
||||||
if $arg == "stats" then
|
if $arg == "stats" then
|
||||||
.withStats |= (ifNullDefault($value; $defaultOptions.withStats) | parseArgBool)
|
.withStats |= (ifNullDefault($value; $defaultOptions.withStats) | argsLib::parseArgBool)
|
||||||
end |
|
end |
|
||||||
if $arg == "substance-filter" then
|
if $arg == "substance-filter" then
|
||||||
.substanceFilter |= ($parsedArgs.longArgs.["substance-filter"] | split(","))
|
.substanceFilter |= ($parsedArgs.longArgs.["substance-filter"] | split(","))
|
||||||
|
@ -390,5 +391,3 @@ def main($ARGS):
|
||||||
else
|
else
|
||||||
usage
|
usage
|
||||||
end;
|
end;
|
||||||
|
|
||||||
main($ARGS)
|
|
|
@ -1,27 +1,32 @@
|
||||||
import "./testdata/tests_export" as $exportDataArray;
|
include "dropins";
|
||||||
include "journalUtils";
|
|
||||||
include "testLib";
|
import "lib/testLib" as testLib;
|
||||||
import "typeLib" as typeLib;
|
import "lib/typeLib" as typeLib;
|
||||||
|
|
||||||
|
import "journalUtils" as journalUtils;
|
||||||
|
|
||||||
|
import "testdata/tests_export" as $exportDataArray;
|
||||||
|
|
||||||
def journalUtilsTests:
|
def journalUtilsTests:
|
||||||
expectPassed(runTest(
|
testLib::expectPassed(testLib::runTest(
|
||||||
"invalid input to experienceByTitle";
|
"invalid input to experienceByTitle";
|
||||||
(
|
(
|
||||||
null | experienceByTitle("Test")
|
null | journalUtils::experienceByTitle("Test")
|
||||||
);
|
);
|
||||||
. == "experienceByTitle takes a array of experiences as input";
|
. == "experienceByTitle takes a array of experiences as input";
|
||||||
true
|
true
|
||||||
)) |
|
)) |
|
||||||
expectPassed(runTest(
|
testLib::expectPassed(testLib::runTest(
|
||||||
"experience not found";
|
"experience not found";
|
||||||
(
|
(
|
||||||
$exportDataArray[0].experiences | experienceByTitle("Test")
|
$exportDataArray[0].experiences | journalUtils::experienceByTitle("Test")
|
||||||
);
|
);
|
||||||
. == null;
|
. == null;
|
||||||
false
|
false
|
||||||
));
|
));
|
||||||
|
|
||||||
def testsMain:
|
def testsMain:
|
||||||
journalUtilsTests |
|
testLib::testTests |
|
||||||
typeLib::typeLibTests |
|
typeLib::typeLibTests |
|
||||||
|
journalUtilsTests |
|
||||||
"Tests Passed\n" | halt_error(0);
|
"Tests Passed\n" | halt_error(0);
|
||||||
|
|
|
@ -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"}]
|
#["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:
|
def ensureIngestion:
|
||||||
. as $experience |
|
. as $ingestion |
|
||||||
typeLib::ensureObject |
|
typeLib::ensureObject |
|
||||||
|
|
||||||
debug(. | typeLib::dumpType) |
|
$ingestion | typeLib::ensureKey("ingestion"; "substanceName") |
|
||||||
|
.substanceName | typeLib::ensureWrapError("experience:substanceName"; typeLib::ensureString);
|
||||||
|
|
||||||
$experience |
|
def ensureTimedNote:
|
||||||
typeLib::ensureKey("experience"; "title") |
|
. as $timedNote |
|
||||||
.title | typeLib::ensureWrapError("experience:title"; typeLib::ensureString) |
|
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 |
|
def ensureExperience:
|
||||||
typeLib::ensureKey("experience"; "text") |
|
. as $experience |
|
||||||
.text | typeLib::ensureWrapError("experience:text"; typeLib::ensureString) |
|
if typeLib::typecheckingEnabled then
|
||||||
|
$experience | typeLib::ensureObject |
|
||||||
|
|
||||||
$experience |
|
$experience | typeLib::ensureKey("experience"; "title") |
|
||||||
typeLib::ensureKey("experience"; "creationDate") |
|
$experience.title | typeLib::ensureWrapError("experience:title"; typeLib::ensureString) |
|
||||||
.creationDate | typeLib::ensureWrapError("experience:creationDate"; typeLib::ensureNumber) |
|
|
||||||
|
|
||||||
$experience |
|
$experience | typeLib::ensureKey("experience"; "text") |
|
||||||
typeLib::ensureKey("experience"; "sortDate") |
|
$experience.text | typeLib::ensureWrapError("experience:text"; typeLib::ensureString) |
|
||||||
.sortDate | typeLib::ensureWrapError("experience:sortDate"; typeLib::ensureNumber) |
|
|
||||||
|
|
||||||
$experience |
|
$experience | typeLib::ensureKey("experience"; "creationDate") |
|
||||||
typeLib::ensureKey("experience"; "isFavorite") |
|
$experience.creationDate | typeLib::ensureWrapError("experience:creationDate"; typeLib::ensureNumber) |
|
||||||
.isFavorite | typeLib::ensureWrapError("experience:isFavorite"; typeLib::ensureBool)
|
|
||||||
|
|
||||||
;
|
$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:
|
def ensureExportData:
|
||||||
. as $exportData |
|
. as $exportData |
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
include "dropins";
|
||||||
|
|
||||||
def debugLog($target; $value):
|
def debugLog($target; $value):
|
||||||
if
|
if
|
||||||
($ENV["JQ_DEBUG"] == $target)
|
($ENV["JQ_DEBUG"] == $target)
|
||||||
|
|
Loading…
Reference in a new issue