# Detect (un)used exports from sibling projects?

**URL:** <https://discourse.elm-lang.org/t/detect-un-used-exports-from-sibling-projects/6689>\
**Category:** Learn\
**Created:** [January 3, 2021, 7:54am UTC](https://discourse.elm-lang.org/t/detect-un-used-exports-from-sibling-projects/6689 "2021-01-03T07:54:07Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![rkb](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/rkb/32/672_2.png) [@rkb](https://discourse.elm-lang.org/u/rkb)\
**Post date:** [January 3, 2021, 7:54am UTC](https://discourse.elm-lang.org/t/detect-un-used-exports-from-sibling-projects/6689/1 "2021-01-03T07:54:07Z")

</div>

I’d like to use [jfmengels/elm-review-unused](https://package.elm-lang.org/packages/jfmengels/elm-review-unused/1.1.4/NoUnused-Exports), but it’s a little too forward in a “monorepo”-style setup [like this one,](https://github.com/r-k-b/elm-review-multi-src-dirs/tree/b271e8ddb7febda6547e5e7fe421a43d6f4965f9) incorrectly marking some exports as unused.

Where there’s multiple sibling Elm projects and two of them refer to a third with `source-directories: [../third/src]`, is it feasible to have elm-review either:

- treat the third as a Package, marking everything within as being used? or
- somehow work with multiple projects at once, allowing it to correctly find unused exports from the shared project?

---

<div class="post-metadata">

**Author:** ![brian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/brian/32/2180_2.png) [@brian](https://discourse.elm-lang.org/u/brian)\
**Post date:** [January 3, 2021, 11:42am UTC](https://discourse.elm-lang.org/t/detect-un-used-exports-from-sibling-projects/6689/2 "2021-01-03T11:42:23Z")

</div>

I have a similar problem: the main codebase I work on has many distinct entrypoints which we compile separately instead of doing a SPA. A colleague and I ended up writing a little script that will:

1. find all the import statements in the project I want to run `elm-review` on.
2. find all the modules that those import, and all the modules that import them.
3. run `elm-review` on the entire list of expanded imports
4. discard results on files that are in the expanded list but not the original list

That works pretty well!

---

<div class="post-metadata">

**Author:** ![jfmengels](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/jfmengels/32/3124_2.png) [@jfmengels](https://discourse.elm-lang.org/u/jfmengels)\
**Post date:** [January 3, 2021, 12:02pm UTC](https://discourse.elm-lang.org/t/detect-un-used-exports-from-sibling-projects/6689/3 "2021-01-03T12:02:56Z")

</div>

### Current state of affairs

`elm-review` only looks at a single project at a time at the moment, so it is not possible for it to work with multiple projects at once.

What I would probably do in your shoes is to treat the third project as a package, as you suggested. In this case, I think you only have to ignore the `NoUnused.Exports` rule for that source directory, meaning you would not lose out on too many reports, especially if you have an IDE which shows you how many times something is used in the rest of the codebase. I’m not sure that the Elm Language Server and the IntelliJ.plugin give you that out of the box, but I know that some plugin for Atom does that

You can potentially try to run `elm-review` from time to time without doing that, to notice and manually remove the elements that are unused in both of the other projects.

### In the future?

I don’t think allowing for multi-repos is impossible, but it would require quite some work on the tool itself, and likely some setup on the user’s side too.

What does a “multirepo”-style setup mean? It means that we would run `elm-review` by targetting multiple `elm.json` files, which has several implications.

#### Finding the elm.json files

The user now needs to run the `elm-review` CLI (or in their IDE when we get to that point) by configuring it to run with all of the `elm.json` files. Sometjing like `elm-review --elmjson project1/elm.json,../../project2/elm.json,project3/elm.json`. I would imagine that this is error-prone, because if you forget to include one project (or include one too many 🤔) , then you can get false positives or false negatives.

#### Dependencies

`elm-review` loads the dependencies of a project. When we look at a single project, it is relatively simple. But when we look at multiple `elm.json`, we somehow need to merge the dependencies of each project, with potentially some conflicts.  
For instance, if one project depends on package A v2, and an other depends on package A but v1, but where the code compiles because they only use the unchanged API present in both versions. Our dependency solver wouldn’t be able to resolve a correct set of dependencies.

#### Project-aware rules

Alternatively, we could make it so that `elm-review` rules (like `NoUnused.Dependencies` and `NoUnused.Exports`) are aware of the multiple projects and know which files is included in which `elm.json`'s source-directories, with `elm-review` not trying to resolve dependencies to a single set, but I think that would introduce a lot of complexity and I’m not sure that would even work out.

## Current thoughts

I don’t know if there is a good solution to this honestly. I’m very curious as to what @brian came up with and whether it’s something that `elm-review` can leverage out of the box, and learn whether it causes a set of false positives or false negatives.

I would love some ideas, but this will probably not be addressed for a while, considering I have little insight in how to resolve it at the moment.

If you know of similar tools that solved this problem in other languages/ecosystems, I’d love to know!

---

<div class="post-metadata">

**Author:** ![rkb](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/rkb/32/672_2.png) [@rkb](https://discourse.elm-lang.org/u/rkb)\
**Post date:** [January 4, 2021, 2:48am UTC](https://discourse.elm-lang.org/t/detect-un-used-exports-from-sibling-projects/6689/4 "2021-01-04T02:48:25Z")

</div>

Thanks! I was about to ask how to actually treat it as a package, then I saw [`Review.Rule.ignoreErrorsForDirectories`](https://package.elm-lang.org/packages/jfmengels/elm-review/2.3.8/Review-Rule#ignoreErrorsForDirectories), which handles that neatly.

I’d also like to see what Brian came up with! As far as I understand it, it’s doing something like [this,](https://github.com/r-k-b/elm-review-multi-src-dirs/commit/1a0858aff7dfc56e19ac5a56e62a5f28d1465bb4) individually specifying all relevant modules across projects, passing that list to elm-review?

To see if I understand it:

1. follow down the dependency graph from a single module (node) to the roots, keeping those modules in set “A”
2. for each module from the first pass, following back **up** the dependency tree, keeping those modules in set “B”
3. call `elm-review` with the paths to each module in the union of sets A and B
4. prune out review errors that don’t apply to modules in set A

---

<div class="post-metadata">

**Author:** ![brian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/brian/32/2180_2.png) [@brian](https://discourse.elm-lang.org/u/brian)\
**Post date:** [January 4, 2021, 4:01pm UTC](https://discourse.elm-lang.org/t/detect-un-used-exports-from-sibling-projects/6689/5 "2021-01-04T16:01:33Z")

</div>

> [@rkb](#):
>
> I’d also like to see what Brian came up with!

It’s one of those kind of internal scripts that rely on a leaning tower of weird shell scripts which you’re fine inflicting on your coworkers but wouldn’t release as open source 😆

Your summary is mostly there, but needs a few tweaks to avoid asking elm-review to do too much:

1. take the list of files you care about—all of them, not just `Main`. I’ll call this set `keep`.
2. get the set of files that import or are imported by those files. **Don’t follow the import graph more than one hop away from the starting file!** We don’t care about errors in places which are two or more hops away. If you have a weird circular dependency between packages but not modules, though, you may want to follow further. I’ll call this set `importersAndImportees`. It will definitely have some overlap with `keep`!
3. call `elm-review` with `keep + importersAndImportees`
4. prune error messages from files in `importersAndImportees - keep`

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [January 14, 2021, 4:01pm UTC](https://discourse.elm-lang.org/t/detect-un-used-exports-from-sibling-projects/6689/6 "2021-01-14T16:01:34Z")

</div>

Closed on January 14, 2021, 4:01pm UTC

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
