From 063657a6871ffcfc5b441223724decb1eb34dbeb Mon Sep 17 00:00:00 2001 From: BinderDavid <dbinder1989@googlemail.com> Date: Tue, 18 Oct 2022 15:43:43 +0000 Subject: [PATCH] Add initial sphinx documentation in docs/ subdirectory. --- README.md | 7 +- docs/.gitignore | 1 + docs/Makefile | 20 +++++ docs/about.rst | 41 ++++++++++ docs/conf.py | 28 +++++++ docs/examples.rst | 91 ++++++++++++++++++++++ docs/hpc.rst | 191 ++++++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 13 ++++ docs/make.bat | 35 +++++++++ 9 files changed, 426 insertions(+), 1 deletion(-) create mode 100644 docs/.gitignore create mode 100644 docs/Makefile create mode 100644 docs/about.rst create mode 100644 docs/conf.py create mode 100644 docs/examples.rst create mode 100644 docs/hpc.rst create mode 100644 docs/index.rst create mode 100644 docs/make.bat diff --git a/README.md b/README.md index 9b73d8f..3376f95 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ # Haskell Program Coverage -This repository provides the `hpc` binary which produces coverage reports in various formats from .tix and .mix files. \ No newline at end of file +This repository provides the `hpc` binary which produces coverage reports in various formats from .tix and .mix files. + +## Documentation + +The documentation of the `hpc-binary` is available online on readthedocs (TODO). +In order to build the documentation locally, you have to install the [sphinx](https://www.sphinx-doc.org/en/master/) documentation generator on your machine, as well as the `sphinx_rtd_theme`, and invoke `make html` in the `docs/` subdirectory. \ No newline at end of file diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..c6a151b --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +_build/ \ No newline at end of file diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d4bb2cb --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/about.rst b/docs/about.rst new file mode 100644 index 0000000..8ac3869 --- /dev/null +++ b/docs/about.rst @@ -0,0 +1,41 @@ +.. _about: + +Observing Code Coverage with HPC +================================ + +Code coverage tools allow a programmer to determine what parts of their +code have been actually executed, and which parts have never actually +been invoked. GHC has an option for generating instrumented code that +records code coverage as part of the Haskell Program Coverage (HPC) +toolkit, which is included with GHC. HPC tools can be used to render the +generated code coverage information into human understandable format. + +Correctly instrumented code provides coverage information of two kinds: +source coverage and boolean-control coverage. Source coverage is the +extent to which every part of the program was used, measured at three +different levels: declarations (both top-level and local), alternatives +(among several equations or case branches) and expressions (at every +level). Boolean coverage is the extent to which each of the values True +and False is obtained in every syntactic boolean context (ie. guard, +condition, qualifier). + +HPC displays both kinds of information in two primary ways: textual +reports with summary statistics (``hpc report``) and sources with color +mark-up (``hpc markup``). For boolean coverage, there are four possible +outcomes for each guard, condition or qualifier: both True and False +values occur; only True; only False; never evaluated. In hpc-markup +output, highlighting with a yellow background indicates a part of the +program that was never evaluated; a green background indicates an +always-True expression and a red background indicates an always-False +one. + +About hpc-bin +============= + +The HPC binary is a tool for generating coverage reports in various output formats for Haskell projects. +The latest source code lives in the `git repository <https://gitlab.haskell.org/hpc/hpc-bin>`__ on ``GitLab``. + +Reporting bugs in Hpc +===================== + +Please report bugs on the `Hpc-bin issue tracker <https://gitlab.haskell.org/hpc/hpc-bin/-/issues>`__. diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..612d6a7 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,28 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +import sphinx_rtd_theme +project = 'hpc-bin' +copyright = '2022, Andy Gill, Colin Runciman' +author = 'Andy Gill, Colin Runciman' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = ['sphinx_rtd_theme'] + +templates_path = ['_templates'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = 'sphinx_rtd_theme' +html_static_path = ['_static'] diff --git a/docs/examples.rst b/docs/examples.rst new file mode 100644 index 0000000..cab4d20 --- /dev/null +++ b/docs/examples.rst @@ -0,0 +1,91 @@ +.. _examples: + +A small example: Reciprocation +============================== + +For an example we have a program, called :file:`Recip.hs`, which computes +exact decimal representations of reciprocals, with recurring parts +indicated in brackets. :: + + reciprocal :: Int -> (String, Int) + reciprocal n | n > 1 = ('0' : '.' : digits, recur) + | otherwise = error + "attempting to compute reciprocal of number <= 1" + where + (digits, recur) = divide n 1 [] + divide :: Int -> Int -> [Int] -> (String, Int) + divide n c cs | c `elem` cs = ([], position c cs) + | r == 0 = (show q, 0) + | r /= 0 = (show q ++ digits, recur) + where + (q, r) = (c*10) `quotRem` n + (digits, recur) = divide n r (c:cs) + + position :: Int -> [Int] -> Int + position n (x:xs) | n==x = 1 + | otherwise = 1 + position n xs + + showRecip :: Int -> String + showRecip n = + "1/" ++ show n ++ " = " ++ + if r==0 then d else take p d ++ "(" ++ drop p d ++ ")" + where + p = length d - r + (d, r) = reciprocal n + + main = do + number <- readLn + putStrLn (showRecip number) + main + +HPC instrumentation is enabled with the `-fhpc` flag: + +.. code-block:: sh + + $ ghc -fhpc Recip.hs + +GHC creates a subdirectory ``.hpc`` in the current directory, and puts +HPC index (``.mix``) files in there, one for each module compiled. You +don't need to worry about these files: they contain information needed +by the ``hpc`` tool to generate the coverage data for compiled modules +after the program is run. + +.. code-block:: sh + + $ ./Recip + 1/3 + = 0.(3) + +Running the program generates a file with the ``.tix`` suffix, in this +case :file:`Recip.tix`, which contains the coverage data for this run of the +program. The program may be run multiple times (e.g. with different test +data), and the coverage data from the separate runs is accumulated in +the ``.tix`` file. To reset the coverage data and start again, just +remove the ``.tix`` file. + +Having run the program, we can generate a textual summary of coverage: + +.. code-block:: none + + $ hpc report Recip + 80% expressions used (81/101) + 12% boolean coverage (1/8) + 14% guards (1/7), 3 always True, + 1 always False, + 2 unevaluated + 0% 'if' conditions (0/1), 1 always False + 100% qualifiers (0/0) + 55% alternatives used (5/9) + 100% local declarations used (9/9) + 100% top-level declarations used (5/5) + +We can also generate a marked-up version of the source. + +.. code-block:: none + + $ hpc markup Recip + writing Recip.hs.html + +This generates one file per Haskell module, and 4 index files, +:file:`hpc_index.html`, :file:`hpc_index_alt.html`, :file:`hpc_index_exp.html`, +:file:`hpc_index_fun.html`. diff --git a/docs/hpc.rst b/docs/hpc.rst new file mode 100644 index 0000000..81921fb --- /dev/null +++ b/docs/hpc.rst @@ -0,0 +1,191 @@ +.. _hpc: + + +Hpc reference +============= + +The hpc command has several sub-commands: + +.. code-block:: none + + $ hpc + Usage: hpc COMMAND ... + + Commands: + help Display help for hpc or a single command + Reporting Coverage: + report Output textual report about program coverage + markup Markup Haskell source with program coverage + Processing Coverage files: + sum Sum multiple .tix files in a single .tix file + combine Combine two .tix files in a single .tix file + map Map a function over a single .tix file + Coverage Overlays: + overlay Generate a .tix file from an overlay file + draft Generate draft overlay that provides 100% coverage + Others: + show Show .tix file in readable, verbose format + version Display version for hpc + +In general, these options act on a ``.tix`` file after an instrumented +binary has generated it. + +The hpc tool assumes you are in the top-level directory of the location +where you built your application, and the ``.tix`` file is in the same +top-level directory. You can use the flag ``--srcdir`` to use ``hpc`` +for any other directory, and use ``--srcdir`` multiple times to analyse +programs compiled from difference locations, as is typical for packages. + +We now explain in more details the major modes of hpc. + +hpc report +^^^^^^^^^^ + +``hpc report`` gives a textual report of coverage. By default, all +modules and packages are considered in generating report, unless include +or exclude are used. The report is a summary unless the ``--per-module`` +flag is used. The ``--xml-output`` option allows for tools to use hpc to +glean coverage. + +.. code-block:: none + + $ hpc help report + Usage: hpc report [OPTION] .. <TIX_FILE> [<MODULE> [<MODULE> ..]] + + Options: + + --per-module show module level detail + --decl-list show unused decls + --exclude=[PACKAGE:][MODULE] exclude MODULE and/or PACKAGE + --include=[PACKAGE:][MODULE] include MODULE and/or PACKAGE + --srcdir=DIR path to source directory of .hs files + multi-use of srcdir possible + --hpcdir=DIR append sub-directory that contains .mix files + default .hpc [rarely used] + --reset-hpcdirs empty the list of hpcdir's + [rarely used] + --xml-output show output in XML + +hpc markup +^^^^^^^^^^ + +``hpc markup`` marks up source files into colored html. + +.. code-block:: none + + $ hpc help markup + Usage: hpc markup [OPTION] .. <TIX_FILE> [<MODULE> [<MODULE> ..]] + + Options: + + --exclude=[PACKAGE:][MODULE] exclude MODULE and/or PACKAGE + --include=[PACKAGE:][MODULE] include MODULE and/or PACKAGE + --srcdir=DIR path to source directory of .hs files + multi-use of srcdir possible + --hpcdir=DIR append sub-directory that contains .mix files + default .hpc [rarely used] + --reset-hpcdirs empty the list of hpcdir's + [rarely used] + --fun-entry-count show top-level function entry counts + --highlight-covered highlight covered code, rather that code gaps + --destdir=DIR path to write output to + +hpc sum +^^^^^^^ + +``hpc sum`` adds together any number of ``.tix`` files into a single +``.tix`` file. ``hpc sum`` does not change the original ``.tix`` file; +it generates a new ``.tix`` file. + +.. code-block:: none + + $ hpc help sum + Usage: hpc sum [OPTION] .. <TIX_FILE> [<TIX_FILE> [<TIX_FILE> ..]] + Sum multiple .tix files in a single .tix file + + Options: + + --exclude=[PACKAGE:][MODULE] exclude MODULE and/or PACKAGE + --include=[PACKAGE:][MODULE] include MODULE and/or PACKAGE + --output=FILE output FILE + --union use the union of the module namespace (default is intersection) + +hpc combine +^^^^^^^^^^^ + +``hpc combine`` is the swiss army knife of ``hpc``. It can be used to +take the difference between ``.tix`` files, to subtract one ``.tix`` +file from another, or to add two ``.tix`` files. hpc combine does not +change the original ``.tix`` file; it generates a new ``.tix`` file. + +.. code-block:: none + + $ hpc help combine + Usage: hpc combine [OPTION] .. <TIX_FILE> <TIX_FILE> + Combine two .tix files in a single .tix file + + Options: + + --exclude=[PACKAGE:][MODULE] exclude MODULE and/or PACKAGE + --include=[PACKAGE:][MODULE] include MODULE and/or PACKAGE + --output=FILE output FILE + --function=FUNCTION combine .tix files with join function, default = ADD + FUNCTION = ADD | DIFF | SUB + --union use the union of the module namespace (default is intersection) + +hpc map +^^^^^^^ + +hpc map inverts or zeros a ``.tix`` file. hpc map does not change the +original ``.tix`` file; it generates a new ``.tix`` file. + +.. code-block:: none + + $ hpc help map + Usage: hpc map [OPTION] .. <TIX_FILE> + Map a function over a single .tix file + + Options: + + --exclude=[PACKAGE:][MODULE] exclude MODULE and/or PACKAGE + --include=[PACKAGE:][MODULE] include MODULE and/or PACKAGE + --output=FILE output FILE + --function=FUNCTION apply function to .tix files, default = ID + FUNCTION = ID | INV | ZERO + --union use the union of the module namespace (default is intersection) + +hpc overlay and hpc draft +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Overlays are an experimental feature of HPC, a textual description of +coverage. hpc draft is used to generate a draft overlay from a .tix +file, and hpc overlay generates a .tix files from an overlay. + +.. code-block:: none + + % hpc help overlay + Usage: hpc overlay [OPTION] .. <OVERLAY_FILE> [<OVERLAY_FILE> [...]] + + Options: + + --srcdir=DIR path to source directory of .hs files + multi-use of srcdir possible + --hpcdir=DIR append sub-directory that contains .mix files + default .hpc [rarely used] + --reset-hpcdirs empty the list of hpcdir's + [rarely used] + --output=FILE output FILE + % hpc help draft + Usage: hpc draft [OPTION] .. <TIX_FILE> + + Options: + + --exclude=[PACKAGE:][MODULE] exclude MODULE and/or PACKAGE + --include=[PACKAGE:][MODULE] include MODULE and/or PACKAGE + --srcdir=DIR path to source directory of .hs files + multi-use of srcdir possible + --hpcdir=DIR append sub-directory that contains .mix files + default .hpc [rarely used] + --reset-hpcdirs empty the list of hpcdir's + [rarely used] + --output=FILE output FILE diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..61a88ec --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,13 @@ +=============== +Hpc User Guide +=============== + +Hpc is a tool for generating coverage reports in various output formats for Haskell projects. + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + about + examples + hpc diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..32bb245 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd -- GitLab