Skip to content
Snippets Groups Projects
Commit 452eead4 authored by f-a's avatar f-a Committed by f-a
Browse files

Add 3.16 changelogs (#11033)

* Add changelog files for 3.16

* Integrate Brandon’s suggestions.
* Integrate Brandon’s suggestions /II.
* Integrate Bodigrim’s suggestions.
* Integrate Artem’s suggestions.
  * Correctly capitalize “AArch” in preparation of #11047 backport
* Integrate Artem’s suggestions /II.

* Remove changelog.d bits
parent 6f6b2c8a
No related branches found
No related tags found
No related merge requests found
Showing
with 12 additions and 568 deletions
# Changelog for `Cabal-hooks`
## 3.16.0 – July 2025
* No changes
## 3.14.2 – April 2025
* No changes
......
Please see https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.14.2.0.md
Please see https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.16.0.0.md
# 3.16.0.0 [Artem Pelenitsyn](mailto:a@pelenitsyn.top) July 2025
* See https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.16.0.0.md
# 3.14.2.0 [Mikolaj Konarski](mailto:mikolaj@well-typed.com) April 2025
* See https://github.com/haskell/cabal/blob/master/release-notes/Cabal-3.14.2.0.md
......
Please see https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.14.2.0.md
Please see https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.16.0.0.md
# Change-log
## 3.16.0.0 [Artem Pelenitsyn](mailto:a@pelenitsyn.top) July 2025
* See https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.16.0.0.md
## 3.14.2.0 [Mikolaj Konarski](mailto:mikolaj@well-typed.com) April 2025
* See https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.14.2.0.md
......
---
synopsis: Add --with-repl flag to specify alternative REPL program
packages: [cabal-install, Cabal]
prs: [10996]
issues: [9115]
---
Added a new `--with-repl` command-line option that allows specifying an alternative
program to use when starting a REPL session, instead of the default GHC.
This is particularly useful for tools like `doctest` and `hie-bios` that need to
intercept the REPL session to perform their own operations. Previously, these tools
had to use `--with-ghc` which required them to proxy all GHC invocations, including
dependency compilation, making the implementation more complex.
The `--with-repl` option only affects the final REPL invocation, simplifying the
implementation of such wrapper tools.
Example usage:
```bash
cabal repl --with-repl=doctest
cabal repl --with-repl=/path/to/custom/ghc
```
This change also removes the special handling for response files with `--interactive`
mode, as tools are now expected to handle response files appropriately.
synopsis: Don't imply that Haddock docs exist, when warning not installed
packages: Cabal
issues: #9694
prs: #9695
synopsis: Fix `cabal clean` permissions on Windows
packages: cabal-install
prs: #10190
issues: #10182
significance:
description: {
- `cabal clean` now removes the read-only mark recursively in the `dist-newstyle` folder on Windows before attempting to delete it.
}
synopsis: Shallow and concurrent cloning of git repos
packages: cabal-install
prs: #10254
description: {
- Clone git repositories specified in source-repository-package stanzas
shallowly, since to build the package from the repository we only need to
read the commit specified. The rest of the repo is not needed.
Note that this does not change the behaviour of `cabal get -s`, which will
still clone the repository in full.
- Clone VCS repositories concurrently, with a maximum of two concurrent tasks
at the same time (just like when downloading packages asynchronously)
}
---
synopsis: "Show why `cabal act-as-setup configure` failed"
packages: [Cabal]
prs: 10273
---
When `cabal act-as-setup configure` fails, it prints a list of "missing or
private dependencies".
Now, it will show you if each failing dependency is missing, private, or an
incompatible version:
```
Error: [Cabal-8010]
Encountered missing or private dependencies:
Lib:{bar-internal,foo-internal} (missing :bar-internal),
base <=1.0 (installed: 4.18.2.1),
package-that-does-not-exist (missing)
```
synopsis: New licence constructors for SPDX licences starting with a digit
packages: Cabal-syntax
prs: #10356
description: {
- LicenseId constructor `NullBSD` is now `N_0BSD`.
- LicenseId constructor `DS389_exception` is now and `N_389_exception`.
- LicenseId constructor `X3D_Slicer_1_0` is now and `N_3D_Slicer_1_0`.
}
synopsis: Avoid partial `Data.List.last` in autogenerated `Paths_<pkg>.hs`
packages: Cabal
prs: #10432
significance:
description: {
- Autogenerated `Paths_<pkg>.hs` now avoids use of the partial function `Data.List.last`.
}
---
synopsis: "A trailing colon after a stanza name in `cabal.project` is now an error"
packages: [cabal-install]
prs: 10525
---
It is now a hard error to use a trailing colon after a stanza name in
`cabal.project` or `*.cabal` files:
```
packages: .
source-repository-package:
type: git
location: https://github.com/haskell/cabal
tag: f34aba976a60940295f41b6649674e9568893894
```
```
$ cabal build
Error parsing project file cabal.project:3:
'source-repository-package' is a stanza, not a field. Remove the trailing ':' to parse a stanza.
```
Previously, the warning message was easily ignored and somewhat misleading, as
the difference between a stanza and a field is not immediately obvious to
Haskellers used to config languages like JSON and YAML (which don't distinguish
between fields which have string or list values and stanzas which have nested
fields):
```
Warning: cabal.project: Unrecognized field
'source-repository-package' on line 3
```
synopsis: Warn on `cabal format`
packages: cabal-install
prs: #10549
issues:
significance:
description: {
- Despite its name, `cabal format` is not a proper formatter for cabal files. By chance users have sometimes found the command eventhough it is not mentioned in the help text, and they used it to format cabal files. This has some downsides like comments are stripped away or common stanzas are inlined, the command is more like a dump of the resolved package description. There are future plans (#7544) to make it an actual formatter so, rather than going through a deprecation cycle, we decided to keep this command for future use and in the meantime just warn the user about the fact that it is not a proper formatter.
}
---
synopsis: "Quieter Git output"
packages: [cabal-install]
prs: 10587
---
When `cabal` clones a Git repo for a `source-repository-package` listed in a
`cabal.project`, it will run various commands to check out the correct
revision, initialize submodules if they're present, and so on.
Now, `cabal` will pass `--quiet` to Git in more cases to help prevent
cluttering command-line output.
---
synopsis: "Don't run submodule commands unless necessary"
packages: [cabal-install]
prs: 10590
---
When `cabal` clones a Git repo for a `source-repository-package` listed in a
`cabal.project`, it will run various commands to check out the correct
revision, initialize submodules if they're present, and so on.
Now, `cabal` will avoid running `git submodule` commands unless the cloned
repository contains a `.gitmodules` file. This will declutter `cabal`'s debug
output by running fewer commands.
---
synopsis: "Report trailing spaces in project import URIs"
packages: [cabal-install, cabal-install-solver]
prs: 10629
issues: 10622
---
> A string is a valid URL potentially surrounded by spaces if, after stripping
> leading and trailing whitespace from it, it is a valid URL."
> SOURCE: [W3C/HTML5/URLs](https://www.w3.org/TR/2010/WD-html5-20100624/urls.html)
Fixes a problem of mistaking a URI for a file path when it has trailing spaces
and warn about such trailing spaces.
---
synopsis: Fix Haddock CSS handling in multi-package projects
packages: [cabal-install, Cabal]
prs: 10637
issues: [10636]
---
When `--css=<css-file>` flag is provided to `cabal haddock-project`:
- the Haddock index is now properly styled by the provided CSS file
- each package in the project now has their docs properly styled by the provided CSS file
---
synopsis: Show source of project parse error or warning
packages: [cabal-install]
prs: 10644
issues: 10635
---
Improves warning and error messages shown when parsing project files and their
imports.
## Warning Messages
To trigger these warning messages, the examples use badly formed comments that
have a single dash instead of two as is required of a line comment in `.cabal`
and `.project` files (and imported `.config` files).
* Before the fix:
The `cabal.project` file name is repeated. Warnings are misattributed to
having been in the project rather than from a configuration file imported by
the project. Warnings are shown in reverse line number order.
```
$ ~/.ghcup/bin/cabal-3.12.1.0 build all --dry-run
...
Warning:
/.../ParseWarningProvenance/cabal.project,
cabal.project, cabal.project, cabal.project, cabal.project: Unrecognized
section '-' on line 123
/.../ParseWarningProvenance/cabal.project,
cabal.project, cabal.project, cabal.project, cabal.project: Unrecognized
section '-' on line 3
/.../ParseWarningProvenance/cabal.project,
cabal.project, cabal.project, cabal.project, cabal.project: Unrecognized
section '-' on line 2
/.../ParseWarningProvenance/cabal.project,
cabal.project, cabal.project, cabal.project, cabal.project: Unrecognized
section '-' on line 1
/.../ParseWarningProvenance/cabal.project,
cabal.project, cabal.project, cabal.project, cabal.project: Unrecognized
section '-' on line 123
/.../ParseWarningProvenance/cabal.project,
cabal.project, cabal.project, cabal.project, cabal.project: Unrecognized
section '-' on line 3
/.../ParseWarningProvenance/cabal.project,
cabal.project, cabal.project, cabal.project, cabal.project: Unrecognized
section '-' on line 2
/.../ParseWarningProvenance/cabal.project,
cabal.project, cabal.project, cabal.project, cabal.project: Unrecognized
section '-' on line 1
```
* After the fix:
The warnings are shown in a list. For warnings within the same `.project` or
imported `.config` file, warnings are sorted by line number. The file that
is the source of the warning is shown.
The warnings associated with configuration files are shown in the order
these files were imported by the project:
```
$ cat cabal.project
packages: no-pkg-dir
import: dir-x/a.config
import: dir-y/a.config
import: x.config
import: y.config
```
```
$ cabal build all --dry-run
...
Warnings found while parsing the project file, cabal.project:
- dir-x/a.config: Unrecognized section '-' on line 1
- dir-x/a.config: Unrecognized section '-' on line 2
- dir-x/a.config: Unrecognized section '-' on line 3
- dir-y/a.config: Unrecognized section '-' on line 123
- x.config: Unrecognized section '-' on line 1
- x.config: Unrecognized section '-' on line 2
- x.config: Unrecognized section '-' on line 3
- y.config: Unrecognized section '-' on line 123
```
## Error Messages from Project
To trigger these error messages, the examples use badly formed conditions:
```
$ cat cabal.project
-- The following failing condition is not on the first line so we can check the
-- line number:
if _
```
* Before the fix:
The parse error is shown with hard line breaks.
```
$ ~/.ghcup/bin/cabal-3.12.1.0 build all --dry-run
...
Error: [Cabal-7090]
Error parsing project file /.../ParseErrorProvenance/cabal.project:3:
"<condition>" (line 1, column 1):
unexpected SecArgName (Position 1 4) "_"
```
* After the fix:
The snippet that failed to parse may be shown and the parse error is shown
as one line, with no hard line breaks.
```
$ cabal build all --dry-run
...
Error: [Cabal-7090]
Error parsing project file cabal.project:3:
- Failed to parse 'if(_)' with error:
"<condition>" (line 1, column 1): unexpected SecArgName (Position 1 4) "_"
```
## Error Messages from Imported Config
With the same setup but now with the error in an imported file:
```
$ cat elif.project
import: dir-elif/elif.config
$ cat dir-elif/elif.config
-- The following failing condition is not on the first line so we can check the
-- line number:
if false
elif _
```
* Before the fix:
The project rather than the imported configuration file is shown as the source file.
```
$ ~/.ghcup/bin/cabal-3.12.1.0 build all --dry-run
...
Error: [Cabal-7090]
Error parsing project file /.../ParseErrorProvenance/elif.project:4:
"<condition>" (line 1, column 1):
unexpected SecArgName (Position 1 6) "_"
```
* After the fix:
The imported configuration file is shown as the source with a snippet of the error.
```
$ cabal build all --dry-run
...
Error: [Cabal-7090]
Error parsing project file dir-elif/elif.config:4:
- dir-elif/elif.config
imported by: elif.project
- Failed to parse 'elif(_)' with error:
"<condition>" (line 1, column 1): unexpected SecArgName (Position 1 6) "_"
```
---
synopsis: Configuration messages without duplicates
packages: [cabal-install-solver]
prs: 10646
issues: 10645
---
The "using configuration from" message no longer has duplicates on Windows when
a `cabal.project` uses forward slashes for its imports but the message reports
the same import again with backslashes.
```diff
$ cat cabal.project
import: dir-a/b.config
$ cabal build all --dry-run
...
When using configuration from:
- - dir-a/b.config
- dir-a\b.config
- cabal.project
```
## Changed `Ord ProjectConfigPath` Instance
For comparison purposes, path separators are normalized to the `buildOS`
platform's path separator.
```haskell
-- >>> let abFwd = ProjectConfigPath $ "a/b.config" :| []
-- >>> let abBwd = ProjectConfigPath $ "a\\b.config" :| []
-- >>> compare abFwd abBwd
-- EQ
```
## Changes in `cabal-testsuite`
### Reading Expected Multiline Strings Verbatim
With `ghc-9.12.1` adding `-XMultilineStrings`, writing multiline string
expectations for `cabal-testsuite/PackageTests/**/*.test.hs` test scripts might
be have been easier but for a catch. We run these tests with older `GHC`
versions so would need to use `-XCPP` for those versions and the C preprocessor
does not play nicely with string gaps. While it is possible to encode a
multiline string as a single line with embedded LF characters or by breaking the
line up arbitrarily and using `++` concatenation or by calling unlines on a list
of lines, string gaps are the multiline strings of Haskell prior to
`-XMultilineStrings`.
To avoid these problems and for the convenience of pasting the expected value
verbatim into a file, `readFileVerbatim` can read the expected multiline output
for tests from a text file. This has the same implementation as `readFile` from
the `strict-io` package to avoid problems at cleanup.
```
Warning: Windows file locking hack: hit the retry limit 3 while trying to remove
C:\Users\<username>\AppData\Local\Temp\cabal-testsuite-8376
cabal.test.hs:
C:\Users\<username>\AppData\Local\Temp\cabal-testsuite-8376\errors.expect.txt: removePathForcibly:DeleteFile
"\\\\?\\C:\\Users\\<username>\\AppData\\Local\\Temp\\cabal-testsuite-8376\\errors.expect.txt":
permission denied (The process cannot access the file because it is being used by another process.)
```
The other process accessing the file is `C:\WINDOWS\System32\svchost.exe`
running a `QueryDirectory` event and this problem only occurs when the test
fails.
### Hidden Actual Value Modification
The `assertOutputContains` function was modifying the actual value (the test
output) with `concatOutput` before checking if it contained the expected value.
This function, now renamed as `lineBreaksToSpaces`, would remove CR values and
convert LF values to spaces.
```haskell
-- | Replace line breaks with spaces, correctly handling @"\\r\\n"@.
--
-- >>> lineBreaksToSpaces "foo\nbar\r\nbaz"
-- "foo bar baz"
--
-- >>> lineBreaksToSpaces "foo\nbar\r\nbaz\n"
-- "foo bar baz"
--
-- >>> lineBreaksToSpaces "\nfoo\nbar\r\nbaz\n"
-- " foo bar baz"
lineBreaksToSpaces :: String -> String
```
With this setup, false positives were possible. An expected value using string
gaps and spaces would match a `concatOutput` modified actual value of
"foo_bar_baz", where '_' was any of space, LF or CRLF in the unmodified actual
value. The latter two are false positive matches.
```haskell
let expect = "foo \
\bar \
\baz"
```
False negatives were also possible. An expected value set up using string gaps
with LF characters or with `-XMultilineStrings` wouldn't match an actual value
of "foo_bar_baz", where '_' was either LF or CRLF because these characters had
been replaced by spaces in the actual value, modified before the comparison.
```haskell
let expect = "foo\n\
\bar\n\
\baz"
```
```haskell
{-# LANGUAGE MultilineStrings #-}
let expect = """
foo
bar
baz
"""
```
We had these problems:
1. The actual value was changed before comparison and this change was not visible.
2. The expected value was not changed in the same way as the actual value. This
made it possible for equal values to become unequal (false negatives) and for
unequal values to become equal (false positives).
### Explicit Changes and Visible Line Delimiters
To fix these problems, an added `assertOn` function takes a `NeedleHaystack`
configuration for how the search is made, what to expect (to find the expected
value or not) and how to display the expected and actual values.
A pilcrow ¶ is often used to visibly display line endings but our terminal
output is restricted to ASCII so lines are delimited between `^` and `$`
markers. The needle (the expected output fragment) is shown annotated this way
and the haystack (the actual output) can optionally be shown this way too.
We can now implement `assertOutputContains` by calling `assertOn`:
```diff
assertOutputContains :: MonadIO m => WithCallStack (String -> Result -> m ())
- assertOutputContains needle result =
- withFrozenCallStack $
- unless (needle `isInfixOf` (concatOutput output)) $
- assertFailure $ " expected: " ++ needle
- where output = resultOutput result
+ assertOutputContains = assertOn
+ needleHaystack
+ {txHaystack =
+ TxContains
+ { txBwd = delimitLines
+ , txFwd = encodeLf
+ }
+ }
```
This is still a lenient match, allowing LF to match CRLF, but `encodeLf` doesn't
replace LF with spaces like `concatOutput` (`lineBreaksToSpaces`) did:
```haskell
-- | Replace line CRLF line breaks with LF line breaks.
--
-- >>> encodeLf "foo\nbar\r\nbaz"
-- "foo\nbar\nbaz"
--
-- >>> encodeLf "foo\nbar\r\nbaz\n"
-- "foo\nbar\nbaz\n"
--
-- >>> encodeLf "\nfoo\nbar\r\nbaz\n"
-- "\nfoo\nbar\nbaz\n"
--
-- >>> encodeLf "\n\n\n"
-- "\n\n\n"
encodeLf :: String -> String
```
If you choose to display the actual value by setting
`NeedleHaystack{displayHaystack = True}` then its lines will be delimited.
```haskell
-- | Mark lines with visible delimiters, @^@ at the start and @$@ at the end.
--
-- >>> delimitLines ""
-- "^$"
--
-- >>> delimitLines "\n"
-- "^$\n"
--
-- >>> delimitLines "\n\n"
-- "^$\n^$\n"
--
-- >>> delimitLines "\n\n\n"
-- "^$\n^$\n^$\n"
--
-- >>> delimitLines $ encodeLf "foo\nbar\r\nbaz"
-- "^foo$\n^bar$\n^baz$"
--
-- >>> delimitLines $ encodeLf "foo\nbar\r\nbaz\n"
-- "^foo$\n^bar$\n^baz$\n"
--
-- >>> delimitLines $ encodeLf "\nfoo\nbar\r\nbaz\n"
-- "^$\n^foo$\n^bar$\n^baz$\n"
delimitLines:: String -> String
```
With `assertOn`, supplying string transformation to both the needle and haystack
before comparison and before display can help find out why an expected value is
or isn't found in the test output.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment