@@ -50,6 +50,7 @@ import qualified Data.ByteString.Char8 as S8
5050import qualified Data.ByteString.Lazy as LBS
5151import Data.Foldable (forM_ )
5252import Data.Map (Map )
53+ import qualified Data.Map as M
5354import Data.Maybe (fromMaybe , mapMaybe )
5455import Data.Monoid ((<>) )
5556import Data.Set (Set )
@@ -83,16 +84,29 @@ getInstalledExes :: (MonadReader env m, HasEnvConfig env, MonadIO m, MonadThrow
8384getInstalledExes loc = do
8485 dir <- exeInstalledDir loc
8586 (_, files) <- liftIO $ handleIO (const $ return ([] , [] )) $ listDir dir
86- return $ mapMaybe (parsePackageIdentifierFromString . toFilePath . filename) files
87+ return $
88+ concat $
89+ M. elems $
90+ -- If there are multiple install records (from a stack version
91+ -- before https://github.com/commercialhaskell/stack/issues/2373
92+ -- was fixed), then we don't know which is correct - ignore them.
93+ M. fromListWith (\ _ _ -> [] ) $
94+ map (\ x -> (packageIdentifierName x, [x])) $
95+ mapMaybe (parsePackageIdentifierFromString . toFilePath . filename) files
8796
8897-- | Mark the given executable as installed
89- markExeInstalled :: (MonadReader env m , HasEnvConfig env , MonadIO m , MonadThrow m )
98+ markExeInstalled :: (MonadReader env m , HasEnvConfig env , MonadIO m , MonadCatch m )
9099 => InstallLocation -> PackageIdentifier -> m ()
91100markExeInstalled loc ident = do
92101 dir <- exeInstalledDir loc
93102 ensureDir dir
94103 ident' <- parseRelFile $ packageIdentifierString ident
95104 let fp = toFilePath $ dir </> ident'
105+ -- Remove old install records for this package.
106+ -- TODO: This is a bit in-efficient. Put all this metadata into one file?
107+ installed <- getInstalledExes loc
108+ forM_ (filter (\ x -> packageIdentifierName ident == packageIdentifierName x) installed)
109+ (markExeNotInstalled loc)
96110 -- TODO consideration for the future: list all of the executables
97111 -- installed, and invalidate this file in getInstalledExes if they no
98112 -- longer exist
0 commit comments