cabal: how to automatically update the build-depends field in the .cabal file? - haskell

Is there a way to automatically update the build-depends field in the .cabal-file? For example, if we start with the following .cabal file:
name: HUnit
version: 1.1.1
synopsis: A unit testing framework for Haskell
homepage: http://hunit.sourceforge.net/
category: Testing
author: Dean Herington
license: BSD3
license-file: LICENSE
cabal-version: >= 1.10
build-type: Simple
library
build-depends: base >= 2 && < 4
exposed-modules: Test.HUnit.Base, Test.HUnit.Lang,
Test.HUnit.Terminal, Test.HUnit.Text, Test.HUnit
default-extensions: CPP
Then, install a package:
cabal install warp
Now, I have to add warp >=3.0 && <3.1 to the build-depends field, to make the file look like this:
name: HUnit
version: 1.1.1
synopsis: A unit testing framework for Haskell
homepage: http://hunit.sourceforge.net/
category: Testing
author: Dean Herington
license: BSD3
license-file: LICENSE
cabal-version: >= 1.10
build-type: Simple
library
build-depends: base >= 2 && < 4, warp >=3.0 && <3.1
exposed-modules: Test.HUnit.Base, Test.HUnit.Lang,
Test.HUnit.Terminal, Test.HUnit.Text, Test.HUnit
default-extensions: CPP
My question is: how do we update this file automatically?

There are two tools in modern cabal-install for aiding with managing bounds of dependencies. First is gen-bounds which suggests proper version-ranges for packages based on the specifications of versions currently installed. The second is outdated, which lists dependencies in the cabal file for which newer versions exist on hackage. Both are documented in the cabal manual: https://www.haskell.org/cabal/users-guide/developing-packages.html#generating-dependency-version-bounds

A possible alternative is to use hpack, yaml, sponge and jq:
You will need hpack package.yaml file.
For example to add aeson as a dependency:
cp package.yaml package.yaml.backup && (yaml2json package.yaml | jq '.dependencies += ["aeson"]' | json2yaml | sponge package.yaml ) && hpack

Related

Haskell cabal confused about file and module name

In my haskell project, I have the following directory structure (some entries are missing but not relevant to this problem)
- quanthas
- quanthas.cabal
- src/
- QuantHas/
- Settings.hs
My Settings.hs file contains this module header
module QuantHas.Settings(module QuantHas.Settings) where
My cabal file looks like this
Name: QuantHas
Version: 0.0
Description:
QuantHas project is an attempt to port QuantLib to Haskell keeping the functional flavor of Haskell.
License: BSD3
License-file: LICENSE
Build-Type: Simple
Cabal-Version: >=1.10
Library
Build-Depends: base >= 3 && < 5, array >= 0.2
Exposed-modules: QuantHas.Time.Frequency
QuantHas.Time.TimeUnit
QuantHas.Time.Period
QuantHas.Time.Date
QuantHas.Time.DayCounter
QuantHas.Time.BusinessDayConvention
QuantHas.Time.Calendar
QuantHas.Time.Calendars.UnitedKingdom
QuantHas.Time.Schedule
QuantHas.Settings
QuantHas.Require
default-language: Haskell2010
hs-source-dirs: src
-- ghc-options: -Wall
test-suite QuantHas-tests
type: exitcode-stdio-1.0
hs-source-dirs: testsuite
main-is: Tests.hs
default-language: Haskell2010
When I execute
cabal install --enable-tests
I get this message
src/Quanthas/Settings.hs:17:8: error:
File name does not match module name:
Saw: ‘QuantHas.Settings’
Expected: ‘Quanthas.Settings’
This seems wrong. However, what if we do what cabal expects. So the Settings.hs module header now is
module Quanthas.Settings(module Quanthas.Settings) where
Cabal now says
src/QuantHas/Settings.hs:17:8: error:
File name does not match module name:
Saw: ‘Quanthas.Settings’
Expected: ‘QuantHas.Settings’
And it's at this ppint that I give up and turn to SO. Can anyone help me understand what is going on?
Versions info:
Platform: Macbook Pro running MacOS 10.12.3
Haskell: 8.0.1
Cabal: 1.24.0.0
Thanks!
The issue is that there is a typo in one of the import statements in a different module. Since you're on a case-insensitive filesystem (OS X), GHC is able to find the module contents, but upon checking the module header finds it mismatches with the import statement and errors out.

Dependency issues running "cabal test" for Haskell

I'm running my first "cabal test" for Haskell, but I get the error:
Package has never been configured. Configuring with default flags. If this
fails, please run configure manually.
Resolving dependencies...
Configuring sample-0.1.0.0...
cabal: At least the following dependencies are missing:
base ==4.7.*
sampel.cabal:
-- Initial sample.cabal generated by cabal init. For further
-- documentation, see http://haskell.org/cabal/users-guide/
name: sample
version: 0.1.0.0
build-type: Simple
cabal-version: >=1.10
executable SampleTest
main-is: SampleTest.hs
build-depends: base >= 4.7 && <4.8, HUnit >=1.2 && <1.3
hs-source-dirs: test, src
default-language: Haskell2010
Any help appreciated.
Versions of GHC come bundled with versions of base. GHC 7.10.2 uses base 4.8.1.0.
Your cabal must be using a slightly out of date template....
You should either change the range of acceptable base version (as you did in your comment above), or use a different version of GHC.

Cabal: Does not exists in Windows 8.1

Today I installed windows 8.1 and haskell on my laptop. I'm trying to build my own haskell library, but I got an error when I try to use cabal sdist. This is the error:
D:\Development\School\AFP\Assignments\Practice\Exercise\Project>cabal sdist
Distribution quality errors:
'license: NONE' is not a recognised license. The known licenses are: GPL,
GPL-2, GPL-3, LGPL, LGPL-2.1, LGPL-3, AGPL, AGPL-3, BSD2, BSD3, MIT, ISC,
MPL-2.0, Apache, Apache-2.0, PublicDomain, AllRightsReserved, OtherLicense
Distribution quality warnings:
No 'category' field.
No 'maintainer' field.
No 'synopsis' field.
A 'license-file' is not specified.
When distributing packages it is encouraged to specify source control
information in the .cabal file using one or more 'source-repository' sections.
See the Cabal user guide for details.
Note: the public hackage server would reject this package.
Warning: Cannot run preprocessors. Run 'configure' command first.
Building source dist for Project-0.1.0.0...
cabal: does not exist
Before I used the "cabal sdist" I used the following commands:
cabal init
cabal sandbox init
cabal install -j
Every command succeed, except for the cabal sdist. The cabal install only gives the following warning:
D:\Development\School\AFP\Assignments\Practice\Exercise\Project>cabal install -j
Resolving dependencies...
In order, the following will be installed:
Project-0.1.0.0 (reinstall)
Warning: Note that reinstalls are always dangerous. Continuing anyway...
Notice: installing into a sandbox located at
D:\Development\School\AFP\Assignments\Practice\Exercise\Project\.cabal-sandbox
Configuring Project-0.1.0.0...
Building Project-0.1.0.0...
Installed Project-0.1.0.0
This is my Project.cabal file:
-- Initial Project.cabal generated by cabal init. For further
-- documentation, see http://haskell.org/cabal/users-guide/
-- Initial Project.cabal generated by cabal init. For further
-- documentation, see http://haskell.org/cabal/users-guide/
name: Project
version: 0.1.0.0
-- synopsis:
description: Education
license: NONE
-- license-file:
-- author:
-- maintainer:
-- copyright:
-- category:
build-type: Simple
extra-source-files: File6, File5, File4, File3, File2
cabal-version: >=1.10
library
exposed-modules: File1
-- other-modules:
-- other-extensions:
build-depends: base >=4.8 && <4.9, QuickCheck >=2.8 && <2.9
hs-source-dirs: src
default-language: Haskell2010
I tried google, but I can't find a good solution. I use the following versions:
Cabal version: 1.22.4.0
Haskell version: 7.10.2
If you need more information, please ask.
I don't know anything about sdist, but the problem is clear: you've specified 'NONE' as the license in your cabal file, but that is not allowed for the sdist option. configure, build, and init don't care about the specific license, but sdist apparently does.
For more info, I searched google for "cabal sdist" and found this.
This [cabal sdist] has the advantage that Cabal will do a bit more checking, and ensure that the tarball has the structure that HackageDB expects.
HackageDB probably expects a valid license, hence why "NONE" is not allowed.
The problem was that cabal could not find the files in extra-source-files. I thought I didn't had to add the extension of the haskell files, but this is required.
I also had another problem. The extra-source-files wasn't using the hs-source-dirs, so I had to explicitly write "src/" infront of a file.

Automatically List Dependencies For a Project

Given a Haskell project, is there a way to automatically calculate the entire list of dependencies? All the libraries it depends on as well as libraries that have been included but are not required.
As I said in the comments, cabal-install already does this (I'm using cabal-install 0.14.0) by guessing the packages via module lookup (like GHCi). It doesn't have any real intelligence w.r.t. versions so it just sets the version to the match major version of what you have installed.
Below you can see me making a dummy package that imports Data.Vector and cabal-install infers I am using vector 0.9.*.
[tommd#mavlo blah]$ pwd
/tmp/blah
[tommd#mavlo blah]$ cat Data/Blah.hs
module Data.Blah where
import Data.Vector
[tommd#mavlo blah]$ cabal init
Package name? [default: blah]
...SNIP...
What does the package build:
1) Library
2) Executable
Your choice? 1
Include documentation on what each field means (y/n)? [default: n]
Guessing dependencies... <--- SEE, SEE! YAY!
Generating LICENSE...
Warning: unknown license type, you must put a copy in LICENSE yourself.
Generating Setup.hs...
Generating blah.cabal...
You may want to edit the .cabal file and add a Description field.
[tommd#mavlo blah]$ cat blah.cabal
-- Initial blah.cabal generated by cabal init. For further documentation,
-- see http://haskell.org/cabal/users-guide/
name: blah
version: 0.1.0.0
synopsis: Sisponys
-- description:
-- license:
license-file: LICENSE
author: Me
maintainer: No#No.No
-- copyright:
-- category:
build-type: Simple
cabal-version: >=1.8
library
exposed-modules: Data.Blah
-- other-modules:
build-depends: base ==4.5.*, vector ==0.9.* <-- SEE?? SEE! YIPPEE!!

How to avoid recompiling in this cabal file?

I've been working on this Haskell project, and I have a cabal file for it. Now, my project is structured as a library that implements a simple interpreter. I also have a very short Main file which needs to be build into an executable to call the library. What I want to do is:
1) compile the library and expose some of the modules
2) compile the executable
I have a cabal file that works and seems to do this. The problem is that when it compiles the executable it recompiles all the modules which have already been compiled in step (1). I don't quite understand why it does this - is there any way to stop it, short of creating two separate cabal files?
I don't really want to create two separate cabal files, because cabal doesn't seem to like having both the cabal files in the same directory, and I don't really want to set up a separate project directory for the second step, since it basically just amounts to compiling a single file.
cabal-version: >= 1.6
build-type: Simple
name: HaSC
version: 0.2.3
license: OtherLicense
category: Language
author: Chris B
maintainer: Chris B
copyright: Chris B 2010 - 2011
synopsis: (HA)skell (S)ound (C)hange applier (HaSC) library
description: HaSC implements a little language for applying sound changes to words
homepage: http://www.chrisdb.me.uk/redmine/projects/haskell-sound-change
stability: Alpha
data-files: doc/HaSCDoc.pdf
license-file: LICENSE
library
build-depends:
base >= 4.3,
containers >= 0.3,
parsec >= 3,
parallel >= 3.1,
deepseq >= 1.1,
mtl >= 1.1,
transformers >= 0.2,
text >= 0.10,
text-icu >= 0.6.3,
pretty >= 1,
directory >= 1.1,
filepath >= 1.2
hs-source-dirs: src
exposed-modules: HaSC.IO.Disk,
HaSC.IO.Memory,
HaSC.Exec
other-modules: HaSC.AST,
HaSC.IO,
HaSC.IdentMap,
HaSC.Parse,
HaSC.Regex,
HaSC.Representation,
HaSC.Transformations,
HaSC.Search,
HaSC.State
executable HaSC
GHC-Options: -rtsopts
hs-source-dirs: src
main-is: Main.hs
In your executable section, add the library in Build-Depends so that the executable depends on the library.
There's a small gotcha, though: You also have to move the Main.hs of the executable (and any other source files specific to the executable) to a different subdirectory and specify a different Hs-Source-Dirs so that it doesn't pick up the library modules by being in the same folder.
executable HaSC
Build-Depends: HaSC
Main-Is: Main.hs
Hs-Source-Dirs: foo -- Directory you moved Main.hs to
For this to work, you will need to specify Cabal-Version >= 1.8. See Cabal ticket #89 for the details.

Resources