-
Notifications
You must be signed in to change notification settings - Fork 725
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 4378f5c 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.