haskell / haskell/cabal

Produce a cabal.project file upon `cabal init` to pin the GHC version explicitly

Open
#10,188 4 comments 2 reactions 0 assignees View on GitHub
cabal-install: cmd/init re: project-file type: RFC
Dominant language
Haskell
Stars
1.7k
Forks
750
Avg merge
4d 3h
Merged PRs (30d)
28

Description

## Context

After spending some time in the contact of beginners, a recurring thing has been noted: The GHC version is indirectly constrained by the bounds on the `base` library.

This is not a very common behaviour in other ecosystems, and each time I explain how this works, I feel like I am just describing a very weird and counter-intuitive situation instead of giving an actual good reason.

From a personal standpoint I also systematically write down:

```cabal
packages: ./

with-compiler: ghc-9.8
```

in my new executable projects.

### Compare the difference in user experience:

#### When exclusively relying on base bounds

```
Error: [Cabal-7107]
Could not resolve dependencies:
[__0] trying: myproject-0.1.0.0 (user goal)
[__1] next goal: base (dependency of myproject)
[__1] rejecting: base-4.18.2.1/installed-4.18.2.1 (conflict: myproject => base^>=4.19)
[__1] skipping: base; 4.20.0.1, 4.20.0.0 (has the same characteristics that caused the previous version to fail: excluded by constraint '^>=4.19' from 'myproject')
[__1] rejecting: base; 4.19.1.0, 4.19.0.0, 4.18.2.1, 4.18.2.0, 4.18.1.0, 4.18.0.0, 4.17.2.1, 4.17.2.0, 4.17.1.0, 4.17.0.0, 4.16.4.0, 4.16.3.0, 4.16.2.0, 4.16.1.0, 4.16.0.0, 4.15.1.0, 4.15.0.0, 4.14.3.0, 4.14.2.0, 4.14.1.0, 4.14.0.0, 4.13.0.0, 4.12.0.0, 4.11.1.0, 4.11.0.0, 4.10.1.0, 4.10.0.0, 4.9.1.0, 4.9.0.0, 4.8.2.0, 4.8.1.0, 4.8.0.0, 4.7.0.2, 4.7.0.1, 4.7.0.0, 4.6.0.1, 4.6.0.0, 4.5.1.0, 4.5.0.0, 4.4.1.0, 4.4.0.0, 4.3.1.0, 4.3.0.0, 4.2.0.2, 4.2.0.1, 4.2.0.0, 4.1.0.0, 4.0.0.0, 3.0.3.2, 3.0.3.1 (constraint from non-reinstallable package requires installed instance)
[__1] fail (backjumping, conflict set: base, myproject)
After searching the rest of the dependency tree exhaustively, these were the goals I've had most trouble fulfilling: base, myproject
```

#### When using `with-compiler`

```
Error: [Cabal-5490]
Cannot find the program 'ghc'. User-specified path 'ghc-9.12' does not refer to an executable and the program is not on the system path.
```

Moreover, with the error codes, we are able to provide better feedback to the user regarding the reason `cabal` fails. Even this infamous search engine gives relevant results:

![Screenshot 2024-07-08 at 22-30-40 Cabal-5490 - Recherche Google](https://github.com/haskell/cabal/assets/29253044/9743a62f-d4a9-43b0-badc-83895653cb50)

---

## This RFC

The point of this RFC is to argue in favour of changing the behaviour of `cabal init` in two ways:

* In non-interactive mode, prouce a `cabal.project` where the `with-compiler` stanza is set to the current GHC
* In interactive mode, prompt the user to enter a `ghc-xxx` string, with the current GHC's version as a default.

We can even add a link to the project file documentation as a comment in the first line.

The whole point is to improve a beginner's first steps in Haskell. Cloning a repository and getting a solver error when running `cabal build` is not people particularly enjoy, especially when they have to go on a wild goose chase to figure out which version of `base` is shipped with which version of `ghc`.

Should this RFC be accepted, I will implement it.

Contributor guide

Open the contributing guide

Research direction

Start at the `cabal init` entry point and inspect how project files are generated in interactive and non-interactive modes. Run `cabal init` in both modes; done means a `cabal.project` is produced with the current GHC in `with-compiler`, and interactive mode prompts with that version as the default.

Written by the indexing model from the issue text.

Assessment

Tech stack
haskell
Domain
build-system, cli
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.