Catalogue initial des outils externes et détection de leurs versions #41

Closed
opened 2026-07-18 09:06:59 +02:00 by fy59 · 0 comments
Owner

Catalogue initial des outils externes et détection de leurs versions

Statut

À faire

Priorité

Haute

Objectif

Créer le catalogue initial des outils externes utilisés par Labfy Investigation et fournir une détection fiable de leur version.

Ce ticket complète les modules déjà validés :

ToolRegistry
ToolProcess
ToolTask

Le catalogue décrit les outils connus par l’application. Le registre décrit leur état sur la machine courante.

ToolCatalog
    description statique des outils connus
            ↓
ToolRegistry
    disponibilité, chemin résolu, version détectée
            ↓
ToolProcess
    exécution sécurisée de la commande de version

Contexte

ToolRegistry permet déjà d’enregistrer un outil, de rechercher son exécutable dans le PATH, de conserver son chemin résolu et sa version détectée, et de distinguer les états UNKNOWN, AVAILABLE et MISSING.

Il manque une source centrale définissant :

  • les outils reconnus par l’application ;
  • leur identifiant interne ;
  • leur nom affiché ;
  • leur exécutable ;
  • leur importance ;
  • les arguments permettant de demander leur version ;
  • la manière de normaliser la sortie obtenue.

Sans catalogue central, chaque fonctionnalité finirait par enregistrer elle-même ses dépendances.

Modules attendus

include/core/tool_catalog.h
src/core/tool_catalog.c
tests/test_tool_catalog.c

Le ticket ne doit pas modifier l’API publique de ToolRegistry, sauf nécessité démontrée pendant l’implémentation.

Responsabilités de ToolCatalog

Le module doit :

  1. conserver une liste statique et immuable des outils connus ;
  2. garantir l’unicité de leurs identifiants ;
  3. exposer leurs informations descriptives ;
  4. enregistrer l’ensemble du catalogue dans un ToolRegistry ;
  5. définir les arguments de détection de version ;
  6. exécuter ces arguments avec ToolProcess ;
  7. normaliser la sortie de version ;
  8. retourner la version détectée sans modifier directement le registre ;
  9. gérer l’annulation ;
  10. rester indépendant de GTK.

Le module ne doit pas installer de dépendance, modifier le PATH, utiliser un shell, analyser un résultat OSINT ni modifier l’interface graphique.

Catalogue initial

Identifiant interne Nom affiché Exécutable Importance Arguments de version
dns.dig dig dig optionnel -v
dns.host host host optionnel -V
network.whois whois whois optionnel --version
http.curl curl curl optionnel --version
tls.openssl OpenSSL openssl optionnel version

Tous ces outils sont optionnels au niveau de l’application entière.

Ne pas ajouter encore nslookup, traceroute, jq, file, exiftool, nmap, subfinder, amass, les outils Python ou les outils installés depuis GitHub.

Structure ToolCatalogEntry

Créer une structure opaque :

typedef struct ToolCatalogEntry ToolCatalogEntry;

Elle conserve au minimum :

identifier
display_name
executable_name
requirement
version_arguments

Les données du catalogue sont statiques et immuables. Elles ne doivent jamais être libérées par l’appelant.

Domaine d’erreur

#define TOOL_CATALOG_ERROR \
    tool_catalog_error_quark()
typedef enum
{
    TOOL_CATALOG_ERROR_INVALID_ARGUMENT,
    TOOL_CATALOG_ERROR_ENTRY_NOT_FOUND,
    TOOL_CATALOG_ERROR_REGISTRATION,
    TOOL_CATALOG_ERROR_TOOL_NOT_REGISTERED,
    TOOL_CATALOG_ERROR_TOOL_NOT_CHECKED,
    TOOL_CATALOG_ERROR_TOOL_MISSING,
    TOOL_CATALOG_ERROR_INVALID_TOOL_STATE,
    TOOL_CATALOG_ERROR_PROCESS,
    TOOL_CATALOG_ERROR_VERSION_COMMAND,
    TOOL_CATALOG_ERROR_VERSION_OUTPUT,
    TOOL_CATALOG_ERROR_CANCELLED
} ToolCatalogError;
GQuark tool_catalog_error_quark(void);

API publique proposée

Consultation

gsize tool_catalog_get_count(void);
const ToolCatalogEntry *tool_catalog_get_entry(
    gsize index
);
const ToolCatalogEntry *tool_catalog_find(
    const char *identifier
);

Accesseurs

const char *tool_catalog_entry_get_identifier(
    const ToolCatalogEntry *entry
);
const char *tool_catalog_entry_get_display_name(
    const ToolCatalogEntry *entry
);
const char *tool_catalog_entry_get_executable_name(
    const ToolCatalogEntry *entry
);
ToolRequirement tool_catalog_entry_get_requirement(
    const ToolCatalogEntry *entry
);
gsize tool_catalog_entry_get_version_argument_count(
    const ToolCatalogEntry *entry
);
const char *tool_catalog_entry_get_version_argument(
    const ToolCatalogEntry *entry,
    gsize index
);

Enregistrement

gboolean tool_catalog_register_defaults(
    ToolRegistry *tool_registry,
    GError **error
);

Détection d’une version

gboolean tool_catalog_detect_version(
    const ToolRegistry *tool_registry,
    const char *identifier,
    GCancellable *cancellable,
    char **out_version,
    GError **error
);

out_version reçoit une chaîne nouvellement allouée, à libérer avec g_free().

La fonction ne doit pas appeler tool_registry_set_version().

Règles d’enregistrement

tool_catalog_register_defaults() doit vérifier avant toute insertion qu’aucun identifiant du catalogue n’existe déjà dans le registre.

En cas de doublon :

  • aucune entrée ne doit être ajoutée ;
  • la fonction retourne FALSE ;
  • l’erreur vaut TOOL_CATALOG_ERROR_REGISTRATION.

Cette prévalidation évite une insertion partielle, car ToolRegistry ne fournit pas de suppression.

Validation de la détection

La fonction doit refuser :

  • un registre NULL ;
  • un identifiant NULL ou vide ;
  • un out_version égal à NULL ;
  • un out_version pointant déjà vers une chaîne ;
  • un GError déjà initialisé.

Au début d’un appel valide :

*out_version = NULL;

Cas d’erreur :

entrée absente du catalogue     → TOOL_CATALOG_ERROR_ENTRY_NOT_FOUND
outil absent du registre        → TOOL_CATALOG_ERROR_TOOL_NOT_REGISTERED
état UNKNOWN                    → TOOL_CATALOG_ERROR_TOOL_NOT_CHECKED
état MISSING                    → TOOL_CATALOG_ERROR_TOOL_MISSING
AVAILABLE sans chemin résolu    → TOOL_CATALOG_ERROR_INVALID_TOOL_STATE

Exécution de la commande de version

Utiliser exclusivement :

tool_process_run()

avec :

executable_path   = chemin résolu du ToolRegistry
arguments         = arguments statiques du ToolCatalogEntry
working_directory = NULL
cancellable       = paramètre reçu

Interdictions :

  • /bin/sh -c ;
  • system() ;
  • popen() ;
  • concaténation d’une ligne de commande ;
  • redirections interprétées ;
  • ajout ou transformation des arguments.

Annulation

Si ToolProcess retourne TOOL_PROCESS_ERROR_CANCELLED, la fonction doit produire :

G_IO_ERROR
G_IO_ERROR_CANCELLED

Aucune version partielle ne doit être retournée.

Code de sortie

Pour une commande de version, un code de sortie non nul est un échec :

TOOL_CATALOG_ERROR_VERSION_COMMAND

Une terminaison par signal produit la même catégorie d’erreur.

La sortie ne doit pas être interprétée lorsque le processus n’a pas terminé normalement avec le code zéro.

Sélection de la sortie

Règle générique :

  1. prendre la première ligne non vide de stdout ;
  2. si stdout ne contient rien d’exploitable, essayer stderr ;
  3. si aucun flux ne contient de texte exploitable, échouer.

Cette règle évite une logique spéciale par outil pendant ce premier ticket.

Normalisation

Le catalogue ne doit pas extraire seulement un numéro sémantique.

La version conservée est la première ligne descriptive exploitable, par exemple :

DiG 9.20.8
curl 8.14.1 (x86_64-pc-linux-gnu)
OpenSSL 3.5.1 1 Jul 2025

Algorithme :

  1. obtenir les octets du flux ;
  2. inspecter au maximum 4096 octets par flux ;
  3. convertir les octets invalides avec g_utf8_make_valid() ;
  4. séparer les lignes ;
  5. ignorer les lignes vides ;
  6. choisir la première ligne non vide ;
  7. retirer espaces et tabulations en début et fin ;
  8. retirer \r et \n ;
  9. refuser un résultat vide ;
  10. retourner une nouvelle chaîne.

Propriété des données

Les entrées et chaînes du catalogue sont empruntées et statiques.

La chaîne placée dans *out_version appartient à l’appelant et doit être libérée avec g_free().

ToolCatalog ne devient jamais propriétaire du registre.

Contraintes de thread

Le catalogue statique est immuable.

tool_catalog_detect_version() :

  • ne modifie pas le catalogue ;
  • ne modifie pas le registre ;
  • copie le chemin nécessaire avant l’exécution ;
  • ne conserve aucun pointeur vers ToolInfo après la préparation.

Le stockage avec tool_registry_set_version() reste la responsabilité du propriétaire du registre, idéalement dans le thread principal.

Tests unitaires obligatoires

Les tests utilisent uniquement de faux exécutables temporaires.

Ils ne doivent pas dépendre des outils réellement installés.

Tests du catalogue

  1. nombre exact d’entrées ;
  2. contenu exact des cinq entrées ;
  3. index invalide ;
  4. recherche par identifiant ;
  5. identifiant inconnu ;
  6. unicité des identifiants ;
  7. arguments de version ;
  8. enregistrement complet dans un registre vide ;
  9. état initial UNKNOWN ;
  10. prévalidation d’un doublon sans insertion partielle.

Tests de détection

  1. arguments invalides ;
  2. entrée inconnue ;
  3. outil non enregistré ;
  4. outil non vérifié ;
  5. outil absent ;
  6. version sur stdout ;
  7. version sur stderr ;
  8. première ligne non vide ;
  9. normalisation des espaces et fins de ligne ;
  10. sortie non UTF-8 ;
  11. sortie vide ;
  12. code de sortie non nul ;
  13. terminaison par signal ;
  14. annulation ;
  15. indépendance du registre ;
  16. plusieurs détections successives.

Noms de tests suggérés

/tool_catalog/entries
/tool_catalog/invalid_index
/tool_catalog/find
/tool_catalog/unique_entries
/tool_catalog/register_defaults
/tool_catalog/register_duplicate
/tool_catalog/detect_invalid_arguments
/tool_catalog/detect_unknown_entry
/tool_catalog/detect_unregistered_tool
/tool_catalog/detect_unchecked_tool
/tool_catalog/detect_missing_tool
/tool_catalog/version_stdout
/tool_catalog/version_stderr
/tool_catalog/version_first_nonempty_line
/tool_catalog/version_normalization
/tool_catalog/version_non_utf8
/tool_catalog/version_empty
/tool_catalog/version_nonzero_exit
/tool_catalog/version_signaled
/tool_catalog/version_cancelled
/tool_catalog/version_registry_independence
/tool_catalog/version_successive_runs

Makefile

TEST_TOOL_CATALOG := tests/test_tool_catalog
$(TEST_TOOL_CATALOG): \
	tests/test_tool_catalog.c \
	src/core/tool_catalog.c \
	src/core/tool_registry.c \
	src/core/tool_process.c
	$(CC) $(TEST_CFLAGS) $^ -o $@ $(TEST_LDFLAGS)

Ajouter le binaire à make test et make clean.

Vérifications

make clean
make
make tests/test_tool_catalog
./tests/test_tool_catalog
make test
git diff --check

Vérification mémoire

G_DEBUG=gc-friendly \
G_SLICE=always-malloc \
valgrind \
    --leak-check=full \
    --show-leak-kinds=all \
    ./tests/test_tool_catalog

Critères d’acceptation

Le ticket est validé lorsque :

  • le catalogue contient exactement les cinq outils prévus ;
  • toutes les entrées sont immuables ;
  • tous les identifiants sont uniques ;
  • le catalogue s’enregistre dans un registre vide ;
  • un doublon empêche toute insertion partielle ;
  • la détection utilise ToolProcess ;
  • aucun shell n’est utilisé ;
  • stdout et stderr sont pris en charge ;
  • la première ligne non vide est normalisée ;
  • une sortie invalide devient un UTF-8 valide ;
  • l’inspection est limitée à 4096 octets par flux ;
  • un code non nul ou un signal est refusé ;
  • l’annulation produit G_IO_ERROR_CANCELLED ;
  • la fonction ne modifie pas directement le registre ;
  • les versions successives sont indépendantes ;
  • les tests ne dépendent d’aucun outil installé ;
  • tous les tests passent ;
  • aucune fuite mémoire n’est détectée ;
  • le test est intégré au Makefile.

Démonstration finale

Après validation :

  1. créer un ToolRegistry ;
  2. appeler tool_catalog_register_defaults() ;
  3. appeler tool_registry_refresh() ;
  4. afficher les outils présents et absents ;
  5. détecter la version d’un outil disponible ;
  6. stocker explicitement la version avec tool_registry_set_version().

Cette démonstration restera hors de l’interface GTK principale.

Suite prévue

#040 — Initialisation des dépendances et analyse asynchrone au démarrage

Ce ticket devra créer le registre global de l’application, enregistrer le catalogue, rafraîchir les disponibilités hors du thread GTK, détecter les versions et publier une tâche dans TaskManager.

# Catalogue initial des outils externes et détection de leurs versions ## Statut À faire ## Priorité Haute ## Objectif Créer le catalogue initial des outils externes utilisés par Labfy Investigation et fournir une détection fiable de leur version. Ce ticket complète les modules déjà validés : ```text ToolRegistry ToolProcess ToolTask ``` Le catalogue décrit les outils connus par l’application. Le registre décrit leur état sur la machine courante. ```text ToolCatalog description statique des outils connus ↓ ToolRegistry disponibilité, chemin résolu, version détectée ↓ ToolProcess exécution sécurisée de la commande de version ``` ## Contexte `ToolRegistry` permet déjà d’enregistrer un outil, de rechercher son exécutable dans le `PATH`, de conserver son chemin résolu et sa version détectée, et de distinguer les états `UNKNOWN`, `AVAILABLE` et `MISSING`. Il manque une source centrale définissant : - les outils reconnus par l’application ; - leur identifiant interne ; - leur nom affiché ; - leur exécutable ; - leur importance ; - les arguments permettant de demander leur version ; - la manière de normaliser la sortie obtenue. Sans catalogue central, chaque fonctionnalité finirait par enregistrer elle-même ses dépendances. ## Modules attendus ```text include/core/tool_catalog.h src/core/tool_catalog.c tests/test_tool_catalog.c ``` Le ticket ne doit pas modifier l’API publique de `ToolRegistry`, sauf nécessité démontrée pendant l’implémentation. ## Responsabilités de ToolCatalog Le module doit : 1. conserver une liste statique et immuable des outils connus ; 2. garantir l’unicité de leurs identifiants ; 3. exposer leurs informations descriptives ; 4. enregistrer l’ensemble du catalogue dans un `ToolRegistry` ; 5. définir les arguments de détection de version ; 6. exécuter ces arguments avec `ToolProcess` ; 7. normaliser la sortie de version ; 8. retourner la version détectée sans modifier directement le registre ; 9. gérer l’annulation ; 10. rester indépendant de GTK. Le module ne doit pas installer de dépendance, modifier le `PATH`, utiliser un shell, analyser un résultat OSINT ni modifier l’interface graphique. ## Catalogue initial | Identifiant interne | Nom affiché | Exécutable | Importance | Arguments de version | |---|---|---|---|---| | `dns.dig` | `dig` | `dig` | optionnel | `-v` | | `dns.host` | `host` | `host` | optionnel | `-V` | | `network.whois` | `whois` | `whois` | optionnel | `--version` | | `http.curl` | `curl` | `curl` | optionnel | `--version` | | `tls.openssl` | `OpenSSL` | `openssl` | optionnel | `version` | Tous ces outils sont optionnels au niveau de l’application entière. Ne pas ajouter encore `nslookup`, `traceroute`, `jq`, `file`, `exiftool`, `nmap`, `subfinder`, `amass`, les outils Python ou les outils installés depuis GitHub. ## Structure ToolCatalogEntry Créer une structure opaque : ```c typedef struct ToolCatalogEntry ToolCatalogEntry; ``` Elle conserve au minimum : ```text identifier display_name executable_name requirement version_arguments ``` Les données du catalogue sont statiques et immuables. Elles ne doivent jamais être libérées par l’appelant. ## Domaine d’erreur ```c #define TOOL_CATALOG_ERROR \ tool_catalog_error_quark() ``` ```c typedef enum { TOOL_CATALOG_ERROR_INVALID_ARGUMENT, TOOL_CATALOG_ERROR_ENTRY_NOT_FOUND, TOOL_CATALOG_ERROR_REGISTRATION, TOOL_CATALOG_ERROR_TOOL_NOT_REGISTERED, TOOL_CATALOG_ERROR_TOOL_NOT_CHECKED, TOOL_CATALOG_ERROR_TOOL_MISSING, TOOL_CATALOG_ERROR_INVALID_TOOL_STATE, TOOL_CATALOG_ERROR_PROCESS, TOOL_CATALOG_ERROR_VERSION_COMMAND, TOOL_CATALOG_ERROR_VERSION_OUTPUT, TOOL_CATALOG_ERROR_CANCELLED } ToolCatalogError; ``` ```c GQuark tool_catalog_error_quark(void); ``` ## API publique proposée ### Consultation ```c gsize tool_catalog_get_count(void); ``` ```c const ToolCatalogEntry *tool_catalog_get_entry( gsize index ); ``` ```c const ToolCatalogEntry *tool_catalog_find( const char *identifier ); ``` ### Accesseurs ```c const char *tool_catalog_entry_get_identifier( const ToolCatalogEntry *entry ); ``` ```c const char *tool_catalog_entry_get_display_name( const ToolCatalogEntry *entry ); ``` ```c const char *tool_catalog_entry_get_executable_name( const ToolCatalogEntry *entry ); ``` ```c ToolRequirement tool_catalog_entry_get_requirement( const ToolCatalogEntry *entry ); ``` ```c gsize tool_catalog_entry_get_version_argument_count( const ToolCatalogEntry *entry ); ``` ```c const char *tool_catalog_entry_get_version_argument( const ToolCatalogEntry *entry, gsize index ); ``` ### Enregistrement ```c gboolean tool_catalog_register_defaults( ToolRegistry *tool_registry, GError **error ); ``` ### Détection d’une version ```c gboolean tool_catalog_detect_version( const ToolRegistry *tool_registry, const char *identifier, GCancellable *cancellable, char **out_version, GError **error ); ``` `out_version` reçoit une chaîne nouvellement allouée, à libérer avec `g_free()`. La fonction ne doit pas appeler `tool_registry_set_version()`. ## Règles d’enregistrement `tool_catalog_register_defaults()` doit vérifier avant toute insertion qu’aucun identifiant du catalogue n’existe déjà dans le registre. En cas de doublon : - aucune entrée ne doit être ajoutée ; - la fonction retourne `FALSE` ; - l’erreur vaut `TOOL_CATALOG_ERROR_REGISTRATION`. Cette prévalidation évite une insertion partielle, car `ToolRegistry` ne fournit pas de suppression. ## Validation de la détection La fonction doit refuser : - un registre `NULL` ; - un identifiant `NULL` ou vide ; - un `out_version` égal à `NULL` ; - un `out_version` pointant déjà vers une chaîne ; - un `GError` déjà initialisé. Au début d’un appel valide : ```c *out_version = NULL; ``` Cas d’erreur : ```text entrée absente du catalogue → TOOL_CATALOG_ERROR_ENTRY_NOT_FOUND outil absent du registre → TOOL_CATALOG_ERROR_TOOL_NOT_REGISTERED état UNKNOWN → TOOL_CATALOG_ERROR_TOOL_NOT_CHECKED état MISSING → TOOL_CATALOG_ERROR_TOOL_MISSING AVAILABLE sans chemin résolu → TOOL_CATALOG_ERROR_INVALID_TOOL_STATE ``` ## Exécution de la commande de version Utiliser exclusivement : ```c tool_process_run() ``` avec : ```text executable_path = chemin résolu du ToolRegistry arguments = arguments statiques du ToolCatalogEntry working_directory = NULL cancellable = paramètre reçu ``` Interdictions : - `/bin/sh -c` ; - `system()` ; - `popen()` ; - concaténation d’une ligne de commande ; - redirections interprétées ; - ajout ou transformation des arguments. ## Annulation Si `ToolProcess` retourne `TOOL_PROCESS_ERROR_CANCELLED`, la fonction doit produire : ```text G_IO_ERROR G_IO_ERROR_CANCELLED ``` Aucune version partielle ne doit être retournée. ## Code de sortie Pour une commande de version, un code de sortie non nul est un échec : ```text TOOL_CATALOG_ERROR_VERSION_COMMAND ``` Une terminaison par signal produit la même catégorie d’erreur. La sortie ne doit pas être interprétée lorsque le processus n’a pas terminé normalement avec le code zéro. ## Sélection de la sortie Règle générique : 1. prendre la première ligne non vide de stdout ; 2. si stdout ne contient rien d’exploitable, essayer stderr ; 3. si aucun flux ne contient de texte exploitable, échouer. Cette règle évite une logique spéciale par outil pendant ce premier ticket. ## Normalisation Le catalogue ne doit pas extraire seulement un numéro sémantique. La version conservée est la première ligne descriptive exploitable, par exemple : ```text DiG 9.20.8 curl 8.14.1 (x86_64-pc-linux-gnu) OpenSSL 3.5.1 1 Jul 2025 ``` Algorithme : 1. obtenir les octets du flux ; 2. inspecter au maximum 4096 octets par flux ; 3. convertir les octets invalides avec `g_utf8_make_valid()` ; 4. séparer les lignes ; 5. ignorer les lignes vides ; 6. choisir la première ligne non vide ; 7. retirer espaces et tabulations en début et fin ; 8. retirer `\r` et `\n` ; 9. refuser un résultat vide ; 10. retourner une nouvelle chaîne. ## Propriété des données Les entrées et chaînes du catalogue sont empruntées et statiques. La chaîne placée dans `*out_version` appartient à l’appelant et doit être libérée avec `g_free()`. `ToolCatalog` ne devient jamais propriétaire du registre. ## Contraintes de thread Le catalogue statique est immuable. `tool_catalog_detect_version()` : - ne modifie pas le catalogue ; - ne modifie pas le registre ; - copie le chemin nécessaire avant l’exécution ; - ne conserve aucun pointeur vers `ToolInfo` après la préparation. Le stockage avec `tool_registry_set_version()` reste la responsabilité du propriétaire du registre, idéalement dans le thread principal. ## Tests unitaires obligatoires Les tests utilisent uniquement de faux exécutables temporaires. Ils ne doivent pas dépendre des outils réellement installés. ### Tests du catalogue 1. nombre exact d’entrées ; 2. contenu exact des cinq entrées ; 3. index invalide ; 4. recherche par identifiant ; 5. identifiant inconnu ; 6. unicité des identifiants ; 7. arguments de version ; 8. enregistrement complet dans un registre vide ; 9. état initial `UNKNOWN` ; 10. prévalidation d’un doublon sans insertion partielle. ### Tests de détection 11. arguments invalides ; 12. entrée inconnue ; 13. outil non enregistré ; 14. outil non vérifié ; 15. outil absent ; 16. version sur stdout ; 17. version sur stderr ; 18. première ligne non vide ; 19. normalisation des espaces et fins de ligne ; 20. sortie non UTF-8 ; 21. sortie vide ; 22. code de sortie non nul ; 23. terminaison par signal ; 24. annulation ; 25. indépendance du registre ; 26. plusieurs détections successives. ## Noms de tests suggérés ```text /tool_catalog/entries /tool_catalog/invalid_index /tool_catalog/find /tool_catalog/unique_entries /tool_catalog/register_defaults /tool_catalog/register_duplicate /tool_catalog/detect_invalid_arguments /tool_catalog/detect_unknown_entry /tool_catalog/detect_unregistered_tool /tool_catalog/detect_unchecked_tool /tool_catalog/detect_missing_tool /tool_catalog/version_stdout /tool_catalog/version_stderr /tool_catalog/version_first_nonempty_line /tool_catalog/version_normalization /tool_catalog/version_non_utf8 /tool_catalog/version_empty /tool_catalog/version_nonzero_exit /tool_catalog/version_signaled /tool_catalog/version_cancelled /tool_catalog/version_registry_independence /tool_catalog/version_successive_runs ``` ## Makefile ```make TEST_TOOL_CATALOG := tests/test_tool_catalog ``` ```make $(TEST_TOOL_CATALOG): \ tests/test_tool_catalog.c \ src/core/tool_catalog.c \ src/core/tool_registry.c \ src/core/tool_process.c $(CC) $(TEST_CFLAGS) $^ -o $@ $(TEST_LDFLAGS) ``` Ajouter le binaire à `make test` et `make clean`. ## Vérifications ```bash make clean make make tests/test_tool_catalog ./tests/test_tool_catalog make test git diff --check ``` ## Vérification mémoire ```bash G_DEBUG=gc-friendly \ G_SLICE=always-malloc \ valgrind \ --leak-check=full \ --show-leak-kinds=all \ ./tests/test_tool_catalog ``` ## Critères d’acceptation Le ticket est validé lorsque : - le catalogue contient exactement les cinq outils prévus ; - toutes les entrées sont immuables ; - tous les identifiants sont uniques ; - le catalogue s’enregistre dans un registre vide ; - un doublon empêche toute insertion partielle ; - la détection utilise `ToolProcess` ; - aucun shell n’est utilisé ; - stdout et stderr sont pris en charge ; - la première ligne non vide est normalisée ; - une sortie invalide devient un UTF-8 valide ; - l’inspection est limitée à 4096 octets par flux ; - un code non nul ou un signal est refusé ; - l’annulation produit `G_IO_ERROR_CANCELLED` ; - la fonction ne modifie pas directement le registre ; - les versions successives sont indépendantes ; - les tests ne dépendent d’aucun outil installé ; - tous les tests passent ; - aucune fuite mémoire n’est détectée ; - le test est intégré au `Makefile`. ## Démonstration finale Après validation : 1. créer un `ToolRegistry` ; 2. appeler `tool_catalog_register_defaults()` ; 3. appeler `tool_registry_refresh()` ; 4. afficher les outils présents et absents ; 5. détecter la version d’un outil disponible ; 6. stocker explicitement la version avec `tool_registry_set_version()`. Cette démonstration restera hors de l’interface GTK principale. ## Suite prévue ```text #040 — Initialisation des dépendances et analyse asynchrone au démarrage ``` Ce ticket devra créer le registre global de l’application, enregistrer le catalogue, rafraîchir les disponibilités hors du thread GTK, détecter les versions et publier une tâche dans `TaskManager`.
fy59 closed this issue 2026-07-18 09:07:06 +02:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: fy59/labfy-investigation#41
No description provided.