Automatically List Dependencies For a Project - haskell

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!!

Related

When does cabal recompile a module which contains Template Haskell?

I understand that cabal will recompile a module if the interface of any of its dependencies has changed. It seems that this simple rule does not hold if the module contains Template Haskell. In that case, even just adding a trailing newline character to a file in the module's (transitive) dependencies will cause the cabal to recompile the file.
Minimal example:
file: Foo.hs
module Foo where
foo = "foo"
file: FooTH.hs
{-# LANGUAGE TemplateHaskell #-}
module FooTH where
import Data.Bifunctor.TH
import Foo
data FooPair a b = FooPair a b
$(deriveBifunctor ''FooPair)
file: MCVE.cabal
name: MCVE
version: 0.1.0.0
synopsis: MCVE
license: MIT
license-file: LICENSE
author: tarleb
maintainer: tarleb#example.com
build-type: Simple
extra-source-files: CHANGELOG.md
cabal-version: >=1.10
library
exposed-modules: Foo
, FooTH
build-depends: base >=4.8 && <4.13
, bifunctors
default-language: Haskell2010
Adding a newline to Foo.hs, e.g. by running echo "\n" >> Foo.hs, will cause recompilation of module FooTH. This ceases to happen if the TH line in FooTH is commented out.
What is the reason for this, and is there a way to avoid this unnecessary recompilation?
There's a feature in Template Haskell called addDependentFile, which adds metadata to the .hi file indicating that the source file in question depends on another file as well. To my knowledge, Cabal will always ask GHC to try to build, though it may have more intelligent logic. Stack tries to bypass that process, and has logic to parse the addDependentFile information out.

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.

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

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

Trying to create cabal package: parse error on `exposed-modules`

I'm trying to create a cabal library package named foo.
The sourcefiles I'm trying to include are: A2_5.hs, A7_1.hs, A8_1.hs, profiling.hs
I have the following in my foo.cabal file:
Name: Foo
Version: 1.0
Cabal-Version: >= 1.2
Author: Chiel92
License: GPL
License-file: LICENSE
Category: Educational Assignment
Description: Description here
Build-Type: Simple
data-files: README.md
Library
Build-Depends: base, criterion
Exposed-modules: A2_5,
A7_1,
A8_1,
profiling
However, when running cabal configure I'm getting an error:
cabal: foo.cabal:14: Parse of field 'exposed-modules' failed.
What is going wrong?
EDIT: The weird thing is: when omit the profiling part, it goes fine
Omitting "profiling" makes it work because "profiling" is not a valid module name. Module names start with upper case letters.
I found the solution: when I write Profiling starting with an uppercase, it works! So apparently the modules that are exposed have to start with an uppercase, even though their filename is lowercase.

Using alex/happy with Cabal

I'm writing a compiler for a class I'm taking. The class isn't specifically Haskell but I'm using Haskell to write my compiler and interpreter. I have a cabal package setup to hopefully make it easy for my prof to run/compile. I have happy and alex in the build-tools field for both executables but Cabal ignores that and then complains that it cannot find the modules that Happy and Alex should be generating. If I manually run:
alex LimpScanner.x
happy LimpParser.y
then cabal runs perfectly.
I thought I had cabal automatically running them earlier but perhaps I remember imperfectly.
limp.cabal:
-- limp.cabal auto-generated by cabal init. For additional options,
-- see
-- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.
-- The name of the package.
Name: limp
-- The package version. See the Haskell package versioning policy
-- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for
-- standards guiding when and how versions should be incremented.
Version: 0.1
-- A short (one-line) description of the package.
Synopsis: LIMP Compiler (Compiler Construction course project)
-- A longer description of the package.
-- Description:
-- URL for the project homepage or repository.
Homepage: http://www.cs.rit.edu/~eca7215/limp/
-- The license under which the package is released.
License: AllRightsReserved
-- The file containing the license text.
License-file: LICENSE
-- The package author(s).
Author: Edward Amsden
-- An email address to which users can send suggestions, bug reports,
-- and patches.
Maintainer: eca7215#cs.rit.edu
-- A copyright notice.
-- Copyright:
Category: Language
Build-type: Simple
-- Extra files to be distributed with the package, such as examples or
-- a README.
-- Extra-source-files:
-- Constraint on the version of Cabal needed to build this package.
Cabal-version: >=1.2
Executable limp
-- .hs or .lhs file containing the Main module.
Main-is: Limp.hs
hs-source-dirs: src
-- Packages needed in order to build this package.
Build-depends: base, array, haskell98
-- Modules not exported by this package.
-- Other-modules:
-- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source.
Build-tools: alex, happy
Executable limpi
Main-is: LimpInterpreter.hs
hs-source-dirs: src
Build-depends: base, array, haskell98
Build-tools: alex, happy
Directory layout:
limp/
├── Setup.hs
├── limp.cabal
└── src/
├── Limp.hs
├── LimpInterpreter.hs
├── LimpParser.ly
├── LimpScanner.x
└── LimpToken.hs
For Warren Harris and others like him (and myself) that may come along later, other-modules needs to be set to a list of module names that (I guess?) are expected to be built by the tools listed in build-tools.
So, in my case, the relevant sections of my .cabal file ended up looking like this:
build-tools: alex, happy
other-modules: Language.Heidi.Parser,
Language.Heidi.Lexer
Apparently what I was missing was actually the Other-modules: field. Once this was added, cabal happily (pardon the pun) built my interpreter.

Resources