In meinem letzten Artikel über Habré habe ich über die Jsqry- Bibliothek geschrieben , die eine einfache und bequeme Abfragesprache (DSL) für JSON-Objekte bietet. Seitdem ist viel Zeit vergangen und auch die Bibliothek hat sich weiterentwickelt. Ein weiterer Grund für den Stolz: Die Bibliothek verfügt über eine Codeabdeckung von 98% durch Tests. In diesem Artikel geht es jedoch nicht nur um sie.
Ich denke, viele von Ihnen kennen das Tool jq
, das praktisch der De-facto-Standard für die Arbeit mit JSON in der Befehlszeile und in Skripten ist. Ich war auch ein aktiver Benutzer davon. Ich war jedoch ständig besorgt über die ungerechtfertigte Komplexität und die nicht intuitive Syntax von Abfragen dieses Dienstprogramms. Und nicht ich allein, hier nur ein paar Zitate aus Hackernachrichten :
Ich benutze jq seit Jahren und kann es immer noch nicht so zum Laufen bringen, wie ich es erwarten würde.
Ich habe das gleiche Problem mit jq. Ich muss mein Google Fu verwenden, um herauszufinden, wie man mehr als eine einfache Auswahl macht.
Ich weiß nicht, wie der Begriff lauten würde, mentales Modell, aber ich kann jq einfach nicht zum Klicken bringen. Meistens, weil ich es nur ab und zu brauche. Es ist frustrierend für mich, weil es ziemlich mächtig scheint.
Ich weiß, dass ich hier vielleicht eine abweichende Meinung habe, aber ich kann meinen Kopf niemals herumwickelnjq
. Ich kann es schaffenjq .
,jq .foo
undjq -r
darüber hinaus ist das DSL für mich nur undurchsichtig.
Sagen wir es einfach: jq ist ein erstaunliches Werkzeug, aber das DSL ist einfach schlecht.
Ja, ich finde jq ähnlich wie das Schreiben von Regexen: Ich muss immer die Syntax nachschlagen, sie erst nach einiger Verwirrung zum Laufen bringen, warum meine Muster nicht übereinstimmen, und dann alles in ein paar Tagen vergessen, also muss ich sie später erneut lernen.
Kurz gesagt, Sie haben es wahrscheinlich schon erraten. Ich hatte eine Idee, warum ich meine JS-Bibliothek nicht in eine ausführbare Befehlszeilendatei verwandeln sollte.Hier gibt es eine Nuance. Die Bibliothek ist in JS geschrieben und ihr DSL basiert auch auf JS. Dies bedeutet, dass wir einen Weg finden müssen, um das Programm und eine JS-Laufzeit in eine in sich geschlossene ausführbare Datei zu packen.
jsqry - GraalVM Edition
Für diejenigen, die sich noch nicht mit dem Thema befassen (gibt es wirklich noch solche? OO), möchte ich Sie daran erinnern, dass GraalVM eine so aufgepumpte JVM von Oracle mit zusätzlichen Funktionen ist, von denen die auffälligsten sind:
- JVM — Java, Javascript, Python, Ruby, R, ..
- AOT- — Java
- JIT- Java.
Graal , , -.
, 1. 2. — JS .
https://github.com/jsqry/jsqry-cli. , — deprecated. , . , 99 . - . , jq
3.7 Linux 64.
.
, Java + JS GraalVM.
App.java. , java- Apache Commons CLI.
java- javascript , src/main/resources.
. -
scripts.add(new String(Files.readAllBytes(Paths.get(jsFileResource.toURI()))));
( , native-image)
java.nio.file.FileSystemNotFoundException: Provider "resource" not installed
"" InputStream
scripts.add(new Scanner(jsFileResource.openStream()).useDelimiter("\\A").next());
, 100% Java .
java.awt.Graphics. GraalVM AWS Lambda .
jsqry — QuickJS edition
- JS QuickJS . qjsc
. ES2020. !
, CLI- jsqry
: https://github.com/jsqry/jsqry-cli2.
.
, jsqry
?
jsqry
( jq) JSON "" DSL.
— JS jsqry .
$ echo '[{"name":"John","age":30},
{"name":"Alice","age":25},
{"name":"Bob","age":50}]' | jsqry 'name'
[
"John",
"Alice",
"Bob"
]
$ echo '[{"name":"John","age":30},
{"name":"Alice","age":25},
{"name":"Bob","age":50}]' | jsqry -1 'name'
"John"
$ echo '[{"name":"John","age":30},{"name":"Alice","age":25},{"name":"Bob","age":50}]' \
| jsqry '[ _.age>=? && _.name.toLowerCase().startsWith(?) ]' --arg 30 --arg-str joh
[
{
"name": "John",
"age": 30
}
]
JSON pretty-printer
$ echo '[{"name":"John","age":30},{"name":"Alice","age":25},{"name":"Bob","age":50}]' \
| jsqry
[
{
"name": "John",
"age": 30
},
{
"name": "Alice",
"age": 25
},
{
"name": "Bob",
"age": 50
}
]
JSON . !
-
2, 100, 2 . . DSL.
$ echo '[1,2,3,4,5]' | jsqry '[_>2] {_+100} s(-_) [-2:]'
[
104,
103
]
JS
jsqry
JS- 1 , JS !
$ echo '["HTTP://EXAMPLE.COM/123",
"https://www.Google.com/search?q=test",
"https://www.YouTube.com/watch?v=_OBlgSz8sSM"]' \
| jsqry '{ _.match(/:\/\/([^\/]+)\//)[1].toLowerCase() }'
[
"example.com",
"www.google.com",
"www.youtube.com"
]
help-
$ jsqry
jsqry ver. 0.1.2
Usage: echo $JSON | jsqry 'query'
-1,--first return first result element
-h,--help print help and exit
-v,--version print version and exit
-c,--compact compact output (no pretty-print)
-u,--unquote unquote output string(s)
-as ARG,
--arg-str ARG supply string query argument
-a ARG,
--arg ARG supply query argument of any other type
jq
( ): 0.1.2.
, Linux x64 . , . .
, :
$ sudo bash -e -c "
wget https://github.com/jsqry/jsqry-cli2/releases/download/v0.1.2/jsqry-linux-amd64 -O/usr/local/bin/jsqry
chmod +x /usr/local/bin/jsqry
echo \"jsqry \$(jsqry -v) installed successfully\"
"
CLI-
GitHub - . - , . , CLI- , . , , , — .
"bash unit testing" BATS, ShellSpec, Bach , , ( 14 ), tush, .
tush
$ command --that --should --execute correctly
| expected stdout output
$ command --that --will --cause error
@ expected stderr output
? expected-exit-code
tush
$
, |
, @
?
— , . , $
, diff
. , diff . :
$ /bin/bash /home/xonix/proj/jsqry-cli2/tests.sh
--- tests.tush expected
+++ tests.tush actual
@@ -1,5 +1,5 @@
$ jsqry -v
-| 0.1.2
+| 0.1.1
$ jsqry -h
| jsqry ver. 0.1.1
!!! TESTS FAILED !!!
, , .
GitHub Action, , :
JSON
JSON . zvakanaka/color-json , StackOverflow . jq
. , null .
, .
npm- QuickJS
npm- jsqry
. package.json . npm i
. prepare-for-qjs.py, nodejs ES, QuickJS. jsqry-cli.js.
UTF-8 QuickJS
QuickJS stdin. , , QuickJS, . , UTF-8 JS-. , , QuickJS: twardoch/svgop.
"" , .
— tests.sh. , , .
— build.sh QuickJS, tests.sh tush
. — .
. ls -lh jsqry
. , , CLI- . , — , QuickJS.
652 KB. , , JS.
jq
. .