Skip to content

Commit 6479469

Browse files
authored
Merge pull request commercialhaskell#3541 from commercialhaskell/3520-revision-matching
Better errors for 00-index, and ignore-revision-mismatch commercialhaskell#3520
2 parents 2634f80 + 17a4a9e commit 6479469

11 files changed

Lines changed: 110 additions & 20 deletions

File tree

ChangeLog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ Other enhancements:
111111
to GHC. See:
112112
[#3454](https://github.com/commercialhaskell/stack/issues/3454)
113113
* Add hpack `package.yaml` to build Stack itself
114+
* Add `ignore-revision-mismatch` setting. See:
115+
[#3520](https://github.com/commercialhaskell/stack/issues/3520).
114116

115117
Bug fixes:
116118

doc/yaml_configuration.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -840,7 +840,25 @@ save-hackage-creds: true
840840
```
841841

842842
Since 1.5.0
843-
843+
844+
### ignore-revision-mismatch
845+
846+
Cabal files in packages can be specified via exact revisions to deal
847+
with Hackage revision metadata. The default behavior of Stack (since
848+
1.6.0) is to fail if an exact match is not found. In some cases
849+
(specifically, when using a legacy `00-index.tar.gz` file), users may
850+
wish to allow a mismatch. In such cases, you can change
851+
`ignore-revision-mismatch` from `false` to `true`.
852+
853+
```yaml
854+
ignore-revision-mismatch: false
855+
```
856+
857+
For more information, see
858+
[the Github issue #3520 discussion](https://github.com/commercialhaskell/stack/issues/3520).
859+
860+
Since 1.6.0
861+
844862
# urls
845863

846864
Customize the URLs where `stack` looks for snapshot build plans.

src/Stack/Config.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ configFromConfigMonoid
373373
configDefaultTemplate = getFirst configMonoidDefaultTemplate
374374
configDumpLogs = fromFirst DumpWarningLogs configMonoidDumpLogs
375375
configSaveHackageCreds = fromFirst True configMonoidSaveHackageCreds
376+
configIgnoreRevisionMismatch = fromFirst False configMonoidIgnoreRevisionMismatch
376377

377378
configAllowDifferentUser <-
378379
case getFirst configMonoidAllowDifferentUser of

src/Stack/Fetch.hs

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ data FetchException
7272
| CouldNotParsePackageSelectors [String]
7373
| UnknownPackageNames (Set PackageName)
7474
| UnknownPackageIdentifiers (HashSet PackageIdentifierRevision) String
75+
Bool -- Do we use any 00-index.tar.gz indices? Just used for more informative error messages
7576
deriving Typeable
7677
instance Exception FetchException
7778

@@ -97,10 +98,11 @@ instance Show FetchException where
9798
show (UnknownPackageNames names) =
9899
"The following packages were not found in your indices: " ++
99100
intercalate ", " (map packageNameString $ Set.toList names)
100-
show (UnknownPackageIdentifiers idents suggestions) =
101+
show (UnknownPackageIdentifiers idents suggestions uses00Index) =
101102
"The following package identifiers were not found in your indices: " ++
102103
intercalate ", " (map packageIdentifierRevisionString $ HashSet.toList idents) ++
103-
(if null suggestions then "" else "\n" ++ suggestions)
104+
(if null suggestions then "" else "\n" ++ suggestions) ++
105+
(if uses00Index then "\n\nYou seem to be using a legacy 00-index.tar.gz tarball.\nConsider changing your configuration to use a 01-index.tar.gz file.\nAlternatively, you can set the ignore-revision-mismatch setting to true.\nFor more information, see: https://github.com/commercialhaskell/stack/issues/3520" else "")
104106

105107
-- | Fetch packages into the cache without unpacking
106108
fetchPackages :: HasConfig env => Set PackageIdentifier -> RIO env ()
@@ -202,12 +204,21 @@ resolvePackages mSnapshotDef idents0 names0 = do
202204
go >>= either throwM return
203205
Right x -> return x
204206
where
205-
go = r <$> resolvePackagesAllowMissing mSnapshotDef idents0 names0
206-
r (missingNames, missingIdents, idents)
207+
go = r <$> getUses00Index <*> resolvePackagesAllowMissing mSnapshotDef idents0 names0
208+
r uses00Index (missingNames, missingIdents, idents)
207209
| not $ Set.null missingNames = Left $ UnknownPackageNames missingNames
208-
| not $ HashSet.null missingIdents = Left $ UnknownPackageIdentifiers missingIdents ""
210+
| not $ HashSet.null missingIdents = Left $ UnknownPackageIdentifiers missingIdents "" uses00Index
209211
| otherwise = Right idents
210212

213+
-- | Does the configuration use a 00-index.tar.gz file for indices?
214+
-- See <https://github.com/commercialhaskell/stack/issues/3520>
215+
getUses00Index :: HasConfig env => RIO env Bool
216+
getUses00Index =
217+
any is00 <$> view packageIndicesL
218+
where
219+
is00 :: PackageIndex -> Bool
220+
is00 index = "00-index.tar.gz" `T.isInfixOf` indexLocation index
221+
211222
-- | Turn package identifiers and package names into a list of
212223
-- @ResolvedPackage@s. Returns any unresolved names and
213224
-- identifier. These are considered unresolved even if the only
@@ -256,23 +267,30 @@ resolvePackagesAllowMissing mSnapshotDef idents0 names0 = do
256267
(missingNames, idents1) = partitionEithers $ map
257268
(\name -> maybe (Left name) Right (getNamed name))
258269
(Set.toList names0)
270+
config <- view configL
259271
let (missingIdents, resolved) =
260272
partitionEithers
261-
$ map (\pir -> maybe (Left pir) Right (lookupResolvedPackage pir cache))
273+
$ map (\pir -> maybe (Left pir) Right (lookupResolvedPackage config pir cache))
262274
$ idents0 <> idents1
263275
return (Set.fromList missingNames, HashSet.fromList missingIdents, resolved)
264276

265-
lookupResolvedPackage :: PackageIdentifierRevision -> PackageCache PackageIndex -> Maybe ResolvedPackage
266-
lookupResolvedPackage (PackageIdentifierRevision ident@(PackageIdentifier name version) cfi) (PackageCache cache) = do
277+
lookupResolvedPackage :: Config -> PackageIdentifierRevision -> PackageCache PackageIndex -> Maybe ResolvedPackage
278+
lookupResolvedPackage config (PackageIdentifierRevision ident@(PackageIdentifier name version) cfi) (PackageCache cache) = do
267279
(index, mdownload, files) <- HashMap.lookup name cache >>= HashMap.lookup version
280+
let moffsetSize =
281+
case cfi of
282+
CFILatest -> Just $ snd $ NE.last files
283+
CFIHash _msize hash' -> -- TODO check size?
284+
lookup hash'
285+
$ concatMap (\(hashes, x) -> map (, x) hashes)
286+
$ NE.toList files
287+
CFIRevision rev -> fmap snd $ listToMaybe $ drop (fromIntegral rev) $ NE.toList files
268288
offsetSize <-
269-
case cfi of
270-
CFILatest -> Just $ snd $ NE.last files
271-
CFIHash _msize hash' -> -- TODO check size?
272-
lookup hash'
273-
$ concatMap (\(hashes, x) -> map (, x) hashes)
274-
$ NE.toList files
275-
CFIRevision rev -> fmap snd $ listToMaybe $ drop (fromIntegral rev) $ NE.toList files
289+
case moffsetSize of
290+
Just x -> Just x
291+
Nothing
292+
| configIgnoreRevisionMismatch config -> Just $ snd $ NE.last files
293+
| otherwise -> Nothing
276294
Just ResolvedPackage
277295
{ rpIdent = ident
278296
, rpDownload = mdownload
@@ -365,9 +383,10 @@ withCabalLoader inner = do
365383
_ <- getPackageCaches
366384
return ()
367385
return (False, doLookup ident)
368-
else return (toUpdate,
369-
throwIO $ UnknownPackageIdentifiers
370-
(HashSet.singleton ident) (T.unpack suggestions))
386+
else do
387+
uses00Index <- unliftIO u getUses00Index
388+
return (toUpdate, throwIO $ UnknownPackageIdentifiers
389+
(HashSet.singleton ident) (T.unpack suggestions) uses00Index)
371390
inner doLookup
372391

373392
lookupPackageIdentifierExact
@@ -376,7 +395,8 @@ lookupPackageIdentifierExact
376395
-> PackageCache PackageIndex
377396
-> m (Maybe ByteString)
378397
lookupPackageIdentifierExact identRev cache = do
379-
forM (lookupResolvedPackage identRev cache) $ \rp -> do
398+
config <- view configL
399+
forM (lookupResolvedPackage config identRev cache) $ \rp -> do
380400
[bs] <- withCabalFiles (indexName (rpIndex rp)) [(rp, ())] $ \_ _ bs -> return bs
381401
return bs
382402

src/Stack/Types/Config.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,10 @@ data Config =
358358
,configSaveHackageCreds :: !Bool
359359
-- ^ Should we save Hackage credentials to a file?
360360
,configRunner :: !Runner
361+
,configIgnoreRevisionMismatch :: !Bool
362+
-- ^ Ignore a revision mismatch when loading up cabal files,
363+
-- and fall back to the latest revision. See:
364+
-- <https://github.com/commercialhaskell/stack/issues/3520>
361365
}
362366

363367
data HpackExecutable
@@ -758,6 +762,8 @@ data ConfigMonoid =
758762
-- ^ See 'configDumpLogs'
759763
, configMonoidSaveHackageCreds :: !(First Bool)
760764
-- ^ See 'configSaveHackageCreds'
765+
, configMonoidIgnoreRevisionMismatch :: !(First Bool)
766+
-- ^ See 'configIgnoreRevisionMismatch'
761767
}
762768
deriving (Show, Generic)
763769

@@ -850,6 +856,7 @@ parseConfigMonoidObject rootDir obj = do
850856
configMonoidAllowDifferentUser <- First <$> obj ..:? configMonoidAllowDifferentUserName
851857
configMonoidDumpLogs <- First <$> obj ..:? configMonoidDumpLogsName
852858
configMonoidSaveHackageCreds <- First <$> obj ..:? configMonoidSaveHackageCredsName
859+
configMonoidIgnoreRevisionMismatch <- First <$> obj ..:? configMonoidIgnoreRevisionMismatchName
853860

854861
return ConfigMonoid {..}
855862
where
@@ -989,6 +996,9 @@ configMonoidDumpLogsName = "dump-logs"
989996
configMonoidSaveHackageCredsName :: Text
990997
configMonoidSaveHackageCredsName = "save-hackage-creds"
991998

999+
configMonoidIgnoreRevisionMismatchName :: Text
1000+
configMonoidIgnoreRevisionMismatchName = "ignore-revision-mismatch"
1001+
9921002
data ConfigException
9931003
= ParseConfigFileException (Path Abs File) ParseException
9941004
| ParseCustomSnapshotException Text ParseException
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import StackTest
2+
import Control.Monad
3+
import Data.List
4+
import System.Directory
5+
6+
main :: IO ()
7+
main = do
8+
copyFile "bad-stack.yaml" "stack.yaml"
9+
stackErrStderr ["build", "--dry-run"] $ \msg ->
10+
unless ("legacy 00-index.tar.gz" `isInfixOf` msg) $
11+
error "Expected a warning about 00-index usage"
12+
copyFile "good-stack.yaml" "stack.yaml"
13+
stack ["build", "--dry-run"]
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
stack.yaml
2+
*.cabal
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
resolver: lts-9.10
2+
3+
package-indices:
4+
- name: Hackage00
5+
download-prefix: https://hackage.haskell.org/package
6+
http: https://hackage.haskell.org/00-index.tar.gz
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
resolver: lts-9.10
2+
3+
package-indices:
4+
- name: Hackage00
5+
download-prefix: https://hackage.haskell.org/package
6+
http: https://hackage.haskell.org/00-index.tar.gz
7+
8+
ignore-revision-mismatch: true
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name: issue3520
2+
version: 0.1.0.0
3+
4+
dependencies:
5+
- base
6+
- mtl
7+
8+
library:
9+
source-dirs: src

0 commit comments

Comments
 (0)