• Stars
    star
    123
  • Rank 281,127 (Top 6 %)
  • Language
    Haskell
  • License
    BSD 3-Clause "New...
  • Created about 7 years ago
  • Updated almost 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Detect dead exports or package imports

Weeder Hackage version Stackage version Linux build status Windows build status

Weeder has moved!

Weeder 2.0 is being developed at https://github.com/ocharles/weeder on different foundations. This repo is for historical reference only.


Most projects accumulate code over time. Weeder detects unused Haskell exports, allowing dead code to be removed (pulling up the weeds). Weeder piggy-backs off files generated by stack, so first obtain stack, then:

  • Install weeder by running stack install weeder --resolver=nightly.
  • Ensure your project has a stack.yaml file. If you don't normally build with stack then run stack init to generate one.
  • Make sure you have ghc-options: {"$locals": -ddump-to-file -ddump-hi} in your stack.yaml.
  • Run weeder . --build, which builds your project with stack and reports any weeds.

What does Weeder detect?

Weeder detects a bunch of weeds, including:

  • You export a function helper from module Foo.Bar, but nothing else in your package uses helper, and Foo.Bar is not an exposed-module. Therefore, the export of helper is a weed. Note that helper itself may or may not be a weed - once it is no longer exported -fwarn-unused-binds will tell you if it is entirely redundant.
  • Your package depends on another package but doesn't use anything from it - the dependency should usually be deleted. This functionality is quite like packunused, but implemented quite differently.
  • Your package has entries in the other-modules field that are either unused (and thus should be deleted), or are missing (and thus should be added). The stack tool warns about the latter already.
  • A source file is used between two different sections in a .cabal file - e.g. in both the library and the executable. Usually it's better to arrange for the executable to depend on the library, but sometimes that would unnecessarily pollute the interface. Useful to be aware of, and sometimes worth fixing, but not always.
  • A file has not been compiled despite being mentioned in the .cabal file. This situation can be because the file is unused, or the stack compilation was incomplete. I recommend compiling both benchmarks and tests to avoid this warning where possible - running weeder . --build will use a suitable command line.

Beware of conditional compilation (e.g. CPP and the Cabal flag mechanism), as these may mean that something is currently a weed, but in different configurations it is not.

I recommend fixing the warnings relating to other-modules and files not being compiled first, as these may cause other warnings to disappear.

What else should I use?

Weeder detects dead exports, which can be deleted. To get the most code deleted from removing an export, use:

  • GHC with -fwarn-unused-binds -fwarn-unused-imports, which finds unused definitions and unused imports in a module.
  • HLint, looking for "Redundant extension" hints, which finds unused extensions.
  • Unused, which works at the level of ctags information, so can be used if you don't want to use stack, can't compile your code, or want to detect unused code between projects.

Ignoring weeds

If you want your package to be detected as "weed free", but it has some weeds you know about but don't consider important, you can add a .weeder.yaml file adjacent to the stack.yaml with a list of exclusions. To generate an initial list of exclusions run weeder . --yaml > .weeder.yaml.

You may wish to generalise/simplify the .weeder.yaml by removing anything above or below the interesting part. As an example of the .weeder.yaml file from ghcid:

- message: Module reused between components
- message:
  - name: Weeds exported
  - identifier: withWaiterPoll

This configuration declares that I am not interested in the message about modules being reused between components (that's the way ghcid works, and I am aware of it). It also says that I am not concerned about withWaiterPoll being a weed - it's a simplified method of file change detection I use for debugging, so even though it's dead now, I sometimes do switch to it.

Running with Continuous Integration

Before running Weeder on your continuous integration (CI) server, you should first ensure there are no existing weeds. One way to achieve that is to ignore existing hints by running weeder . --yaml > .weeder.yaml and checking in the resulting .weeder.yaml.

On the CI you should then run weeder . (or weeder . --build to compile as well). To avoid the cost of compilation you may wish to fetch the latest Weeder binary release.

For the CI systems Travis, Appveyor and Azure Pipelines add the line:

curl -sSL https://raw.github.com/ndmitchell/weeder/master/misc/run.sh | sh -s .

The arguments after -s are passed to weeder, so modify the final . if you want other arguments. This command works on Windows, Mac and Linux.

What about Cabal users?

Weeder requires the textual .hi file for each source file in the project. Stack generates that already, so it was easy to integrate in to. There's no reason that information couldn't be extracted by either passing flags to Cabal, or converting the .hi files afterwards. I welcome patches to do that integration.

What about false positives?

Weeder strives to avoid incorrectly warning about something that is required, if you find such an instance please report it on the issue tracker. Unfortunately there are some cases where there are still false positives, as GHC doesn't put enough information in the .hi files:

Data.Coerce If you use Data.Coerce.coerce the constructors for the data type must be in scope, but if they aren't used anywhere other than automatically by coerce then Weeder will report unused imports. You can ignore such warnings by adding - message: Unused import to your .weeder.yaml file.

Declaration QuasiQuotes If you use a declaration-level quasi-quote then weeder won't see the use of the quoting function, potentially leading to an unused import warning, and marking the quoting function as a weed. The only solution is to ignore the entries with a .weeder.yaml file.

Stack extra-deps Packages marked extra-deps in your stack.yaml will be weeded, due to a bug in stack. The only solution is to ignore the packages with a .weeder.yaml file.

Linking to C functions If a library provides C functions, and these are used directly from another library/executable, the library providing these functions may be marked as a redundant build-depends, see more details.

More Repositories

1

hlint

Haskell source code suggestions
Haskell
1,427
star
2

ghcid

Very low feature GHCi based IDE
Haskell
1,121
star
3

shake

Shake build system
Haskell
744
star
4

hoogle

Haskell API search engine
Haskell
689
star
5

tagsoup

Haskell library for parsing and extracting information from (possibly malformed) HTML/XML documents
Haskell
229
star
6

bake

UNMAINTAINED: Continuous integration server
Haskell
130
star
7

record-dot-preprocessor

A preprocessor for a Haskell record syntax using dot
Haskell
126
star
8

debug

Haskell library for debugging
JavaScript
122
star
9

rattle

Forward build system with speculation and caching
Haskell
101
star
10

spaceleak

Notes on space leaks
Haskell
101
star
11

extra

Extra Haskell functions
Haskell
89
star
12

build-shootout

Comparison of build program expressive power
Haskell
88
star
13

cmdargs

Haskell library for command line argument processing
Haskell
88
star
14

uniplate

Haskell library for simple, concise and fast generic operations.
Haskell
71
star
15

safe

Haskell library for safe (pattern match free) functions
Haskell
45
star
16

ghc-make

An alternative to ghc --make which supports parallel compilation of modules and runs faster when nothing needs compiling.
Haskell
39
star
17

interpret

Rust
37
star
18

neil

General tools for Neil
Haskell
37
star
19

profiterole

GHC prof manipulation script
Haskell
30
star
20

nsis

Haskell DSL for producing Windows Installer using NSIS
Haskell
26
star
21

derive

A Haskell program and library to derive instances for data types
TeX
25
star
22

supero

Haskell optimisation tool based on supercompilation
Haskell
25
star
23

offline-stack

Install Stack without internet access
Haskell
18
star
24

hexml

A bad XML parser
C
18
star
25

catch

Haskell pattern match analsyis checker
Haskell
15
star
26

js-jquery

Haskell library to obtain minified jQuery code
Haskell
9
star
27

rexe

.exe forwarder, to allow replacing binaries on PATH
Haskell
8
star
28

office

Macros for Microsoft Office
VBA
7
star
29

VSHaskell

Visual Studio 2010 addin
C#
7
star
30

record-hasfield

A version of HasField that will be available in future GHC
Haskell
7
star
31

shake-paper

Paper on the new GHC Shake-based build system
HTML
6
star
32

lasagna

Checker for Haskell layering violations
Haskell
5
star
33

guihaskell

A graphical REPL and development environment for Haskell
Haskell
5
star
34

hwwg

Haskell Website Working Group
5
star
35

shake-bazel

Experimenting with Shake and Bazel combined
Haskell
4
star
36

blogs

TeX
4
star
37

haskell-parser

Haskell parser based on that from GHC
Haskell
4
star
38

idris-playground

Playing around with Idris
Idris
4
star
39

proplang

A Haskell library for functional GUI development
Haskell
4
star
40

thesis

My PhD thesis - Transformation and Analysis of Functional Programs
Haskell
3
star
41

js-flot

Haskell library to obtain minified Flot code
Haskell
3
star
42

filepattern

A file path matching library
Haskell
3
star
43

qed

Experiments writing a prover
Haskell
3
star
44

core-playground

Simple Core language for Haskell experiments
Haskell
3
star
45

js-dgtable

Haskell library to obtain minified jquery.dgtable code
JavaScript
3
star
46

neil-check

Run neil and hlint on all my projects
Haskell
3
star
47

shake-examples

3
star
48

proof

Haskell library for writing proofs
Haskell
2
star
49

ci-check

Test the various supported CI's
2
star
50

hogle-dead

This repo has been moved to the master branch of https://github.com/ndmitchell/hoogle.
Haskell
2
star
51

stack-3137

Reproduce https://github.com/commercialhaskell/stack/issues/3137
Haskell
2
star
52

winhaskell

Windows Haskell GUI interpretter
C++
1
star
53

fossilizer

Generate 3D images of fossil bedding surfaces
JavaScript
1
star
54

bug-i386-ghc84

1
star
55

proposition

Haskell library for manipulating propositions.
Haskell
1
star
56

tex2hs

A program to check for type errors in a Latex document
Haskell
1
star
57

ndmitchell

1
star
58

hlint-test

Haskell
1
star
59

ghc-process

Compiling and linking files in a single process using the GHC API
Haskell
1
star
60

shark

A bad replacement for cabal/stack
1
star
61

index-search

Searching compressed text indicies
C
1
star
62

awesomo

Prototype optimiser for Haskell programs
Haskell
1
star
63

ninjasmith

Ninja file generator and tester
Haskell
1
star