| Version 2 (modified by duncan, 13 months ago) |
|---|
This page is for trying to clarify some ideas and design for cabal handling sets of packages people want to build.
Goal
Recently people have written various cabal extension/wrapper tools to address use cases that the main Cabal/cabal-install tool does not handle very well. These tools are each designed to address a few use cases, and the different tools overlap somewhat in what they cover.
The goal here is:
- to see if we can identify some more unified idea and explain what the various existing tools are trying to do in terms of that idea;
- then to come up with a design (mechanisms) that implements that idea; and
- a user interface that covers the main use cases in a reasonably simple way, but hopefully sufficiently flexible to expose what the design can do
Example use cases
Developer working on a single package
The developer is actively developing a package. The package is in some intermediate state i.e. it doesn't make sense for other, not-in-development projects to depend on it (e.g. it might be buggy, have an unstable API at the moment.) The developer might want, in addition to building the package, to run tests and/or benchmarks.
Current workflow (assuming that cabal repl exists): cabal configure --enable-tests --enable-benchmarks cabal install --only-dependencies # does this pull in test/benchmark deps? cabal build -or cabal build && cabal test -or- cabal build && cabal benchmark -or- cabal repl
Problems with current workflow:
- Dependencies might be added/removed during development, forcing the developer to re-run configure --enable-tests --enable-benchmarks, cabal install --only-dependencies.
- It's not possible to build the package without configuring it and install its dependencies, thus those should be implied by build.
- It's not possible to run tests/benchmarks without first building the package, so building should be implied by running cabal test/bench.
Ideal workflow:
cabal build -or- cabal test -or- cabal bench -or- cabal repl
Developer working on multiple packages
Like "Developer working on a single package", except the developer also has to change one or more dependencies in order to make the current package work e.g. perhaps he/she needs to add a new function to one of the dependencies and use it in the package under development. The dependencies might not be owner by the developer so he/she can't simply change them and make a new release. He/she needs to use the modified version until the changes have been accepted upstream.
Current workflow:
cd dep cabal configure && cabal build cd pkg cabal configure --package-db=../dep/dist/package.conf.inplace # Like previous use case when it comes to running tests, install other dependencies, etc.
Problems with current workflow:
- Every time the package depended upon needs to be changed, the four steps above have to be repeated.
- Otherwise the same as in "Developer working on a single package"
Ideal workflow (UI up for discussion):
cabal build --package-root=$HOME/src # Looks for additional packages here
Similar for cabal test, cabal bench, and cabal repl
Existing tools
cabal-dev
- http://hackage.haskell.org/package/cabal-dev
- https://github.com/creswick/cabal-dev/blob/master/README.md
cabal-src
- http://hackage.haskell.org/package/cabal-src
- https://github.com/yesodweb/cabal-src/blob/master/README.md
cabal-meta
cab
virthualenv
- http://hackage.haskell.org/package/virthualenv
- https://github.com/Paczesiowa/virthualenv/blob/master/README.md
Package environments ideas
Roles: The package author and package builder are distinct roles (though in many use cases the same individual may fill both roles):
- The package author specifies information in the package .cabal file.
- The package environment is controlled by the person/agent doing the build.
A package environment consists of:
- source package set
- installed package store
- constraints for package versions and flags
- other build configuration (profiling, optimisation, C lib locations etc)
The source package set is a finite mapping of source package id to a location where we can find a source package. This includes references to source tarballs (remotely or locally) and references to local build trees.
The installed package store is a location where packages are installed, plus a package database where installed packages are registered.
The constraints include:
- package version constraints, like "foo == 1.0"
- configuration flags for particular packages (that is the "flags" stuff in .cabal files)
- enabling/disabling of test suites or benchmarks
These constraints influence which source packages can be used and the configuration influence what the dependencies of those packagea are.
Other build configuration includes most of the other command line flags that package builders can currently specify when they do cabal configure:
- enable/disable profiling
- dynamic or static linking
- where to look for C libraries
- optimisation settings
- etc
Mechanisms for an implementation
The existing hackage index format gives us a source package set but has the limitation that it cannot refer to local build trees. It is relatively straightfoward to generalise the existing hackage index format to make it possible to refer to local tarballs or directories.
TODO: what about references to repositories (darcs, git etc) ?
