haskell / haskell/cabal

`cabal install haskell-src-exts-1.10.1` indeterministically fails to regenerate the happy parser

Open
#2,311 11 comments 0 reactions 0 assignees View on GitHub
cabal-install: other type: bug
Dominant language
Haskell
Stars
1.7k
Forks
750
Avg merge
4d 3h
Merged PRs (30d)
28

Description

I noticed this because with GHC 7.8.4 `cabal install haskell-src-exts-1.10.1` would sometimes succeed and sometimes fail with a compile failure in `InternalParser.hs`, depending on whether it was regenerated or not (GHC 7.8.4 requires parsers created by a recent enough `happy`)

I tracked this down to the way source-tarball are extracted, which seem to ignore the timestamps recored in the tarballs, and instead extracts the file with current system time.

So here's two example runs (I looked at the timestamps before `cabal` would decide whether to preprocess any files), which result in two cases in which the two files are in a different relative temporal relationship to each other:
- case 1: `.hs` file older than `.ly` file (`.hs` file will be regenerated)

```
-rw-rw-r-- 1 hvr hvr 505437 2015-01-02 19:59:46.556436392 +0100 haskell-src-exts-1.10.1-30225/haskell-src-exts-1.10.1/dist/dist-sandbox-4ac2267c/build/Language/Haskell/Exts/InternalParser.hs
-rw-rw-r-- 1 hvr hvr 91522 2015-01-02 19:59:46.560436366 +0100 haskell-src-exts-1.10.1-30225/haskell-src-exts-1.10.1/src/Language/Haskell/Exts/InternalParser.ly
```
- case 2: `.hs` exact same age as `.ly` file (`.hs` file is not regenerated -> compile failure)

```
-rw-rw-r-- 1 hvr hvr 505437 2015-01-02 20:01:46.371660280 +0100 haskell-src-exts-1.10.1-31835/haskell-src-exts-1.10.1/dist/dist-sandbox-4ac2267c/build/Language/Haskell/Exts/InternalParser.hs
-rw-rw-r-- 1 hvr hvr 91522 2015-01-02 20:01:46.371660280 +0100 haskell-src-exts-1.10.1-31835/haskell-src-exts-1.10.1/src/Language/Haskell/Exts/InternalParser.ly
```

Depending on whether case 1 or 2 occured (which depends on the operating system's clock accuracy, and interaction with process scheduling), the parser would be either regenerated or not.

There are a couple ways to workaround/fix this issue, here's just some ideas:
1. A simple fix which would work in this case is to change the logic which decides whether to preprocess parsers to also regenerate in case of same-timestamps (this works as long as `.ly` is always extracted before the `.hs` -- does `cabal sdist` enforce this ordering in the tarball?)
2. `cabal install some-package` could always consider a `.ly` file to be regenerated, because of GHC 7.8.x and later requiring recent enough `happy` to have generated the parser
3. Extract files from source-tarball with recorded time-stamp. This would at least make the situation deterministic, although the parser would then probably never be regenerated, as the generated `.hs` file's timestamp would normally away be younger than the `.ly` file's.

/cc @feuerbach

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.