Hpack
hpack: A modern format for Haskell packages
Install / Use
/learn @sol/HpackREADME
hpack: A modern format for Haskell packages
Hpack is a format for Haskell packages. It is a modern alternative to the Cabal package format and follows different design principles.
Design principles
The guiding design principles for Hpack are:
- Don't require the user to state the obvious, make sensible assumptions by default
- Give the user 100% control when needed
- Don't require the user to repeat things, facilitate DRYness
Tool integration
Hpack packages are described in a file named package.yaml. Both
cabal2nix and
stack support package.yaml natively. For
other build tools the hpack executable can be used to generate a .cabal
file from package.yaml.
There is no user guide
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
- Given this package.yaml running
hpackwill generate hpack.cabal - Given this package.yaml running
hpackwill generate getopt-generics.cabal - Given this package.yaml running
hpackwill generate sensei.cabal - Given this package.yaml running
hpackwill generate base-orphans.cabal
Documentation
<!--ts-->- hpack: A modern format for Haskell packages
Handling of Paths_ modules
Cabal generates a Paths_ module for every package. How exactly Hpack behaves
in regards to that module depends on the value of the spec-version field.
If the spec-version is explicitly specified and at least 0.36.0 the modern
behavior is used, otherwise Hpack falls back to the legacy behavior.
To use the modern behavior, require at least
spec-version: 0.36.0
in your package.yaml.
Modern behavior
If you want to use the Paths_ module for a component, you have to explicitly
specify it under generated-other-modules.
Example:
library:
source-dirs: src
generated-other-modules: Paths_name # substitute name with the package name
Legacy behavior
For historic reasons Hpack adds the Paths_ module to other-modules when
generating a .cabal file.
To prevent Hpack from adding the Paths_ module to other-modules add the
following to package.yaml:
library:
when:
- condition: false
other-modules: Paths_name # substitute name with the package name
Quick-reference
Top-level fields
| Hpack | Cabal | Default | Notes | Example | Since |
| --- | --- | --- | --- | --- | --- |
| spec-version | | | The minimum version of hpack that is required to parse this package description. | spec-version: 0.30.0 | 0.30.0 |
| name | · | | | | |
| version | · | 0.0.0 | | | |
| synopsis | · | | | | |
| description | · | | | | |
| category | · | | May be a list (since 0.38.3) | | |
| stability | · | | | | |
| homepage | · | If github given, <repo>#readme | | | |
| bug-reports | · | If github given, <repo>/issues | | | |
| author | · | | May be a list | | |
| maintainer | · | author | May be a list | | |
| copyright | · | | May be a list | |
| license | · | Inferred from license-file | Both SPDX license expressions and traditional Cabal license identifiers are accepted. | license: MIT | SPDX: 0.29.0 |
| license-file | license-file or license-files | LICENSE if file exists | May be a list | | |
| tested-with | · | | May be a list (since 0.34.3) | | |
| build-type | · | Simple, or Custom if custom-setup exists | Must be Simple, Configure, Make, or Custom | | |
| extra-source-files | · | | Accepts glob patterns | | |
| extra-doc-files | · | | Accepts glob patterns | | 0.21.2 |
| extra-files | · | | Accepts glob patterns | | 0.38.1 |
| data-files | · | | Accepts glob patterns | | |
| data-dir | · | | | | |
| github | source-repository head | | Accepts owner/repo or owner/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 | | |
| internal-libraries | library <name> | | Map from internal library name to a dict of library fields and global top-level fields. | | 0.21.0 |
| 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) | | |
| defaults | | | See Defaults, may be a list | | |
cabal-version
Hpack does not require you to specify a cabal-version manually. When
generating a .cabal file, Hpack sets the cabal-version automatically based
on the features that are used.
If you want to override this behavior you can use verbatim to set
cabal-version manually, e.g.:
verbatim:
cabal-version: 2.2
Defaults
Hpack allows the inclusion of common fields from a file on GitHub or a local file.
To use this feature a user must specify a GitHub repository, Git reference and a path to a file within that repository; alternatively, a path to the local file must be given.
Example:
defaults:
github: sol/hpack-template
ref: 2017
path: defaults.yaml
This will include all common fields from https://github.com/sol/hpack-template/blob/2017/defaults.yaml into the package specification.
| Field | Default | Notes | Example |
| ----- | ------- | ----- | ------- |
| github | For github defaults. | Accepts <owner>/<repo> | github: sol/hpack-template |
| ref | | For github defaults. | ref: 2017 |
| path | .hpack/defaults.yaml | For github defaults. A relative path to a file within the repository, path segments are separated by / and must not contain : and \. | path: defaults.yaml |
| local | | For local defaults. New in 0.26.0. | |
Exactly one of github and local must be given in a defaults section.
Hpack supports shorthand syntax for specifying github and ref as a string:
defaults: sol/hpack-template@2017
This is equivalent to:
defaults:
github: sol/hpack-template
ref: 2017
Note: Hpack caches downloaded files under
~/.hpack/defaults/<owner>/<repo>/<path>. Once downloaded, a file is reused
from the cache. If the content on GitHub changes the file is not updated. For
this reason it is recommended to only use tags as Git references.
-
If a defaults file has changed on GitHub and you want to use the latest version, then you have to delete that file from the cache manually.
-
If you want to prevent Hpack from accessing the network to downloa
