Comment réduire les doublons dans les champs dépendants d’un fichier .cabal?

Voici un fichier .cabal:

Name: myprogram Version: 0.1 -- blah blah blah Cabal-version: >=1.9.2 Executable myprogram HS-source-dirs: src Main-is: Main.hs Build-depends: attoparsec == 0.10.*, base == 4.3.*, -- long long list of packages Test-Suite test HS-source-dirs: test, src Type: exitcode-stdio-1.0 Main-is: Main.hs Build-depends: attoparsec == 0.10.*, base == 4.3.*, -- long long list of packages QuickCheck == 2.4.* 

Y a-t-il un moyen de remplacer la longue liste de paquets dépendants de la construction pour la suite de tests avec “les mêmes que pour l’exécutable, plus QuickCheck”?

Modifier: informations de version.

  • cabal-dev 0.9
  • cabal-install 0.10.2
  • Bibliothèque Cabal 1.10.2.0
  • GHC 7.0.4
  • Plateforme Haskell 2011.4.0.0

    Y a-t-il un moyen de remplacer la longue liste de paquets dépendants de la construction pour la suite de tests avec “les mêmes que pour l’exécutable, plus QuickCheck”?

    Pas que je sache de. Cependant, il est possible de ne mentionner la liste des paquets build-depends qu’une seule fois, en structurant votre projet en trois cibles:

    1. une bibliothèque qui contient tout votre code et qui a besoin de la longue liste dépend de la compilation.
    2. un exécutable composé d’un seul fichier et dépendant de la base et de la bibliothèque ci-dessus.
    3. une suite de tests qui dépend de la bibliothèque ci-dessus et des packages de test que vous utilisez.

    Peut-être que cette approche est ce que la réponse d’indygemma propose, mais le dossier proposé par Cabal n’y parviendra pas, comme le souligne Norman Ramsey dans un commentaire. Voici les points principaux de ce dont vous avez besoin dans un fichier Cabal. Pour un exemple complet qui fonctionne pour moi, vous pouvez regarder ce fichier Cabal .

     name: my-program version: ... library hs-source-dirs: src-lib build-depends: base, containers, ... exposed-modules: My.Program.Main, ... executable my-program hs-source-dirs: src-exec main-is: my-program.hs Build-depends: base, my-program test-suite tests type: exitcode-stdio-1.0 hs-source-dirs: src-test main-is: tests.hs other-modules: ... build-depends: base, my-program, test-framework, ... 

    Les points importants:

    • Il existe trois répertoires sources distincts pour les trois cibles. Ceci est nécessaire pour empêcher GHC de recomstackr les fichiers de bibliothèque lors de la création des autres cibles.

    • Tout le code de l’application se trouve dans la bibliothèque. L’exécutable est juste un wrapper, comme ceci:

       import My.Program.Main (realMain) main = realMain 
    • La bibliothèque expose tous les modules nécessaires au test.

    Le dernier point souligne l’inconvénient de cette approche: vous devez exposer des modules internes. Le principal avantage de cette approche est que vous avez moins de doublons dans le fichier Cabal, et peut-être plus important, moins de duplication dans le processus de compilation: le code de la bibliothèque ne sera généré qu’une fois, puis lié à l’exécutable et à la suite .

    Vous pouvez également envisager d’utiliser hpack au lieu d’écrire manuellement le fichier .cabal:

    Au format package.yaml de hpack, vous pouvez spécifier un champ de dependencies commun dont les entrées sont ajoutées au champ build-depends volume de chaque composant lors de la génération du fichier .cabal.

    Par exemple, consultez le package.yaml de hpack et le fichier hpack.cabal généré.

    Pour commencer à utiliser hpack avec un package existant, vous pouvez utiliser hpack-convert qui générera le package.yaml à partir d’un fichier .cabal existant.

    Pour créer un nouveau paquet qui utilise hpack, vous pouvez utiliser le modèle simple-hpack stack new mypkg simple-hpack comme simple-hpack : stack new mypkg simple-hpack .

    Si vous utilisez stack pour le développement, vous n’avez pas besoin d’appeler manuellement hpack pour régénérer le fichier .cabal à partir d’un package.yaml mis à jour – la stack le fera automatiquement.

    Pas facile:

    • vous pouvez utiliser m4 et spécifier vos dépendances une fois, mais vous devrez alors retraiter votre fichier Cabal via m4 chaque fois que vous le modifierez.

    • vous pouvez déplacer le code que vous testez dans une bibliothèque, puis spécifier la bibliothèque dans votre Build-depend pour le test. Cela nécessite que vous installiez une bibliothèque juste pour exécuter le test.

    • Vous pouvez simplement ne pas mettre le test dans le fichier cabal. Construisez-le avec ghc –make, ce qui entraînera des dépendances. Mais alors vous perdez l’intégration de la cabale.

    Il existe une section de bibliothèque facultative pour les fichiers .cabal, qui résout votre problème.

     name: myprogram version: 0.1 -- blah blah blah cabal-version: >=1.9.2 library build-depends: attoparsec == 0.10.* , base == 4.3.* -- long long list of packages executable myprogram hs-source-dirs: src main-is: Main.hs test-suite test hs-source-dirs: test, src type: exitcode-stdio-1.0 main-is: Main.hs build-depends: QuickCheck == 2.4.*