haskell / cabal

Official upstream development repository for Cabal and cabal-install
https://haskell.org/cabal
Other
1.61k stars 690 forks source link

cabal list-bin can already list multiple binary but just refuses to #9732

Open andreabedini opened 6 months ago

andreabedini commented 6 months ago

cabal list-bin returns the path of a executable in the current project matching a specified target. E.g.

λ cabal list-bin cabal
/home/andrea/code/cabal/master/dist-newstyle/build/x86_64-linux/ghc-9.6.4/cabal-install-3.11.0.0/x/cabal/build/cabal/cabal

The command accepts one and only one target:

λ cabal list-bin
Error: cabal: One target is required, none provided
λ cabal list-bin cabal unit-tests
Error: cabal: One target is required, given multiple

The funny thing is that all is effectively one target, so cabal list-bin all almost works ...

λ cabal list-bin all
Error: cabal: The list-bin command is for finding a single binary at once. The
target 'all' refers to all the packages in the project which includes the
executable 'cabal', the executable 'test-runtime-deps', the executable
'setup', the executable 'cabal-tests', the executable 'hackage-benchmark', the
test suite 'unit-tests', the test suite 'rpmvercmp', the test suite
'parser-tests', the test suite 'no-thunks-test', the test suite
'hackage-tests', the test suite 'custom-setup-tests', the test suite
'check-tests', the test suite 'cabal-benchmarks', the test suite 'unit-tests',
the test suite 'mem-use-tests', the test suite 'long-tests', the test suite
'integration-tests2', the test suite 'unit-tests' and the test suite
'unit-tests'.

Combinations like all:tests and all:exes give a similar result:

λ cabal list-bin all:tests
Error: cabal: The list-bin command is for finding a single binary at once. The
target 'all:tests' refers to all the test suites in the project which includes
the test suite 'unit-tests', the test suite 'rpmvercmp', the test suite
'parser-tests', the test suite 'no-thunks-test', the test suite
'hackage-tests', the test suite 'custom-setup-tests', the test suite
'check-tests', the test suite 'cabal-benchmarks', the test suite 'unit-tests',
the test suite 'mem-use-tests', the test suite 'long-tests', the test suite
'integration-tests2', the test suite 'unit-tests' and the test suite
'unit-tests'.
λ cabal list-bin all:exes
Error: cabal: The list-bin command is for finding a single binary at once. The
target 'all:exes' refers to all the executables in the project which includes
the executable 'cabal', the executable 'test-runtime-deps', the executable
'setup', the executable 'cabal-tests' and the executable 'hackage-benchmark'.

The error lists all the matching targets so we must have a way to iterate over them!

@fendor

mpickering commented 6 months ago

Isn't the point that list-bin gives either zero or one answers, because if it gives multiple answers then $(cabal list-bin ...) fails?

Are you proposing that list-bin should be allowed to return multiple results?

philderbeast commented 6 months ago

Stack has a similar command that returns multiple exes;

$ stack ide targets --exes
cabal-install:exe:cabal
cabal-testsuite:exe:cabal-tests
cabal-testsuite:exe:setup
cabal-testsuite:exe:test-runtime-deps
solver-benchmarks:exe:hackage-benchmark

$ stack ide targets --tests
Cabal-tests:test:check-tests
Cabal-tests:test:custom-setup-tests
Cabal-tests:test:hackage-tests
Cabal-tests:test:no-thunks-test
Cabal-tests:test:parser-tests
Cabal-tests:test:rpmvercmp
Cabal-tests:test:unit-tests
cabal-benchmarks:test:cabal-benchmarks
cabal-install:test:integration-tests2
cabal-install:test:long-tests
cabal-install:test:mem-use-tests
cabal-install:test:unit-tests
cabal-install-solver:test:unit-tests
solver-benchmarks:test:unit-tests
andreabedini commented 6 months ago

Isn't the point that list-bin gives either zero or one answers, because if it gives multiple answers then $(cabal list-bin ...) fails?

This is a good point.

Are you proposing that list-bin should be allowed to return multiple results?

Perhaps under a different command? Perhaps list-bins like cabal-plan?

λ cabal-plan list-bins
Cabal-tests:test:check-tests  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/Cabal-tests-3/t/check-tests/build/check-tests/check-tests
Cabal-tests:test:custom-setup-tests  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/Cabal-tests-3/t/custom-setup-tests/build/custom-setup-tests/custom-setup-tests
Cabal-tests:test:hackage-tests  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/Cabal-tests-3/t/hackage-tests/build/hackage-tests/hackage-tests
Cabal-tests:test:no-thunks-test  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/Cabal-tests-3/t/no-thunks-test/build/no-thunks-test/no-thunks-test
Cabal-tests:test:parser-tests  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/Cabal-tests-3/t/parser-tests/build/parser-tests/parser-tests
Cabal-tests:test:rpmvercmp  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/Cabal-tests-3/t/rpmvercmp/build/rpmvercmp/rpmvercmp
Cabal-tests:test:unit-tests  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/Cabal-tests-3/t/unit-tests/build/unit-tests/unit-tests
alex:exe:alex  /home/andrea/.cabal/store/ghc-9.6.4/alex-3.5.0.0-e-alex-5a2b80e00d9a49e8478136c249dafe90ecd3b132c66d82a39fa24dd0f577ba41/bin/alex
cabal-benchmarks:test:cabal-benchmarks  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/cabal-benchmarks-3/t/cabal-benchmarks/build/cabal-benchmarks/cabal-benchmarks
cabal-install:exe:cabal  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/cabal-install-3.11.0.0/x/cabal/build/cabal/cabal
cabal-install:test:integration-tests2  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/cabal-install-3.11.0.0/t/integration-tests2/build/integration-tests2/integration-tests2
cabal-install:test:long-tests  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/cabal-install-3.11.0.0/t/long-tests/build/long-tests/long-tests
cabal-install:test:mem-use-tests  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/cabal-install-3.11.0.0/t/mem-use-tests/build/mem-use-tests/mem-use-tests
cabal-install:test:unit-tests  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/cabal-install-3.11.0.0/t/unit-tests/build/unit-tests/unit-tests
cabal-install-solver:test:unit-tests  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/cabal-install-solver-3.11.0.0/t/unit-tests/build/unit-tests/unit-tests
cabal-testsuite:exe:cabal-tests  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/cabal-testsuite-3/build/cabal-tests/cabal-tests
cabal-testsuite:exe:setup  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/cabal-testsuite-3/build/setup/setup
cabal-testsuite:exe:test-runtime-deps  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/cabal-testsuite-3/build/test-runtime-deps/test-runtime-deps
happy:exe:happy  /home/andrea/.cabal/store/ghc-9.6.4/happy-1.20.1.1-e-happy-5d2cb1f20b337ca4b455575e6d86a6d3afa94612f714745960f587f15420f050/bin/happy
hsc2hs:exe:hsc2hs  /home/andrea/.cabal/store/ghc-9.6.4/hsc2hs-0.68.10-e-hsc2hs-a4946925ece439133faec67ee16e6c44532e84c9fc4949d89b66614c823a056c/bin/hsc2hs
open-browser:exe:example  /home/andrea/.cabal/store/ghc-9.6.4/open-browser-0.2.1.0-e-example-16aff3a3531b1e6b7f0c4a5edaec7c5cd82d3ae582b887f63c83a7139a9b1cd0/bin/example
pretty-show:exe:ppsh  /home/andrea/.cabal/store/ghc-9.6.4/pretty-show-1.10-e-ppsh-bad54a4a82951feafb98773240e419cced984c9a481befe5d0dfda946f672683/bin/ppsh
solver-benchmarks:exe:hackage-benchmark  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/solver-benchmarks-3/x/hackage-benchmark/build/hackage-benchmark/hackage-benchmark
solver-benchmarks:test:unit-tests  /home/andrea/code/cabal/setup-wrapper/dist-newstyle/build/x86_64-linux/ghc-9.6.4/solver-benchmarks-3/t/unit-tests/build/unit-tests/unit-tests
ulysses4ever commented 6 months ago

Some discussion about this in

Isn't the point that list-bin gives either zero or one answers, because if it gives multiple answers then $(cabal list-bin ...) fails?

Not sure it's all that good of an idea judging by how often people ask for an ability to get a list out of it, and I'm yet to see people excited by this idea outside the old cabal team. I'd rather there was a flag that people would apply in scripting scenarios (e.g. $(cabal list-bin --force-unique ...)) if they want today's strict behavior. A separate command altogether is also possible, perhaps, but feels a little like an overkill: it'd mostly duplicate the existing list-bin; also it will take time to teach people to use it (the old subcommand should participate in that by issuing a suggesting to use the new one if there're multiple results).

So, I'd prefer augmenting list-bin. If we make this change, I don't think many things will fail because the scripting use cases that work today will probably work under the new version: after all, we're making it more lenient rather than more strict (which would break more).

gbaz commented 6 months ago

"I'm yet to see people excited by this idea outside the old cabal team" <- nobody's excited by this or asking for it because it already works, and was widely demanded, which is why the feature was implemented.

I think we can add an --all flag to list-bin to get the new behavior, and put that in the error message as a suggestion. But the behavior should be opt-in rather than opt-out to not disrupt any existing uses.

(Remember, existing uses always may be widespread but silent, and the only people who speak up are the ones who have new complaints -- the folks happy with how it works don't hang out on the tracker looking for tickets that might change thins for them!)

ulysses4ever commented 6 months ago

My point is very simple: people who are happy with the current behavior will be just as happy with the new behavior because they probably rely on the happy parth rather than on the exceptional path.

But the opt-in strategy with a suggestion sounds fine too.

alt-romes commented 6 months ago

Yes, let's please do opt-in. --all sounds nice to me.

philderbeast commented 6 months ago

I find the command name confusing, a list command that returns one thing, the full path to an executable. What is the history there? Is it named after the ls shell command (a command that takes [FILE] and has a default)?

$ ls --help
Usage: ls [OPTION]... [FILE]...
List information about the FILEs (the current directory by default).
...
$ cabal --help
...
[running and testing]
  list-bin               List the path to a single executable.
$ cabal list-bin --help
List the path to a single executable.

Usage: cabal list-bin [FLAGS] TARGET

List the path to **a** build product.

Could we please add a cabal targets command before we change the cabal list-bin behaviour?

philderbeast commented 6 months ago

Yes, let's please do opt-in. --all sounds nice to me.

That's the all:exes all:tests all:benches target form, isn't it?

andreasabel commented 1 month ago

I would also like list-bin to make it easier to discover targets for cabal run. Here is a record of my difficult conversation with cabal: :-D

$ cabal test
No tests to run for the package stm-2.5.3.1

$ cabal list-bins
Error: cabal: unrecognised command: list-bins (try --help)
Maybe you meant `list-bin`?

$ cabal list-bin
Error: [Cabal-7024]
One target is required, none provided

$ cabal list-bin all
Error: [Cabal-7044]
The list-bin command is for finding a single binary at once. 
The target 'all' refers to all the packages in the project 
which includes the test suite 'stm' and the benchmark 'chanbench'.

$ cabal run stm
Error: [Cabal-7070]
The run command is for running executables, 
but the target 'stm' refers to the library stm from the package stm-2.5.3.1.

$ cabal run test:stm
(finally doing what I want)

This conversation is definitely improvable.

Mikolaj commented 1 month ago

@andreasabel: I'm confused: the https://hackage.haskell.org/package/stm-2.5.3.1/stm.cabal file only mentions a library. not exes nor tests. How come? Are you working in a larger project stm is a member package of?

Kleidukos commented 1 month ago

I get the following non-helpful output from the maximal verbosity level:


❯ cabal -v3 test
zsh: correct 'test' to 'tests' [nyae]? n
Searching for curl in path.
Found curl at /usr/bin/curl
Searching for powershell in path.
Cannot find powershell on the path
Searching for wget in path.
Found wget at /usr/bin/wget
Selected http transport implementation: curl
File monitor 'config' unchanged.
this build was affected by the following (project) config files:
- cabal.project
File monitor 'improved-plan' unchanged.
No tests to run for the package stm-2.5.3.1
andreasabel commented 1 month ago

@Mikolaj wrote:

I'm confused: the hackage.haskell.org/package/stm-2.5.3.1/stm.cabal file only mentions a library. not exes nor tests. How come? Are you working in a larger project stm is a member package of?

I was working on master which has a testsuite project: https://github.com/haskell/stm/blob/cb861ea10065f229bbc5b6a1e2b9bde998f18184/testsuite/testsuite.cabal Oh, this testsuite itself is named stm, which explains part of my confusion. Seems like:

fgaz commented 1 month ago
  • Why cabal test does not work but cabal run test:stm does remains mysterious to the end-user, but maybe this is orthogonal to the present issue here...

This is because cabal test defaults to ., not all. In your case . is the stm package. From https://cabal.readthedocs.io/en/stable/cabal-commands.html#cabal-test:

runs the specified test suites (all the test suites in the current package by default)

In the biweekly call we agreed that all would be a less surprising default.

ulysses4ever commented 1 month ago

I would also like list-bin to make it easier to discover targets for cabal run

Is this PR doing anything helpful: https://github.com/haskell/cabal/pull/9744?