Подтвердить что ты не робот

Как уменьшить дублирование в полях, зависящих от сборки файла .cabal?

Вот файл .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.*

Можно ли каким-либо образом заменить длинный список пакетов, зависящих от сборки, для набора тестов с "такими же, как и для исполняемого файла, а также QuickCheck"?

Изменить: информацию о версии.

  • cabal-dev 0.9
  • cabal-install 0.10.2
  • Библиотека Cabal 1.10.2.0
  • GHC 7.0.4
  • Платформа Haskell 2011.4.0.0
4b9b3361

Ответ 1

Можно ли каким-либо образом заменить длинный список пакетов, зависящих от сборки, для набора тестов с "такими же, как и для исполняемого файла, а также QuickCheck"?

Не то, чтобы я знал. Тем не менее, существует способ упоминать только один список пакетов, зависящих от сборки, путем структурирования вашего проекта в три цели:

  • библиотека, которая содержит весь ваш код и нуждается в длинном списке, зависящем от сборки.
  • исполняемый файл, который состоит только из одного файла и зависит от базы и библиотеки сверху.
  • тестовый пакет, который зависит от библиотеки сверху и пакетов тестирования, которые вы используете.

Возможно, такой подход - это то, что предлагает indygemma, но предложенный там файл кабалы не достигнет этого, как замечает Норман Рэмси в комментарии. Здесь основные моменты того, что вам нужно в файле кэба. Для полного примера, который работает для меня, вы можете посмотреть этот файл 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 и, что еще важнее, меньше дублирования в процессе сборки: библиотечный код будет создан только один раз, а затем будет связан как с исполняемым, так и с тестовым набором.

Ответ 2

Вы также можете использовать hpack вместо записи файла .cabal вручную:

В формате hpack package.yaml вы можете указать общее поле dependencies, чьи записи добавляются в поле всех компонентов build-depends при создании файла .cabal.

Например, см. hpack package.yaml и сгенерированный hpack.cabal.

Чтобы начать использовать hpack с существующим пакетом, вы можете использовать hpack-convert, который будет генерировать package.yaml из существующего файла .cabal.

Чтобы создать новый пакет, использующий hpack, вы можете использовать шаблон stack simple-hpack следующим образом: stack new mypkg simple-hpack.

Если вы используете stack для разработки, вам не нужно вручную вызывать hpack для восстановления файла .cabal с обновленный пакет package.yaml - stack сделает это автоматически.

Ответ 3

Нет простого способа:

  • вы можете использовать m4 и указывать свои зависимости один раз, но тогда вам нужно будет перерабатывать ваш файл Cabal через m4 всякий раз вы меняете его.

  • вы можете переместить код, который вы тестируете, в библиотеку, а затем указать библиотеку в вашем Build-depends для теста. Это требует, чтобы вы установили библиотеку даже для запуска теста.

  • Вы просто не можете поместить тест в файл cabal. Постройте его с помощью ghc -make, который будет тянуть зависимости. Но тогда вы теряете интеграцию с кабкой.

Ответ 4

Для файлов .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.*