Journal Peigner la girafe: BPM

Posté par (page perso) . Licence CC by-sa
7
23
août
2014

BPM est un Mestionnaire de Projet Basique (Basic Projet Manager) pour Emacs. Mais d'abord, la girafe.

"Peigner la girafe" c'est par exemple quand tu dois repeindre le garage ; mais comme c'est un gros truc, et que tu es feignant tu cherches une raison de pas le faire :

  • J'irai plus vite avec mon rouleau
  • Mais le rouleau je l'ai prêté à Jeannot
  • Et Jeannot on est fâchés
  • Car je lui ai jamais rendu son tapis en poil de girafe
  • Parce que le chien a fait un gros trou dedans

Et c'est comme ça que tu te retrouves dans le jardin à peigner la girafe pour boucher le trou du tapis pour le rendre à Jeannot pour qu'il te rende ton rouleau pour un jour (peut-être) repeindre le garage.

On dit aussi "comb the yack" c'est pareil.

Exemple pratique (Case study) J'ai une web application (en php en l’occurrence, peu importe) à remettre debout. Pffrt. Si t'es bon à un truc, le fais jamais gratos (Joker) en plus c'est plein de bugs blah. Des liens morts, voire pire des require absents, ce genre d'horreur, où est mon peigne. Me voilà à chantourner des regexps parfumées juste pour trouver les bugs et pas me mettre réellement à bosser.

J'ai donc écrit rapideuspi une fonction pour lister tout ça dans un buffer Ah mais ce buffer pourrait être en org-mode, pour profiter du formatage, de l'arborescence, des liens… Et attends, ça pourrait aussi être récursif, ça pourrait aussi être récursif, ça pourrait Sys Error: shameless_yack_combing.

BPM

Emacs n'a jamais été, jamais voulu être un IDE ; c'est sans doute ce qui explique l'échec de trucs comme ECB (dernier commit il y a 4 ans 1/2) c'est juste pas comme ça que ça marche.

C'est pas une raison pour ne pas pouvoir rapidement lister tous les

  • Liens HTTP (^.*<a.*href=\"\\([^\"]+\\)\"[^>]+>\\([^<]+\\)</a>)
  • Scripts divers mais surtout JS (^.*<script.*src=\"\\([^\"]+\\)\")
  • CSS (^.*<link.*href=\"\\([^\"]+\\)\".*rel=\"stylesheet\")
  • Requires (^require.*\'\\(.*\\)')

Et si à l'intérieur des scripts se trouvent des appels Ajax, oui j'aimerais bien leur liste (avec une idée du contexte - ben oui en JS ça peut être un load() ou un $.ajax ou que sais-je) merci.

Features

  • Prend en argument soit un fichier seul, soit un répertoire et un motif de filtrage sur le nom de fichier
  • Affiche tout dans un buffer syntax-coloré, avec un lien (clic ou RETURN) vers chaque fichier trouvé / linké
  • La page est construite en nodes, TAB pour cycler l'état (tout ouvert / juste les titres) des nodes
  • Affiche les erreurs en 'font-lock-warning-face (rouge, mais ça dépend des pays)
  • Profite du puissant moteur d'export d'org-mode (intégré à Emacs depuis 10 ans) et permet de générer une page web (valide) ou un doc quelconque, à mettre sous le nez du CdP pénible qui veut "la liste de toutes les pages avec leurs dépendances".

Sous le capot

Avant, j'ouvrais les buffer et je me promenais dedans avec mes regexps, après il fallait les fermer, mais pas s'il étaient ouverts avants, et ils restaient dans recentf

(if (get-buffer base_name)
  (setq killer nil))
  (find-file fname)
...
  (if killer
    (kill-buffer (current-buffer)))

enfin un vrai bigntz, alors que

(with-temp-buffer
  (insert-file-contents-literally fname)
...)

à chaque fois j'oublie qu'il est infiniment plus facile de manipuler des buffers que des fichiers.
- Fait (largement) moins de 150 lignes (en comptant le disclaimer GPL).
- N'ouvre pas les fichiers
- Donc va super-vite
- Pourrait être encore plus élégant et modulaire (en tout cas c'est ce que dit la girafe)
- Genre linker directement sur la ligne du fichier où a été trouvé le match… Comment on dit simple ou double quote en girafe regexp ?

Bon, au boulot maintenant.

  • # Tu en fais des caisses.

    Posté par . Évalué à 10.

    Et je n'ai rien compris.

    J'ai vraiment pas envie de paraître chieur, donc ne le prend pas mal.

    • [^] # Re: Tu en fais des caisses.

      Posté par (page perso) . Évalué à 7.

      Je te rassure moi non plus je n'ai pas compris grand chose et pourtant je suis utilisateur avancé d'Emacs.
      Il me semble qu'il s'agit d'une extension similaire à org-mode mais avec une différence qui doit m'échapper.
      Quelques éclaircissements de l'auteur sont attendus je pense.

      • [^] # Re: Tu en fais des caisses.

        Posté par (page perso) . Évalué à 10.

        C'est une fonction qui parse du PHP et qui génère un fichier org-mode avec les liens cassé et les dépendances manquantes.

        « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

        • [^] # Re: Tu en fais des caisses.

          Posté par . Évalué à 10.

          aaaah, dit comme ça, c'est plus clair. Je pense que l'auteur, en plus de fumer la moquette, doit également fumer des poils de girafe.

        • [^] # Re: Tu en fais des caisses.

          Posté par (page perso) . Évalué à 10. Dernière modification le 23/08/14 à 23:44.

          C'est une fonction qui parse du PHP (…)

          Presque. C'est techniquement un programme (5 fonctions, 1 macro, voir le repo) qui parse ce qu'on lui donne (voir le journal, section "features" point 1 :

          • Prend en argument soit un fichier seul, soit un répertoire et un motif de filtrage sur le nom de fichier

          La capture d'écran est un exemple de sortie.

          C'est surtout un outil qui peut être utile à quiconque développe des projets web (JavaScript/html), en n'importe quel langage, et c'est pour ça que je l'ai posté ici en tentant de le présenter au mieux. Je crois que je vais m'en tenir au journaux bookmarks ;)

          • [^] # Re: Tu en fais des caisses.

            Posté par (page perso) . Évalué à 10.

            c'est pour ça que je l'ai posté ici en tentant de le présenter au mieux. Je crois que je vais m'en tenir au journaux bookmarks ;)

            On sent bien qu'il y a un effort rédactionnel afin de sortir des sentiers battus. Il y a de bonnes idées dans ton journal. Le problème est que l'idée est trop bonne du coup, tu as oublié d'écrire des choses tellement tu étais dedans, et pour les autres, c'est pas facile à suivre. En général, lorsque j'ai une bonne idée, je rédige mon truc puis essaye d'attendre quelques jours avant de le publier afin d'avoir un peu de recul pour me relire et essayer d'avoir un regard plus objectif. Il est très rare que je ne doive pas rajouter des phrases de liaisons ici ou la pour rendre le texte plus clair…

            Bref, je t'encourage à continuer à faire des vrais journaux. Moi je trouve que c'est un bon début.

            • [^] # Re: Tu en fais des caisses.

              Posté par (page perso) . Évalué à 3.

              J'ajouterais que se faire relire par quelqu'un peut être bénéfique pour savoir si on a écrit quelque chose de compréhensible.

              « Rappelez-vous toujours que si la Gestapo avait les moyens de vous faire parler, les politiciens ont, eux, les moyens de vous faire taire. » Coluche

              • [^] # Re: Tu en fais des caisses.

                Posté par (page perso) . Évalué à -10.

                J'ajouterais que se faire relire par quelqu'un peut être bénéfique pour savoir si on a écrit quelque chose de compréhensible.

                Autour de moi hier au moment de poster, il n'y avait que des gens qui n'y connaissent rien à l'informatique. Je pensais pas que c'était devenu l'essentiel du public d'ici.

                Ce journal est clair, il est écrit en français correct avec une capture d'écran et des exemples. Il s'adresse juste à des gens qui connaissent un peu le développement web, pour leur proposer un outil qui peut leur être utile. Et aussi discuter macros, regexps, mais là je crois que c'est raté.

                Ceux qui "n'y comprennent rien" (Le niveau baisse, ici aussi) n'ont rien à y faire.

                • [^] # Re: Tu en fais des caisses.

                  Posté par . Évalué à 10.

                  Ce journal est clair

                  En étant le rédacteur, tu es l'objectivité même !

                • [^] # Re: Tu en fais des caisses.

                  Posté par (page perso) . Évalué à 10.

                  Ceux qui "n'y comprennent rien" (Le niveau baisse, ici aussi) n'ont rien à y faire.

                  Faut pas se braquer comme ça… on te dit juste que le "style" rend la chose difficilement lisible. Il y a beaucoup de périphrases, de digressions, d'informations plus ou moins adaptées, voire parfois erronées. Ça rend le discours super confus, y compris pour les gens qui ont "le niveau".
                  Par exemple le commentaire sur ECB qui serait mort depuis 4.5 ans, qui n'apporte franchement rien à ton propos, et qui ignore notamment le fait que le projet est désormais maintenu par Alex sur GitHub (https://github.com/alexott/ecb). Sans être particulièrement actif, il suit le développement d'Emacs (dernier commit il y a 6 mois).

                  Bon en même temps j'ai regardé un peu le code, et de façon intéressante ça part dans tous les sens, un peu dans le même genre :)

                  • les noms des fonctions sont en vrac, et ne suivent pas la convention de préfixe
                  • string-starts-with-p ? euh tu reproches quoi à string-prefix-p ? aussi c'est franchement dommage d'implémenter une détection de préfixe en générant une regexp (mouche, bazooka, tout ça). D'après elp.el (le profiler l'Emacs), ton implémentation est 20 fois plus lente que celle qu'Emacs fournit de base (et qui est aussi écrite en lisp, je précise quand même):
                  Function Name         Call Count  Elapsed Time  Average Time
                  string-starts-with-p  1000        0.0256070000  2.560...e-05
                  string-prefix-p       1000        0.0013509999  1.350...e-06
                  
                  • c'est aussi un peu dommage de n'utiliser rx.el (qui est un magnifique outil de composition de regexp) que pour la seule expression régulière inutile de tout le programme. Les horreurs genre "<a .*?\\bhref=\\(['\"]\\)\\([^'\"]*\\)\\1.*?>\\(.*?\\)</a>" y gagneraient vraiment en lisibilité, notamment en permettant de commenter la chose.
                  (rx "<a "
                      ;; skip attributes up to href 
                      (*? anything)
                      word-start "href="
                      ;; open quote
                      (group (or "'" "\""))
                      ;; url
                      (* (not (any "'" "\"")))
                      ;; close quote
                      (backref 1)
                      ;; skip remaining attributes
                      (*? anything) ">"
                      ;; anchor text
                      (group (*? anything))
                      "</a>")

                  ce qui permet au passage de matcher des liens sur plusieurs lignes (nonobstant les erreurs venant du fait que je ne l'ai même pas essayée), même si il y a encore du boulot pour la rendre vraiment correcte, et encore plus pour rendre ça efficace (à mon avis, parser le fragment XML serait moins coûteux que ce genre de regexps)

                  • px-bpm-error "leake" un symbole err_msg (qui devrait être err-msg au passage) dans la table de symbols globale, sans aucune raison, d'autant que la variable est à chaque fois assignée juste avant d'être retournée. Un peu pareil pour url-full (les variables locales se définissent avec let, sinon setq crée automatiquement un symbole global)
                  • px-bpm-read-file définit dynamiquement une fonction globale px-bpm-parse. Je pense que tu voulais définir une fonction locale. C'est pas comme ça que defun marche, tu "confonds" probablement avec le def de python (voir par exemple cl-flet pour ça en emacs-lisp)
                  • les liens org sont construits à coups de concat, au lieu d'utiliser org-make-link-string qui est fait pour
                  • etc.

                  Un conseil, fais passer le byte-compiler sur ton fichier, et corrige les warnings, y en a plutôt pas mal pour un programme si court :)

                  Voilà, en espérant pas trop faire baisser le niveau ;) (désolé, elle était facile)

                  • [^] # Re: Tu en fais des caisses.

                    Posté par (page perso) . Évalué à 7. Dernière modification le 24/08/14 à 20:11.

                    Wow. C'est exactement le genre de message que j'espérais en postant ce journal. Commençons par la fin (comme pour le debug)

                    Compiling /home/me/.emacs.d/elisp/bpm/bpm.el...done
                    Wrote /home/me/.emacs.d/elisp/bpm/bpm.elc

                    Tous les warnings ont été éliminés sans pitié, et tu n'y es pas pour rien :

                    utiliser rx.el

                    Yo, je connaissais pas. Je construisais mes regexp (péniblement) avec regexp⁻builder. Là, les trois autres, rx est si simple, si logique, je les ai écrites du premier coup :)

                    Merci !

                    string-starts-with-p ? euh tu reproches quoi à string-prefix-p ?

                    Ben le principal reproche que je ferai à ce prédicat, c'est de pas s'être fait connaitre plus tôt. Merci.

                    px-bpm-error "leake" un symbole err_msg

                    Yep

                    (qui devrait être err-msg au passage)

                    Rha, le truc bête, violer les conventions en nommant une variable qui devrait pas exister :|

                    dans la table de symbols globale, sans aucune raison, d'autant que la variable est à chaque fois assignée juste avant d'être retournée.

                    J'utilise trop de fonctions pour leur effet secondaire, sans comprendre que c'est pas la peine de (setq plop "plop") quand tu veux "returner" "plop", juste "plop". Encore un truc que je re-découvre genre pour la 4eme fois… (NB c'est le contraire donc ça a à voir : je me suis aussi fait insulter par le compilateur pour avoir utilisé mapcar au lieu de mapc)

                    Merci encore.

                    les liens org sont construits à coups de concat, au lieu d'utiliser org-make-link-string qui est fait pour

                    Je me doutais qu'il existait une fonction pour ça, et j'ai oublié. Quelle horreur ce concat, quand j'y repense brr.

                    Merci !

                  • [^] # Re: Tu en fais des caisses.

                    Posté par (page perso) . Évalué à 4. Dernière modification le 24/08/14 à 20:23.

                    Juste, c'est bète, j'ai pas trouvé comment placer un groupe "flottant" (c'est ça qu'on appelle un "shy group" ?) CàD la chaine "rel="stylesheet"" n'importe où dans la chaine, donc j'ai fait

                    (px-bpm-parse fname
                                  (rx
                                   "<link "
                                   ;; C'est dommage non?
                                   (* (not (any "rel=\"icon\"")))
                                   word-start "href="
                                   ;; open quote
                                   (or "'" "\"")
                                   ;; Wah comment c'est cool de pouvoir commenter dans une regexp
                                   (group (* (not (any "'" "\""))))
                                   ;; close quote
                                   (or "'" "\"")
                                   ;; skip remaining attributes
                                   (*? anything) ">") 'list-css)

                    Ce qui est triste (et naze) si tu sais comment faire, please show me (again) to the light.

                  • [^] # Re: Tu en fais des caisses.

                    Posté par (page perso) . Évalué à 4.

                    Si DLFP était un réseau social (ce qu'à Dieu ne plaise) je t'ajouterais direct :)

                    Vraiment merci pour rx. Je l'avais vu passer sur StackOverflow mais je la pensais encore comme un outil du genre regexp builder, pas pour ce qu'elle est vraiment: Un moyen de parser du texte avec des "s" expressions Emacs Lisp, une vraie couche d'abstraction… Wow. (Eh, la meilleure seule doc que j'ai trouvé est la lib elle-même)

    • [^] # Re: Tu en fais des caisses.

      Posté par . Évalué à 6.

      Moi j'ai bien aimé le ton.
      J'ai à peu près compris où il voulait en venir.
      Et j'aime bien les girafes.
      Juste été un peu abusé par le titre.
      C'est pas de la gestion de projet, juste un outil d'audit de code.
      C'est déjà bien mais correspond pas au titre.

  • # Mise en demeure

    Posté par . Évalué à 6.

    Je demande à linuxfr de dévoiler les informations permettant d'identifier l'auteur du journal, qui, en vertu de l'article 521-1 du code pénal, a reconnu ici-même s'être livré à des actes de cruauté envers une pauvre girafe innocente, qui plus est pourrait être établie dans un endroit inapproprié, et soumise à un harcèlement constant d'un chien.

    Par contre, j'aimerais bien savoir comment on rebouche un trou avec un peigne?!

    • [^] # Re: Mise en demeure

      Posté par (page perso) . Évalué à 2. Dernière modification le 24/08/14 à 13:03.

      Par contre, j'aimerais bien savoir comment on rebouche un trou avec un peigne?!

      Et moi (pour également rester au plus près du sujet du journal) j'aimerais bien savoir comment, en Emacs Regexp capturer ces deux groupes en matchant

      <a href="(ça)">(et ça)</a>
      <a href='(ça)'>(et ça)</a>

      (donc bien sur pas)

      <a href='(ça)">(et donc pas ça)</a>

      Mais pas non plus

      <a href="'.$(ça).'">(et donc pas ça non plus)</a>
      • [^] # Re: Mise en demeure

        Posté par (page perso) . Évalué à 2.

        Yo, comme ça (match-string 2 et 3) "<a .*?\\bhref=\\(['\"]\\)\\([^'\"]*\\)\\1.*?>\\(.*?\\)</a>"

  • # C’est cela, oui…

    Posté par . Évalué à 2.

    C'est cela, oui…

  • # Pinaillage

    Posté par . Évalué à 1.

    "Peigner la girafe" c'est par exemple quand tu dois repeindre le garage ; mais comme c'est un gros truc, et que tu es feignant tu cherches une raison de pas le faire […]

    « Peigner la girafe » c'est encore pire que ça : c'est une activité longue et ennuyeuse, mais surtout inutile : l'image −littérale, hein− généralement retenue, c'est un homme qui peigne la girafe en commençant par le bas et en escaladant la girafe par le coup.

    Cela dit le résultat est pas mal, en 199 lignes.

    • [^] # Re: Pinaillage

      Posté par . Évalué à 2.

      un homme qui peigne la girafe en commençant par le bas et en escaladant la girafe par le coup.

      Coup sur coup ? C'est effectivement une solution : tu assommes la girafe, puis tu l'escalade. C'est plus simple.

    • [^] # Re: Pinaillage

      Posté par . Évalué à 1. Dernière modification le 27/08/14 à 20:28.

      [commentaire supprimé pour cause de pathétisme avancé]

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.