Generating documentation for my own code with Haddock and stack - haskell

I have annotated my code in Haddock style and would like to generate browse-able documentation. Since I am also using stack, I want to integrate the documentation generation into the workflow. However, I have not yet been able to generate anything useful.
I can run
stack haddock
and it will generate documentation in the style I want (to be found deep inside ~/.stack/), but it only seems to generate documentation for the packages I depend on, rather than for my own code.
When I run
stack haddock --help
I get the impression that I can use the additional argument --haddock to generate documentation for my own project, and --no-haddock-deps to leave out the documentation for my dependencies. However, when I run
stack haddock --haddock --no-haddock-deps
nothing seems to happen. If I stack clean first it will recompile all my code but no output is generated seeming to relate in any way to documentation.
As an intermediate solution I have also tried running Haddock by itself, i.e.
haddock my-source.hs
but then I get an error that it cannot find a module the file depends on (which is installed locally by stack). This gives me the impression that documentation generation will have to go through stack somehow. I have looked for, but not really found any explanations related to configuring my .cabal and stack.yaml files for documentation.
TL;DR
How can I use stack and Haddock to generate documentation for the code in my own package?

According to this ticket on the stack issue tracker, Stack can currently only build documentation for libraries, but not executables.
Cabal can be configured to work with the stack databases with this command:
cabal configure --package-db=clear --package-db=global --package-db=$(stack path --snapshot-pkg-db) --package-db=$(stack path --local-pkg-db)
after which you can run cabal haddock --executables to generate the documentation.
By the way, stack haddock is only a shortcut for stack build --haddock, so there is no need to write stack haddock --haddock.

https://www.reddit.com/r/haskell/comments/5ugm9s/how_to_generate_haddock_docs_for_nonlibrary_code/ddtwqzc/
The following solution only works when individual files are specified:
stack exec -- haddock --html src/Example.hs src/Main.hs --hyperlinked-source --odir=dist/docs

Related

module ‘main:Main’ is defined in multiple files

I have tried to load a file by typing ghc Interact Interact.hs
This produces the following error:
<no location info>: error:
module ‘main:Main’ is defined in multiple files: Interact.hs
Interact.hs``
I therefore searched on stack overflow and found the answers here (stack ghci with error module ‘main:Main’ is defined in multiple files:) which seem relevant.
However, unfortunately, they are undecipherable for the uninitiate, taking for granted concepts that I do not have at my disposal. For example, what are the following two sentences even suggesting?
I would run Stack with --verbose and see how GHCi is being invoked, and double-check the package.yaml and generated Cabal file. (If you edit your question to include that, we may be able to offer more specific help with it.)
I don't know what it means to check a package or a generated Cabal file (nor what a generated cabal file in). There is not definition of what is meant by 'invoked'.
I'm sure that the answers in the link above are very useful to those who already possess the requisite concepts. But to the uninitiated, they don't help.
Can someone please provide answers which clarify the particular questions I have above, so that I can understand the information provided in stack ghci with error module ‘main:Main’ is defined in multiple files:?
I typed stack --verbose into the terminal and this produced
Missing: COMMAND|FILE
Usage: stack [--help] [--version] [--numeric-version] [--hpack- numeric-version]
[--docker*] [--nix*] ([--verbosity VERBOSITY] | [-v|--verbose] |
[--silent]) [--[no-]time-in-log] [--stack-root STACK-ROOT]
[--work-dir WORK-DIR] [--[no-]system-ghc] [--[no-]install-ghc]
[--arch ARCH] [--ghc-variant VARIANT] [--ghc-build BUILD]
[-j|--jobs JOBS] [--extra-include-dirs DIR] [--extra-lib-dirs DIR]
[--with-gcc PATH-TO-GCC] [--with-hpack HPACK]
[--[no-]skip-ghc-check] [--[no-]skip-msys] [--local-bin-path DIR]
[--[no-]modify-code-page] [--[no-]allow-different-user]
[--[no-]dump-logs] [--resolver RESOLVER] [--compiler COMPILER]
[--[no-]terminal] [--color WHEN] [--terminal-width INT]
[--stack-yaml STACK-YAML] COMMAND|FILE
You gave GHC the same file twice. GHC will automatically try finding a file by adding appropriate file extensions, so when you gave it Interact it found Interact.hs once, then you gave it the same file again.
I'm not sure what you were trying to achieve with your command. If you are trying to add a directory called Interact that GHC will search for modules, you want ghc -iInteract Interact.hs. If you are trying to name the binary that GHC outputs, you want ghc -o Interact Interact.hs (but that would be the default name anyway, so in that case you might as well just use ghc Interact.hs).
The stack documentation is probably irrelevant to you since you are using ghc directly.

linking rather than building in stack/cabal

question:
What do I have to do in the .cabal file in order to cause the libraries to link rather than build?
background:
I am trying to get coverage details from the command stack test --coverage
when I run this build I get the error message
Error: The coverage report for xmonad's test-suite "properties" did not consider any code. One possible cause of this is if your test-suite builds the library code (see stack issue #1008). It may also indicate a bug in stack or the hpc program. Please report this issue if you think your coverage report should have meaningful results.
Only one tix file found in /home/paul/temp/xmonad_coverage/.stack-work/install/x86_64-linux/09c83ca90bc1875ad3d1b5ea4a2a0c369c6367f3ad989533e627c073ee9962e0/8.0.1/hpc/, so not generating a unified coverage report.
on the stack documentation site, https://docs.haskellstack.org/en/stable/coverage/, it says that in order to run coverage I must have :
These test-suites link against your library, rather than building the
library directly. Coverage information is only given for libraries, ignoring
the modules which get compiled directly into your executable. A common case
where this doesn't happen is when your test-suite and library both have
something like hs-source-dirs: src/. In this case, when building your test-
suite you may also be compiling your library, instead of just linking against
it.
when I look in my .cabal file for the library there is
hs-source-dirs: src
and for test there is.
hs-source-dirs: tests
I don't understand the purpose of these and whether these are causing the library to build rather than be linked to.
could this be the reason that stack test --coverage is failing? or am I looking in the wrong place?
Turns out that I could fix this by doing the following:
stack clean; stack build; stack test --coverage --ghc-options "-fforce-recomp"
as described by Michael Sloan at https://github.com/commercialhaskell/stack/issues/1305
his explanation for a similar problem was:
Looks like what's happening is that the library isn't getting rebuilt, despite
reconfiguring with --ghc-options -fhpc and building the package. As a result, the .tix
file generated by the test only includes coverage info for the test itself

How to exclude dependencies when building haddocks?

Is there any way to build haddock docs for specific packages? I'm trying to build haddocks for my package/app alone, but the following command seems to be doing this for all dependencies, as well:
stack haddock webservice
(where webservice is the name of my package/app)
The flag you're looking for is --no-haddock-deps as in
stack haddock --no-haddock-deps webservice

Both versions of the gtk package are visible when running `stack ghc`

A minimal reproduction can be found here:
https://github.com/IvanMalison/stack-gtk2hs-bug
Everything works as expected when I use normal stack commands, but when I run the failing command:
stack ghc -- --make main.hs
I get the following error:
main.hs:3:1: error:
Ambiguous interface for ‘Graphics.UI.Gtk’:
it was found in multiple packages: gtk-0.14.6 gtk3-0.14.6
main.hs:4:1: error:
Ambiguous interface for ‘Graphics.UI.Gtk.Abstract.Widget’:
it was found in multiple packages: gtk-0.14.6 gtk3-0.14.6
main.hs:5:1: error:
Ambiguous interface for ‘Graphics.UI.Gtk.Layout.Table’:
it was found in multiple packages: gtk-0.14.6 gtk3-0.14.6
The output of stack exec ghc-pkg -- --no-user-package-db list is https://gist.github.com/f19f900988f49e4d03cd61f1cab48baa . This output makes me expect that the reason that this is happening is that some other stack install required gtk (not gtk3 which is what is specified as a dependency in this package) and somehow this package is visible from the stack ghc command for some reason.
Am I misunderstanding the stack ghc command? Shouldn't this essentially do the same thing as stack build?
There's no builtin way to do this with stack currently. However, it is possible to get stack ghci to do this. The most straightforward way to do it is to make a cabal package which has the executable target. However, if you really want to just use straight ghc, there is a way. Copy-pasting from my comment here:
stack ghc works a bit differently than stack ghci. It's essentially a synonym for stack exec -- ghc, which will run the right compiler with the right databases, but won't set up anything related to your local packages like include directories etc. Note that stack ghci takes TARGET arguments whereas stack ghc does not. Retrospectively, this is a bit inconsistent, but stack ghc came before stack ghci.
It does make sense to have the ability to do something like this, though not sure how to best achieve that. Some potential options:
--no-interactive argument on stack ghci. Would be a bit obtuse. Weird to run a ghci command when, though it would be using the stack ghci logic.
Add --target TARGET option to stack ghc, to tell it to use the environment of a particular local package target.
Here's a workaround for now. Put the following in ~/.local/bin/stack-run-ghc.sh and make it user executable:
#/bin/sh
ghc $(echo "$*" | sed 's/--interactive//g')
This takes the arguments, removes --interactive, and calls ghc. With this, I can build stack using ghc via the following:
stack ghci --with-ghc stack-run-ghc.sh --ghci-options src/main/Main.hs

Stack not resolving dependencies properly

I'm trying to set up Hakyll on a fresh Ubuntu 16.04 instance, but I can't seem to get the Stack-based setup instructions right.
Starting out with stack install hakyll, I get:
Error: While constructing the build plan, the following exceptions were encountered:
In the dependencies for hakyll-4.9.3.0:
http-conduit-2.1.11 must match >=2.2 && <2.3 (latest applicable is 2.2.3)
Plan construction failed.
I got a similar error when tying to stack-install http-conduit-2.1.11, this time with:
Error: While constructing the build plan, the following exceptions were encountered:
In the dependencies for http-conduit-2.2.3:
http-client-0.4.31.2 must match >=0.5 && <0.6 (latest applicable is 0.5.5)
http-client-tls-0.2.4.1 must match >=0.3 && <0.4 (latest applicable is 0.3.3.1)
Plan construction failed.
After resolving dependencies for this (also using Stack), I tried once again to stack install http-conduit-2.1.11, but I once again got the same dependency error.
The packages http-client-0.4.31.2 and http-client-tls-0.2.4.1 appear in my ~/.stack/precompiled/x86_64-linux/ghc-8.0.1/1.24.0.0/, which isn't explicitly in my $PATH, however that feels like an extremely hacky solution, and I haven't found any documentation recommending this approach.
How can I correctly install Hakyll on my machine?
Dependency management with stack is meant to be reproducible and declarative, that means that a stack project will only compile once all dependencies are recorded in the .cabal file(s) of the project and once the stack.yaml of the project defines versions for these dependencies either in the resolver or the extra-deps section.
Your confusion seems to stem from a misunderstanding of what stack install does. The command line help has this to say about it:
build Build the package(s) in this directory/configuration
install Shortcut for 'build --copy-bins'
...
--[no-]copy-bins Enable/disable copying binaries to the local-bin-path
(see 'stack path')
stack install does not save any dependencies.
So the proper way of making hakyll available as a dependency to your code is:
Create a proper stack project with stack init if you already have a Cabal package, or stack new if you don't.
Add hakyll to the library or executable build-depends in your .cabal file.
Attempt to stack build and follow the instructions in any error messages until all issues are resolved.
A simpler solution than #sjakobi's in this case was to specify a resolver as a command line option when starting a new Stack project:
stack install hakyll --resolver=5.11 --install-ghc

Resources