¿Cómo reducir la duplicación en los campos build-depends de un archivo.cabal?


Aquí está a.archivo 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.*

¿Hay alguna manera de que pueda reemplazar la larga lista de paquetes build-depends para el conjunto de pruebas con "lo mismo que para el ejecutable, más QuickCheck"?

Editar: información de la versión.

  • cabal-dev 0.9
  • cabal-install 0.10.2
  • Cabal library 1.10.2.0
  • GHC 7.0.4
  • Haskell Platform 2011.4.0.0
Author: dave4420, 2012-04-15

5 answers

Desde la versión 2.2 Cabal soporta estrofas comunes, a dedup build info campos: https://cabal.readthedocs.io/en/latest/developing-packages.html#common-stanzas

cabal-version:       2.2
name:                myprogram
version:             0.1
-- blah blah blah

common deps
  build-depends: base ^>= 4.11,
                 -- long long list of packages
  ghc-options: -Wall

library
  import: deps
  exposed-modules: Foo

test-suite tests
  import: deps
  type: exitcode-stdio-1.0
  main-is: Tests.hs
  build-depends: foo
 4
Author: phadej,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-20 16:53:03

¿Hay alguna manera de que pueda reemplazar la larga lista de paquetes build-depends para el conjunto de pruebas con "lo mismo que para el ejecutable, más QuickCheck"?

No, que yo sepa. Sin embargo, hay una manera de mencionar solo la lista de paquetes build-depends una vez, estructurando su proyecto en tres objetivos:

  1. una biblioteca que contiene todo su código, y necesita la larga lista build-depends.
  2. un ejecutable que consiste en un solo archivo, y depende de la base y biblioteca desde arriba.
  3. un conjunto de pruebas que depende de la biblioteca de arriba, y de los paquetes de pruebas que está utilizando.

Tal vez este enfoque es lo que propone la respuesta de indygemma, pero el archivo de la Cábala propuesto allí no lo logrará del todo, como señala Norman Ramsey en un comentario. Estos son los puntos principales de lo que necesita en un archivo de la Cábala. Para un ejemplo completo que funcione para mí, puedes mirar este archivo 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, ...

Importante puntos:

  • Hay tres directorios de origen separados para los tres destinos. Esto es necesario para evitar que GHC recompile archivos de biblioteca al compilar los otros destinos.

  • Todo el código de la aplicación está en la biblioteca. El ejecutable es solo un wrapper, así:

    import My.Program.Main (realMain)
    main = realMain
    
  • La biblioteca expone todos los módulos que son necesarios para las pruebas.

El último punto destaca el inconveniente de este enfoque: Se termina tener que exponer módulos internos. El principal beneficio de este enfoque es que tiene menos duplicación en el archivo Cabal, y quizás lo más importante, menos duplicación en el proceso de compilación: El código de la biblioteca se construirá solo una vez, y luego se vinculará tanto al ejecutable como al conjunto de pruebas.

 32
Author: Toxaris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-18 11:36:39

También podría considerar usar hpack en lugar de escribir el .archivo cabal a mano:

En el paquete de hpack.formato yaml, puede especificar un campo común dependencies cuyas entradas se agregan al campo build-depends de cada componente al generar el .archivo cabal.

Por ejemplo, vea el propio paquete de hpack.yaml y el hpack generado .cabal .

Para comenzar a usar hpack con un paquete existente, puede usar hpack-convert que generará el paquete.yaml de un existente .archivo cabal.

Para crear un nuevo paquete que use hpack, puede usar la plantilla simple-hpack de stack de la siguiente manera: stack new mypkg simple-hpack.

Si utiliza stack para el desarrollo, no tiene que llamar a hpack manualmente para regenerar el .archivo cabal de un paquete actualizado.yaml-stack lo hará automáticamente.

 3
Author: sjakobi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-08 23:31:30

No es fácil:

  • Puede usar m4 y especificar sus dependencias una vez, pero luego necesitará reprocesar su archivo Cabal a través de m4 cada vez que lo cambie.

  • Puede mover el código que está probando a una biblioteca y, a continuación, especificar la biblioteca en su Build-depends para la prueba. Eso requiere que instale una biblioteca incluso solo para ejecutar la prueba.

  • Simplemente no puedes poner la prueba en el archivo de la cábala en absoluto. Construir con ghc make make, que extraerá dependencias. Pero entonces pierdes la integración de la cábala.

 -1
Author: Omari Norman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-30 02:38:41

Hay una sección opcional library para .archivos cabal, que resuelve su problema.

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.*
 -5
Author: indygemma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-15 16:58:52