• [^] # Re: Bravo

    Posté par . En réponse au journal Résolution des dépendances par système de branches. Évalué à 2.

    La gestion des dépendances inverses est intéressante, surtout que en dehors du solveur.

    Le packageur crée un fichier de la sorte :

    [paquet]
    Name=nom
    Version=version
    Distribution=section de la distrib
    Depends=dépendances (>= version); ...


    Ces fichiers sont envoyés sur le serveur, qui en fonction de Distribution crée les dists/distro/packages.lzma. Ce fichier compressé est la simple concaténation des fichiers écrits par les packageurs.

    Du côté de Setup, ces fichiers sont récupérés, et inscrits dans la base de donnée (par un code monstrueux de 700 lignes d'ailleurs).

    C'est là que tout est joué : dans la base de donnée, chaque paquet a une simple liste de dépendances, et chaque dépendant est une structure :

    struct _Depend
    {
    int8_t type; // DEPEND_TYPE
    int8_t op; // DEPEND_OP
    int32_t pkgname; // Index de la chaîne du nom du paquet de la dépendance
    int32_t pkgver; // Index de la chaîne de la version du paquet de la dépendance
    };


    Type permet de spécifier le type, c'est à dire une dépendance, une suggestion, un conflit, une fourniture, et une dépendance inverse. Les dépendances inverses ne sont pas données par le packageur, mais c'est databasewriter.cpp, qui connaissant tous les paquets de la BDD, s'occupe de faire les liens inverse (pour chaque dépendance, une dépendance inverse est crée de l'autre côté).

    Ainsi, du côté du solveur, le code de gestion des dépendances inverses se limite à ... ceci :

    else if (dep->type == DEPEND_TYPE_REVDEP && action == Solver::Remove)
    {
    act = Solver::Remove;
    // TODO: Vérifier que la dépendance inverse est installée avant de surcharger l'arbre
    }


    Donc, si on retire un paquet, on retire également ses dépendances inverses (et le TODO est là pour me rappeler que quand j'aurai codé l'installation, je devrai voir si le paquet n'est pas déjà non-installé, pour ne pas le supprimer deux fois, et donc créer trop de branches).

    C'est simple, ça marche :

    $ ./setup add -libinitng
    {
    "libinitng" "0.6.99+gitAug302009~1"
    "initng" "0.6.99+gitAug302009~1"
    "initng-plugins" "0.6.99+gitAug302009~1"
    "initng-plugins" "0.6.98"
    "initng" "0.6.98"
    }
    {
    "libinitng" "0.6.98"
    }


    Ici, on voit qu'on a deux solutions :

    * Retirer libinitng-0.6.98 dont rien ne dépend
    * Retirer tous les autres paquets (puisque je n'ai pas encore la gestion des paquets supprimés/installés, tout est supprimés). On voit qu'on a correctement remonté tout l'arbre : initng dépend de libinitng, et les initng-plugins dépendent de initng.

    C'est ok :) .