Greboca  

Suport technique et veille technologique

Aujourd’hui, les grandes entreprises et administrations publiques hésitent entre continuer à utiliser des logiciels propriétaires ou basculer vers les Logiciels Libres. Pourtant, la plupart des logiciels libres sont capables de bien traiter les données issues des logiciels propriétaire, et parfois avec une meilleur compatibilité.

C’est alors la barrière de la prise en main qui fait peur, et pourtant...

Les logiciels libres

L’aspect « Logiciel Libre » permet une évolution rapide et une plus grande participation des utilisateurs. Les aides et tutoriels foisonnent sur Internet ou sont directement inclus dans le logiciel lui-même.

Enfin, les concepteurs sont plus proches des utilisateurs, ce qui rend les logiciels libres plus agréable à utiliser et conviviaux.

Grâce à la disponibilité des logiciels libres, vous trouverez facilement des services de support techniques et la licence n’est plus un frein à l’utilisation de ces logiciels par votre personnel.

Notre support technique concerne essentiellement les logiciels libres, que ce soit sous forme de services ponctuels ou de tutoriels.

LinuxFr.org : les journaux  -  Aujourd'hui on ne parle pas de k-pop, mais de JSON !

 -  Juin 2023 - 

Sommaire

ATTENTION, sous ses faux airs d’impartialité, ce journal est une pub éhontée pour mon projet json-search

Bonjour, il y a quelques temps, j'ai posté ce lien
dans lequel on m'a demandé "pourquoi ne pas écrire un journal ?"
Au lieu de ne parler que de mon projet, je pop donc une comparaison de plusieurs outils pour chercher des éléments dans un fichier JSON.
(C'est donc de la j-pop)

J'ai pris ce fichier (un peu impartialement) car je voulais un fichier open source appartenant à un projet un peu connu. Et quoi de mieux qu'un module pulse audio pour cet article j-pop. (Ok, j'ai pris le 1er json flathub de plus de 20 lignes…)

Les outils dont je vais parler :

json-search

gron

jq

Des 3 commandes dont je parle ici, jq est de loin la plus puissante, et pour être honnête, on peut tout faire avec.
Je connais assez mal la syntaxe, mais je vais quand même essayer d'en expliquer l'utilisation que je sais en faire.
Et notez que je manque sûrement de vocabulaire et qu'il va donc peut-être y avoir des imprécisions dans mes explications.

Comment chercher dans les valeurs tout ce qui concerne des libs:

Avec json-search:

[uso]$  cat org.freedesktop.LinuxAudio.Plugins.Yoshimi.json | json-search -Vsil "lib"
 - .modules[4].post_install[1]: "mv ${FLATPAK_DEST}/lib/lv2/yoshimi.lv2 ${FLATPAK_DEST}/lv2"
 - .modules[4].build-options.env.LDFLAGS: "-L${FLATPAK_DEST}/lib -lpng16 -lXrender -lXcursor -lXfixes -lXext -lXft -lfontconfig -lXinerama -lpthread -ldl -lm  -lX11"
 - .modules[1].cleanup[2]: "/lib/pkgconfig"
 - .modules[0].cleanup[5]: "/lib/pkgconfig"
 - .cleanup[4]: "/lib/lv2"
 - .cleanup[3]: "/lib/jack"
 - .cleanup[2]: "/lib/libjack*"
 - .build-options.prepend-ld-library-path: "/app/extensions/Plugins/Yoshimi/lib"
 - .build-options.prepend-pkg-config-path: "/app/extensions/Plugins/Yoshimi/lib/pkgconfig"

Les options utilisées sont :

  • '-V' pour chercher dans les valeurs et pas dans les clés
  • '-s' pour matcher des bouts de chaîne de caractère et pas une comparaison exacte
  • '-i' pour être insensible à la casse
  • '-l' pour avoir la "localisation" des éléments, par exemple " .modules[1].cleanup[2]:" avant "/lib/libjack*"

Avec gron :

[uso]$ gron org.freedesktop.LinuxAudio.Plugins.Yoshimi.json | grep -i lib
json.cleanup[2] = "/lib/libjack*";
json.cleanup[3] = "/lib/jack";
json.cleanup[4] = "/lib/lv2";
json.modules[0].cleanup[5] = "/lib/pkgconfig";
json.modules[1].cleanup[2] = "/lib/pkgconfig";
json.modules[4].post_install[1] = "mv ${FLATPAK_DEST}/lib/lv2/yoshimi.lv2 ${FLATPAK_DEST}/lv2";
json.modules[4]["build-options"].env.LDFLAGS = "-L${FLATPAK_DEST}/lib -lpng16 -lXrender -lXcursor -lXfixes -lXext -lXft -lfontconfig -lXinerama -lpthread -ldl -lm  -lX11";
json["build-options"]["prepend-ld-library-path"] = "/app/extensions/Plugins/Yoshimi/lib";
json["build-options"]["prepend-pkg-config-path"] = "/app/extensions/Plugins/Yoshimi/lib/pkgconfig";

'gron FILE' permet de transformer le fichier json en une sortie grepable. Et 'grep' matche toutes les lignes contenant "lib" avec -i pour être insensible à la casse.

Plus d'infos sur 'build-options'

comment avoir un tableau json de tous les objets 'build-options':

[uso]$ cat org.freedesktop.LinuxAudio.Plugins.Yoshimi.json | json-search build-options

note que j'ai utilisé ... pour simplifier le résultat

[
{
  "env":{
    "LV2_PATH":"${FLATPAK_DEST}/lv2",
    "LDFLAGS":"-L${FLATPAK_DEST}/lib -lpng16 -lXrender -lXcursor -lXfixes -lXext -lXft -lfontconfig -lXinerama -lpthread -ldl -lm  -lX11"
  },
  "arch":{
    "x86_64":{
      "config_opts":[
        "-DBuildOptions_X86_64Core2=YES"
      ]
    },
    "aarch64":{...}
  }
},
{"cflags":"-fPIC"},
{...},
{...}
]

comment reconstruire l'arbre json en ne gardant que les éléments build option :

[uso]$ gron org.freedesktop.LinuxAudio.Plugins.Yoshimi.json | grep 'build-options' | gron -u

"gron org.freedesktop.LinuxAudio.Plugins.Yoshimi.json" en fait une sortie grepable. Grep prend ce qui concerne "build-options" et "-u" reconstruit le json.

ici aussi j'utilise ... pour simplifier

{
  "build-options": {...},
  "modules": [
    {
      "build-options": {
        "cflags": "-fPIC",
        "cxxflags": "-fPIC"
      }
    },
    {
        "build-options": {...}
    },
     null,
     null,
    {
      "build-options": {
        "arch": ...,
          "x86_64": ...,
        },
        "env": {...}
      }
    }
  ]
}

récupérer 'build-options' à la racine

[uso]$ cat org.freedesktop.LinuxAudio.Plugins.Yoshimi.json | jq '."build-options"'
[uso]$ cat org.freedesktop.LinuxAudio.Plugins.Yoshimi.json | json-search  -M 1 build-options

Sortent le même résultat: (bon jq est en couleur)

{
  "prefix": "/app/extensions/Plugins/Yoshimi",
  "prepend-pkg-config-path": "/app/extensions/Plugins/Yoshimi/lib/pkgconfig",
  "prepend-ld-library-path": "/app/extensions/Plugins/Yoshimi/lib"
}

jq prend un filtre en paramètre (ici '."build-options"'),
Pour des manipulations simples, on peut retenir que . permet de récupérer un élément d'un objet/array.
Pour récupérer une valeur d'un objet, on va soit utiliser .KEY soit ."MY-KEY" si on a des valeurs qui ont besoin d'être entre quotes.
Pour récupérer une valeur d'un tableau, on peut utiliser .[IDX].
On peut chaîner ces .KEY/.[IDX] pour obtenir un genre de chemin. (example .KEY0.[0])

# Cherchons une "build-options" plus imbriquée :

Qui serait à la place de TARGET dans ce json: '{"modules": [{},{},{},{"build-options": TARGET} ] }'

  cat org.freedesktop.LinuxAudio.Plugins.Yoshimi.json | jq '.modules[4]."build-options"' 
  cat org.freedesktop.LinuxAudio.Plugins.Yoshimi.json | jq '.modules[4]' | json-search build-options 
  cat org.freedesktop.LinuxAudio.Plugins.Yoshimi.json | json-search build-options | json-search -p env
  cat org.freedesktop.LinuxAudio.Plugins.Yoshimi.json | json-search build-options |  jq '.[0]'

Les 4 commandes ont le même résultat

  {
  "env":{
    "LV2_PATH":"${FLATPAK_DEST}/lv2",
    "LDFLAGS":"-L${FLATPAK_DEST}/lib -lpng16 -lXrender -lXcursor -lXfixes -lXext -lXft -lfontconfig -lXinerama -lpthread -ldl -lm  -lX11"
  },
  "arch":{
    "x86_64":{
      "config_opts":[
        "-DBuildOptions_X86_64Core2=YES"
      ]
    },
    "aarch64":{
      "config_opts":[
        "-DBuildOptions_RasPi4=YES"
      ]
    }
  }
}

La 1ère commande met le chemin en entier, par contre il faut faire attention à mettre les "doubles quotes" autour de build-options, car le '-' casse sinon.
La 2ème commande fait un mélange de jq et json-search, bien que plus lourde syntaxiquement, je la trouve plus simple à retenir.
La 3ème n'utilise que json-search, mais triche un peu. En premier, je cherche tous les 'build-options', puis je cherche "env", mais n'utilise que l'option -p pour afficher l'élément parent trouvé.
Enfin la dernière commande : je réutilise json-search pour avoir tous les 'build-options', mais après jq, pour avoir le 1er élément du tableau affiché par json-search.

Si on veut mélanger gron et jq, on peut aussi faire :

  cat org.freedesktop.LinuxAudio.Plugins.Yoshimi.json | jq '.modules[4]' | gron | grep build-options | gron -u

Pour avoir un résultat assez similaire (mais pas exactement) :

Frequent… fre…

Eh non

Question ask by myself to myself about json-search

uso (Q)> Mais pourquoi ne pas juste utiliser jq ?
uso (A)> Bah en fait les 2 outils sont complémentaires, mais jq fait mal à la tête.

uso (Q)> En vrai gron fait le taff, ça ne sert donc à rien ton truc
uso (A)> Alors oui, mais c'est plus simple d'utilisation. Bon, j'ai peut-être connu l'existence de gron il y a ~2 semaines et comme tout bon dev, je code avant de réfléchir.

uso (Q)> Non, mais le C, c'est un très mauvais choix de langages, y'a le rust, c'est pas sécure, y'a le rust, plus personne en fait, y'a le rust.
uso (A)> Je pourrais mentir à dire que le C est un langages très peu verboses, mentir à dire que j'aime beaucoup json-c comme bibliothèque, mentir a dire que la performance m’intéresse. Tous ça pour ne pas dire, que sur un projets personnel, je prend les langages amusant.

uso (Q)> Mais pourquoi la licence WTFPL, il y a Fuck dans le nom ?
uso (A)> Car il y a Fuck dans le nom ¯_(ツ)_/¯

uso (Q)> GPLu d'idée de questions, pourquoi pas du copyleft ?
uso (A)> Bah j'aurais tendance à utiliser du copyleft pour des projets d'une plus grosse envergure

Conclusion:

Bon bah vous avez pleins d'exemples sur des trucs à faire avec json-search, jq et gron.
Ça reste une utilisation très simple, et je n'ai absolument pas parlé de comment modifier ces json, qui pourrait valoir un autre journal juste pour ça… Mais je ne sais pas faire.

J'aurais aussi pu parler de mlr, mais ça à l'air de faire mal à la tête et ça ne me semble être utile que pour une utilisation beaucoup plus puissante.

benchmark

car comme dirait l'autre: "L’optimisation tardive est la source de tous l'émo" (à moins que ça soit les émeus, je ne me rappelle plus de la citation exacte) :

[uso]$ time ./bench-json-search.sh ; time ./bench-gron.sh  ; time ./bench-jq.sh                  
./bench-json-search.sh  0.72s user 1.68s system 135% cpu 1.782 total
./bench-gron.sh  3.96s user 5.78s system 178% cpu 5.450 total
./bench-jq.sh  13.47s user 1.71s system 104% cpu 14.559 total
[uso]$ % cat bench-*
for i in {1..1000}
do
    cat org.freedesktop.LinuxAudio.Plugins.Yoshimi.json | gron | grep build-options | gron -u > /dev/null
done
for i in {1..1000}
do
    cat org.freedesktop.LinuxAudio.Plugins.Yoshimi.json | jq '."build-options"'  > /dev/null
done
for i in {1..1000}
do
    cat org.freedesktop.LinuxAudio.Plugins.Yoshimi.json | json-search build-options  > /dev/null
done

Commentaires : voir le flux Atom ouvrir dans le navigateur

par uso

LinuxFr.org : les journaux

LinuxFr.org : Journaux

firefox, nouvelle fenêtre dans une session isolée

 -  15 avril - 

Les fenêtres de navigation privées de firefox partagent leurs cookies de session or je souhaitais avoir des fenêtres de navigation isolées, (qui ne (...)


Pretendo tente de déprogrammer l'obsolescence des consoles Nintendo

 -  9 avril - 

Ah Nal,Gros N vient de faire un gros doigt aux utilisateurs de ses consoles 3DS et Wii U en annonçant la fermeture des services en ligne pour (...)


[Trolldi] Vulgarisation sur l'IA pour décideur pressé

 -  5 avril - 

Cher 'Nal,Je fais un article-marque-page sur un post tout frais de Ploum où il est question d'un fantasme vieux comme le Talmud avec le Golem. (...)


Super Marian and Robin: les roms en collant

 -  3 avril - 

Bonjour Nal,Je t'écris pour te proposer de tester mon nouveau jeu: Super Marian and Robin.Il s'agit d'un jeu de plateformes pour un ou deux (...)


Le roi est mort, vive le roi ! Les alternatives de Redis sont là

 -  3 avril - 

Bonjour Nal !Après le changement de licence de Redis, ce qui devait arriver arriva, et des alternatives libres apparaissent.Tout d'abord, on a (...)