Как уменьшить дублирование в полях build-depends файла. cabal?
здесь .cabal file:
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.*
есть ли способ заменить длинный список зависящих от сборки пакетов для набора тестов на "то же, что и для исполняемого файла, плюс QuickCheck"?
Edit: информация о версии.
- cabal-dev 0.9
- cabal-установить 0.10.2
- Cabal library 1.10.2.0
- GHC 7.0.4
- Платформа Haskell 2011.4.0.0
5 ответов:
начиная с версии 2.2 Cabal поддерживает общие строфы, чтобы дедуп build info поля: 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
есть ли способ заменить длинный список зависящих от сборки пакетов для набора тестов на "то же, что и для исполняемого файла, плюс QuickCheck"?
насколько мне известно, нет. Однако, есть способ только упомянуть список
build-depends
пакеты один раз, структурируя свой проект на три цели:
- библиотека, которая содержит весь ваш код и нуждается в длинном списке build-depends.
- исполняемый файл, который состоит только из одного файл, и зависит от базы и библиотеки сверху.
- набор тестов, который зависит от библиотеки сверху, и пакеты тестирования, которые вы используете.
возможно, этот подход-это то, что предлагает ответ indygemma, но предложенный там файл Cabal не совсем достигнет этого, как указывает Норман Рэмси в комментарии. Вот основные моменты того, что вам нужно в файле 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, ...
важные моменты:
есть три отдельных исходных каталога для трех целей. Это необходимо, чтобы остановить GHC от перекомпиляции файлов библиотеки при создании других целевых объектов.
весь код приложения в библиотеке. Исполняемый файл-это просто оболочка, как это:
import My.Program.Main (realMain) main = realMain
библиотека предоставляет все модули, которые необходимы для тестирование.
последний пункт подчеркивает недостаток этого подхода: вы в конечном итоге должны выставлять внутренние модули. Основное преимущество этого подхода заключается в том, что у вас меньше дублирования в файле Cabal и, возможно, что более важно, меньше дублирования в процессе сборки: код библиотеки будет построен только один раз, а затем связан как с исполняемым файлом, так и с набором тестов.
вы также можете рассмотреть возможность использования hpack вместо того, чтобы писать .cabal файл от руки:
в пакете hpack.формат yaml, вы можете указать общий
dependencies
поле, записи которого добавляются к каждому компоненту'build-depends
поле при создании .файл междусобойчик.например, см. hpack по пакета.и YAML и созданный hpack.Кабал.
чтобы начать использовать hpack с существующим пакетом, вы можете использовать hpack-преобразования который будет генерировать пакет.ямл из существующего .файл междусобойчик.
создать новый пакет, который использует hpack, вы можете использовать стек
simple-hpack
шаблон вот так:stack new mypkg simple-hpack
.если вы используете стек для развития вам не нужно звонить
hpack
вручную, чтобы восстановить .файл cabal из обновленного пакета.yaml-stack сделает это автоматически.
нет простой способ:
можно использовать m4 и укажите свои зависимости один раз, но тогда вам нужно будет повторно обработать ваш файл Cabal через m4 всякий раз, когда вы его меняете.
вы можете переместить тестируемый код в библиотеку, а затем указать библиотеку в своей сборке-зависит от теста. Это требует установки библиотеки даже просто для запуска теста.
вы можете просто не ставить тест в файл кабала вообще. Постройте его с помощью ghc --make, который будет тянуть в зависимости. Но тогда вы теряете кабальную интеграцию.
по желанию библиотека для .cabal файлы, что решает вашу проблему.
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.*