Skip to content

No easy way to build instantiated backpack signature units for tooling #6201

@DanielG

Description

@DanielG

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions