Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cabal ui #7422

Closed
tonyday567 opened this issue Jun 1, 2021 · 17 comments
Closed

cabal ui #7422

tonyday567 opened this issue Jun 1, 2021 · 17 comments

Comments

@tonyday567
Copy link

https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/139

I was going to add to #7420, but worried that this doesn't quite fit the YOLO principle espoused there.

If ghcup is not the tool for this, I can imagine a table of checkboxes for package dependencies, including the main ones around the project bounds, with an ability to click boxes, running cabal configure behind the scenes to see what adding/deleting the latest version (say) of a dependency does.

My workflow may be awful, but that would save me a lot of looking at hackage pages (and SemVar howtos). In a rush, without cabal knowledge, or any CI ATM, my stack-based project workflow includes waiting for a Hackage build to fail, and only then trying to work out how to get matrix lights green.

@Mikolaj
Copy link
Member

Mikolaj commented Jun 2, 2021

You probably mean cabal build --dry, not cabal configure that writes stuff to cabal.project.local. Did you try cabal build --dry --upgrade-dependencies --allow-newer? If it works, you read form it (add -v if needed) the versions to use. If not, it prints why it failed, so you change that. What's missing?

@tonyday567
Copy link
Author

Hi Mikolaj,

Thanks for the response.

Ok, yes, I mean cabal build --configure-only now I understand the flags a bit more. The work that needs doing to get a good build.

And apologies if I'm not explaining things well. I am an ex-stack user that hasn't run a cabal command for many years, so I'm trying to get up to speed.

What I find lacking are examples of how to take a random library, that may or may not fill a need you have, that will be a few years old and not properly maintained, and (quickly) fix it up for a modern build set (just an example). That's a very common job for me, and I can do it with stack, but I'm I have no visibility of how people go about this using cabal.

I may well be reinventing flags and workflows that already exist. Apologies in advance.

I'm not sure what --upgrade-dependencies does. All I could find was:

"Pick the latest version for all dependencies, rather than trying to pick an installed version." I'm not sure what an installed version is, but does this use all the upper bounds in the cabal file, or does it go to the package list and say, hey, is there a new version of doctest out?

What's missing?

Good question. I think my suggestion splits into a few different aspects:

  • ergonomics, covered by Improve debug logging in Cabal/cabal-install #7420
  • some more cabal smarts. Debug messages could, in some cases, not only be shortened, but also become interactive, turned into suggestions and file edits.
  • is there demand for a more interactive approach to using cabal, along the lines of how the ghcup ui works?

Is there space in the cabal project for design and scope questions such as the last two aspects, once exact print arrives? Or is this out of scope (which I would so respect given your legacy responsibilities), and I should bug elsewhere?

@Mikolaj
Copy link
Member

Mikolaj commented Jun 2, 2021

--upgrade-dependencies ignores packages you have installed (that would otherwise be preferred to save time) and insists on the newest packages the solver can find.

Installed means that it's been installed previously and it's in the store. That way many versions can be installed and are re-used, without the need to compile them each time you build another package that uses them.

--upgrade-dependencies doesn't only use upper bounds from the main cabal file, but does use the install plan the solver found, which takes into account also bounds in cabal files of dependencies, etc. Or fails telling you there is no set of versions that satisfy (solve) the constraints.

I'm sceptical about interactive approach to cabal, because the philosophy of cabal is that solves everything for you, you don't need to prod it. Just have the cabal file open, run cabal, tweak bounds according to what it tells you one at a time and it should be fine. Tedious, but mostly automated. The only real decisions, which make full automation problematic, is guessing which bounds are too conservative and which package you'd rather fix and which leave alone to solve the constraints.

@tonyday567
Copy link
Author

Just have the cabal file open, run cabal, tweak bounds according to what it tells you one at a time and it should be fine. Tedious, but mostly automated.

My tolerance for tedium is lower than yours, I'd guess. But that doesn't make you wrong!

There may be a problem, however, with applying a design principle for a user tool "that everything is solved for you" but having a rider clause that user tedium is out of scope.

This:

➜  numhask git:(ghc901) ✗ cabal build --minimize-conflict-set
Resolving dependencies...
cabal: Could not resolve dependencies:
[__0] trying: numhask-0.8.0.0 (user goal)
[__1] rejecting: numhask:!test (constraint from config file, command line
flag, or user target requires opposite flag selection)
[__1] trying: numhask:*test
[__2] next goal: doctest (dependency of numhask *test)
[__2] rejecting: doctest-0.18.1, doctest-0.18 (conflict: numhask *test =>
doctest>=0.17 && <0.18)
[__2] trying: doctest-0.17
[__3] next goal: ghc (dependency of doctest)
[__3] rejecting: ghc-9.0.1/installed-9.0.1 (conflict: doctest => ghc>=7.0 &&
<8.11)
[__3] trying: ghc-8.10.2
[__4] next goal: base (dependency of numhask)
[__4] rejecting: base-4.15.0.0/installed-4.15.0.0 (conflict: ghc => base<0 &&
>=4.14 && <4.15)
[__4] skipping: base-4.15.0.0, base-4.14.1.0, base-4.14.0.0, base-4.13.0.0,
base-4.12.0.0, base-4.11.1.0, base-4.11.0.0, base-4.10.1.0, base-4.10.0.0,
base-4.9.1.0, base-4.9.0.0, base-4.8.2.0, base-4.8.1.0, base-4.8.0.0,
base-4.7.0.2, base-4.7.0.1, base-4.7.0.0, base-4.6.0.1, base-4.6.0.0,
base-4.5.1.0, base-4.5.0.0, base-4.4.1.0, base-4.4.0.0, base-4.3.1.0,
base-4.3.0.0, base-4.2.0.2, base-4.2.0.1, base-4.2.0.0, base-4.1.0.0,
base-4.0.0.0, base-3.0.3.2, base-3.0.3.1 (has the same characteristics that
caused the previous version to fail: excluded by constraint '<0 && >=4.14 &&
<4.15' from 'ghc')
[__4] fail (backjumping, conflict set: base, ghc, numhask)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: ghc, base, doctest, numhask,
numhask:test

could be summarised to:

try adding doctest 0.18.1

And then, if the user tool can find a way to get me out of the picture altogether, by running that suggestion as a command, I would rate that a very nice design.

@danidiaz
Copy link
Collaborator

danidiaz commented Jun 4, 2021

@Mikolaj For the purpose of finding which are the newest versions available for my package's dependencies in the Hackage index (irrespective of if my package compiles with them yet) could cabal outdated be an alternative to cabal build --dry-run --upgrade-dependencies --allow-newer ?

@Mikolaj
Copy link
Member

Mikolaj commented Jun 4, 2021

@danidiaz: quite possibly, there were no such comfy commands in my time :)

@tonyday567: could you try? best, with the help of a Haskell IRC channel or Matrix or somewhere, so that the turnaround is quicker than in an issue tracker

Regarding improving the failure messages of the solver --- by all means, that would be invaluable and I think this is a good starting point (unless there is a better workflow, e.g., using cabal outdated). Generally, I think it's best to find the best workflow, improve its command-line operation, only then add things on top of that (e.g., UI or interactive scripts rewriting configs for you at a keypress or something else).

@tonyday567
Copy link
Author

Yes, this issue started as ghcup is pretty, why cant cabal be pretty. But I agree that the search for good commands might be a sounder way to progress.

I’m not sure there’s anything to try out, in that cabal is working for me. cabal outdated sounds like just what I need, but I’m also in explorer mode, finding tips and tricks, so its not just that.

Calling this issue a discussion rather than a blockage might be more accurate.

@Mikolaj
Copy link
Member

Mikolaj commented Jun 4, 2021

@tonyday567: I'm asking you to try out and brainstorm with people and find the best workflow and describe here briefly. That would already help anybody finding this issue. Then, if you see how the commands in this workflow could be improved, and then how a UI or some other extra script or automation would help you in this workflow, please do propose it, let's discuss and, best, implement it. :) We'll try to help. No user frustration should ever go to waste. :)

@tonyday567
Copy link
Author

@Mikolaj: yes, of course, it sounds fun! Apologies for the delayed response but life intersected. How do we begin?

@Mikolaj
Copy link
Member

Mikolaj commented Jun 9, 2021

You are the driver. :) If I may suggest, for a start, it may help people that search and find this issue, if you shared whether the use of cabal outdated helped in your workflow, etc. Focusing on the manual use of commandline for now, No scripts, no UI.

@fendor
Copy link
Collaborator

fendor commented Jun 9, 2021

--upgrade-dependencies ignores packages you have installed (that would otherwise be preferred to save time) and insists on the newest packages the solver can find.

In v2-build, --upgrade-dependencies doesn't do anything, as the build-plan never re-uses existing packages, right?
It should be an outdated flag...

@Mikolaj
Copy link
Member

Mikolaj commented Jun 9, 2021

In v2-build, --upgrade-dependencies doesn't do anything, as the build-plan never re-uses existing packages, right?
It should be an outdated flag...

Let me open an issue about that, because if I got fooled, probably others do, too: #7437

@tonyday567
Copy link
Author

@Mikolaj

cabal outdated found the out of date packages where I had an upper bound (a package without an upper bound is always in date).

cabal gen-bounds was the command I needed - when you have a hot mess of bounds, some ok but others with no or dodgy bounds.

Now that I understand the ecosystem a bit better, I appreciate your pov that cabal should be kept as simple as possible.

@Mikolaj
Copy link
Member

Mikolaj commented Sep 8, 2021

@tonyday567: good to know that cabal gen-bounds was the key ingredient to make your workflow viable.

Please keep considering the big picture when you work with cabal in the future and let's brainstorm any tweaks to cabal that may help in your uses cases. Feel free to close this issue and open new ones, or keep this one open for your future feedback.

@tonyday567
Copy link
Author

Will do and will close this in favour of clarity going forward.

Since you asked about big picture, I'll close off by sketching out my bounds usage. I use it in conjunction with cabal-deps. gen-bounds doesn't handle variations from cabal.project, such as allow-newer, so it doesn't always get a good build. It took me a long while, but I finally found --ghc-options=-Wunused-packages so I no longer spend time refining bounds of packages I don't use.

Discovery of all of this was hard - I waded through a lot of dead or dying projects, around some roadblocks and misleading intel to find these gems. But solutions where you wrap all of it up, disappearing cabal, ghc and whatever into some opaque process ... well that's stack again, or a wrapped cabal-extras. Cabal UI needs a spirit guide - a claptrap not a gatekeeper.

It feels like the project is on track with the syntax split. Keep splitting and tunnelling down. Again, just a big picture thought bubble, but I railed last week against haddocks and not being able to use markdown, and today I found Distribution/Simple/PreProcess/Unlit.hs. Another hidden cabal gem! It does it right compared with ghc and would open up ghc to using markdown. But adding a --use-markdown flag to cabal would be the wrong way to expose it. Just a guess, but the right way to expose it might be by carving it out of cabal and seeing what breaks.

@Mikolaj
Copy link
Member

Mikolaj commented Sep 9, 2021

Great job. Any future suggestions are welcome. Please also open issues about documentation improvements that would have made your journey less thorny. It may also be worth giving feedback to https://github.com/haskell/cabal-userguide that @JonathanLorimer pushes forward.

@Mikolaj
Copy link
Member

Mikolaj commented Sep 9, 2021

BTW, a related ticket just under review, for anybody to comment on: #7425

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants