Em meu último artigo sobre Habré, escrevi sobre a biblioteca Jsqry , que fornece uma linguagem de consulta (DSL) simples e conveniente para objetos JSON. Muito tempo se passou e a biblioteca também se desenvolveu. Outro motivo de orgulho - a biblioteca tem 98% de cobertura de código por testes. No entanto, este artigo não é inteiramente sobre ela.
Acho que muitos de vocês estão familiarizados com a ferramenta jq
, que é praticamente o padrão de fato para trabalhar com JSON na linha de comando e scripts. Eu também era um usuário ativo dele. Mas o tempo todo eu estava preocupado com a complexidade injustificada e a sintaxe não intuitiva das consultas desse utilitário. E não apenas eu, aqui estão apenas algumas citações de notícias de hackers :
Eu uso o jq há anos e ainda não consigo fazer com que funcione como eu esperava.
Eu tenho o mesmo problema com jq. Eu preciso usar meu fu do google para descobrir como fazer qualquer coisa além de uma simples seleção.
Não sei qual seria o termo modelo mental, mas simplesmente não consigo fazer o jq clicar. Principalmente porque eu só preciso disso de vez em quando. É frustrante para mim porque parece muito poderoso.
Sei que posso ser uma opinião divergente aqui, mas nunca consigo entenderjq
. Eu posso controlarjq .
,jq .foo
ejq -r
, mas, além disso, o DSL é apenas opaco para mim.
Vamos apenas dizer: jq é uma ferramenta incrível, mas o DSL é simplesmente ruim.
Sim, acho jq semelhante a escrever regexes: sempre tenho que procurar a sintaxe, só fazê-la funcionar depois de alguma confusão por que meus padrões não combinam, então esqueço tudo em alguns dias, então tenho que reaprendê-la mais tarde.
Em suma, você provavelmente já adivinhou. Tive uma ideia, por que não transformar minha biblioteca JS em um executável de linha de comando.Há uma nuance aqui. A biblioteca é escrita em JS e seu DSL também depende de JS. Isso significa que precisamos encontrar uma maneira de empacotar o programa e algum tempo de execução JS em um arquivo executável autocontido.
jsqry - edição GraalVM
Para aqueles que ainda não estão no assunto (ainda existe tal? OO), deixe-me lembrar que GraalVM é uma JVM bastante bombada da Oracle com recursos adicionais, os mais perceptíveis dos quais são:
- 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
. .