1
1
mirror of https://github.com/sol/hpack.git synced 2024-10-04 11:47:15 +03:00
hpack: A modern format for Haskell packages
Go to file
2017-10-28 07:24:44 +08:00
driver Expose main driver as a library 2016-02-05 21:17:11 +08:00
src Accept section-specific fields in conditionals (fix #116, close #175) 2017-10-27 17:53:31 +08:00
test Accept section-specific fields in conditionals (fix #116, close #175) 2017-10-27 17:53:31 +08:00
.ghci aeson 0.10.0 compatibility 2015-09-22 16:45:31 +08:00
.gitignore Add .stack-work to .gitignore. 2017-05-18 15:56:29 -07:00
.travis-setup.sh Build with stack also 2016-02-21 15:38:43 +02:00
.travis.yml Update travis-ci config 2017-09-30 23:12:04 +08:00
appveyor.yml Add appveyor.yml (thx @phadej) 2016-02-26 07:39:42 +08:00
CHANGELOG.md Update CHANGELOG 2017-10-28 07:24:44 +08:00
hpack.cabal Add end-to-end tests 2017-10-26 21:26:23 +08:00
LICENSE Refactoring 2016-03-27 09:45:26 +08:00
package.yaml GHC 7.8.* compat 2017-10-26 21:15:46 +08:00
README.md Add frameworks and extra-frameworks-dirs fields 2017-10-11 19:32:02 -07:00
Setup.lhs Add Setup.lhs 2014-12-24 12:01:07 +08:00
stack.yaml Require HUnit >= 1.6.0.0 2017-09-26 10:39:19 +08:00

hpack: An alternative format for Haskell packages

The Hpack package format is based on YAML. Packages are described in a file named package.yaml.

Hpack is designed to remove redundancies from your package descriptions.

There is reference documentation below, but introductory documentation is still lacking. For the time being, take a look at the slides from my talk about Hpack at the Singapore Haskell meetup: http://typeful.net/talks/hpack

Examples

Documentation

Getting started

One easy way of getting started is to use hpack-convert to convert an existing cabal file into a package.yaml.

Quick-reference

Top-level fields

Hpack Cabal Default Notes Example Since
name ·
version · 0.0.0
synopsis ·
description ·
category ·
stability ·
homepage · If github given, <repo>#readme
bug-reports · If github given, <repo>/issues
author · May be a list
maintainer · May be a list
copyright · May be a list
license ·
license-file license-file or license-files LICENSE if file exists May be a list
tested-with ·
build-type · Simple, or Custom if custom-setup section exists Must be Simple, Configure, Make, or Custom
cabal-version >= 1.10 or >= 1.21 >= 1.21 if library component has reexported-modules field
extra-source-files · Accepts glob patterns
data-files · Accepts glob patterns
github source-repository head Accepts user/repo or user/repo/subdir github: foo/bar
git source-repository head No effect if github given git: https://my.repo.com/foo
custom-setup · See Custom setup
flags flag <name> Map from flag name to flag (see Flags)
library · See Library fields
executables executable <name> Map from executable name to executable (see Executable fields)
executable executable <package-name> Shortcut for executables: { package-name: ... } 0.18.0
tests test-suite <name> Map from test name to test (see Test fields)
benchmarks benchmark <name> Map from benchmark name to benchmark (see Benchmark fields)

Custom setup

Hpack Cabal Default Notes Example
dependencies setup-depends Implies build-type: Custom

Global top-level fields

These fields are merged with all library, executable, test, and benchmark components.

Hpack Cabal Default Notes
source-dirs hs-source-dirs
default-extensions ·
other-extensions ·
ghc-options ·
ghc-prof-options ·
ghcjs-options ·
cpp-options ·
cc-options ·
c-sources · Accepts glob patterns
js-sources · Accepts glob patterns
extra-lib-dirs ·
extra-libraries ·
include-dirs ·
install-includes ·
frameworks ·
extra-frameworks-dirs ·
ld-options ·
buildable · May be overridden by later stanza
dependencies build-depends
build-tools ·
when Accepts a list of conditionals (see Conditionals)

Library fields

Hpack Cabal Default Notes
exposed ·
exposed-modules · All modules in source-dirs less other-modules
other-modules · All modules in source-dirs less exposed-modules
reexported-modules ·
default-language Haskell2010

Executable fields

Hpack Cabal Default Notes
main main-is
other-modules ·
default-language Haskell2010

Test fields

Hpack Cabal Default Notes
type exitcode-stdio-1.0
main main-is
other-modules ·
default-language Haskell2010

Benchmark fields

Hpack Cabal Default Notes
type exitcode-stdio-1.0
main main-is
other-modules ·
default-language Haskell2010

Flags

Hpack Cabal Default Notes
description · Optional
manual · Required (unlike Cabal)
default · Required (unlike Cabal)

Conditionals

Conditionals with no else branch:

  • Must have a condition field
  • May have any number of other fields

For example,

when:
  - condition: os(darwin)
    extra-lib-dirs: lib/darwin

becomes

if os(darwin)
  extra-lib-dirs:
    lib/darwin

Conditionals with an else branch:

  • Must have a condition field
  • Must have a then field, itself an object containing any number of other fields
  • Must have a else field, itself an object containing any number of other fields
  • All other top-level fields are ignored

For example,

when:
  - condition: flag(fast)
    then:
      ghc-options: -O2
    else:
      ghc-options: -O0

becomes

if flag(fast)
  ghc-options: -O2
else
  ghc-options: -O0

File globbing

At place where you can specify a list of files you can also use glob patterns. Glob patters and ordinary file names can be freely mixed, e.g.:

extra-source-files:
  - static/*.js
  - static/site.css

Glob patterns are expanded according to the following rules:

  • ? and * are expanded according to POSIX (they match arbitrary characters, except for directory separators)
  • ** is expanded in a zsh-like fashion (matching across directory separators)
  • ?, * and ** do not match a . at the beginning of a file/directory

Not repeating yourself

It is possible to use YAML anchors (&), aliases (*) and merge keys (<<) to define fields and reference them later.

executables:
  my-exe-1: &my-exe
    main: my-exe-1.hs
    dependencies: [base, my-lib]
    ghc-options: [-threaded]
  my-exe-2:
    <<: *my-exe
    main: my-exe-2.hs

Warnings for unknown fields will not be emitted for top-level fields starting with an underscore, so you can declare global aliases too:

_exe-ghc-options: &exe-ghc-options
  - -threaded
  - -rtsopts

executables:
  my-exe-1:
    ghc-options: *exe-ghc-options

It is also possible to use the !include directive:

# ...

tests:
  hlint: !include "../common/hlint.yaml"

hlint.yaml:

source-dirs: test
main: hlint.hs
dependencies: [base, hlint]

This can also be used to provide entire libraries of snippets:

_common/lib: !include "../common/lib.yaml"

name: example1
version: '0.1.0.0'
synopsis: Example
<<: *legal

<<: *defaults

library:
  source-dirs: src

tests:
  hlint: *test_hlint

lib.yaml:

- &legal
  maintainer: Some One <someone@example.com>
  copyright: (c) 2017 Some One
  license: BSD3

- &defaults
  dependencies:
    - base
    - containers
  ghc-options:
    - -Wall
    - -Werror

- &test_hlint
  source-dirs: test
  main: hlint.hs
  dependencies: [hlint]

Vim integration

To run hpack automatically on modifications to package.yaml add the following to your ~/.vimrc:

autocmd BufWritePost package.yaml silent !hpack --silent

Stack support

Stack has built-in support for Hpack. If you are using Stack you can use package.yaml instead of a .cabal file. No additional steps are required.