haskell / haskell/cabal

No easy way to build instantiated backpack signature units for tooling

Open
#6,201 6 comments 0 reactions 0 assignees View on GitHub
Cabal: Backpack
Dominant language
Haskell
Stars
1.7k
Forks
750
Avg merge
4d 3h
Merged PRs (30d)
28

Description

**Describe the bug**

There is no (non-hacky) way to refer to the instantiated units of a backpack signature (indef) component.

When refering to an indefinite backpack component as a target on the commandline only the un-instantiated unit will be built, not all of it's instantiations.

(Please note I'm not 100% sure about the backpack nomenclature so I hope I'm making sense)

**To Reproduce**
Steps to reproduce the behavior:

I have a small backpack example (stolen from ezyang's blog post series) over in the cabal-helper repo so I'm going to use that since it's also part of my test-suite:

```
# Ok, setup the testcase
$ cd /tmp
$ git clone https://github.com/DanielG/cabal-helper.git
$ cd cabal-helper/tests/bkpregex/
$ echo "packages: ." > cabal.project

# Now do a build with the indef target, which also has two instantiations
$ cabal v2-build lib:regex-indef

# Now see if the dist-dirs for lib:regex-indef's units exist or not, indicating if they've been built
$ distdirs="$(jq -r '."install-plan" | .[] | select(."component-name" == "lib:regex-indef") | ."dist-dir" ' < dist-newstyle/cache/plan.json)"
$ for distdir in $distdirs; do if [ -e $distdir ]; then echo exists $distdir; else echo NOPE $distdir; fi; done
exists /tmp/cabal-helper/tests/bkpregex/dist-newstyle/build/x86_64-linux/ghc-8.4.4/bkpregex-0.1.0.0/l/regex-indef
NOPE /tmp/cabal-helper/tests/bkpregex/dist-newstyle/build/x86_64-linux/ghc-8.4.4/bkpregex-0.1.0.0/l/regex-indef/bkpregex-0.1.0.0-inplace-regex-indef+AYP8n8MTOrTJ1O1qStoQzp
NOPE /tmp/cabal-helper/tests/bkpregex/dist-newstyle/build/x86_64-linux/ghc-8.4.4/bkpregex-0.1.0.0/l/regex-indef/bkpregex-0.1.0.0-inplace-regex-indef+FWgKbpc2n5z9FKNeEqm0Ar
```

If instantiated units are being built is a bit hard to see, so here I'm demonstrating they don't get built by finding their corresponding distdirs in plan.json. As you can see non of the `regex-indef+...` units' distdirs exist after building the `lib:regex-indef` target.

**Expected behavior**
Either the target `lib:regex-indef` should build the instantiations or plan.json should have a field telling tooling which target to use.

My current workaround is to identify backpack units in plan.json by looking for `"+"` in the ID then finding which units depend on this unit and building those, well really "that", component with `--only-dependencies` instead. That works but is quite horrifying.

Currently we have the `"component-name"` field, for example one of the units from above looks like this:

```
{
"type": "configured",
"id": "bkpregex-0.1.0.0-inplace-regex-indef+FWgKbpc2n5z9FKNeEqm0Ar",
"pkg-name": "bkpregex",
"pkg-version": "0.1.0.0",
"flags": {},
"style": "local",
"pkg-src": {
"type": "local",
"path": "/tmp/cabal-helper/tests/bkpregex/."
},
"dist-dir": "/tmp/cabal-helper/tests/bkpregex/dist-newstyle/build/x86_64-linux/ghc-8.4.4/bkpregex-0.1.0.0/l/regex-indef/bkpregex-0.1.0.0-inplace-regex-indef+FWgKbpc2n5z9FKNeEqm0Ar",
"depends": [
"base-4.11.1.0",
"bkpregex-0.1.0.0-inplace-regex-types"
],
"exe-depends": [],
"component-name": "lib:regex-indef"
}
```

but this tells us that this instantiated unit is supposedly part of "lib:regex-indef" which is kind of true but really it's a lie. This unit is not in the plan because of lib:regex-indef, it's in the plan because lib:regex-example has mixins which instantiate lib:regex-indef:

```
mixins: regex-indef (Regex as Regex.String)
requires (Str as Str.String),
regex-indef (Regex as Regex.ByteString)
requires (Str as Str.ByteString)
```

if this field referred to lib:regex-example my code would be happy but it would be somewhat less efficient than just letting me build the lib:regex-indef target together with instantiations.

Maybe just adding support to use unit-ids as commandline targets would be even better though. That problem is also going to come up as part of `show-build-info` so just adding generic support for all commands might be nice.

**Additional context**

As far as I can tell 4378f5c20ad8052a127d3760ded91edb09ad6423 is to blame here, commit message:

```
Tweak target selection semantics for indefinite packages.

Suppose you have a Backpack package foo-indef, which has
some signatures; furthermore, elsewhere in your install plan
ths packages gets instantiated. When you type
'cabal new-build foo-indef', what should get built?

Previously: foo-indef, as well as all of its instantiations,
get built.

Now: only the indefinite foo-indef is typechecked.

This is what you want!
```

Err actually I want the instantiations to get built when building the foo-indef target! Well really I'd be happy if I could refer to the instantiations any other way but I think the most reasonable thing to do would be to just revert this commit.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.